Back to index

webcit  8.12-dfsg
serv_func.c
Go to the documentation of this file.
00001 
00002 #include "webcit.h"
00003 #include "webserver.h"
00004 
00005 int is_uds = 0;
00006 char serv_sock_name[PATH_MAX] = "";
00007 
00008 HashList *EmbeddableMimes = NULL;
00009 StrBuf *EmbeddableMimeStrs = NULL;
00010 
00011 
00012 void SetInlinMimeRenderers(void)
00013 {
00014        StrBuf *Buf;
00015 
00016        Buf = NewStrBuf();
00017 
00018        /* Tell the server what kind of richtext we prefer */
00019        serv_putbuf(EmbeddableMimeStrs);
00020        StrBuf_ServGetln(Buf);
00021 
00022        FreeStrBuf(&Buf);
00023 }
00024 
00025 
00026 void DeleteServInfo(ServInfo **FreeMe)
00027 {
00028        if (*FreeMe == NULL)
00029               return;
00030        FreeStrBuf(&(*FreeMe)->serv_nodename);
00031        FreeStrBuf(&(*FreeMe)->serv_humannode);
00032        FreeStrBuf(&(*FreeMe)->serv_fqdn);
00033        FreeStrBuf(&(*FreeMe)->serv_software);
00034        FreeStrBuf(&(*FreeMe)->serv_bbs_city);
00035        FreeStrBuf(&(*FreeMe)->serv_sysadm);
00036        FreeStrBuf(&(*FreeMe)->serv_default_cal_zone);
00037        FreeStrBuf(&(*FreeMe)->serv_svn_revision);
00038        free(*FreeMe);
00039        *FreeMe = NULL;
00040 }
00041 
00042 /*
00043  * get info about the server we've connected to
00044  *
00045  * browser_host             the citadel we want to connect to
00046  * user_agent        which browser uses our client?
00047  */
00048 ServInfo *get_serv_info(StrBuf *browser_host, StrBuf *user_agent)
00049 {
00050        ServInfo *info;
00051        StrBuf *Buf;
00052        int a;
00053        int rc;
00054 
00055        Buf = NewStrBuf();
00056 
00057        /* Tell the server what kind of client is connecting */
00058        serv_printf("IDEN %d|%d|%d|%s|%s",
00059                   DEVELOPER_ID,
00060                   CLIENT_ID,
00061                   CLIENT_VERSION,
00062                   ChrPtr(user_agent),
00063                   ChrPtr(browser_host)
00064        );
00065        StrBuf_ServGetln(Buf);
00066        if (GetServerStatus(Buf, NULL) != 2) {
00067               syslog(0, "get_serv_info(IDEN): unexpected answer [%s]\n",
00068                      ChrPtr(Buf));
00069               FreeStrBuf(&Buf);
00070               return NULL;
00071        }
00072 
00073        /*
00074         * Tell the server that when we save a calendar event, we
00075         * want invitations to be generated by the Citadel server
00076         * instead of by the client.
00077         */
00078        serv_puts("ICAL sgi|1");
00079        StrBuf_ServGetln(Buf);
00080        if (GetServerStatus(Buf, NULL) != 2) {
00081               syslog(0, "get_serv_info(ICAL sgi|1): unexpected answer [%s]\n",
00082                      ChrPtr(Buf));
00083               FreeStrBuf(&Buf);
00084               return NULL;
00085        }
00086 
00087        /* Now ask the server to tell us a little bit about itself... */
00088        serv_puts("INFO");
00089        StrBuf_ServGetln(Buf);
00090        if (GetServerStatus(Buf, NULL) != 1) {
00091               syslog(0, "get_serv_info(INFO sgi|1): unexpected answer [%s]\n",
00092                      ChrPtr(Buf));
00093               FreeStrBuf(&Buf);
00094               return NULL;
00095        }
00096 
00097        info = (ServInfo*)malloc(sizeof(ServInfo));
00098        memset(info, 0, sizeof(ServInfo));
00099        a = 0;
00100        while (rc = StrBuf_ServGetln(Buf),
00101               (rc >= 0) &&
00102               ((rc != 3) || 
00103               strcmp(ChrPtr(Buf), "000")))
00104        {
00105               switch (a) {
00106               case 0:
00107                      info->serv_pid = StrToi(Buf);
00108                      WC->ctdl_pid = info->serv_pid;
00109                      break;
00110               case 1:
00111                      info->serv_nodename = NewStrBufDup(Buf);
00112                      break;
00113               case 2:
00114                      info->serv_humannode = NewStrBufDup(Buf);
00115                      break;
00116               case 3:
00117                      info->serv_fqdn = NewStrBufDup(Buf);
00118                      break;
00119               case 4:
00120                      info->serv_software = NewStrBufDup(Buf);
00121                      break;
00122               case 5:
00123                      info->serv_rev_level = StrToi(Buf);
00124                      break;
00125               case 6:
00126                      info->serv_bbs_city = NewStrBufDup(Buf);
00127                      break;
00128               case 7:
00129                      info->serv_sysadm = NewStrBufDup(Buf);
00130                      break;
00131               case 14:
00132                      info->serv_supports_ldap = StrToi(Buf);
00133                      break;
00134               case 15:
00135                      info->serv_newuser_disabled = StrToi(Buf);
00136                      break;
00137               case 16:
00138                      info->serv_default_cal_zone = NewStrBufDup(Buf);
00139                      break;
00140               case 20:
00141                      info->serv_supports_sieve = StrToi(Buf);
00142                      break;
00143               case 21:
00144                      info->serv_fulltext_enabled = StrToi(Buf);
00145                      break;
00146               case 22:
00147                      info->serv_svn_revision = NewStrBufDup(Buf);
00148                      break;
00149               case 23:
00150                      info->serv_supports_openid = StrToi(Buf);
00151                      break;
00152               case 24:
00153                      info->serv_supports_guest = StrToi(Buf);
00154                      break;
00155               }
00156               ++a;
00157        }
00158        FreeStrBuf(&Buf);
00159        return info;
00160 }
00161 
00162 int GetConnected (void)
00163 {
00164        StrBuf *Buf;
00165        wcsession *WCC = WC;
00166 
00167        if (WCC->ReadBuf == NULL)
00168               WCC->ReadBuf = NewStrBufPlain(NULL, SIZ * 4);
00169        if (is_uds) /* unix domain socket */
00170               WCC->serv_sock = uds_connectsock(serv_sock_name);
00171        else        /* tcp socket */
00172               WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
00173        
00174        if (WCC->serv_sock < 0) {
00175               WCC->connected = 0;
00176               FreeStrBuf(&WCC->ReadBuf);
00177               return 1;
00178        }
00179        else {
00180               long Status;
00181               int short_status;
00182               Buf = NewStrBuf();
00183               WCC->connected = 1;
00184               StrBuf_ServGetln(Buf);      /* get the server greeting */
00185               short_status = GetServerStatus(Buf, &Status);
00186               FreeStrBuf(&Buf);
00187 
00188               /* Server isn't ready for us? */
00189               if (short_status != 2) {
00190                      if (Status == 571) {
00191                             hprintf("HTTP/1.1 503 Service Unavailable\r\n");
00192                             hprintf("Content-type: text/plain; charset=utf-8\r\n");
00193                             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."));
00194                      }
00195                      else {
00196                             wc_printf("%ld %s\n",
00197                                    Status,
00198                                    _("Received unexpected answer from Citadel server; bailing out.")
00199                             );
00200                             hprintf("HTTP/1.1 502 Bad Gateway\r\n");
00201                             hprintf("Content-type: text/plain; charset=utf-8\r\n");
00202                      }
00203                      end_burst();
00204                      end_webcit_session();
00205                      return 1;
00206               }
00207 
00208               /*
00209                * From what host is our user connecting?  Go with
00210                * the host at the other end of the HTTP socket,
00211                * unless we are following X-Forwarded-For: headers
00212                * and such a header has already turned up something.
00213                */
00214               if ( (!follow_xff) || (StrLength(WCC->Hdr->HR.browser_host) == 0) ) {
00215                      if (WCC->Hdr->HR.browser_host == NULL) {
00216                             WCC->Hdr->HR.browser_host = NewStrBuf();
00217                             Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), 
00218                                 WCC->Hdr->HR.browser_host, HFreeStrBuf);
00219                      }
00220                      locate_host(WCC->Hdr->HR.browser_host, WCC->Hdr->http_sock);
00221               }
00222               if (WCC->serv_info == NULL) {
00223                      WCC->serv_info = get_serv_info(WCC->Hdr->HR.browser_host, WCC->Hdr->HR.user_agent);
00224               }
00225               if (WCC->serv_info == NULL){
00226                      begin_burst();
00227                      wc_printf(_("Received unexpected answer from Citadel server; bailing out."));
00228                      hprintf("HTTP/1.1 502 Bad Gateway\r\n");
00229                      hprintf("Content-type: text/plain; charset=utf-8\r\n");
00230                      end_burst();
00231                      end_webcit_session();
00232                      return 1;
00233               }
00234               if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
00235                      begin_burst();
00236                      wc_printf(_("You are connected to a Citadel "
00237                               "server running Citadel %d.%02d. \n"
00238                               "In order to run this version of WebCit "
00239                               "you must also have Citadel %d.%02d or"
00240                               " newer.\n\n\n"),
00241                             WCC->serv_info->serv_rev_level / 100,
00242                             WCC->serv_info->serv_rev_level % 100,
00243                             MINIMUM_CIT_VERSION / 100,
00244                             MINIMUM_CIT_VERSION % 100
00245                             );
00246                      hprintf("HTTP/1.1 200 OK\r\n");
00247                      hprintf("Content-type: text/plain; charset=utf-8\r\n");
00248                      end_burst();
00249                      end_webcit_session();
00250                      return 1;
00251               }
00252               SetInlinMimeRenderers();
00253        }
00254        return 0;
00255 }
00256 
00257 
00258 void FmOut(StrBuf *Target, const char *align, const StrBuf *Source)
00259 {
00260        const char *ptr, *pte;
00261        const char *BufPtr = NULL;
00262        StrBuf *Line = NewStrBufPlain(NULL, SIZ);
00263        StrBuf *Line1 = NewStrBufPlain(NULL, SIZ);
00264        StrBuf *Line2 = NewStrBufPlain(NULL, SIZ);
00265        int bn = 0;
00266        int bq = 0;
00267        int i;
00268        long len;
00269        int intext = 0;
00270 
00271        StrBufAppendPrintf(Target, "<div class=\"fmout-%s\">\n", align);
00272 
00273        if (StrLength(Source) > 0) 
00274               do 
00275               {
00276                      StrBufSipLine(Line, Source, &BufPtr);
00277                      bq = 0;
00278                      i = 0;
00279                      ptr = ChrPtr(Line);
00280                      len = StrLength(Line);
00281                      pte = ptr + len;
00282 
00283                      if ((intext == 1) && (isspace(*ptr))) {
00284                             StrBufAppendBufPlain(Target, HKEY("<br>"), 0);
00285                      }
00286                      intext = 1;
00287                      if (isspace(*ptr)) while ((ptr < pte) &&
00288                                             ((*ptr == '>') ||
00289                                              isspace(*ptr)))
00290                                       {
00291                                              if (*ptr == '>')
00292                                                     bq++;
00293                                              ptr ++;
00294                                              i++;
00295                                       }
00296 
00297                      /*
00298                       * Quoted text should be displayed in italics and in a
00299                       * different colour.  This code understands Citadel-style
00300                       * " >" quotes and will convert to <BLOCKQUOTE> tags.
00301                       */
00302                      if (i > 0) StrBufCutLeft(Line, i);
00303               
00304 
00305                      for (i = bn; i < bq; i++)                        
00306                             StrBufAppendBufPlain(Target, HKEY("<blockquote>"), 0);
00307                      for (i = bq; i < bn; i++)                        
00308                             StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
00309                      bn = bq;
00310 
00311                      if (StrLength(Line) == 0)
00312                             continue;
00313 
00314                      /* Activate embedded URL's */
00315                      UrlizeText(Line1, Line, Line2);
00316 
00317                      StrEscAppend(Target, Line1, NULL, 0, 0);
00318 
00319                      StrBufAppendBufPlain(Target, HKEY("\n"), 0);
00320               }
00321               while ((BufPtr != StrBufNOTNULL) &&
00322                      (BufPtr != NULL));
00323 
00324        for (i = 0; i < bn; i++) {
00325               StrBufAppendBufPlain(Target, HKEY("</blockquote>"), 0);
00326        }
00327        StrBufAppendBufPlain(Target, HKEY("</div><br>\n"), 0);
00328        FreeStrBuf(&Line);
00329        FreeStrBuf(&Line1);
00330        FreeStrBuf(&Line2);
00331 }
00332 
00333 
00334 
00335 /*
00336  *  Transmit message text (in memory) to the server.
00337  */
00338 void text_to_server(char *ptr)
00339 {
00340        char buf[256];
00341        int ch, a, pos, len;
00342 
00343        pos = 0;
00344        buf[0] = 0;
00345 
00346        while (ptr[pos] != 0) {
00347               ch = ptr[pos++];
00348               if (ch == 10) {
00349                      len = strlen(buf);
00350                      while ( (isspace(buf[len - 1]))
00351                             && (buf[0] !=  '\0') 
00352                             && (buf[1] !=  '\0') )
00353                             buf[--len] = 0;
00354                      serv_puts(buf);
00355                      buf[0] = 0;
00356                      if (ptr[pos] != 0) strcat(buf, " ");
00357               } else {
00358                      a = strlen(buf);
00359                      buf[a + 1] = 0;
00360                      buf[a] = ch;
00361                      if ((ch == 32) && (strlen(buf) > 200)) {
00362                             buf[a] = 0;
00363                             serv_puts(buf);
00364                             buf[0] = 0;
00365                      }
00366                      if (strlen(buf) > 250) {
00367                             serv_puts(buf);
00368                             buf[0] = 0;
00369                      }
00370               }
00371        }
00372        serv_puts(buf);
00373 }
00374 
00375 
00376 /*
00377  * Transmit message text (in memory) to the server, converting to Quoted-Printable encoding as we go.
00378  */
00379 void text_to_server_qp(char *ptr)
00380 {
00381        unsigned char ch, buf[256];
00382        int pos;
00383        int output_len = 0;
00384 
00385        pos = 0;
00386        buf[0] = 0;
00387        output_len = 0;
00388 
00389        while (ptr[pos] != 0) {
00390               ch = (unsigned char)(ptr[pos++]);
00391 
00392               if (ch == 13) {
00393                      /* ignore carriage returns */
00394               }
00395               else if (ch == 10) {
00396                      /* hard line break */
00397                      if (output_len > 0) {
00398                             if (isspace(buf[output_len-1])) {
00399                                    sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
00400                                    output_len += 2;
00401                             }
00402                      }
00403                      buf[output_len++] = 0;
00404                      serv_puts((char *)buf);
00405                      output_len = 0;
00406               }
00407               else if (ch == 9) {
00408                      buf[output_len++] = ch;
00409               }
00410               else if ( (ch >= 32) && (ch <= 60) ) {
00411                      buf[output_len++] = ch;
00412               }
00413               else if ( (ch >= 62) && (ch <= 126) ) {
00414                      buf[output_len++] = ch;
00415               }
00416               else {
00417                      sprintf((char *)&buf[output_len], "=%02X", ch);
00418                      output_len += 3;
00419               }
00420               
00421               if (output_len > 72) {
00422                      /* soft line break */
00423                      if (isspace(buf[output_len-1])) {
00424                             sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
00425                             output_len += 2;
00426                      }
00427                      buf[output_len++] = '=';
00428                      buf[output_len++] = 0;
00429                      serv_puts((char *)buf);
00430                      output_len = 0;
00431               }
00432        }
00433 
00434        /* end of data - transmit anything that's left */
00435        if (output_len > 0) {
00436               if (isspace(buf[output_len-1])) {
00437                      sprintf((char *)&buf[output_len-1], "=%02X", buf[output_len-1]);
00438                      output_len += 2;
00439               }
00440               buf[output_len++] = 0;
00441               serv_puts((char *)buf);
00442               output_len = 0;
00443        }
00444 }
00445 
00446 
00447 
00448 
00449 /*
00450  * translate server message output to text (used for editing room info files and such)
00451  */
00452 void server_to_text()
00453 {
00454        char buf[SIZ];
00455 
00456        int count = 0;
00457 
00458        while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
00459               if ((buf[0] == 32) && (count > 0)) {
00460                      wc_printf("\n");
00461               }
00462               wc_printf("%s", buf);
00463               ++count;
00464        }
00465 }
00466 
00467 
00468 
00469 
00470 /*
00471  * Read text from server, appending to a string buffer until the
00472  * usual 000 terminator is found.  Caller is responsible for freeing
00473  * the returned pointer.
00474  */
00475 int read_server_text(StrBuf *Buf, long *nLines)
00476 {
00477        wcsession *WCC = WC;
00478        StrBuf *ReadBuf;
00479        long nRead;
00480        long nTotal = 0;
00481        long nlines;
00482        
00483        nlines = 0;
00484        ReadBuf = NewStrBuf();
00485        while ((WCC->serv_sock!=-1) &&
00486               (nRead = StrBuf_ServGetln(ReadBuf), (nRead >= 0) &&
00487               ((nRead != 3)||(strcmp(ChrPtr(ReadBuf), "000") != 0))))
00488        {
00489               StrBufAppendBuf(Buf, ReadBuf, 0);
00490               StrBufAppendBufPlain(Buf, HKEY("\n"), 0);
00491               nTotal += nRead;
00492               nlines ++;
00493        }
00494        FreeStrBuf(&ReadBuf);
00495        *nLines = nlines;
00496        return nTotal;
00497 }
00498 
00499 
00500 int GetServerStatusMsg(StrBuf *Line, long* FullState, int PutImportantMessage, int MajorOK)
00501 {
00502        int rc;
00503        if (FullState != NULL)
00504               *FullState = StrTol(Line);
00505        rc = ChrPtr(Line)[0] - 48;
00506        if ((!PutImportantMessage) || 
00507            (MajorOK == rc)||
00508            (StrLength(Line) <= 4))
00509               return rc;
00510 
00511        AppendImportantMessage(ChrPtr(Line) + 4, StrLength(Line) - 4);
00512        return rc;
00513 }
00514 
00515 
00516 void tmplput_serv_ip(StrBuf *Target, WCTemplputParams *TP)
00517 {
00518        StrBufAppendPrintf(Target, "%d", WC->ctdl_pid);
00519 }
00520 
00521 void tmplput_serv_admin(StrBuf *Target, WCTemplputParams *TP)
00522 {
00523        wcsession *WCC = WC;
00524        if (WCC->serv_info == NULL)
00525               return;
00526        StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_sysadm, 0);
00527 }
00528 
00529 void tmplput_serv_nodename(StrBuf *Target, WCTemplputParams *TP)
00530 {
00531        wcsession *WCC = WC;
00532        if (WCC->serv_info == NULL)
00533               return;
00534        StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_nodename, 0);
00535 }
00536 
00537 void tmplput_serv_humannode(StrBuf *Target, WCTemplputParams *TP)
00538 {
00539        wcsession *WCC = WC;
00540        if (WCC->serv_info == NULL)
00541               return;
00542        StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_humannode, 0);
00543 }
00544 
00545 void tmplput_serv_fqdn(StrBuf *Target, WCTemplputParams *TP)
00546 {
00547        wcsession *WCC = WC;
00548        if (WCC->serv_info == NULL)
00549               return;
00550        StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_fqdn, 0);
00551 }
00552 
00553 void tmplput_serv_software(StrBuf *Target, WCTemplputParams *TP)
00554 {
00555        wcsession *WCC = WC;
00556        if (WCC->serv_info == NULL)
00557               return;
00558        StrBufAppendTemplate(Target, TP, WCC->serv_info->serv_software, 0);
00559 }
00560 
00561 void tmplput_serv_rev_level(StrBuf *Target, WCTemplputParams *TP)
00562 {
00563        wcsession *WCC = WC;
00564        if (WCC->serv_info == NULL)
00565               return;
00566        StrBufAppendPrintf(Target, "%d.%02d",
00567                          WCC->serv_info->serv_rev_level / 100,
00568                          WCC->serv_info->serv_rev_level % 100);
00569 }
00570 int conditional_serv_newuser_disabled(StrBuf *Target, WCTemplputParams *TP)
00571 {
00572        wcsession *WCC = WC;
00573        if (WCC->serv_info == NULL)
00574               return 0;
00575        return WCC->serv_info->serv_newuser_disabled != 0;
00576 }
00577 
00578 int conditional_serv_supports_guest(StrBuf *Target, WCTemplputParams *TP)                                                                                                                                       
00579 {
00580        wcsession *WCC = WC;
00581         if (WCC->serv_info == NULL)
00582               return 0;
00583         return WCC->serv_info->serv_supports_guest != 0;
00584 }
00585 
00586 int conditional_serv_supports_openid(StrBuf *Target, WCTemplputParams *TP)
00587 {
00588        wcsession *WCC = WC;
00589        if (WCC->serv_info == NULL)
00590               return 0;
00591        return WCC->serv_info->serv_supports_openid != 0;
00592 }
00593 
00594 int conditional_serv_fulltext_enabled(StrBuf *Target, WCTemplputParams *TP)
00595 {
00596        wcsession *WCC = WC;
00597        if (WCC->serv_info == NULL)
00598               return 0;
00599        return WCC->serv_info->serv_fulltext_enabled != 0;
00600 }
00601 
00602 int conditional_serv_ldap_enabled(StrBuf *Target, WCTemplputParams *TP)
00603 {
00604        wcsession *WCC = WC;
00605        if (WCC->serv_info == NULL)
00606               return 0;
00607        return WCC->serv_info->serv_supports_ldap != 0;
00608 }
00609 
00610 void tmplput_serv_bbs_city(StrBuf *Target, WCTemplputParams *TP)
00611 {
00612        wcsession *WCC = WC;
00613        if (WCC->serv_info == NULL)
00614               return;
00615        StrBufAppendTemplate(Target, TP, WC->serv_info->serv_bbs_city, 0);
00616 }
00617 
00618 void tmplput_mesg(StrBuf *Target, WCTemplputParams *TP)
00619 {
00620        int n = 0;
00621        int Done = 0;
00622        StrBuf *Line;
00623        StrBuf *Buf;
00624 
00625        Buf = NewStrBuf();
00626        Line = NewStrBuf();
00627        serv_printf("MESG %s", TP->Tokens->Params[0]->Start);
00628 
00629        StrBuf_ServGetln(Line);
00630        if (GetServerStatus(Line, NULL) == 1) {
00631               while (!Done &&  (StrBuf_ServGetln(Line)>=0)) {
00632                      if ( (StrLength(Line)==3) && 
00633                           !strcmp(ChrPtr(Line), "000")) 
00634                             Done = 1;
00635                      else
00636                      {
00637                             if (n > 0)
00638                                    StrBufAppendBufPlain(Buf, "\n", 1, 0);
00639                             StrBufAppendBuf(Buf, Line, 0);
00640                      }
00641                      n++;
00642               }
00643        
00644               FlushStrBuf(Line);
00645               FmOut(Line, "center", Buf);
00646               StrBufAppendTemplate(Target, TP, Line, 1);
00647        }
00648        FreeStrBuf(&Buf);
00649        FreeStrBuf(&Line);
00650 }
00651 
00652 
00653 void RegisterEmbeddableMimeType(const char *MimeType, long MTLen, int Priority)
00654 {
00655        StrBuf *MT;
00656        MT = NewStrBufPlain(MimeType, MTLen);
00657        Put(EmbeddableMimes, IKEY(Priority), MT, HFreeStrBuf);
00658 }
00659 
00660 void CreateMimeStr(void)
00661 {
00662        HashPos  *it;
00663        void *vMime;
00664        long len = 0;
00665        const char *Key;
00666 
00667        it = GetNewHashPos(EmbeddableMimes, 0);
00668        while (GetNextHashPos(EmbeddableMimes, it, &len, &Key, &vMime) &&
00669                (vMime != NULL)) {
00670               if (StrLength(EmbeddableMimeStrs) > 0)
00671                      StrBufAppendBufPlain(EmbeddableMimeStrs, HKEY("|"), 0);
00672               else 
00673                      StrBufAppendBufPlain(EmbeddableMimeStrs, HKEY("MSGP "), 0);
00674               StrBufAppendBuf(EmbeddableMimeStrs, (StrBuf*) vMime, 0);
00675        }
00676        DeleteHashPos(&it);
00677 }
00678 
00679 void
00680 ServerStartModule_SERV_FUNC
00681 (void)
00682 {
00683        EmbeddableMimes = NewHash(1, Flathash);
00684        EmbeddableMimeStrs = NewStrBuf();
00685 }
00686 
00687 
00688 void
00689 ServerShutdownModule_SERV_FUNC
00690 (void)
00691 {
00692        FreeStrBuf(&EmbeddableMimeStrs);
00693        DeleteHash(&EmbeddableMimes);
00694 }
00695 
00696 void 
00697 InitModule_SERVFUNC
00698 (void)
00699 {
00700        is_uds = strcasecmp(ctdlhost, "uds") == 0;
00701        if (is_uds)
00702               snprintf(serv_sock_name, PATH_MAX, "%s/citadel.socket", ctdlport);
00703 
00704        RegisterConditional(HKEY("COND:SERV:OPENID"), 2, conditional_serv_supports_openid, CTX_NONE);
00705        RegisterConditional(HKEY("COND:SERV:NEWU"), 2, conditional_serv_newuser_disabled, CTX_NONE);
00706        RegisterConditional(HKEY("COND:SERV:FULLTEXT_ENABLED"), 2, conditional_serv_fulltext_enabled, CTX_NONE);
00707        RegisterConditional(HKEY("COND:SERV:LDAP_ENABLED"), 2, conditional_serv_ldap_enabled, CTX_NONE);
00708         RegisterConditional(HKEY("COND:SERV:SUPPORTS_GUEST"), 2, conditional_serv_supports_guest, CTX_NONE);
00709        RegisterNamespace("SERV:PID", 0, 0, tmplput_serv_ip, NULL, CTX_NONE);
00710        RegisterNamespace("SERV:NODENAME", 0, 1, tmplput_serv_nodename, NULL, CTX_NONE);
00711        RegisterNamespace("SERV:HUMANNODE", 0, 1, tmplput_serv_humannode, NULL, CTX_NONE);
00712        RegisterNamespace("SERV:FQDN", 0, 1, tmplput_serv_fqdn, NULL, CTX_NONE);
00713        RegisterNamespace("SERV:SOFTWARE", 0, 1, tmplput_serv_software, NULL, CTX_NONE);
00714        RegisterNamespace("SERV:REV_LEVEL", 0, 0, tmplput_serv_rev_level, NULL, CTX_NONE);
00715        RegisterNamespace("SERV:BBS_CITY", 0, 1, tmplput_serv_bbs_city, NULL, CTX_NONE);
00716        RegisterNamespace("SERV:MESG", 1, 2, tmplput_mesg, NULL, CTX_NONE);
00717        RegisterNamespace("SERV:ADMIN", 0, 1, tmplput_serv_admin, NULL, CTX_NONE);
00718 }
00719 
00720 
00721 
00722 void 
00723 SessionDestroyModule_SERVFUNC
00724 (wcsession *sess)
00725 {
00726        DeleteServInfo(&sess->serv_info);
00727 }