* cleanup
[citadel.git] / webcit / serv_func.c
1 /*
2  * $Id$
3  */
4
5 #include "webcit.h"
6 #include "webserver.h"
7
8 int is_uds = 0;
9 char serv_sock_name[PATH_MAX] = "";
10
11 HashList *EmbeddableMimes = NULL;
12 StrBuf *EmbeddableMimeStrs = NULL;
13
14
15 void SetInlinMimeRenderers(void)
16 {
17         StrBuf *Buf;
18
19         Buf = NewStrBuf();
20         /** Tell the server what kind of richtext we prefer */
21         serv_putbuf(EmbeddableMimeStrs);
22         StrBuf_ServGetln(Buf);
23
24         FreeStrBuf(&Buf);
25 }
26
27
28 void DeleteServInfo(ServInfo **FreeMe)
29 {
30         if (*FreeMe == NULL)
31                 return;
32         FreeStrBuf(&(*FreeMe)->serv_nodename);
33         FreeStrBuf(&(*FreeMe)->serv_humannode);
34         FreeStrBuf(&(*FreeMe)->serv_fqdn);
35         FreeStrBuf(&(*FreeMe)->serv_software);
36         FreeStrBuf(&(*FreeMe)->serv_bbs_city);
37         FreeStrBuf(&(*FreeMe)->serv_sysadm);
38         FreeStrBuf(&(*FreeMe)->serv_moreprompt);
39         FreeStrBuf(&(*FreeMe)->serv_default_cal_zone);
40         FreeStrBuf(&(*FreeMe)->serv_svn_revision);
41         free(*FreeMe);
42         *FreeMe = NULL;
43 }
44
45 /*
46  * get info about the server we've connected to
47  *
48  * browser_host         the citadel we want to connect to
49  * user_agent           which browser uses our client?
50  */
51 ServInfo *get_serv_info(StrBuf *browser_host, StrBuf *user_agent)
52 {
53         ServInfo *info;
54         StrBuf *Buf;
55         int a;
56
57         Buf = NewStrBuf();
58         /** Tell the server what kind of client is connecting */
59         serv_printf("IDEN %d|%d|%d|%s|%s",
60                     DEVELOPER_ID,
61                     CLIENT_ID,
62                     CLIENT_VERSION,
63                     ChrPtr(user_agent),
64                     ChrPtr(browser_host)
65         );
66         StrBuf_ServGetln(Buf);
67
68         /*
69          * Tell the server that when we save a calendar event, we
70          * want invitations to be generated by the Citadel server
71          * instead of by the client.
72          */
73         serv_puts("ICAL sgi|1");
74         StrBuf_ServGetln(Buf);
75
76         /** Now ask the server to tell us a little bit about itself... */
77         serv_puts("INFO");
78         StrBuf_ServGetln(Buf);
79         if (GetServerStatus(Buf, NULL) != 1) {
80                 FreeStrBuf(&Buf);
81                 return NULL;
82         }
83
84         info = (ServInfo*)malloc(sizeof(ServInfo));
85         memset(info, 0, sizeof(ServInfo));
86         a = 0;
87         while (StrBuf_ServGetln(Buf), (strcmp(ChrPtr(Buf), "000")!= 0)) {
88 /*              lprintf (1, "a: %d [%s]", a, ChrPtr(Buf));*/
89                 switch (a) {
90                 case 0:
91                         info->serv_pid = StrToi(Buf);
92                         WC->ctdl_pid = info->serv_pid;
93                         break;
94                 case 1:
95                         info->serv_nodename = NewStrBufDup(Buf);
96                         break;
97                 case 2:
98                         info->serv_humannode = NewStrBufDup(Buf);
99                         break;
100                 case 3:
101                         info->serv_fqdn = NewStrBufDup(Buf);
102                         break;
103                 case 4:
104                         info->serv_software = NewStrBufDup(Buf);
105                         break;
106                 case 5:
107                         info->serv_rev_level = StrToi(Buf);
108                         break;
109                 case 6:
110                         info->serv_bbs_city = NewStrBufDup(Buf);
111                         break;
112                 case 7:
113                         info->serv_sysadm = NewStrBufDup(Buf);
114                         break;
115                 case 9:
116                         info->serv_moreprompt = NewStrBufDup(Buf);
117                         break;
118                 case 14:
119                         info->serv_supports_ldap = StrToi(Buf);
120                         break;
121                 case 15:
122                         info->serv_newuser_disabled = StrToi(Buf);
123                         break;
124                 case 16:
125                         info->serv_default_cal_zone = NewStrBufDup(Buf);
126                         break;
127                 case 20:
128                         info->serv_supports_sieve = StrToi(Buf);
129                         break;
130                 case 21:
131                         info->serv_fulltext_enabled = StrToi(Buf);
132                         break;
133                 case 22:
134                         info->serv_svn_revision = NewStrBufDup(Buf);
135                         break;
136                 case 23:
137                         info->serv_supports_openid = StrToi(Buf);
138                         break;
139                 }
140                 ++a;
141         }
142         FreeStrBuf(&Buf);
143         return info;
144 }
145
146 int GetConnected (void)
147 {
148         StrBuf *Buf;
149         wcsession *WCC = WC;
150
151         if (WCC->ReadBuf == NULL)
152                 WCC->ReadBuf = NewStrBufPlain(NULL, SIZ * 4);
153         if (is_uds) /* unix domain socket */
154                 WCC->serv_sock = uds_connectsock(serv_sock_name);
155         else        /* tcp socket */
156                 WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
157         
158         if (WCC->serv_sock < 0) {
159                 do_logout();
160                 FreeStrBuf(&WCC->ReadBuf);
161                 return 1;
162         }
163         else {
164                 long Status;
165                 Buf = NewStrBuf();
166                 WCC->connected = 1;
167                 StrBuf_ServGetln(Buf);  /* get the server greeting */
168                 GetServerStatus(Buf, &Status);
169                 FreeStrBuf(&Buf);
170
171                 /* Are there too many users already logged in? */
172                 if (Status == 571) {
173                         wc_printf(_("This server is already serving its maximum number of users and cannot accept any additional logins at this time.  Please try again later or contact your system administrator."));
174                         end_burst();
175                         end_webcit_session();
176                         return 1;
177                 }
178
179                 /*
180                  * From what host is our user connecting?  Go with
181                  * the host at the other end of the HTTP socket,
182                  * unless we are following X-Forwarded-For: headers
183                  * and such a header has already turned up something.
184                  */
185                 if ( (!follow_xff) || (StrLength(WCC->Hdr->HR.browser_host) == 0) ) {
186                         if (WCC->Hdr->HR.browser_host == NULL) {
187                                 WCC->Hdr->HR.browser_host = NewStrBuf();
188                                 Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), 
189                                     WCC->Hdr->HR.browser_host, HFreeStrBuf);
190                         }
191                         locate_host(WCC->Hdr->HR.browser_host, WCC->Hdr->http_sock);
192                 }
193                 if (WCC->serv_info == NULL)
194                         WCC->serv_info = get_serv_info(WCC->Hdr->HR.browser_host, WCC->Hdr->HR.user_agent);
195                 if (WCC->serv_info == NULL){
196                         begin_burst();
197                         wc_printf(_("Received unexpected answer from Citadel "
198                                   "server; bailing out."));
199                         hprintf("HTTP/1.1 200 OK\r\n");
200                         hprintf("Content-type: text/plain; charset=utf-8\r\n");
201                         end_burst();
202                         end_webcit_session();
203                         return 1;
204                 }
205                 if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
206                         begin_burst();
207                         wc_printf(_("You are connected to a Citadel "
208                                   "server running Citadel %d.%02d. \n"
209                                   "In order to run this version of WebCit "
210                                   "you must also have Citadel %d.%02d or"
211                                   " newer.\n\n\n"),
212                                 WCC->serv_info->serv_rev_level / 100,
213                                 WCC->serv_info->serv_rev_level % 100,
214                                 MINIMUM_CIT_VERSION / 100,
215                                 MINIMUM_CIT_VERSION % 100
216                                 );
217                         hprintf("HTTP/1.1 200 OK\r\n");
218                         hprintf("Content-type: text/plain; charset=utf-8\r\n");
219                         end_burst();
220                         end_webcit_session();
221                         return 1;
222                 }
223                 SetInlinMimeRenderers();
224         }
225         return 0;
226 }
227
228 /*
229  *  Read Citadel variformat text and spit it out as HTML.
230  *  align html align string
231  */
232 inline void fmout(char *align)
233 {
234         _fmout(WC->WBuf, align);
235 }
236
237 void _fmout(StrBuf *Target, char *align)
238 {
239         int intext = 0;
240         int bq = 0;
241         char buf[SIZ];
242
243         StrBufAppendPrintf(Target, "<div align=%s>\n", align);
244         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
245
246                 if ((intext == 1) && (isspace(buf[0]))) {
247                         wc_printf("<br />");
248                 }
249                 intext = 1;
250
251                 /*
252                  * Quoted text should be displayed in italics and in a
253                  * different colour.  This code understands Citadel-style
254                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
255                  */
256                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
257                         StrBufAppendBufPlain(Target, HKEY("<BLOCKQUOTE>"), 0);
258                         bq = 1;
259                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
260                         StrBufAppendBufPlain(Target, HKEY("</BLOCKQUOTE>"), 0);
261                         bq = 0;
262                 }
263                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
264                         strcpy(buf, &buf[2]);
265                 }
266                 /* Activate embedded URL's */
267                 url(buf, sizeof(buf));
268
269                 escputs(buf);
270                 StrBufAppendBufPlain(Target, HKEY("\n"), 0);
271         }
272         if (bq == 1) {
273                 wc_printf("</I>");
274         }
275         wc_printf("</div><br />\n");
276 }
277
278 void FmOut(StrBuf *Target, char *align, StrBuf *Source)
279 {
280         const char *ptr, *pte;
281         const char *BufPtr = NULL;
282         StrBuf *Line = NewStrBufPlain(NULL, SIZ);
283         StrBuf *Line1 = NewStrBufPlain(NULL, SIZ);
284         StrBuf *Line2 = NewStrBufPlain(NULL, SIZ);
285         int bn = 0;
286         int bq = 0;
287         int i;
288         long len;
289         int intext = 0;
290
291         StrBufAppendPrintf(Target, "<div class=\"fmout-%s\">\n", align);
292
293         if (StrLength(Source) > 0) 
294                 do 
295                 {
296                         StrBufSipLine(Line, Source, &BufPtr);
297                         bq = 0;
298                         i = 0;
299                         ptr = ChrPtr(Line);
300                         len = StrLength(Line);
301                         pte = ptr + len;
302
303                         if ((intext == 1) && (isspace(*ptr))) {
304                                 StrBufAppendBufPlain(Target, HKEY("<br>"), 0);
305                         }
306                         intext = 1;
307                         if (isspace(*ptr)) while ((ptr < pte) &&
308                                                   ((*ptr == '>') ||
309                                                    isspace(*ptr)))
310                                            {
311                                                    if (*ptr == '>')
312                                                            bq++;
313                                                    ptr ++;
314                                                    i++;
315                                            }
316
317                         /**
318                          * Quoted text should be displayed in italics and in a
319                          * different colour.  This code understands Citadel-style
320                          * " >" quotes and will convert to <BLOCKQUOTE> tags.
321                          */
322                         if (i > 0) StrBufCutLeft(Line, i);
323                 
324
325                         for (i = bn; i < bq; i++)                               
326                                 StrBufAppendBufPlain(Target, HKEY("<blockquote>"), 0);
327                         for (i = bq; i < bn; i++)                               
328                                 StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
329                         bn = bq;
330
331                         if (StrLength(Line) == 0)
332                                 continue;
333                         /** Activate embedded URL's */
334                         UrlizeText(Line1, Line, Line2);
335
336                         StrEscAppend(Target, Line1, NULL, 0, 0);
337
338                         StrBufAppendBufPlain(Target, HKEY("\n"), 0);
339                 }
340                 while ((BufPtr != StrBufNOTNULL) &&
341                        (BufPtr != NULL));
342
343         for (i = 0; i < bn; i++) {
344                 StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
345         }
346         StrBufAppendBufPlain(Target, HKEY("</div><br>\n"), 0);
347         FreeStrBuf(&Line);
348         FreeStrBuf(&Line1);
349         FreeStrBuf(&Line2);
350 }
351
352
353 /*
354  * Read Citadel variformat text and spit it out as HTML in a form
355  * suitable for embedding in another message (forward/quote).
356  * (NO LINEBREAKS ALLOWED HERE!)
357  */
358 void pullquote_fmout(void) {
359         int intext = 0;
360         int bq = 0;
361         char buf[SIZ];
362
363         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
364
365                 if ((intext == 1) && (isspace(buf[0]))) {
366                         wc_printf("<br />");
367                 }
368                 intext = 1;
369
370                 /**
371                  * Quoted text should be displayed in italics and in a
372                  * different colour.  This code understands Citadel-style
373                  * " >" quotes and will convert to <BLOCKQUOTE> tags.
374                  */
375                 if ((bq == 0) && (!strncmp(buf, " >", 2))) {
376                         wc_printf("<BLOCKQUOTE>");
377                         bq = 1;
378                 } else if ((bq == 1) && (strncmp(buf, " >", 2))) {
379                         wc_printf("</BLOCKQUOTE>");
380                         bq = 0;
381                 }
382                 if ((bq == 1) && (!strncmp(buf, " >", 2))) {
383                         strcpy(buf, &buf[2]);
384                 }
385
386                 msgescputs(buf);
387         }
388         if (bq == 1) {
389                 wc_printf("</I>");
390         }
391 }
392
393
394
395
396 /*
397  *  Transmit message text (in memory) to the server.
398  */
399 void text_to_server(char *ptr)
400 {
401         char buf[256];
402         int ch, a, pos, len;
403
404         pos = 0;
405         buf[0] = 0;
406
407         while (ptr[pos] != 0) {
408                 ch = ptr[pos++];
409                 if (ch == 10) {
410                         len = strlen(buf);
411                         while ( (isspace(buf[len - 1]))
412                                 && (buf[0] !=  '\0') 
413                                 && (buf[1] !=  '\0') )
414                                 buf[--len] = 0;
415                         serv_puts(buf);
416                         buf[0] = 0;
417                         if (ptr[pos] != 0) strcat(buf, " ");
418                 } else {
419                         a = strlen(buf);
420                         buf[a + 1] = 0;
421                         buf[a] = ch;
422                         if ((ch == 32) && (strlen(buf) > 200)) {
423                                 buf[a] = 0;
424                                 serv_puts(buf);
425                                 buf[0] = 0;
426                         }
427                         if (strlen(buf) > 250) {
428                                 serv_puts(buf);
429                                 buf[0] = 0;
430                         }
431                 }
432         }
433         serv_puts(buf);
434 }
435
436
437 /*
438  * Transmit message text (in memory) to the server, converting to Quoted-Printable encoding as we go.
439  */
440 void text_to_server_qp(char *ptr)
441 {
442         unsigned char ch, buf[256];
443         int pos;
444         int output_len = 0;
445
446         pos = 0;
447         buf[0] = 0;
448         output_len = 0;
449
450         while (ptr[pos] != 0) {
451                 ch = (unsigned char)(ptr[pos++]);
452
453                 if (ch == 13) {
454                         /* ignore carriage returns */
455                 }
456                 else if (ch == 10) {
457                         /* hard line break */
458                         if (output_len > 0) {
459                                 if (isspace(buf[output_len-1])) {
460                                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
461                                         output_len += 2;
462                                 }
463                         }
464                         buf[output_len++] = 0;
465                         serv_puts((char *)buf);
466                         output_len = 0;
467                 }
468                 else if (ch == 9) {
469                         buf[output_len++] = ch;
470                 }
471                 else if ( (ch >= 32) && (ch <= 60) ) {
472                         buf[output_len++] = ch;
473                 }
474                 else if ( (ch >= 62) && (ch <= 126) ) {
475                         buf[output_len++] = ch;
476                 }
477                 else {
478                         sprintf((char *)&buf[output_len], "=%02X", ch);
479                         output_len += 3;
480                 }
481                 
482                 if (output_len > 72) {
483                         /* soft line break */
484                         if (isspace(buf[output_len-1])) {
485                                 sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
486                                 output_len += 2;
487                         }
488                         buf[output_len++] = '=';
489                         buf[output_len++] = 0;
490                         serv_puts((char *)buf);
491                         output_len = 0;
492                 }
493         }
494
495         /* end of data - transmit anything that's left */
496         if (output_len > 0) {
497                 if (isspace(buf[output_len-1])) {
498                         sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
499                         output_len += 2;
500                 }
501                 buf[output_len++] = 0;
502                 serv_puts((char *)buf);
503                 output_len = 0;
504         }
505 }
506
507
508
509
510 /*
511  * translate server message output to text (used for editing room info files and such)
512  */
513 void server_to_text()
514 {
515         char buf[SIZ];
516
517         int count = 0;
518
519         while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
520                 if ((buf[0] == 32) && (count > 0)) {
521                         wc_printf("\n");
522                 }
523                 wc_printf("%s", buf);
524                 ++count;
525         }
526 }
527
528
529
530
531 /*
532  * Read text from server, appending to a string buffer until the
533  * usual 000 terminator is found.  Caller is responsible for freeing
534  * the returned pointer.
535  */
536 int read_server_text(StrBuf *Buf, long *nLines)
537 {
538         wcsession *WCC = WC;
539         long nRead;
540         long nTotal = 0;
541         long nlines;
542         
543         nlines = 0;
544         while ((WCC->serv_sock!=-1) &&
545                (nRead = StrBuf_ServGetln(Buf), (nRead >= 0) ))
546         {
547                 if (strcmp(ChrPtr(Buf) + nTotal, "000") != 0) {
548                         StrBufCutRight(Buf, nRead);
549                         break;
550                 }
551                 nTotal += nRead;
552                 nlines ++;
553         }
554
555         *nLines = nlines;
556         return nTotal;
557 }
558
559
560 int GetServerStatus(StrBuf *Line, long* FullState)
561 {
562         if (FullState != NULL)
563                 *FullState = StrTol(Line);
564         return ChrPtr(Line)[0] - 48;
565 }
566
567
568 void tmplput_serv_ip(StrBuf *Target, WCTemplputParams *TP)
569 {
570         StrBufAppendPrintf(Target, "%d", WC->ctdl_pid);
571 }
572
573 void tmplput_serv_nodename(StrBuf *Target, WCTemplputParams *TP)
574 {
575         wcsession *WCC = WC;
576         if (WCC->serv_info == NULL)
577                 return;
578         StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_nodename, 0);
579 }
580
581 void tmplput_serv_humannode(StrBuf *Target, WCTemplputParams *TP)
582 {
583         wcsession *WCC = WC;
584         if (WCC->serv_info == NULL)
585                 return;
586         StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_humannode, 0);
587 }
588
589 void tmplput_serv_fqdn(StrBuf *Target, WCTemplputParams *TP)
590 {
591         wcsession *WCC = WC;
592         if (WCC->serv_info == NULL)
593                 return;
594         StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_fqdn, 0);
595 }
596
597 void tmplput_serv_software(StrBuf *Target, WCTemplputParams *TP)
598 {
599         wcsession *WCC = WC;
600         if (WCC->serv_info == NULL)
601                 return;
602         StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_software, 0);
603 }
604
605 void tmplput_serv_rev_level(StrBuf *Target, WCTemplputParams *TP)
606 {
607         wcsession *WCC = WC;
608         if (WCC->serv_info == NULL)
609                 return;
610         StrBufAppendPrintf(Target, "%d.%02d",
611                             WCC->serv_info->serv_rev_level / 100,
612                             WCC->serv_info->serv_rev_level % 100);
613 }
614 int conditional_serv_newuser_disabled(StrBuf *Target, WCTemplputParams *TP)
615 {
616         wcsession *WCC = WC;
617         if (WCC->serv_info == NULL)
618                 return 0;
619         return WCC->serv_info->serv_newuser_disabled != 0;
620 }
621
622 int conditional_serv_supports_openid(StrBuf *Target, WCTemplputParams *TP)
623 {
624         wcsession *WCC = WC;
625         if (WCC->serv_info == NULL)
626                 return 0;
627         return WCC->serv_info->serv_supports_openid != 0;
628 }
629
630 int conditional_serv_fulltext_enabled(StrBuf *Target, WCTemplputParams *TP)
631 {
632         wcsession *WCC = WC;
633         if (WCC->serv_info == NULL)
634                 return 0;
635         return WCC->serv_info->serv_fulltext_enabled != 0;
636 }
637
638 void tmplput_serv_bbs_city(StrBuf *Target, WCTemplputParams *TP)
639 {
640         wcsession *WCC = WC;
641         if (WCC->serv_info == NULL)
642                 return;
643         StrBufAppendTemplate(Target, TP, WC->serv_info->serv_bbs_city, 0);
644 }
645
646 void tmplput_mesg(StrBuf *Target, WCTemplputParams *TP)
647 {
648         int n = 0;
649         int Done = 0;
650         StrBuf *Line;
651         StrBuf *Buf;
652
653         Buf = NewStrBuf();
654         Line = NewStrBuf();
655         serv_printf("MESG %s", TP->Tokens->Params[0]->Start);
656
657         StrBuf_ServGetln(Line);
658         if (GetServerStatus(Line, NULL) == 1) {
659                 while (!Done &&  (StrBuf_ServGetln(Line)>=0)) {
660                         if ( (StrLength(Line)==3) && 
661                              !strcmp(ChrPtr(Line), "000")) 
662                                 Done = 1;
663                         else
664                         {
665                                 if (n > 0)
666                                         StrBufAppendBufPlain(Buf, "\n", 1, 0);
667                                 StrBufAppendBuf(Buf, Line, 0);
668                         }
669                         n++;
670                 }
671         
672                 FlushStrBuf(Line);
673                 FmOut(Line, "center", Buf);
674                 StrBufAppendTemplate(Target, TP, Line, 1);
675         }
676         FreeStrBuf(&Buf);
677         FreeStrBuf(&Line);
678 }
679
680
681 void RegisterEmbeddableMimeType(const char *MimeType, long MTLen, int Priority)
682 {
683         StrBuf *MT;
684         MT = NewStrBufPlain(MimeType, MTLen);
685         Put(EmbeddableMimes, IKEY(Priority), MT, HFreeStrBuf);
686 }
687
688 void CreateMimeStr(void)
689 {
690         HashPos  *it;
691         void *vMime;
692         long len = 0;
693         const char *Key;
694
695         it = GetNewHashPos(EmbeddableMimes, 0);
696         while (GetNextHashPos(EmbeddableMimes, it, &len, &Key, &vMime) &&
697                (vMime != NULL)) {
698                 if (StrLength(EmbeddableMimeStrs) > 0)
699                         StrBufAppendBufPlain(EmbeddableMimeStrs, HKEY("|"), 0);
700                 else 
701                         StrBufAppendBufPlain(EmbeddableMimeStrs, HKEY("MSGP "), 0);
702                 StrBufAppendBuf(EmbeddableMimeStrs, (StrBuf*) vMime, 0);
703         }
704         DeleteHashPos(&it);
705 }
706
707 void
708 ServerStartModule_SERV_FUNC
709 (void)
710 {
711         EmbeddableMimes = NewHash(1, Flathash);
712         EmbeddableMimeStrs = NewStrBuf();
713 }
714
715
716 void
717 ServerShutdownModule_SERV_FUNC
718 (void)
719 {
720         FreeStrBuf(&EmbeddableMimeStrs);
721         DeleteHash(&EmbeddableMimes);
722 }
723
724 void 
725 InitModule_SERVFUNC
726 (void)
727 {
728         is_uds = strcasecmp(ctdlhost, "uds") == 0;
729         if (is_uds)
730                 snprintf(serv_sock_name, PATH_MAX, "%s/citadel.socket", ctdlport);
731
732         RegisterConditional(HKEY("COND:SERV:OPENID"), 2, conditional_serv_supports_openid, CTX_NONE);
733         RegisterConditional(HKEY("COND:SERV:NEWU"), 2, conditional_serv_newuser_disabled, CTX_NONE);
734         RegisterConditional(HKEY("COND:SERV:HAVEFULLTEXT"), 2, conditional_serv_fulltext_enabled, CTX_NONE);
735         RegisterNamespace("SERV:PID", 0, 0, tmplput_serv_ip, NULL, CTX_NONE);
736         RegisterNamespace("SERV:NODENAME", 0, 1, tmplput_serv_nodename, NULL, CTX_NONE);
737         RegisterNamespace("SERV:HUMANNODE", 0, 1, tmplput_serv_humannode, NULL, CTX_NONE);
738         RegisterNamespace("SERV:FQDN", 0, 1, tmplput_serv_fqdn, NULL, CTX_NONE);
739         RegisterNamespace("SERV:SOFTWARE", 0, 1, tmplput_serv_software, NULL, CTX_NONE);
740         RegisterNamespace("SERV:REV_LEVEL", 0, 0, tmplput_serv_rev_level, NULL, CTX_NONE);
741         RegisterNamespace("SERV:BBS_CITY", 0, 1, tmplput_serv_bbs_city, NULL, CTX_NONE);
742         RegisterNamespace("SERV:MESG", 1, 2, tmplput_mesg, NULL, CTX_NONE);
743 /*TODO //       RegisterNamespace("SERV:LDAP_SUPP", 0, 0, tmplput_serv_ldap_enabled, 0); */
744 }
745
746
747
748 void 
749 SessionDestroyModule_SERVFUNC
750 (wcsession *sess)
751 {
752         DeleteServInfo(&sess->serv_info);
753 }