Export format has changed due to the addition of a new
[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  * \brief Read Citadel variformat text and spit it out as HTML.
110  * \param align html align string
111  */
112 void fmout(char *align)
113 {
114         int intext = 0;
115         int bq = 0;
116         char buf[SIZ];
117
118         wprintf("<div align=%s>\n", align);
119         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
120
121                 if ((intext == 1) && (isspace(buf[0]))) {
122                         wprintf("<br />");
123                 }
124                 intext = 1;
125
126                 /**
127                  * Quoted text should be displayed in italics and in a
128                  * different colour.  This code understands Citadel-style
129                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
130                  */
131                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
132                         wprintf("<BLOCKQUOTE>");
133                         bq = 1;
134                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
135                         wprintf("</BLOCKQUOTE>");
136                         bq = 0;
137                 }
138                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
139                         strcpy(buf, &buf[2]);
140                 }
141                 /** Activate embedded URL's */
142                 url(buf, sizeof(buf));
143
144                 escputs(buf);
145                 wprintf("\n");
146         }
147         if (bq == 1) {
148                 wprintf("</I>");
149         }
150         wprintf("</div><br />\n");
151 }
152
153
154
155
156 /**
157  * \brief Read Citadel variformat text and spit it out as HTML in a form
158  * suitable for embedding in another message (forward/quote).
159  * (NO LINEBREAKS ALLOWED HERE!)
160  */
161 void pullquote_fmout(void) {
162         int intext = 0;
163         int bq = 0;
164         char buf[SIZ];
165
166         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
167
168                 if ((intext == 1) && (isspace(buf[0]))) {
169                         wprintf("<br />");
170                 }
171                 intext = 1;
172
173                 /**
174                  * Quoted text should be displayed in italics and in a
175                  * different colour.  This code understands Citadel-style
176                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
177                  */
178                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
179                         wprintf("<BLOCKQUOTE>");
180                         bq = 1;
181                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
182                         wprintf("</BLOCKQUOTE>");
183                         bq = 0;
184                 }
185                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
186                         strcpy(buf, &buf[2]);
187                 }
188
189                 msgescputs(buf);
190         }
191         if (bq == 1) {
192                 wprintf("</I>");
193         }
194 }
195
196
197
198
199 /**
200  * \brief Transmit message text (in memory) to the server.
201  *
202  * \param ptr Pointer to the message being transmitted
203  */
204 void text_to_server(char *ptr)
205 {
206         char buf[256];
207         int ch, a, pos, len;
208
209         pos = 0;
210         buf[0] = 0;
211
212         while (ptr[pos] != 0) {
213                 ch = ptr[pos++];
214                 if (ch == 10) {
215                         len = strlen(buf);
216                         while ( (isspace(buf[len - 1]))
217                                 && (buf[0] !=  '\0') 
218                                 && (buf[1] !=  '\0') )
219                                 buf[--len] = 0;
220                         serv_puts(buf);
221                         buf[0] = 0;
222                         if (ptr[pos] != 0) strcat(buf, " ");
223                 } else {
224                         a = strlen(buf);
225                         buf[a + 1] = 0;
226                         buf[a] = ch;
227                         if ((ch == 32) && (strlen(buf) > 200)) {
228                                 buf[a] = 0;
229                                 serv_puts(buf);
230                                 buf[0] = 0;
231                         }
232                         if (strlen(buf) > 250) {
233                                 serv_puts(buf);
234                                 buf[0] = 0;
235                         }
236                 }
237         }
238         serv_puts(buf);
239 }
240
241
242 /**
243  * \brief Transmit message text (in memory) to the server,
244  *        converting to Quoted-Printable encoding as we go.
245  *
246  * \param ptr Pointer to the message being transmitted
247  */
248 void text_to_server_qp(char *ptr)
249 {
250         unsigned char ch, buf[256];
251         int pos;
252         int output_len = 0;
253
254         pos = 0;
255         buf[0] = 0;
256         output_len = 0;
257
258         while (ptr[pos] != 0) {
259                 ch = (unsigned char)(ptr[pos++]);
260
261                 if (ch == 13) {
262                         /* ignore carriage returns */
263                 }
264                 else if (ch == 10) {
265                         /* hard line break */
266                         if (output_len > 0) {
267                                 if (isspace(buf[output_len-1])) {
268                                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
269                                         output_len += 2;
270                                 }
271                         }
272                         buf[output_len++] = 0;
273                         serv_puts((char *)buf);
274                         output_len = 0;
275                 }
276                 else if (ch == 9) {
277                         buf[output_len++] = ch;
278                 }
279                 else if ( (ch >= 32) && (ch <= 60) ) {
280                         buf[output_len++] = ch;
281                 }
282                 else if ( (ch >= 62) && (ch <= 126) ) {
283                         buf[output_len++] = ch;
284                 }
285                 else {
286                         sprintf((char *)&buf[output_len], "=%02X", ch);
287                         output_len += 3;
288                 }
289                 
290                 if (output_len > 72) {
291                         /* soft line break */
292                         if (isspace(buf[output_len-1])) {
293                                 sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
294                                 output_len += 2;
295                         }
296                         buf[output_len++] = '=';
297                         buf[output_len++] = 0;
298                         serv_puts((char *)buf);
299                         output_len = 0;
300                 }
301         }
302
303         /* end of data - transmit anything that's left */
304         if (output_len > 0) {
305                 if (isspace(buf[output_len-1])) {
306                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
307                         output_len += 2;
308                 }
309                 buf[output_len++] = 0;
310                 serv_puts((char *)buf);
311                 output_len = 0;
312         }
313 }
314
315
316
317
318 /**
319  * \brief translate server message output to text
320  * (used for editing room info files and such)
321  */
322 void server_to_text()
323 {
324         char buf[SIZ];
325
326         int count = 0;
327
328         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
329                 if ((buf[0] == 32) && (count > 0)) {
330                         wprintf("\n");
331                 }
332                 wprintf("%s", buf);
333                 ++count;
334         }
335 }
336
337
338
339 /**
340  * Read binary data from server into memory using a series of
341  * server READ commands.
342  * \param buffer the output buffer
343  * \param total_len the maximal length of buffer
344  */
345 void read_server_binary(char *buffer, size_t total_len) {
346         char buf[SIZ];
347         size_t bytes = 0;
348         size_t thisblock = 0;
349
350         memset(buffer, 0, total_len);
351         while (bytes < total_len) {
352                 thisblock = 4095;
353                 if ((total_len - bytes) < thisblock) {
354                         thisblock = total_len - bytes;
355                         if (thisblock == 0) return;
356                 }
357                 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
358                 serv_getln(buf, sizeof buf);
359                 if (buf[0] == '6') {
360                         thisblock = (size_t)atoi(&buf[4]);
361                         if (!WC->connected) return;
362                         serv_read(&buffer[bytes], thisblock);
363                         bytes += thisblock;
364                 }
365                 else {
366                         lprintf(3, "Error: %s\n", &buf[4]);
367                         return;
368                 }
369         }
370 }
371
372
373 /**
374  * \brief Read text from server, appending to a string buffer until the
375  * usual 000 terminator is found.  Caller is responsible for freeing
376  * the returned pointer.
377  */
378 char *read_server_text(void) {
379         char *text = NULL;
380         size_t bytes_allocated = 0;
381         size_t bytes_read = 0;
382         int linelen;
383         char buf[SIZ];
384
385         text = malloc(SIZ);
386         if (text == NULL) {
387                 return(NULL);
388         }
389         text[0] = 0;
390         bytes_allocated = SIZ;
391
392         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
393                 linelen = strlen(buf);
394                 buf[linelen] = '\n';
395                 buf[linelen+1] = 0;
396                 ++linelen;
397
398                 if ((bytes_read + linelen) >= (bytes_allocated - 2)) {
399                         bytes_allocated = 2 * bytes_allocated;
400                         text = realloc(text, bytes_allocated);
401                 }
402
403                 strcpy(&text[bytes_read], buf);
404                 bytes_read += linelen;
405         }
406
407         return(text);
408 }
409
410
411
412 /*@}*/