Back to index

webcit  8.12-dfsg
Defines | Functions | Variables
webcit.c File Reference
#include <stdio.h>
#include <stdarg.h>
#include "webcit.h"
#include "dav.h"
#include "webserver.h"

Go to the source code of this file.

Defines

#define SHOW_ME_VAPPEND_PRINTF

Functions

void stuff_to_cookie (int unset_cookie)
int GetConnected (void)
void PutRequestLocalMem (void *Data, DeleteHashDataFunc DeleteIt)
void DeleteWebcitHandler (void *vHandler)
void WebcitAddUrlHandler (const char *UrlString, long UrlSLen, const char *DisplayName, long dslen, WebcitHandlerFunc F, long Flags)
void tmplput_HANDLER_DISPLAYNAME (StrBuf *Target, WCTemplputParams *TP)
void wc_printf (const char *format,...)
void hprintf (const char *format,...)
void wDumpContent (int print_standard_html_footer)
void output_headers (int do_httpheaders, int do_htmlhead, int do_room_banner, int unset_cookies, int suppress_check, int cache)
void output_custom_content_header (const char *ctype)
void http_redirect (const char *whichpage)
void http_transmit_thing (const char *content_type, int is_static)
void convenience_page (const char *titlebarcolor, const char *titlebarmsg, const char *messagetext)
void blank_page (void)
void url_do_template (void)
void display_success (const char *successmessage)
void authorization_required (void)
void begin_ajax_response (void)
void end_ajax_response (void)
void ajax_servcmd (void)
void seconds_since_last_gexp (void)
void push_destination (void)
void pop_destination (void)
int ReadPostData (void)
int Conditional_REST_DEPTH (StrBuf *Target, WCTemplputParams *TP)
void session_loop (void)
void display_default_landing_page (void)
void sleeeeeeeeeep (int seconds)
int Conditional_IS_HTTPS (StrBuf *Target, WCTemplputParams *TP)
void AppendImportantMessage (const char *pch, long len)
int ConditionalImportantMesage (StrBuf *Target, WCTemplputParams *TP)
void tmplput_importantmessage (StrBuf *Target, WCTemplputParams *TP)
void tmplput_trailing_javascript (StrBuf *Target, WCTemplputParams *TP)
void tmplput_csslocal (StrBuf *Target, WCTemplputParams *TP)
void tmplput_packagestring (StrBuf *Target, WCTemplputParams *TP)
void InitModule_WEBCIT (void)
void ServerStartModule_WEBCIT (void)
void ServerShutdownModule_WEBCIT (void)
void SessionNewModule_WEBCIT (wcsession *sess)
void SessionDetachModule_WEBCIT (wcsession *sess)
void SessionDestroyModule_WEBCIT (wcsession *sess)

Variables

StrBuf * csslocal = NULL
HashList * HandlerHash = NULL
char static_local_dir [PATH_MAX]

Define Documentation

Definition at line 12 of file webcit.c.


Function Documentation

void ajax_servcmd ( void  )

Definition at line 365 of file webcit.c.

