0ce784cf057b4e6f1aaa37f5415eae252fbf89de
[citadel.git] / webcit / serv_func.c
1 /*
2  * $Id$
3  */
4
5 #include "webcit.h"
6 #include "webserver.h"
7
8 struct serv_info serv_info; /**< our connection data to the server */
9
10 /*
11  * get info about the server we've connected to
12  *
13  * browser_host         the citadell we want to connect to
14  * user_agent           which browser uses our client?
15  */
16 void get_serv_info(char *browser_host, char *user_agent)
17 {
18         char buf[SIZ];
19         int a;
20
21         /** Tell the server what kind of client is connecting */
22         serv_printf("IDEN %d|%d|%d|%s|%s",
23                 DEVELOPER_ID,
24                 CLIENT_ID,
25                 CLIENT_VERSION,
26                 user_agent,
27                 browser_host
28         );
29         serv_getln(buf, sizeof buf);
30
31         /** Tell the server what kind of richtext we prefer */
32         serv_puts("MSGP text/html|text/plain");
33         serv_getln(buf, sizeof buf);
34
35 #ifdef WEBCIT_WITH_CALENDAR_SERVICE
36         /**
37          * Tell the server that when we save a calendar event, we
38          * want invitations to be generated by the Citadel server
39          * instead of by the client.
40          */
41         serv_puts("ICAL sgi|1");
42         serv_getln(buf, sizeof buf);
43 #endif
44
45         /** Now ask the server to tell us a little bit about itself... */
46         serv_puts("INFO");
47         serv_getln(buf, sizeof buf);
48         if (buf[0] != '1')
49                 return;
50
51         a = 0;
52         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
53                 switch (a) {
54                 case 0:
55                         serv_info.serv_pid = atoi(buf);
56                         WC->ctdl_pid = serv_info.serv_pid;
57                         break;
58                 case 1:
59                         safestrncpy(serv_info.serv_nodename, buf, sizeof serv_info.serv_nodename);
60                         break;
61                 case 2:
62                         safestrncpy(serv_info.serv_humannode, buf, sizeof serv_info.serv_humannode);
63                         break;
64                 case 3:
65                         safestrncpy(serv_info.serv_fqdn, buf, sizeof serv_info.serv_fqdn);
66                         break;
67                 case 4:
68                         safestrncpy(serv_info.serv_software, buf, sizeof serv_info.serv_software);
69                         break;
70                 case 5:
71                         serv_info.serv_rev_level = atoi(buf);
72                         break;
73                 case 6:
74                         safestrncpy(serv_info.serv_bbs_city, buf, sizeof serv_info.serv_bbs_city);
75                         break;
76                 case 7:
77                         safestrncpy(serv_info.serv_sysadm, buf, sizeof serv_info.serv_sysadm);
78                         break;
79                 case 9:
80                         safestrncpy(serv_info.serv_moreprompt, buf, sizeof serv_info.serv_moreprompt);
81                         break;
82                 case 14:
83                         serv_info.serv_supports_ldap = atoi(buf);
84                         break;
85                 case 15:
86                         serv_info.serv_newuser_disabled = atoi(buf);
87                         break;
88                 case 16:
89                         safestrncpy(serv_info.serv_default_cal_zone, buf, sizeof serv_info.serv_default_cal_zone);
90                         break;
91                 case 20:
92                         serv_info.serv_supports_sieve = atoi(buf);
93                         break;
94                 case 21:
95                         serv_info.serv_fulltext_enabled = atoi(buf);
96                         break;
97                 }
98                 ++a;
99         }
100 }
101
102
103
104 /**
105  * \brief Read Citadel variformat text and spit it out as HTML.
106  * \param align html align string
107  */
108 void fmout(char *align)
109 {
110         int intext = 0;
111         int bq = 0;
112         char buf[SIZ];
113
114         wprintf("<div align=%s>\n", align);
115         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
116
117                 if ((intext == 1) && (isspace(buf[0]))) {
118                         wprintf("<br />");
119                 }
120                 intext = 1;
121
122                 /**
123                  * Quoted text should be displayed in italics and in a
124                  * different colour.  This code understands Citadel-style
125                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
126                  */
127                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
128                         wprintf("<BLOCKQUOTE>");
129                         bq = 1;
130                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
131                         wprintf("</BLOCKQUOTE>");
132                         bq = 0;
133                 }
134                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
135                         strcpy(buf, &buf[2]);
136                 }
137                 /** Activate embedded URL's */
138                 url(buf);
139
140                 escputs(buf);
141                 wprintf("\n");
142         }
143         if (bq == 1) {
144                 wprintf("</I>");
145         }
146         wprintf("</div><br />\n");
147 }
148
149
150
151
152 /**
153  * \brief Read Citadel variformat text and spit it out as HTML in a form
154  * suitable for embedding in another message (forward/quote).
155  * (NO LINEBREAKS ALLOWED HERE!)
156  */
157 void pullquote_fmout(void) {
158         int intext = 0;
159         int bq = 0;
160         char buf[SIZ];
161
162         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
163
164                 if ((intext == 1) && (isspace(buf[0]))) {
165                         wprintf("<br />");
166                 }
167                 intext = 1;
168
169                 /**
170                  * Quoted text should be displayed in italics and in a
171                  * different colour.  This code understands Citadel-style
172                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
173                  */
174                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
175                         wprintf("<BLOCKQUOTE>");
176                         bq = 1;
177                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
178                         wprintf("</BLOCKQUOTE>");
179                         bq = 0;
180                 }
181                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
182                         strcpy(buf, &buf[2]);
183                 }
184
185                 msgescputs(buf);
186         }
187         if (bq == 1) {
188                 wprintf("</I>");
189         }
190 }
191
192
193
194
195 /**
196  * \brief Transmit message text (in memory) to the server.
197  *
198  * \param ptr Pointer to the message being transmitted
199  */
200 void text_to_server(char *ptr)
201 {
202         char buf[256];
203         int ch, a, pos, len;
204
205         pos = 0;
206         buf[0] = 0;
207
208         while (ptr[pos] != 0) {
209                 ch = ptr[pos++];
210                 if (ch == 10) {
211                         len = strlen(buf);
212                         while ( (isspace(buf[len - 1]))
213                                 && (buf[0] !=  '\0') 
214                                 && (buf[1] !=  '\0') )
215                                 buf[--len] = 0;
216                         serv_puts(buf);
217                         buf[0] = 0;
218                         if (ptr[pos] != 0) strcat(buf, " ");
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  * \brief Transmit message text (in memory) to the server,
240  *        converting to Quoted-Printable encoding as we go.
241  *
242  * \param ptr Pointer to the message being transmitted
243  */
244 void text_to_server_qp(char *ptr)
245 {
246         unsigned char ch, buf[256];
247         int pos;
248         int output_len = 0;
249
250         pos = 0;
251         buf[0] = 0;
252         output_len = 0;
253
254         while (ptr[pos] != 0) {
255                 ch = (unsigned char)(ptr[pos++]);
256
257                 if (ch == 13) {
258                         /* ignore carriage returns */
259                 }
260                 else if (ch == 10) {
261                         /* hard line break */
262                         if (output_len > 0) {
263                                 if (isspace(buf[output_len-1])) {
264                                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
265                                         output_len += 2;
266                                 }
267                         }
268                         buf[output_len++] = 0;
269                         serv_puts((char *)buf);
270                         output_len = 0;
271                 }
272                 else if (ch == 9) {
273                         buf[output_len++] = ch;
274                 }
275                 else if ( (ch >= 32) && (ch <= 60) ) {
276                         buf[output_len++] = ch;
277                 }
278                 else if ( (ch >= 62) && (ch <= 126) ) {
279                         buf[output_len++] = ch;
280                 }
281                 else {
282                         sprintf((char *)&buf[output_len], "=%02X", ch);
283                         output_len += 3;
284                 }
285                 
286                 if (output_len > 72) {
287                         /* soft line break */
288                         if (isspace(buf[output_len-1])) {
289                                 sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
290                                 output_len += 2;
291                         }
292                         buf[output_len++] = '=';
293                         buf[output_len++] = 0;
294                         serv_puts((char *)buf);
295                         output_len = 0;
296                 }
297         }
298
299         /* end of data - transmit anything that's left */
300         if (output_len > 0) {
301                 if (isspace(buf[output_len-1])) {
302                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
303                         output_len += 2;
304                 }
305                 buf[output_len++] = 0;
306                 serv_puts((char *)buf);
307                 output_len = 0;
308         }
309 }
310
311
312
313
314 /**
315  * \brief translate server message output to text
316  * (used for editing room info files and such)
317  */
318 void server_to_text()
319 {
320         char buf[SIZ];
321
322         int count = 0;
323
324         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
325                 if ((buf[0] == 32) && (count > 0)) {
326                         wprintf("\n");
327                 }
328                 wprintf("%s", buf);
329                 ++count;
330         }
331 }
332
333
334
335 /**
336  * Read binary data from server into memory using a series of
337  * server READ commands.
338  * \param buffer the output buffer
339  * \param total_len the maximal length of buffer
340  */
341 void read_server_binary(char *buffer, size_t total_len) {
342         char buf[SIZ];
343         size_t bytes = 0;
344         size_t thisblock = 0;
345
346         memset(buffer, 0, total_len);
347         while (bytes < total_len) {
348                 thisblock = 4095;
349                 if ((total_len - bytes) < thisblock) {
350                         thisblock = total_len - bytes;
351                         if (thisblock == 0) return;
352                 }
353                 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
354                 serv_getln(buf, sizeof buf);
355                 if (buf[0] == '6') {
356                         thisblock = (size_t)atoi(&buf[4]);
357                         if (!WC->connected) return;
358                         serv_read(&buffer[bytes], thisblock);
359                         bytes += thisblock;
360                 }
361                 else {
362                         lprintf(3, "Error: %s\n", &buf[4]);
363                         return;
364                 }
365         }
366 }
367
368
369 /**
370  * \brief Read text from server, appending to a string buffer until the
371  * usual 000 terminator is found.  Caller is responsible for freeing
372  * the returned pointer.
373  */
374 char *read_server_text(void) {
375         char *text = NULL;
376         size_t bytes_allocated = 0;
377         size_t bytes_read = 0;
378         int linelen;
379         char buf[SIZ];
380
381         text = malloc(SIZ);
382         if (text == NULL) {
383                 return(NULL);
384         }
385         text[0] = 0;
386         bytes_allocated = SIZ;
387
388         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
389                 linelen = strlen(buf);
390                 buf[linelen] = '\n';
391                 buf[linelen+1] = 0;
392                 ++linelen;
393
394                 if ((bytes_read + linelen) >= (bytes_allocated - 2)) {
395                         bytes_allocated = 2 * bytes_allocated;
396                         text = realloc(text, bytes_allocated);
397                 }
398
399                 strcpy(&text[bytes_read], buf);
400                 bytes_read += linelen;
401         }
402
403         return(text);
404 }
405
406
407
408 /*@}*/