00024976c9d45955be657e5700ebca8c4956604e
[citadel.git] / webcit / serv_func.c
1 /*
2  * $Id$
3  */
4 /**
5  * \defgroup ServFuncs Handles various types of data transfer operations with the Citadel service.
6  *
7  */
8
9 /*@{*/ 
10 #include "webcit.h"
11 #include "webserver.h"
12
13 struct serv_info serv_info; /**< our connection data to the server */
14
15 /**
16  * \brief get info about the server we've connected to
17  * \param browser_host the citadell we want to connect to
18  * \param user_agent which browser uses our client?
19  */
20 void get_serv_info(char *browser_host, char *user_agent)
21 {
22         char buf[SIZ];
23         int a;
24
25         /** Tell the server what kind of client is connecting */
26         serv_printf("IDEN %d|%d|%d|%s|%s",
27                 DEVELOPER_ID,
28                 CLIENT_ID,
29                 CLIENT_VERSION,
30                 user_agent,
31                 browser_host
32         );
33         serv_getln(buf, sizeof buf);
34
35         /** Tell the server what kind of richtext we prefer */
36         serv_puts("MSGP text/html|text/plain");
37         serv_getln(buf, sizeof buf);
38
39 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
40         /**
41          * Tell the server that when we save a calendar event, we
42          * want invitations to be generated by the Citadel server
43          * instead of by the client.
44          */
45         serv_puts("ICAL sgi|1");
46         serv_getln(buf, sizeof buf);
47 #endif
48
49         /** Now ask the server to tell us a little bit about itself... */
50         serv_puts("INFO");
51         serv_getln(buf, sizeof buf);
52         if (buf[0] != '1')
53                 return;
54
55         a = 0;
56         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
57                 switch (a) {
58                 case 0:
59                         serv_info.serv_pid = atoi(buf);
60                         WC->ctdl_pid = serv_info.serv_pid;
61                         break;
62                 case 1:
63                         safestrncpy(serv_info.serv_nodename, buf, sizeof serv_info.serv_nodename);
64                         break;
65                 case 2:
66                         safestrncpy(serv_info.serv_humannode, buf, sizeof serv_info.serv_humannode);
67                         break;
68                 case 3:
69                         safestrncpy(serv_info.serv_fqdn, buf, sizeof serv_info.serv_fqdn);
70                         break;
71                 case 4:
72                         safestrncpy(serv_info.serv_software, buf, sizeof serv_info.serv_software);
73                         break;
74                 case 5:
75                         serv_info.serv_rev_level = atoi(buf);
76                         break;
77                 case 6:
78                         safestrncpy(serv_info.serv_bbs_city, buf, sizeof serv_info.serv_bbs_city);
79                         break;
80                 case 7:
81                         safestrncpy(serv_info.serv_sysadm, buf, sizeof serv_info.serv_sysadm);
82                         break;
83                 case 9:
84                         safestrncpy(serv_info.serv_moreprompt, buf, sizeof serv_info.serv_moreprompt);
85                         break;
86                 case 14:
87                         serv_info.serv_supports_ldap = atoi(buf);
88                         break;
89                 }
90                 ++a;
91         }
92 }
93
94
95
96 /**
97  * \brief Read Citadel variformat text and spit it out as HTML.
98  * \param align html align string
99  */
100 void fmout(char *align)
101 {
102         int intext = 0;
103         int bq = 0;
104         char buf[SIZ];
105
106         wprintf("<div align=%s>\n", align);
107         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
108
109                 if ((intext == 1) && (isspace(buf[0]))) {
110                         wprintf("<br />");
111                 }
112                 intext = 1;
113
114                 /**
115                  * Quoted text should be displayed in italics and in a
116                  * different colour.  This code understands Citadel-style
117                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
118                  */
119                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
120                         wprintf("<BLOCKQUOTE>");
121                         bq = 1;
122                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
123                         wprintf("</BLOCKQUOTE>");
124                         bq = 0;
125                 }
126                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
127                         strcpy(buf, &buf[2]);
128                 }
129                 /** Activate embedded URL's */
130                 url(buf);
131
132                 escputs(buf);
133                 wprintf("\n");
134         }
135         if (bq == 1) {
136                 wprintf("</I>");
137         }
138         wprintf("</div><br />\n");
139 }
140
141
142
143
144 /**
145  * \brief Read Citadel variformat text and spit it out as HTML in a form
146  * suitable for embedding in another message (forward/quote).
147  * (NO LINEBREAKS ALLOWED HERE!)
148  */
149 void pullquote_fmout(void) {
150         int intext = 0;
151         int bq = 0;
152         char buf[SIZ];
153
154         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
155
156                 if ((intext == 1) && (isspace(buf[0]))) {
157                         wprintf("<br />");
158                 }
159                 intext = 1;
160
161                 /**
162                  * Quoted text should be displayed in italics and in a
163                  * different colour.  This code understands Citadel-style
164                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
165                  */
166                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
167                         wprintf("<BLOCKQUOTE>");
168                         bq = 1;
169                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
170                         wprintf("</BLOCKQUOTE>");
171                         bq = 0;
172                 }
173                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
174                         strcpy(buf, &buf[2]);
175                 }
176
177                 msgescputs(buf);
178         }
179         if (bq == 1) {
180                 wprintf("</I>");
181         }
182 }
183
184
185
186
187 /**
188  * \brief Transmit message text (in memory) to the server.
189  * \param ptr the output buffer
190  * \param convert_to_html if set to 1, the message is converted into something
191  * which kind of resembles HTML.
192  */
193 void text_to_server(char *ptr, int convert_to_html)
194 {
195         char buf[SIZ];
196         char conv[4];
197         int ch, a, pos;
198
199         pos = 0;
200         buf[0] = 0;
201
202         while (ptr[pos] != 0) {
203                 ch = ptr[pos++];
204                 if (ch == 10) {
205                         while ( (isspace(buf[strlen(buf) - 1]))
206                           && (strlen(buf) > 1) )
207                                 buf[strlen(buf) - 1] = 0;
208                         serv_puts(buf);
209                         buf[0] = 0;
210                         if (convert_to_html) {
211                                 strcat(buf, "<br />");
212                         }
213                         else {
214                                 if (ptr[pos] != 0) strcat(buf, " ");
215                         }
216                 } else if ((convert_to_html)&&(strchr("#&;`'|*?-~<>^()[]{}$\\", ch) != NULL)) {
217                         sprintf(conv, "%c", ch);
218                         stresc(&buf[strlen(buf)], conv, 0, 0);
219                 } else {
220                         a = strlen(buf);
221                         buf[a + 1] = 0;
222                         buf[a] = ch;
223                         if ((ch == 32) && (strlen(buf) > 200)) {
224                                 buf[a] = 0;
225                                 serv_puts(buf);
226                                 buf[0] = 0;
227                         }
228                         if (strlen(buf) > 250) {
229                                 serv_puts(buf);
230                                 buf[0] = 0;
231                         }
232                 }
233         }
234         serv_puts(buf);
235
236 }
237
238
239
240 /**
241  * \brief translate server message output to text
242  * (used for editing room info files and such)
243  */
244 void server_to_text()
245 {
246         char buf[SIZ];
247
248         int count = 0;
249
250         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
251                 if ((buf[0] == 32) && (count > 0)) {
252                         wprintf("\n");
253                 }
254                 wprintf("%s", buf);
255                 ++count;
256         }
257 }
258
259
260
261 /**
262  * Read binary data from server into memory using a series of
263  * server READ commands.
264  * \param buffer the output buffer
265  * \param total_len the maximal length of buffer
266  */
267 void read_server_binary(char *buffer, size_t total_len) {
268         char buf[SIZ];
269         size_t bytes = 0;
270         size_t thisblock = 0;
271
272         memset(buffer, 0, total_len);
273         while (bytes < total_len) {
274                 thisblock = 4095;
275                 if ((total_len - bytes) < thisblock) {
276                         thisblock = total_len - bytes;
277                         if (thisblock == 0) return;
278                 }
279                 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
280                 serv_getln(buf, sizeof buf);
281                 if (buf[0] == '6') {
282                         thisblock = (size_t)atoi(&buf[4]);
283                         if (!WC->connected) return;
284                         serv_read(&buffer[bytes], thisblock);
285                         bytes += thisblock;
286                 }
287                 else {
288                         lprintf(3, "Error: %s\n", &buf[4]);
289                         return;
290                 }
291         }
292 }
293
294
295 /**
296  * \brief Read text from server, appending to a string buffer until the
297  * usual 000 terminator is found.  Caller is responsible for freeing
298  * the returned pointer.
299  */
300 char *read_server_text(void) {
301         char *text = NULL;
302         size_t bytes_allocated = 0;
303         size_t bytes_read = 0;
304         int linelen;
305         char buf[SIZ];
306
307         text = malloc(SIZ);
308         if (text == NULL) {
309                 return(NULL);
310         }
311         text[0] = 0;
312         bytes_allocated = SIZ;
313
314         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
315                 linelen = strlen(buf);
316                 buf[linelen] = '\n';
317                 buf[linelen+1] = 0;
318                 ++linelen;
319
320                 if ((bytes_read + linelen) >= (bytes_allocated - 2)) {
321                         bytes_allocated = 2 * bytes_allocated;
322                         text = realloc(text, bytes_allocated);
323                 }
324
325                 strcpy(&text[bytes_read], buf);
326                 bytes_read += linelen;
327         }
328
329         return(text);
330 }
331
332
333
334 /*@}*/