{
       wcsession *WCC = WC;
       int Done = 0;
       StrBuf *Buf;
       char *junk;
       size_t len;

       syslog(LOG_DEBUG, "ajax_servcmd() g_cmd=\"%s\"", bstr("g_cmd") );
       begin_ajax_response();
       Buf = NewStrBuf();
       serv_puts(bstr("g_cmd"));
       StrBuf_ServGetln(Buf);
       StrBufAppendBuf(WCC->WBuf, Buf, 0);
       StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
       
       switch (GetServerStatus(Buf, NULL)) {
       case 8:
              serv_puts("\n\n000");
              if ( (StrLength(Buf)==3) && 
                   !strcmp(ChrPtr(Buf), "000")) {
                     StrBufAppendBufPlain(WCC->WBuf, HKEY("\000"), 0);
                     break;
              }
       case 1:
              while (!Done) {
                     if (StrBuf_ServGetln(Buf) < 0)
                            break;
                     if ( (StrLength(Buf)==3) && 
                          !strcmp(ChrPtr(Buf), "000")) {
                            Done = 1;
                     }
                     StrBufAppendBuf(WCC->WBuf, Buf, 0);
                     StrBufAppendBufPlain(WCC->WBuf, HKEY("\n"), 0);
              }
              break;
       case 4:
              text_to_server(bstr("g_input"));
              serv_puts("000");
              break;
       case 6:
              len = atol(&ChrPtr(Buf)[4]);
              StrBuf_ServGetBLOBBuffered(Buf, len);
              break;
       case 7:
              len = atol(&ChrPtr(Buf)[4]);
              junk = malloc(len);
              memset(junk, 0, len);
              serv_write(junk, len);
              free(junk);
       }
       
       end_ajax_response();
       
       /*
        * This is kind of an ugly hack, but this is the only place it can go.
        * If the command was GEXP, then the instant messenger window must be
        * running, so reset the "last_pager_check" watchdog timer so
        * that page_popup() doesn't try to open it a second time. TODO: page_popup isn't with us anymore.
        */
       if (!strncasecmp(bstr("g_cmd"), "GEXP", 4)) {
              WCC->last_pager_check = time(NULL);
       }
       FreeStrBuf(&Buf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void AppendImportantMessage ( const char *  pch,
long  len 
)

Definition at line 839 of file webcit.c.

{
       wcsession *WCC = WC;

       if (StrLength(WCC->ImportantMsg) > 0) {
              StrBufAppendBufPlain(WCC->ImportantMsg, HKEY("\n"), 0);
       }
              
       StrBufAppendBufPlain(WCC->ImportantMsg, pch, len, 0);
}
void authorization_required ( void  )

Definition at line 305 of file webcit.c.

{
       wcsession *WCC = WC;
       const char *message = "";

       hprintf("HTTP/1.1 401 Authorization Required\r\n");
       hprintf(
              "Server: %s / %s\r\n"
              "Connection: close\r\n",
              PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software)
       );
       hprintf("WWW-Authenticate: Basic realm=\"%s\"\r\n", ChrPtr(WC->serv_info->serv_humannode));
       hprintf("Content-Type: text/html\r\n");
       begin_burst();
       wc_printf("<h1>");
       wc_printf(_("Authorization Required"));
       wc_printf("</h1>\r\n");

       if (WCC->ImportantMsg != NULL) {
              message = ChrPtr(WCC->ImportantMsg);
       }

       wc_printf(
              _("The resource you requested requires a valid username and password. "
              "You could not be logged in: %s\n"),
              message
       );
       wDumpContent(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void begin_ajax_response ( void  )

Definition at line 339 of file webcit.c.

                               {
       wcsession *WCC = WC;

       FlushStrBuf(WCC->HBuf);
       output_headers(0, 0, 0, 0, 0, 0);

       hprintf("Content-type: text/html; charset=UTF-8\r\n"
              "Server: %s\r\n"
              "Connection: close\r\n"
              ,
              PACKAGE_STRING);
       begin_burst();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void blank_page ( void  )

Definition at line 274 of file webcit.c.

                      {
       output_headers(1, 1, 0, 0, 0, 0);
       wDumpContent(2);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int Conditional_IS_HTTPS ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 834 of file webcit.c.

{
       return is_https != 0;
}

Here is the caller graph for this function:

int Conditional_REST_DEPTH ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 564 of file webcit.c.

{
       long Depth, IsDepth;
       long offset = 0;
       wcsession *WCC = WC;

       if (WCC->Hdr->HR.Handler != NULL)
              offset ++;
       Depth = GetTemplateTokenNumber(Target, TP, 2, 0);
       IsDepth = GetCount(WCC->Directory) + offset;

//     LogTemplateError(Target, "bla", 1, TP, "REST_DEPTH: %ld : %ld\n", Depth, IsDepth);
       if (Depth < 0) {
              Depth = -Depth;
              return IsDepth > Depth;
       }
       else 
              return Depth == IsDepth;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ConditionalImportantMesage ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 850 of file webcit.c.

{
       wcsession *WCC = WC;
       if (WCC != NULL)
              return (StrLength(WCC->ImportantMsg) > 0);
       else
              return 0;
}

Here is the caller graph for this function:

void convenience_page ( const char *  titlebarcolor,
const char *  titlebarmsg,
const char *  messagetext 
)

Definition at line 256 of file webcit.c.

{
       hprintf("HTTP/1.1 200 OK\n");
       output_headers(1, 1, 1, 0, 0, 0);
       wc_printf("<div id=\"room_banner_override\">\n");
       wc_printf("<table width=100%% border=0 bgcolor=\"#%s\"><tr><td>", titlebarcolor);
       wc_printf("<span class=\"titlebar\">%s</span>\n", titlebarmsg);
       wc_printf("</td></tr></table>\n");
       wc_printf("</div>\n<div id=\"content\">\n");
       escputs(messagetext);
       wc_printf("<hr />\n");
       wDumpContent(1);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void DeleteWebcitHandler ( void *  vHandler)

Definition at line 35 of file webcit.c.

{
       WebcitHandler *Handler = (WebcitHandler*) vHandler;
       FreeStrBuf(&Handler->Name);
       FreeStrBuf(&Handler->DisplayName);
       free (Handler);
}

Here is the caller graph for this function:

Definition at line 795 of file webcit.c.

                                        {
       wcsession *WCC = WC;

       if (WCC && WCC->serv_info && WCC->serv_info->serv_supports_guest) {
              /* default action */

              if (havebstr("go")) {
                     syslog(9, "Explicit room selection: %s", bstr("go"));
                     StrBuf *teh_room = NewStrBufPlain(bstr("go"), strlen(bstr("go")));
                     smart_goto(teh_room);
                     FreeStrBuf(&teh_room);
              }
              else if (default_landing_page) {
                     http_redirect(default_landing_page);
              }
              else {
                     StrBuf *teh_lobby = NewStrBufPlain(HKEY("_BASEROOM_"));
                     smart_goto(teh_lobby);
                     FreeStrBuf(&teh_lobby);
              }
       }
       else {
              display_login();
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void display_success ( const char *  successmessage)

Definition at line 296 of file webcit.c.

{
       convenience_page("007700", "OK", successmessage);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void end_ajax_response ( void  )

Definition at line 357 of file webcit.c.

                             {
       wDumpContent(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int GetConnected ( void  )

Definition at line 162 of file serv_func.c.

{
       StrBuf *Buf;
       wcsession *WCC = WC;

       if (WCC->ReadBuf == NULL)
              WCC->ReadBuf = NewStrBufPlain(NULL, SIZ * 4);
       if (is_uds) /* unix domain socket */
              WCC->serv_sock = uds_connectsock(serv_sock_name);
       else        /* tcp socket */
              WCC->serv_sock = tcp_connectsock(ctdlhost, ctdlport);
       
       if (WCC->serv_sock < 0) {
              WCC->connected = 0;
              FreeStrBuf(&WCC->ReadBuf);
              return 1;
       }
       else {
              long Status;
              int short_status;
              Buf = NewStrBuf();
              WCC->connected = 1;
              StrBuf_ServGetln(Buf);      /* get the server greeting */
              short_status = GetServerStatus(Buf, &Status);
              FreeStrBuf(&Buf);

              /* Server isn't ready for us? */
              if (short_status != 2) {
                     if (Status == 571) {
                            hprintf("HTTP/1.1 503 Service Unavailable\r\n");
                            hprintf("Content-type: text/plain; charset=utf-8\r\n");
                            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."));
                     }
                     else {
                            wc_printf("%ld %s\n",
                                   Status,
                                   _("Received unexpected answer from Citadel server; bailing out.")
                            );
                            hprintf("HTTP/1.1 502 Bad Gateway\r\n");
                            hprintf("Content-type: text/plain; charset=utf-8\r\n");
                     }
                     end_burst();
                     end_webcit_session();
                     return 1;
              }

              /*
               * From what host is our user connecting?  Go with
               * the host at the other end of the HTTP socket,
               * unless we are following X-Forwarded-For: headers
               * and such a header has already turned up something.
               */
              if ( (!follow_xff) || (StrLength(WCC->Hdr->HR.browser_host) == 0) ) {
                     if (WCC->Hdr->HR.browser_host == NULL) {
                            WCC->Hdr->HR.browser_host = NewStrBuf();
                            Put(WCC->Hdr->HTTPHeaders, HKEY("FreeMeWithTheOtherHeaders"), 
                                WCC->Hdr->HR.browser_host, HFreeStrBuf);
                     }
                     locate_host(WCC->Hdr->HR.browser_host, WCC->Hdr->http_sock);
              }
              if (WCC->serv_info == NULL) {
                     WCC->serv_info = get_serv_info(WCC->Hdr->HR.browser_host, WCC->Hdr->HR.user_agent);
              }
              if (WCC->serv_info == NULL){
                     begin_burst();
                     wc_printf(_("Received unexpected answer from Citadel server; bailing out."));
                     hprintf("HTTP/1.1 502 Bad Gateway\r\n");
                     hprintf("Content-type: text/plain; charset=utf-8\r\n");
                     end_burst();
                     end_webcit_session();
                     return 1;
              }
              if (WCC->serv_info->serv_rev_level < MINIMUM_CIT_VERSION) {
                     begin_burst();
                     wc_printf(_("You are connected to a Citadel "
                              "server running Citadel %d.%02d. \n"
                              "In order to run this version of WebCit "
                              "you must also have Citadel %d.%02d or"
                              " newer.\n\n\n"),
                            WCC->serv_info->serv_rev_level / 100,
                            WCC->serv_info->serv_rev_level % 100,
                            MINIMUM_CIT_VERSION / 100,
                            MINIMUM_CIT_VERSION % 100
                            );
                     hprintf("HTTP/1.1 200 OK\r\n");
                     hprintf("Content-type: text/plain; charset=utf-8\r\n");
                     end_burst();
                     end_webcit_session();
                     return 1;
              }
              SetInlinMimeRenderers();
       }
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void hprintf ( const char *  format,
  ... 
)

Definition at line 96 of file webcit.c.

{
       wcsession *WCC = WC;
       va_list arg_ptr;

       va_start(arg_ptr, format);
       StrBufVAppendPrintf(WCC->HBuf, format, arg_ptr);
       va_end(arg_ptr);
}
void http_redirect ( const char *  whichpage)

Definition at line 211 of file webcit.c.

                                          {
       hprintf("HTTP/1.1 302 Moved Temporarily\n");
       hprintf("Location: %s\r\n", whichpage);
       hprintf("URI: %s\r\n", whichpage);
       hprintf("Content-type: text/html; charset=utf-8\r\n");
       stuff_to_cookie(0);
       begin_burst();
       wc_printf("<html><body>");
       wc_printf("Go <a href=\"%s\">here</A>.", whichpage);
       wc_printf("</body></html>\n");
       end_burst();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void http_transmit_thing ( const char *  content_type,
int  is_static 
)

Definition at line 234 of file webcit.c.

{
       syslog(9, "http_transmit_thing(%s)%s", content_type, ((is_static > 0) ? " (static)" : ""));
       output_headers(0, 0, 0, 0, 0, is_static);

       hprintf("Content-type: %s\r\n"
              "Server: %s\r\n"
              "Connection: close\r\n",
              content_type,
              PACKAGE_STRING);

       end_burst();
}

Here is the call graph for this function:

Here is the caller graph for this function:

void InitModule_WEBCIT ( void  )

Definition at line 896 of file webcit.c.

{
       char dir[SIZ];
       WebcitAddUrlHandler(HKEY("blank"), "", 0, blank_page, ANONYMOUS|COOKIEUNNEEDED|ISSTATIC);
       WebcitAddUrlHandler(HKEY("landing"), "", 0, display_default_landing_page, ANONYMOUS|COOKIEUNNEEDED);
       WebcitAddUrlHandler(HKEY("do_template"), "", 0, url_do_template, ANONYMOUS);
       WebcitAddUrlHandler(HKEY("sslg"), "", 0, seconds_since_last_gexp, AJAX|LOGCHATTY);
       WebcitAddUrlHandler(HKEY("ajax_servcmd"), "", 0, ajax_servcmd, 0);
       WebcitAddUrlHandler(HKEY("webcit"), "", 0, blank_page, URLNAMESPACE);
       WebcitAddUrlHandler(HKEY("push"), "", 0, push_destination, AJAX);
       WebcitAddUrlHandler(HKEY("pop"), "", 0, pop_destination, 0);

       WebcitAddUrlHandler(HKEY("401"), "", 0, authorization_required, ANONYMOUS|COOKIEUNNEEDED);
       RegisterConditional(HKEY("COND:IMPMSG"), 0, ConditionalImportantMesage, CTX_NONE);
       RegisterConditional(HKEY("COND:REST:DEPTH"), 0, Conditional_REST_DEPTH, CTX_NONE);
       RegisterConditional(HKEY("COND:IS_HTTPS"), 0, Conditional_IS_HTTPS, CTX_NONE);

       RegisterNamespace("CSSLOCAL", 0, 0, tmplput_csslocal, NULL, CTX_NONE);
       RegisterNamespace("IMPORTANTMESSAGE", 0, 0, tmplput_importantmessage, NULL, CTX_NONE);
       RegisterNamespace("TRAILING_JAVASCRIPT", 0, 0, tmplput_trailing_javascript, NULL, CTX_NONE);
       RegisterNamespace("URL:DISPLAYNAME", 0, 1, tmplput_HANDLER_DISPLAYNAME, NULL, CTX_NONE);
       RegisterNamespace("PACKAGESTRING", 0, 1, tmplput_packagestring, NULL, CTX_NONE);

       
       snprintf(dir, SIZ, "%s/webcit.css", static_local_dir);
       if (!access(dir, R_OK)) {
              syslog(9, "Using local Stylesheet [%s]", dir);
              csslocal = NewStrBufPlain(HKEY("<link href=\"static.local/webcit.css\" rel=\"stylesheet\" type=\"text/css\" />"));
       }
       else
              syslog(9, "No Site-local Stylesheet [%s] installed.", dir);

}

Here is the call graph for this function:

Here is the caller graph for this function:

void output_custom_content_header ( const char *  ctype)

Definition at line 200 of file webcit.c.

                                                     {
       hprintf("HTTP/1.1 200 OK\r\n");
       hprintf("Content-type: %s; charset=utf-8\r\n",ctype);
       hprintf("Server: %s / %s\r\n", PACKAGE_STRING, ChrPtr(WC->serv_info->serv_software));
       hprintf("Connection: close\r\n");
}

Here is the call graph for this function:

void output_headers ( int  do_httpheaders,
int  do_htmlhead,
int  do_room_banner,
int  unset_cookies,
int  suppress_check,
int  cache 
)

Definition at line 134 of file webcit.c.

  {
       wcsession *WCC = WC;
       char httpnow[128];

       hprintf("HTTP/1.1 200 OK\n");
       http_datestring(httpnow, sizeof httpnow, time(NULL));

       if (do_httpheaders) {
              if (WCC->serv_info != NULL)
                     hprintf("Content-type: text/html; charset=utf-8\r\n"
                            "Server: %s / %s\n"
                            "Connection: close\r\n",
                            PACKAGE_STRING, 
                            ChrPtr(WCC->serv_info->serv_software));
              else
                     hprintf("Content-type: text/html; charset=utf-8\r\n"
                            "Server: %s / [n/a]\n"
                            "Connection: close\r\n",
                            PACKAGE_STRING);
       }

       if (cache > 0) {
              char httpTomorow[128];

              http_datestring(httpTomorow, sizeof httpTomorow, 
                            time(NULL) + 60 * 60 * 24 * 2);

              hprintf("Pragma: public\r\n"
                     "Cache-Control: max-age=3600, must-revalidate\r\n"
                     "Last-modified: %s\r\n"
                     "Expires: %s\r\n",
                     httpnow,
                     httpTomorow
              );
       }
       else {
              hprintf("Pragma: no-cache\r\n"
                     "Cache-Control: no-store\r\n"
                     "Expires: -1\r\n"
              );
       }

       if (cache < 2) stuff_to_cookie(unset_cookies);

       if (do_htmlhead) {
              begin_burst();
              do_template("head");
              if ( (WCC->logged_in) && (!unset_cookies) ) {
                     DoTemplate(HKEY("paging"), NULL, &NoCtx);
              }
              if (do_room_banner) {
                     tmplput_roombanner(NULL, NULL);
              }
       }

       if (do_room_banner) {
              wc_printf("<div id=\"content\">\n");
       }
}

Here is the call graph for this function:

void pop_destination ( void  )

Definition at line 478 of file webcit.c.

                           {
       wcsession *WCC = WC;

       /*
        * If we are in the middle of a new user signup, the server may request that
        * we first pass through a registration screen.
        */
       if ((WCC) && (WCC->need_regi)) {
              if ((WCC->PushedDestination != NULL) && (StrLength(WCC->PushedDestination) > 0)) {
                     /* Registering will take us to the My Citadel Config room, so save our place */
                     StrBufAppendBufPlain(WCC->PushedDestination, HKEY("?go="), 0);
                     StrBufUrlescAppend(WCC->PushedDestination, WCC->CurRoom.name, NULL);
              }
              WCC->need_regi = 0;
              display_reg(1);
              return;
       }

       /*
        * Do something reasonable if we somehow ended up requesting a pop without
        * having first done a push.
        */
       if ( (!WCC) || (WCC->PushedDestination == NULL) || (StrLength(WCC->PushedDestination) == 0) ) {
              do_welcome();
              return;
       }

       /*
        * All righty then!  We have a destination saved, so go there now.
        */
       syslog(9, "Pop: %s", ChrPtr(WCC->PushedDestination));
       http_redirect(ChrPtr(WCC->PushedDestination));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void push_destination ( void  )

Definition at line 460 of file webcit.c.

                            {
       wcsession *WCC = WC;

       if (!WCC) {
              wc_printf("no session");
              return;
       }

       FreeStrBuf(&WCC->PushedDestination);
       WCC->PushedDestination = NewStrBufDup(SBSTR("url"));
       syslog(9, "Push: %s", ChrPtr(WCC->PushedDestination));
       wc_printf("OK");
}

Here is the call graph for this function:

Here is the caller graph for this function:

void PutRequestLocalMem ( void *  Data,
DeleteHashDataFunc  DeleteIt 
)

Definition at line 26 of file webcit.c.

{
        wcsession *WCC = WC;
       int n;
       
       n = GetCount(WCC->Hdr->HTTPHeaders);
       Put(WCC->Hdr->HTTPHeaders, IKEY(n), Data, DeleteIt);
}

Here is the caller graph for this function:

int ReadPostData ( void  )

Read the entire input data at once.

Definition at line 514 of file webcit.c.

{
       int rc;
       int urlencoded_post = 0;
       wcsession *WCC = WC;
       StrBuf *content = NULL;
       
       urlencoded_post = (strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "application/x-www-form-urlencoded", 33) == 0) ;

       content = NewStrBufPlain(NULL, WCC->Hdr->HR.ContentLength + 256);

       if (!urlencoded_post)
       {
              StrBufPrintf(content, 
                   "Content-type: %s\n"
                          "Content-length: %ld\n\n",
                          ChrPtr(WCC->Hdr->HR.ContentType), 
                          WCC->Hdr->HR.ContentLength);
       }

       rc = client_read_to(WCC->Hdr, content, 
                         WCC->Hdr->HR.ContentLength,
                         SLEEPING);
       if (rc < 0)
              return rc;
              
       
       if (urlencoded_post) {
              ParseURLParams(content);
       } else if (!strncasecmp(ChrPtr(WCC->Hdr->HR.ContentType), "multipart", 9)) {
              char *Buf;
              char *BufEnd;
              long len;

              len = StrLength(content);
              Buf = SmashStrBuf(&content);
              BufEnd = Buf + len;
              mime_parser(Buf, BufEnd, *upload_handler, NULL, NULL, NULL, 0);
              free(Buf);
       } else if (WCC->Hdr->HR.ContentLength > 0) {
              WCC->upload = content;
              WCC->upload_length = StrLength(WCC->upload);
              content = NULL;
       }
       FreeStrBuf(&content);
       return 1;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void seconds_since_last_gexp ( void  )

Definition at line 436 of file webcit.c.

{
       char buf[256];

       if ( (time(NULL) - WC->last_pager_check) < 30) {
              wc_printf("NO\n");
       }
       else {
              memset(buf, 0, 5);
              serv_puts("NOOP");
              serv_getln(buf, sizeof buf);
              if (buf[3] == '*') {
                     wc_printf("YES");
              }
              else {
                     wc_printf("NO");
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void ServerShutdownModule_WEBCIT ( void  )

Definition at line 940 of file webcit.c.

{
       FreeStrBuf(&csslocal);
       DeleteHash(&HandlerHash);
}

Here is the caller graph for this function:

void ServerStartModule_WEBCIT ( void  )

Definition at line 932 of file webcit.c.

{
       HandlerHash = NewHash(1, NULL);
}

Here is the caller graph for this function:

void session_loop ( void  )

Definition at line 589 of file webcit.c.

{
       int xhttp;
       StrBuf *Buf;
       
       /*
        * We stuff these with the values coming from the client cookies,
        * so we can use them to reconnect a timed out session if we have to.
        */
       wcsession *WCC;
      
       WCC= WC;
       WCC->upload_length = 0;
       WCC->upload = NULL;
       WCC->Hdr->nWildfireHeaders = 0;

       if (WCC->Hdr->HR.ContentLength > 0) {
              if (ReadPostData() < 0) {
                     return;
              }
       }

       Buf = NewStrBuf();
       WCC->trailing_javascript = NewStrBuf();

       /* Convert base64-encoded URL's back to plain text */
       if (!strncmp(ChrPtr(WCC->Hdr->this_page), "/B64", 4)) {
              StrBufCutLeft(WCC->Hdr->this_page, 4);
              StrBufDecodeBase64(WCC->Hdr->this_page);
              http_redirect(ChrPtr(WCC->Hdr->this_page));
              goto SKIP_ALL_THIS_CRAP;
       }

       /* If there are variables in the URL, we must grab them now */
       if (WCC->Hdr->PlainArgs != NULL)
              ParseURLParams(WCC->Hdr->PlainArgs);

       /* If the client sent a nonce that is incorrect, kill the request. */
       if (havebstr("nonce")) {
              syslog(9, "Comparing supplied nonce %s to session nonce %d", 
                     bstr("nonce"), WCC->nonce
              );
              if (ibstr("nonce") != WCC->nonce) {
                     syslog(9, "Ignoring request with mismatched nonce.");
                     hprintf("HTTP/1.1 404 Security check failed\r\n");
                     hprintf("Content-Type: text/plain\r\n");
                     begin_burst();
                     wc_printf("Security check failed.\r\n");
                     end_burst();
                     goto SKIP_ALL_THIS_CRAP;
              }
       }

       /*
        * If we're not connected to a Citadel server, try to hook up the connection now.
        */
       if (!WCC->connected) {
              if (GetConnected()) {
                     hprintf("HTTP/1.1 503 Service Unavailable\r\n");
                     hprintf("Content-Type: text/html\r\n");
                     begin_burst();
                     wc_printf("<html><head><title>503 Service Unavailable</title></head><body>\n");
                     wc_printf(_("This program was unable to connect or stay "
                            "connected to the Citadel server.  Please report "
                            "this problem to your system administrator.")
                     );
                     wc_printf("<br>");
                     wc_printf("<a href=\"http://www.citadel.org/doku.php/"
                            "faq:generalquestions:webcit_unable_to_connect\">%s</a>",
                            _("Read More...")
                     );
                     wc_printf("</body></html>\n");
                     end_burst();
                     goto SKIP_ALL_THIS_CRAP;
              }
       }

       /*
        * If we're not logged in, but we have authentication data (either from
        * a cookie or from http-auth), try logging in to Citadel using that.
        */
       if (   (!WCC->logged_in)
              && (StrLength(WCC->Hdr->c_username) > 0)
              && (StrLength(WCC->Hdr->c_password) > 0)
       ) {
              long Status;

              FlushStrBuf(Buf);
              serv_printf("USER %s", ChrPtr(WCC->Hdr->c_username));
              StrBuf_ServGetln(Buf);
              if (GetServerStatus(Buf, &Status) == 3) {
                     serv_printf("PASS %s", ChrPtr(WCC->Hdr->c_password));
                     StrBuf_ServGetln(Buf);
                     if (GetServerStatus(Buf, NULL) == 2) {
                            become_logged_in(WCC->Hdr->c_username,
                                           WCC->Hdr->c_password, Buf);
                     } else {
                            /* Should only display when password is wrong */
                            WCC->ImportantMsg = NewStrBufPlain(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
                            authorization_required();
                            FreeStrBuf(&Buf);
                            goto SKIP_ALL_THIS_CRAP;
                     }
              }
              else if (Status == 541) {
                     WCC->logged_in = 1;
              }
       }

       xhttp = (WCC->Hdr->HR.eReqType != eGET) &&
              (WCC->Hdr->HR.eReqType != ePOST) &&
              (WCC->Hdr->HR.eReqType != eHEAD);

       /*
        * If a 'go' (or 'gotofirst') parameter has been specified, attempt to goto that room
        * prior to doing anything else.
        */
       if (havebstr("go")) {
              int ret;
              syslog(9, "Explicit room selection: %s", bstr("go"));
              ret = gotoroom(sbstr("go"));       /* do quietly to avoid session output! */
              if ((ret/100) != 2) {
                     syslog(1, "Unable to change to [%s]; Reason: %d", bstr("go"), ret);
              }
       }
       else if (havebstr("gotofirst")) {
              int ret;
              syslog(9, "Explicit room selection: %s", bstr("gotofirst"));
              ret = gotoroom(sbstr("gotofirst"));       /* do quietly to avoid session output! */
              if ((ret/100) != 2) {
                     syslog(1, "Unable to change to [%s]; Reason: %d", bstr("gotofirst"), ret);
              }
       }

       /*
        * If we aren't in any room yet, but we have cookie data telling us where we're
        * supposed to be, and 'go' was not specified, then go there.
        */
       else if ( (StrLength(WCC->CurRoom.name) == 0) && ( (StrLength(WCC->Hdr->c_roomname) > 0) )) {
              int ret;

              syslog(9, "We are in '%s' but cookie indicates '%s', going there...",
                     ChrPtr(WCC->CurRoom.name),
                     ChrPtr(WCC->Hdr->c_roomname)
              );
              ret = gotoroom(WCC->Hdr->c_roomname);     /* do quietly to avoid session output! */
              if ((ret/100) != 2) {
                     syslog(1, "COOKIEGOTO: Unable to change to [%s]; Reason: %d",
                            ChrPtr(WCC->Hdr->c_roomname), ret);
              }
       }

       if (WCC->Hdr->HR.Handler != NULL) {
              if (   (!WCC->logged_in)
                     && ((WCC->Hdr->HR.Handler->Flags & ANONYMOUS) == 0)
                     && (WCC->serv_info->serv_supports_guest == 0)
              ) {
                     display_login();
              }
              else {
                     if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0) {
                            begin_ajax_response();
                     }
                     WCC->Hdr->HR.Handler->F();
                     if ((WCC->Hdr->HR.Handler->Flags & AJAX) != 0) {
                            end_ajax_response();
                     }
              }
       }
       /* When all else fails, display the default landing page or a main menu. */
       else {
              /* 
               * ordinary browser users get a nice login screen, DAV etc. requsets
               * are given a 401 so they can handle it appropriate.
               */
              if (!WCC->logged_in)  {
                     if (xhttp) {
                            authorization_required();
                     }
                     else {
                            display_default_landing_page();
                     }
              }
              /*
               * Toplevel dav requests? or just a flat browser request? 
               */
              else {
                     if (xhttp) {
                            dav_main();
                     }
                     else {
                            display_main_menu();
                     }
              }
       }

SKIP_ALL_THIS_CRAP:
       FreeStrBuf(&Buf);
       fflush(stdout);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 980 of file webcit.c.

{
       FreeStrBuf(&sess->WBuf);
       FreeStrBuf(&sess->HBuf);
       FreeStrBuf(&sess->ImportantMsg);
       FreeStrBuf(&sess->PushedDestination);
}

Here is the caller graph for this function:

Definition at line 959 of file webcit.c.

{
       DeleteHash(&sess->Directory);

       FreeStrBuf(&sess->upload);
       sess->upload_length = 0;
       
       FreeStrBuf(&sess->trailing_javascript);

       if (StrLength(sess->WBuf) > SIZ * 30) /* Bigger than 120K? release. */
       {
              FreeStrBuf(&sess->WBuf);
              sess->WBuf = NewStrBuf();
       }
       else
              FlushStrBuf(sess->WBuf);
       FlushStrBuf(sess->HBuf);
}

Here is the caller graph for this function:

Definition at line 950 of file webcit.c.

{
       sess->ImportantMsg = NewStrBuf();
       sess->WBuf = NewStrBufPlain(NULL, SIZ * 4);
       sess->HBuf = NewStrBufPlain(NULL, SIZ / 4);
}

Here is the caller graph for this function:

void sleeeeeeeeeep ( int  seconds)

Definition at line 825 of file webcit.c.

{
       struct timeval tv;

       tv.tv_sec = seconds;
       tv.tv_usec = 0;
       select(0, NULL, NULL, NULL, &tv);
}

Here is the caller graph for this function:

void stuff_to_cookie ( int  unset_cookie)

Definition at line 27 of file cookie_conversion.c.

{
       wcsession *WCC = WC;
       char buf[SIZ];

       if (unset_cookies) {
              hprintf("Set-cookie: webcit=%s; path=/\r\n", unset);
       }
       else
       {
              StrBufAppendPrintf(WCC->HBuf, "Set-cookie: webcit=");
              snprintf(buf, sizeof(buf), "%d", WCC->wc_session);
              StrBufHexescAppend(WCC->HBuf, NULL, buf);
              StrBufHexescAppend(WCC->HBuf, NULL, "|");
              StrBufHexescAppend(WCC->HBuf, WCC->wc_username, NULL);
              StrBufHexescAppend(WCC->HBuf, NULL, "|");
              StrBufHexescAppend(WCC->HBuf, WCC->wc_password, NULL);
              StrBufHexescAppend(WCC->HBuf, NULL, "|");
              StrBufHexescAppend(WCC->HBuf, WCC->CurRoom.name, NULL);
              StrBufHexescAppend(WCC->HBuf, NULL, "|");
              StrBufHexescAppend(WCC->HBuf, NULL, get_selected_language());
              StrBufHexescAppend(WCC->HBuf, NULL, "|");

              if (server_cookie != NULL) {
                     StrBufAppendPrintf(WCC->HBuf, 
                                      ";path=/ \r\n%s\r\n", 
                                      server_cookie);
              }
              else {
                     StrBufAppendBufPlain(WCC->HBuf,
                                        HKEY("; path=/\r\n"), 0);
              }
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tmplput_csslocal ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 879 of file webcit.c.

{
       StrBufAppendBuf(Target, 
                     csslocal, 0);
}

Here is the caller graph for this function:

void tmplput_HANDLER_DISPLAYNAME ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 59 of file webcit.c.

{
       wcsession *WCC = WC;
       if (WCC->Hdr->HR.Handler != NULL)
              StrBufAppendTemplate(Target, TP, WCC->Hdr->HR.Handler->DisplayName, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void tmplput_importantmessage ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 859 of file webcit.c.

{
       wcsession *WCC = WC;
       
       if (WCC != NULL) {
              if (StrLength(WCC->ImportantMsg) > 0) {
                     StrEscAppend(Target, WCC->ImportantMsg, NULL, 0, 0);
                     FlushStrBuf(WCC->ImportantMsg);
              }
       }
}

Here is the caller graph for this function:

void tmplput_packagestring ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 885 of file webcit.c.

{
       StrBufAppendBufPlain(Target, 
                          HKEY(PACKAGE_STRING), 0);
}

Here is the caller graph for this function:

void tmplput_trailing_javascript ( StrBuf *  Target,
WCTemplputParams TP 
)

Definition at line 871 of file webcit.c.

{
       wcsession *WCC = WC;

       if (WCC != NULL)
              StrBufAppendTemplate(Target, TP, WCC->trailing_javascript, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void url_do_template ( void  )

Definition at line 283 of file webcit.c.

                           {
       const StrBuf *MimeType;
       const StrBuf *Tmpl = sbstr("template");
       begin_burst();
       MimeType = DoTemplate(SKEY(Tmpl), NULL, &NoCtx);
       http_transmit_thing(ChrPtr(MimeType), 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void wc_printf ( const char *  format,
  ... 
)

Definition at line 73 of file webcit.c.

{
       wcsession *WCC = WC;
       va_list arg_ptr;

       if (WCC->WBuf == NULL)
              WCC->WBuf = NewStrBuf();
#ifdef UBER_VERBOSE_DEBUGGING
       StrBufAppendPrintf(WCC->WBuf, "\n%s:%s:%d[", FILE, FUNCTION, LINE);
#endif

       va_start(arg_ptr, format);
       StrBufVAppendPrintf(WCC->WBuf, format, arg_ptr);
       va_end(arg_ptr);
#ifdef UBER_VERBOSE_DEBUGGING
       StrBufAppendPrintf(WCC->WBuf, "]\n");
#endif
}
void wDumpContent ( int  print_standard_html_footer)

Definition at line 115 of file webcit.c.

{
       if (print_standard_html_footer) {
              wc_printf("</div> <!-- end of 'content' div -->\n");
              do_template("trailing");
       }

       /* If we've been saving it all up for one big output burst,
        * go ahead and do that now.
        */
       end_burst();
}

Here is the call graph for this function:

void WebcitAddUrlHandler ( const char *  UrlString,
long  UrlSLen,
const char *  DisplayName,
long  dslen,
WebcitHandlerFunc  F,
long  Flags 
)

Definition at line 43 of file webcit.c.

{
       WebcitHandler *NewHandler;  
       NewHandler = (WebcitHandler*) malloc(sizeof(WebcitHandler));
       NewHandler->F = F;
       NewHandler->Flags = Flags;
       NewHandler->Name = NewStrBufPlain(UrlString, UrlSLen);
       StrBufShrinkToFit(NewHandler->Name, 1);
       NewHandler->DisplayName = NewStrBufPlain(DisplayName, dslen);
       StrBufShrinkToFit(NewHandler->DisplayName, 1);
       Put(HandlerHash, UrlString, UrlSLen, NewHandler, DeleteWebcitHandler);
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

StrBuf* csslocal = NULL

Definition at line 19 of file webcit.c.

HashList* HandlerHash = NULL

Definition at line 20 of file webcit.c.

char static_local_dir[PATH_MAX]

Definition at line 88 of file sysdep.c.