Cleaned up some of the comments ... removed vestiges of last year's doxygen experiment
[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 HashList *ServHash = NULL;//// TODO;
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         /*
36          * Tell the server that when we save a calendar event, we
37          * want invitations to be generated by the Citadel server
38          * instead of by the client.
39          */
40         serv_puts("ICAL sgi|1");
41         serv_getln(buf, sizeof buf);
42
43         /** Now ask the server to tell us a little bit about itself... */
44         serv_puts("INFO");
45         serv_getln(buf, sizeof buf);
46         if (buf[0] != '1')
47                 return;
48
49         a = 0;
50         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
51                 switch (a) {
52                 case 0:
53                         serv_info.serv_pid = atoi(buf);
54                         WC->ctdl_pid = serv_info.serv_pid;
55                         break;
56                 case 1:
57                         safestrncpy(serv_info.serv_nodename, buf, sizeof serv_info.serv_nodename);
58                         break;
59                 case 2:
60                         safestrncpy(serv_info.serv_humannode, buf, sizeof serv_info.serv_humannode);
61                         break;
62                 case 3:
63                         safestrncpy(serv_info.serv_fqdn, buf, sizeof serv_info.serv_fqdn);
64                         break;
65                 case 4:
66                         safestrncpy(serv_info.serv_software, buf, sizeof serv_info.serv_software);
67                         break;
68                 case 5:
69                         serv_info.serv_rev_level = atoi(buf);
70                         break;
71                 case 6:
72                         safestrncpy(serv_info.serv_bbs_city, buf, sizeof serv_info.serv_bbs_city);
73                         break;
74                 case 7:
75                         safestrncpy(serv_info.serv_sysadm, buf, sizeof serv_info.serv_sysadm);
76                         break;
77                 case 9:
78                         safestrncpy(serv_info.serv_moreprompt, buf, sizeof serv_info.serv_moreprompt);
79                         break;
80                 case 14:
81                         serv_info.serv_supports_ldap = atoi(buf);
82                         break;
83                 case 15:
84                         serv_info.serv_newuser_disabled = atoi(buf);
85                         break;
86                 case 16:
87                         safestrncpy(serv_info.serv_default_cal_zone, buf, sizeof serv_info.serv_default_cal_zone);
88                         break;
89                 case 20:
90                         serv_info.serv_supports_sieve = atoi(buf);
91                         break;
92                 case 21:
93                         serv_info.serv_fulltext_enabled = atoi(buf);
94                         break;
95                 case 22:
96                         safestrncpy(serv_info.serv_svn_revision, buf, sizeof serv_info.serv_svn_revision);
97                         break;
98                 case 23:
99                         serv_info.serv_supports_openid = atoi(buf);
100                         break;
101                 }
102                 ++a;
103         }
104 }
105
106
107
108 /**
109  *  Read Citadel variformat text and spit it out as HTML.
110  *  align html align string
111  */
112 inline void fmout(char *align)
113 {
114         _fmout(WC->WBuf, align);
115 }
116
117 void _fmout(StrBuf *Target, char *align)
118 {
119         int intext = 0;
120         int bq = 0;
121         char buf[SIZ];
122
123         StrBufAppendPrintf(Target, "<div align=%s>\n", align);
124         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
125
126                 if ((intext == 1) && (isspace(buf[0]))) {
127                         wprintf("<br />");
128                 }
129                 intext = 1;
130
131                 /**
132                  * Quoted text should be displayed in italics and in a
133                  * different colour.  This code understands Citadel-style
134                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
135                  */
136                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
137                         StrBufAppendBufPlain(Target, HKEY("<BLOCKQUOTE>"), 0);
138                         bq = 1;
139                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
140                         StrBufAppendBufPlain(Target, HKEY("</BLOCKQUOTE>"), 0);
141                         bq = 0;
142                 }
143                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
144                         strcpy(buf, &buf[2]);
145                 }
146                 /** Activate embedded URL's */
147                 url(buf, sizeof(buf));
148
149                 escputs(buf);//// TODO: Target
150                 StrBufAppendBufPlain(Target, HKEY("\n"), 0);
151         }
152         if (bq == 1) {
153                 wprintf("</I>");
154         }
155         wprintf("</div><br />\n");
156 }
157
158
159
160
161 /**
162  *  Read Citadel variformat text and spit it out as HTML in a form
163  * suitable for embedding in another message (forward/quote).
164  * (NO LINEBREAKS ALLOWED HERE!)
165  */
166 void pullquote_fmout(void) {
167         int intext = 0;
168         int bq = 0;
169         char buf[SIZ];
170
171         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
172
173                 if ((intext == 1) && (isspace(buf[0]))) {
174                         wprintf("<br />");
175                 }
176                 intext = 1;
177
178                 /**
179                  * Quoted text should be displayed in italics and in a
180                  * different colour.  This code understands Citadel-style
181                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
182                  */
183                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
184                         wprintf("<BLOCKQUOTE>");
185                         bq = 1;
186                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
187                         wprintf("</BLOCKQUOTE>");
188                         bq = 0;
189                 }
190                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
191                         strcpy(buf, &buf[2]);
192                 }
193
194                 msgescputs(buf);
195         }
196         if (bq == 1) {
197                 wprintf("</I>");
198         }
199 }
200
201
202
203
204 /**
205  *  Transmit message text (in memory) to the server.
206  *
207  *  ptr Pointer to the message being transmitted
208  */
209 void text_to_server(char *ptr)
210 {
211         char buf[256];
212         int ch, a, pos, len;
213
214         pos = 0;
215         buf[0] = 0;
216
217         while (ptr[pos] != 0) {
218                 ch = ptr[pos++];
219                 if (ch == 10) {
220                         len = strlen(buf);
221                         while ( (isspace(buf[len - 1]))
222                                 && (buf[0] !=  '\0') 
223                                 && (buf[1] !=  '\0') )
224                                 buf[--len] = 0;
225                         serv_puts(buf);
226                         buf[0] = 0;
227                         if (ptr[pos] != 0) strcat(buf, " ");
228                 } else {
229                         a = strlen(buf);
230                         buf[a + 1] = 0;
231                         buf[a] = ch;
232                         if ((ch == 32) && (strlen(buf) > 200)) {
233                                 buf[a] = 0;
234                                 serv_puts(buf);
235                                 buf[0] = 0;
236                         }
237                         if (strlen(buf) > 250) {
238                                 serv_puts(buf);
239                                 buf[0] = 0;
240                         }
241                 }
242         }
243         serv_puts(buf);
244 }
245
246
247 /**
248  *  Transmit message text (in memory) to the server,
249  *        converting to Quoted-Printable encoding as we go.
250  *
251  *  ptr Pointer to the message being transmitted
252  */
253 void text_to_server_qp(char *ptr)
254 {
255         unsigned char ch, buf[256];
256         int pos;
257         int output_len = 0;
258
259         pos = 0;
260         buf[0] = 0;
261         output_len = 0;
262
263         while (ptr[pos] != 0) {
264                 ch = (unsigned char)(ptr[pos++]);
265
266                 if (ch == 13) {
267                         /* ignore carriage returns */
268                 }
269                 else if (ch == 10) {
270                         /* hard line break */
271                         if (output_len > 0) {
272                                 if (isspace(buf[output_len-1])) {
273                                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
274                                         output_len += 2;
275                                 }
276                         }
277                         buf[output_len++] = 0;
278                         serv_puts((char *)buf);
279                         output_len = 0;
280                 }
281                 else if (ch == 9) {
282                         buf[output_len++] = ch;
283                 }
284                 else if ( (ch >= 32) && (ch <= 60) ) {
285                         buf[output_len++] = ch;
286                 }
287                 else if ( (ch >= 62) && (ch <= 126) ) {
288                         buf[output_len++] = ch;
289                 }
290                 else {
291                         sprintf((char *)&buf[output_len], "=%02X", ch);
292                         output_len += 3;
293                 }
294                 
295                 if (output_len > 72) {
296                         /* soft line break */
297                         if (isspace(buf[output_len-1])) {
298                                 sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
299                                 output_len += 2;
300                         }
301                         buf[output_len++] = '=';
302                         buf[output_len++] = 0;
303                         serv_puts((char *)buf);
304                         output_len = 0;
305                 }
306         }
307
308         /* end of data - transmit anything that's left */
309         if (output_len > 0) {
310                 if (isspace(buf[output_len-1])) {
311                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
312                         output_len += 2;
313                 }
314                 buf[output_len++] = 0;
315                 serv_puts((char *)buf);
316                 output_len = 0;
317         }
318 }
319
320
321
322
323 /**
324  *  translate server message output to text
325  * (used for editing room info files and such)
326  */
327 void server_to_text()
328 {
329         char buf[SIZ];
330
331         int count = 0;
332
333         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
334                 if ((buf[0] == 32) && (count > 0)) {
335                         wprintf("\n");
336                 }
337                 wprintf("%s", buf);
338                 ++count;
339         }
340 }
341
342
343
344 /**
345  * Read binary data from server into memory using a series of
346  * server READ commands.
347  * \return the read content as StrBuf
348  */
349 int read_server_binary(StrBuf *Ret, size_t total_len) 
350 {
351         char buf[SIZ];
352         size_t bytes = 0;
353         size_t thisblock = 0;
354         StrBuf *Buf;
355         
356         Buf = NewStrBuf();
357         if (Ret == NULL)
358             return -1;
359
360         while (bytes < total_len) {
361                 thisblock = 4095;
362                 if ((total_len - bytes) < thisblock) {
363                         thisblock = total_len - bytes;
364                         if (thisblock == 0) {
365                                 FlushStrBuf(Ret); 
366                                 FreeStrBuf(&Buf);
367                                 return -1; 
368                         }
369                 }
370                 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
371                 if (StrBuf_ServGetln(Buf) > 0)
372                 {
373                     if (ChrPtr(Buf)[0] == '6')
374                     {
375                             StrBufCutLeft(Buf, 4); //thisblock = (size_t)atoi(&buf[4]);
376                             thisblock = StrTol(Buf);
377                             if (!WC->connected) {
378                                     FlushStrBuf(Ret); 
379                                     FreeStrBuf(&Buf); 
380                                     return -1; 
381                             }
382                             StrBuf_ServGetBLOB(Ret, thisblock);
383                             bytes += thisblock;
384                     }
385                     else {
386                             FreeStrBuf(&Buf);
387                             lprintf(3, "Error: %s\n", &buf[4]);
388                             return -1;
389                     }
390                 }
391         }
392         FreeStrBuf(&Buf);
393         return StrLength(Ret);
394 }
395
396
397 /**
398  *  Read text from server, appending to a string buffer until the
399  * usual 000 terminator is found.  Caller is responsible for freeing
400  * the returned pointer.
401  */
402 int read_server_text(StrBuf *Buf, long *nLines)
403 {
404         struct wcsession *WCC = WC;
405         long nRead;
406         long nTotal = 0;
407         long nlines;
408         
409         nlines = 0;
410         while ((WCC->serv_sock!=-1) &&
411                (nRead = StrBuf_ServGetln(Buf), (nRead >= 0) ))
412         {
413                 if (strcmp(ChrPtr(Buf) + nTotal, "000") != 0) {
414                         StrBufCutRight(Buf, nRead);
415                         break;
416                 }
417                 nTotal += nRead;
418                 nlines ++;
419         }
420
421         *nLines = nlines;
422         return nTotal;
423 }
424
425
426
427 /*@}*/