]> code.citadel.org Git - citadel.git/blob - webcit/serv_func.c
* Add site config options for Citadel servers which support LDAP
[citadel.git] / webcit / serv_func.c
1 /*
2  * serv_func.c
3  *
4  * Handles various types of data transfer operations with the Citadel service.
5  *
6  * $Id$
7  */
8
9 #include <ctype.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <stdio.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <sys/types.h>
16 #include <sys/wait.h>
17 #include <sys/socket.h>
18 #include <sys/time.h>
19 #include <limits.h>
20 #include <netinet/in.h>
21 #include <netdb.h>
22 #include <string.h>
23 #include <pwd.h>
24 #include <errno.h>
25 #include <stdarg.h>
26 #include <pthread.h>
27 #include <signal.h>
28 #include "webcit.h"
29 #include "webserver.h"
30
31 struct serv_info serv_info;
32
33 /*
34  * get info about the server we've connected to
35  */
36 void get_serv_info(char *browser_host, char *user_agent)
37 {
38         char buf[SIZ];
39         int a;
40
41         /* Tell the server what kind of client is connecting */
42         serv_printf("IDEN %d|%d|%d|%s|%s",
43                 DEVELOPER_ID,
44                 CLIENT_ID,
45                 CLIENT_VERSION,
46                 user_agent,
47                 browser_host
48         );
49         serv_gets(buf);
50
51         /* Tell the server what kind of richtext we prefer */
52         serv_puts("MSGP text/html|text/plain");
53         serv_gets(buf);
54
55         /* Now ask the server to tell us a little bit about itself... */
56         serv_puts("INFO");
57         serv_gets(buf);
58         if (buf[0] != '1')
59                 return;
60
61         a = 0;
62         while (serv_gets(buf), strcmp(buf, "000")) {
63                 switch (a) {
64                 case 0:
65                         serv_info.serv_pid = atoi(buf);
66                         break;
67                 case 1:
68                         strcpy(serv_info.serv_nodename, buf);
69                         break;
70                 case 2:
71                         strcpy(serv_info.serv_humannode, buf);
72                         break;
73                 case 3:
74                         strcpy(serv_info.serv_fqdn, buf);
75                         break;
76                 case 4:
77                         strcpy(serv_info.serv_software, buf);
78                         break;
79                 case 5:
80                         serv_info.serv_rev_level = atoi(buf);
81                         break;
82                 case 6:
83                         strcpy(serv_info.serv_bbs_city, buf);
84                         break;
85                 case 7:
86                         strcpy(serv_info.serv_sysadm, buf);
87                         break;
88                 case 9:
89                         strcpy(serv_info.serv_moreprompt, buf);
90                         break;
91                 case 14:
92                         serv_info.serv_supports_ldap = atoi(buf);
93                         break;
94                 }
95                 ++a;
96         }
97 }
98
99
100
101 /* 
102  * Function to spit out Citadel variformat text in HTML
103  * If fp is non-null, it is considered to be the file handle to read the
104  * text from.  Otherwise, text is read from the server.
105  */
106 void fmout(FILE *fp, char *align)
107 {
108
109         int intext = 0;
110         int bq = 0;
111         char buf[SIZ];
112
113         wprintf("<DIV ALIGN=%s>\n", align);
114         while (1) {
115                 if (fp == NULL)
116                         serv_gets(buf);
117                 if (fp != NULL) {
118                         if (fgets(buf, SIZ, fp) == NULL)
119                                 strcpy(buf, "000");
120                         buf[strlen(buf) - 1] = 0;
121                 }
122                 if (!strcmp(buf, "000")) {
123                         if (bq == 1)
124                                 wprintf("</I>");
125                         wprintf("</DIV><BR>\n");
126                         return;
127                 }
128                 if ((intext == 1) && (isspace(buf[0]))) {
129                         wprintf("<BR>");
130                 }
131                 intext = 1;
132
133                 /* Quoted text should be displayed in italics and in a
134                  * different colour.  This code understands both Citadel/UX
135                  * style " >" quotes and FordBoard-style " :-)" quotes.
136                  */
137                 if ((bq == 0) &&
138                     ((!strncmp(buf, " >", 2)) || (!strncmp(buf, " :-)", 4)))) {
139                         wprintf("<SPAN CLASS=\"pull_quote\">");
140                         bq = 1;
141                 } else if ((bq == 1) &&
142                   (strncmp(buf, " >", 2)) && (strncmp(buf, " :-)", 4))) {
143                         wprintf("</SPAN>");
144                         bq = 0;
145                 }
146                 /* Activate embedded URL's */
147                 url(buf);
148
149                 escputs(buf);
150                 wprintf("\n");
151         }
152 }
153
154
155
156
157 /*
158  * Transmit message text (in memory) to the server.
159  * If convert_to_html is set to 1, the message is converted into something
160  * which kind of resembles HTML.
161  */
162 void text_to_server(char *ptr, int convert_to_html)
163 {
164         char buf[SIZ];
165         int ch, a, pos;
166
167         if (convert_to_html) {
168                 serv_puts("<HTML><BODY>");
169         }
170
171         pos = 0;
172         strcpy(buf, "");
173
174         while (ptr[pos] != 0) {
175                 ch = ptr[pos++];
176                 if (ch == 10) {
177                         while ( (isspace(buf[strlen(buf) - 1]))
178                           && (strlen(buf) > 1) )
179                                 buf[strlen(buf) - 1] = 0;
180                         serv_puts(buf);
181                         strcpy(buf, "");
182                         if (convert_to_html) {
183                                 strcat(buf, "<BR>");
184                         }
185                         else {
186                                 if (ptr[pos] != 0) strcat(buf, " ");
187                         }
188                 } else {
189                         a = strlen(buf);
190                         buf[a + 1] = 0;
191                         buf[a] = ch;
192                         if ((ch == 32) && (strlen(buf) > 200)) {
193                                 buf[a] = 0;
194                                 serv_puts(buf);
195                                 strcpy(buf, "");
196                         }
197                         if (strlen(buf) > 250) {
198                                 serv_puts(buf);
199                                 strcpy(buf, "");
200                         }
201                 }
202         }
203         serv_puts(buf);
204
205         if (convert_to_html) {
206                 serv_puts("</BODY></HTML>\n");
207         }
208
209 }
210
211
212
213 /*
214  * translate server message output to text
215  * (used for editing room info files and such)
216  */
217 void server_to_text()
218 {
219         char buf[SIZ];
220
221         int count = 0;
222
223         while (serv_gets(buf), strcmp(buf, "000")) {
224                 if ((buf[0] == 32) && (count > 0)) {
225                         wprintf("\n");
226                 }
227                 wprintf("%s", buf);
228                 ++count;
229         }
230 }
231
232
233
234 /*
235  * Read binary data from server into memory using a series of
236  * server READ commands.
237  */
238 void read_server_binary(char *buffer, size_t total_len) {
239         char buf[SIZ];
240         size_t bytes = 0;
241         size_t thisblock = 0;
242
243         memset(buffer, 0, total_len);
244         while (bytes < total_len) {
245                 thisblock = 4095;
246                 if ((total_len - bytes) < thisblock) {
247                         thisblock = total_len - bytes;
248                         if (thisblock == 0) return;
249                 }
250                 serv_printf("READ %d|%d", (int)bytes, (int)thisblock);
251                 serv_gets(buf);
252                 if (buf[0] == '6') {
253                         thisblock = (size_t)atoi(&buf[4]);
254                         if (!WC->connected) return;
255                         serv_read(&buffer[bytes], thisblock);
256                         bytes += thisblock;
257                 }
258                 else {
259                         lprintf(3, "Error: %s\n", &buf[4]);
260                         return;
261                 }
262         }
263 }
264
265
266 /*
267  * Read text from server, appending to a string buffer until the
268  * usual 000 terminator is found.  Caller is responsible for freeing
269  * the returned pointer.
270  */
271 char *read_server_text(void) {
272         char *text = NULL;
273         size_t bytes_allocated = 0;
274         size_t bytes_read = 0;
275         int linelen;
276         char buf[SIZ];
277
278         text = malloc(SIZ);
279         if (text == NULL) {
280                 return(NULL);
281         }
282         strcpy(text, "");
283         bytes_allocated = SIZ;
284
285         while (serv_gets(buf), strcmp(buf, "000")) {
286                 linelen = strlen(buf);
287                 buf[linelen] = '\n';
288                 buf[linelen+1] = 0;
289                 ++linelen;
290
291                 if ((bytes_read + linelen) >= (bytes_allocated - 2)) {
292                         bytes_allocated = 2 * bytes_allocated;
293                         text = realloc(text, bytes_allocated);
294                 }
295
296                 strcpy(&text[bytes_read], buf);
297                 bytes_read += linelen;
298         }
299
300         return(text);
301 }