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