* Rewrote the HTTP engine and application coupling to run in a worker thread
authorArt Cancro <ajc@citadel.org>
Fri, 3 Dec 1999 05:09:55 +0000 (05:09 +0000)
committerArt Cancro <ajc@citadel.org>
Fri, 3 Dec 1999 05:09:55 +0000 (05:09 +0000)
  model and to run as a single multithreaded program (eliminated helper
  processes and pipes).  It currently runs but has many large bugs.

26 files changed:
webcit/ChangeLog
webcit/Makefile.in
webcit/auth.c
webcit/braindamage.c [deleted file]
webcit/child.h [deleted file]
webcit/context_loop.c
webcit/cookie_conversion.c
webcit/graphics.c
webcit/locate_host.c
webcit/mainmenu.c
webcit/messages.c
webcit/mime_parser.c
webcit/netconf.c
webcit/paging.c
webcit/roomops.c
webcit/serv_func.c
webcit/siteconfig.c
webcit/sysmsgs.c
webcit/tcp_sockets.c
webcit/tools.c
webcit/userlist.c
webcit/webcit.c
webcit/webcit.h
webcit/webserver.c
webcit/who.c
webcit/wildmat.c [deleted file]

index 16dd4d70c62bffa05f5e163b6712a6340e952f97..e4df588537220e33008d592d6606746f8b7f60b0 100644 (file)
@@ -1,4 +1,9 @@
 $Log$
+Revision 1.109  1999/12/03 05:09:54  ajc
+* Rewrote the HTTP engine and application coupling to run in a worker thread
+  model and to run as a single multithreaded program (eliminated helper
+  processes and pipes).  It currently runs but has many large bugs.
+
 Revision 1.108  1999/12/03 00:18:20  ajc
 * Added ".c.o" rule to Makefile
 
@@ -319,4 +324,3 @@ Sun Dec  6 19:50:55 EST 1998 Art Cancro <ajc@uncnsrd.mt-kisco.ny.us>
 
 1998-12-03 Nathan Bryant <bryant@cs.usm.maine.edu>
        * webserver.c: warning fix
-
index a88fd4080fb86464bd4c541bef5e034b5484276d..2cd30c9a65e29de4f8ea9bbe2f367389dcb01e82 100644 (file)
@@ -10,7 +10,7 @@ srcdir=@srcdir@
 
 # End of configuration section
 
-all: webserver webcit
+all: webserver
 
 .SUFFIXES: .c .o
 
@@ -22,23 +22,20 @@ distclean: clean
 
 
 webserver: webserver.o context_loop.o tools.o \
-       cookie_conversion.o locate_host.o $(LIBOBJS)
+       cookie_conversion.o locate_host.o \
+       webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
+       roomops.o messages.o userlist.o paging.o sysmsgs.o \
+       mime_parser.o graphics.o netconf.o siteconfig.o $(LIBOBJS)
        $(CC) webserver.o context_loop.o tools.o cookie_conversion.o \
-       locate_host.o $(LIBOBJS) $(LIBS) -o webserver
+       webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
+       roomops.o messages.o userlist.o paging.o sysmsgs.o \
+       locate_host.o siteconfig.o \
+       mime_parser.o graphics.o netconf.o \
+       $(LIBOBJS) $(LIBS) -o webserver
 
 .c.o:
        $(CC) $(CFLAGS) $(DEFS) -c -D_REENTRANT -DWEBCITDIR=\"`pwd`\" $<
 
-
-webcit: webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
-       roomops.o tools.o messages.o userlist.o paging.o sysmsgs.o \
-       mime_parser.o graphics.o netconf.o cookie_conversion.o siteconfig.o \
-       wildmat.o braindamage.o
-       $(CC) webcit.o auth.o tcp_sockets.o mainmenu.o serv_func.o who.o \
-       tools.o roomops.o messages.o userlist.o paging.o sysmsgs.o siteconfig.o \
-       mime_parser.o graphics.o netconf.o cookie_conversion.o \
-       wildmat.o braindamage.o -o webcit
-
 Makefile: $(srcdir)/Makefile.in config.status
        CONFIG_FILES=Makefile CONFIG_HEADERS= $(SHELL) ./config.status
 
index 28d89efba3319e3e89520b954307fb8c47002afc..64147f1a1917de166230a53a6a156c3ddc9d5928 100644 (file)
@@ -6,16 +6,28 @@
  * $Id$
  */
 
+
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
-#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
 #include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
 
 char *axdefs[] =
 {
@@ -35,7 +47,7 @@ void display_login(char *mesg)
 {
        char buf[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(3);
 
        /* Da banner */
@@ -172,7 +184,7 @@ void do_logout(void)
        strcpy(WC->wc_password, "");
        strcpy(WC->wc_roomname, "");
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(2);      /* note "2" causes cookies to be unset */
 
        wprintf("<CENTER>");
@@ -204,7 +216,7 @@ void validate(void)
        char buf[256];
        int a;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        strcpy(buf, bstr("user"));
@@ -283,7 +295,7 @@ void display_reg(int during_login)
        char buf[256];
        int a;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
@@ -387,7 +399,7 @@ void display_changepw(void)
 {
        char buf[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
diff --git a/webcit/braindamage.c b/webcit/braindamage.c
deleted file mode 100644 (file)
index 564cda5..0000000
+++ /dev/null
@@ -1,58 +0,0 @@
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <string.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <stdarg.h>
-#include "webcit.h"
-#include "child.h"
-
-/*
- * browser_braindamage_check()
- * 
- * Given the value of the HTTP "User-agent:" directive supplied by
- * a web browser, determine using a local configuration file whether
- * the browser is capable of handling JavaScript.
- *
- * This function returns one of the following values:
- * B_YES        (Yes, it's ok to use JavaScript)
- * B_NO         (No, fall back to HTML)
- * B_ASK        (We don't know; ask the user)
- */
-
-int browser_braindamage_check(char *browser)
-{
-       FILE *fp;
-       char buf[256];
-       int thisval;
-
-       fp = fopen("static/braindamage", "r");
-       if (fp == NULL)
-               return (B_ASK);
-
-       while (fgets(buf, 256, fp) != NULL) {
-               buf[strlen(buf)-1] = 0;
-               thisval = (-1);
-               if (!strncasecmp(buf, "YES", 3)) {
-                       thisval = B_YES;
-                       strcpy(buf, &buf[3]);
-               } else if (!strncasecmp(buf, "NO", 2)) {
-                       thisval = B_NO;
-                       strcpy(buf, &buf[2]);
-               } else if (!strncasecmp(buf, "ASK", 3)) {
-                       thisval = B_ASK;
-                       strcpy(buf, &buf[3]);
-               }
-               if (thisval >= 0) {
-                       while (isspace(buf[0])) strcpy(buf, &buf[1]);
-                       if (wildmat(buf, browser)) {
-                               return(thisval);
-                       }
-               }
-       }
-
-       fclose(fp);
-       return (B_ASK);
-}
diff --git a/webcit/child.h b/webcit/child.h
deleted file mode 100644 (file)
index d698e36..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * child.h: prototypes for the `webcit' child process
- *
- * $Id$
- */
-
-void become_logged_in(char *, char *, char *);
-void do_login(void);
-void display_login(char *mesg);
-void do_welcome(void);
-void do_logout(void);
-void display_main_menu(void);
-void display_advanced_menu(void);
-void list_all_rooms_by_floor(void);
-void slrp_highest(void);
-void gotonext(void);
-void ungoto(void);
-void get_serv_info(char *, char *);
-int connectsock(char *host, char *service, char *protocol);
-void serv_gets(char *strbuf);
-void serv_puts(char *string);
-void whobbs(void);
-void fmout(FILE * fp);
-void wDumpContent(int);
-void serv_printf(const char *format,...);
-char *bstr(char *key);
-char *urlesc(char *);
-void urlescputs(char *);
-void output_headers(int);
-void wprintf(const char *format,...);
-void extract(char *dest, char *source, int parmnum);
-int extract_int(char *source, int parmnum);
-void output_static(char *what);
-void escputs(char *strbuf);
-void url(char *buf);
-void escputs1(char *strbuf, int nbsp);
-long extract_long(char *source, long int parmnum);
-void dump_vars(void);
-void embed_main_menu(void);
-void serv_read(char *buf, int bytes);
-int haschar(char *st, char ch);
-void readloop(char *oper);
-void text_to_server(char *ptr);
-void display_enter(void);
-void post_message(void);
-void confirm_delete_msg(void);
-void delete_msg(void);
-void confirm_move_msg(void);
-void move_msg(void);
-void userlist(void);
-void showuser(void);
-void display_page(void);
-void page_user(void);
-void do_chat(void);
-void display_private(char *rname, int req_pass);
-void goto_private(void);
-void zapped_list(void);
-void display_zap(void);
-void zap(void);
-void display_error(char *);
-void display_success(char *);
-void display_entroom(void);
-void entroom(void);
-void display_editroom(void);
-void editroom(void);
-void server_to_text(void);
-void save_edit(char *description, char *enter_cmd, int regoto);
-void display_edit(char *description, char *check_cmd,
-                 char *read_cmd, char *save_cmd);
-void gotoroom(char *gname, int display_name);
-void confirm_delete_room(void);
-void delete_room(void);
-void validate(void);
-void display_graphics_upload(char *, char *, char *);
-void do_graphics_upload(char *upl_cmd);
-void serv_read(char *buf, int bytes);
-void serv_gets(char *strbuf);
-void serv_write(char *buf, int nbytes);
-void serv_puts(char *string);
-void serv_printf(const char *format,...);
-void load_floorlist(void);
-void select_floor_to_edit_pic(void);
-void display_reg(int);
-void register_user(void);
-void display_changepw(void);
-void changepw(void);
-void display_edit_node(void);
-void display_netconf(void);
-void display_confirm_unshare(void);
-void display_confirm_delete_node(void);
-void delete_node(void);
-void unshare(void);
-void display_add_node(void);
-void add_node(void);
-void display_share(void);
-void share(void);
-void terminate_session(void);
-void edit_me(void);
-void display_siteconfig(void);
-void siteconfig(void);
-void display_generic(void);
-void do_generic(void);
-int browser_braindamage_check(char *);
-void display_menubar(int);
-void embed_room_banner(char *);
-void smart_goto(char *);
-void ExpressMessageCat(char *);
index 2f0c5a3824d73d47cd9aa51823706af68562c31c..9a66b02284cd1c561cd07de9adba7e099195d040 100644 (file)
 #include "webcit.h"
 #include "webserver.h"
 
-/*
- * We keep one of these around for each active session
- */
-struct wc_session {
-       struct wc_session *next;        /* Next session in list */
-       int session_id;         /* Session ID */
-       pid_t webcit_pid;       /* PID of the webcit process */
-       int inpipe[2];          /* Data from webserver to session */
-       int outpipe[2];         /* Data from session to webserver */
-       pthread_mutex_t critter;        /* Critical section uses pipes */
-       time_t lastreq;         /* Timestamp of most recent http */
-};
-
-struct wc_session *SessionList = NULL;
-extern const char *defaulthost;
-extern const char *defaultport;
-
 /* Only one thread may manipulate SessionList at a time... */
-pthread_mutex_t MasterCritter;
-
-
-/*
- * Grab a lock on the session, so other threads don't try to access
- * the pipes at the same time.
- */
-static void lock_session(struct wc_session *session)
-{
-       printf("Locking session %d...\n", session->session_id);
-       pthread_mutex_lock(&session->critter);
-       printf("   ...got lock\n");
-}
-
-/*
- * Let go of the lock.
- */
-static void unlock_session(struct wc_session *session)
-{
-       printf("Unlocking.\n");
-       pthread_mutex_unlock(&session->critter);
-}
-
-/*
- * Remove a session context from the list.
- * Set do_lock to 1, to lock the list while manipulating it.  The ONLY
- * situation in which this should _not_ be done is when it's already locked
- * by the caller.
- */
-void remove_session(struct wc_session *TheSession, int do_lock)
-{
-       struct wc_session *sptr;
-
-       printf("Removing session.\n");
-
-       /* Lock the list while manipulating it */
-       if (do_lock)
-               pthread_mutex_lock(&MasterCritter);
-
-       if (SessionList == TheSession) {
-               SessionList = SessionList->next;
-       } else {
-               for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
-                       if (sptr->next == TheSession) {
-                               sptr->next = TheSession->next;
-                       }
-               }
-       }
-
-       if (do_lock)
-               pthread_mutex_unlock(&MasterCritter);
-
-       /* Now finish destroying the session */
-       close(TheSession->inpipe[1]);
-       close(TheSession->outpipe[0]);
-       if (do_lock)
-               unlock_session(TheSession);
-       free(TheSession);
-
-}
-
+pthread_mutex_t SessionListMutex;
 
+struct wcsession *SessionList = NULL;
 
+pthread_key_t MyConKey;                         /* TSD key for MySession() */
 
 void do_housekeeping(void)
 {
-       struct wc_session *sptr;
+       struct wcsession *sptr;
 
-       pthread_mutex_lock(&MasterCritter);
+       pthread_mutex_lock(&SessionListMutex);
 
        /* Kill idle sessions */
        for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
                if ((time(NULL) - (sptr->lastreq)) > (time_t) WEBCIT_TIMEOUT) {
-                       kill(sptr->webcit_pid, 15);
+                       /* FIX do something here */
                }
        }
 
-       /* Remove dead sessions */
-       for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
-               if (kill(sptr->webcit_pid, 0)) {
-                       remove_session(sptr, 0);
-               }
-       }
-
-       pthread_mutex_unlock(&MasterCritter);
+       pthread_mutex_unlock(&SessionListMutex);
 }
 
 
@@ -156,12 +74,23 @@ void housekeeping_loop(void)
 }
 
 
-
-
-
+/*
+ * Generate a unique WebCit session ID (which is not the same thing as the
+ * Citadel session ID).
+ *
+ * FIX ... we really should check to make sure we're generating a truly
+ * unique session ID by traversing the SessionList.
+ *
+ */
 int GenerateSessionID(void)
 {
-       return getpid();
+       static int seq = (-1);
+
+       if (seq < 0) {
+               seq = (int) time(NULL);
+       }
+               
+       return ++seq;
 }
 
 
@@ -239,42 +168,37 @@ static int lingering_close(int fd)
        return close(fd);
 }
 
+
+
+
 /*
- * This loop gets called once for every HTTP connection made to WebCit.
+ * This loop gets called once for every HTTP connection made to WebCit.  At
+ * this entry point we have an HTTP socket with a browser allegedly on the
+ * other end, but we have not yet bound to a WebCit session.
+ *
+ * The job of this function is to locate the correct session and bind to it,
+ * or create a session if necessary and bind to it, then run the WebCit
+ * transaction loop.  Afterwards, we unbind from the session.  When this
+ * function returns, the worker thread is then free to handle another
+ * transaction.
  */
-void *context_loop(int sock)
+void context_loop(int sock)
 {
-       char (*req)[256];
+       struct httprequest *req = NULL;
+       struct httprequest *last = NULL;
+       struct httprequest *hptr;
        char buf[256], hold[256];
-       char browser_host[256];
-       char browser[256];
-       int num_lines = 0;
-       int a;
-       int f;
        int desired_session = 0;
        int got_cookie = 0;
-       char str_session[256];
-       struct wc_session *sptr;
-       struct wc_session *TheSession;
-       int ContentLength;
+       struct wcsession *TheSession, *sptr;
        int CloseSession = 0;
 
-       if ((req = malloc((long) sizeof(char[256][256]))) == NULL) {
-               sprintf(buf, "Can't malloc buffers; dropping connection.\n");
-               fprintf(stderr, "%s", buf);
-               write(sock, buf, strlen(buf));
-               close(sock);
-               pthread_exit(NULL);
-       }
-       bzero(req, sizeof(char[256][256]));     /* clear it out */
-       strcpy(browser, "unknown");
 
-       printf("Reading request from socket %d\n", sock);
+       fprintf(stderr, "Reading request from socket %d\n", sock);
 
        /*
         * Find out what it is that the web browser is asking for
         */
-       ContentLength = 0;
        do {
                req_gets(sock, buf, hold);
                if (!strncasecmp(buf, "Cookie: webcit=", 15)) {
@@ -282,13 +206,18 @@ void *context_loop(int sock)
                                NULL, NULL, NULL);
                        got_cookie = 1;
                }
-               else if (!strncasecmp(buf, "Content-length: ", 16)) {
-                       ContentLength = atoi(&buf[16]);
-               }
-               else if (!strncasecmp(buf, "User-agent: ", 12)) {
-                       strcpy(browser, &buf[12]);
-               }
-               strcpy(&req[num_lines++][0], buf);
+
+               hptr = (struct httprequest *)
+                       malloc(sizeof(struct httprequest));
+               if (req == NULL)
+                       req = hptr;
+               else
+                       last->next = hptr;
+               hptr->next = NULL;
+               last = hptr;
+
+               strcpy(hptr->line, buf);
+
        } while (strlen(buf) > 0);
 
 
@@ -297,7 +226,7 @@ void *context_loop(int sock)
         * set.  If there isn't, the client browser has cookies turned off
         * (or doesn't support them) and we have to barf & bail.
         */
-       strcpy(buf, &req[0][0]);
+       strcpy(buf, req->line);
        if (!strncasecmp(buf, "GET ", 4)) strcpy(buf, &buf[4]);
        else if (!strncasecmp(buf, "HEAD ", 5)) strcpy(buf, &buf[5]);
        if (buf[1]==' ') buf[1]=0;
@@ -307,12 +236,12 @@ void *context_loop(int sock)
         * robots.txt file...
         */
        if (!strncasecmp(buf, "/robots.txt", 11)) {
-               strcpy(&req[0][0], "GET /static/robots.txt HTTP/1.0");
+               strcpy(req->line, "GET /static/robots.txt HTTP/1.0");
        }
 
        /* Do the non-root-cookie check now. */
        else if ( (strcmp(buf, "/")) && (got_cookie == 0)) {
-               strcpy(&req[0][0], "GET /static/nocookies.html HTTP/1.0");
+               strcpy(req->line, "GET /static/nocookies.html HTTP/1.0");
        }
 
 
@@ -322,25 +251,13 @@ void *context_loop(int sock)
         */
        TheSession = NULL;
        if (desired_session != 0) {
-               pthread_mutex_lock(&MasterCritter);
+               pthread_mutex_lock(&SessionListMutex);
                for (sptr = SessionList; sptr != NULL; sptr = sptr->next) {
-                       if (sptr->session_id == desired_session) {
+                       if (sptr->wc_session == desired_session) {
                                TheSession = sptr;
                        }
                }
-               pthread_mutex_unlock(&MasterCritter);
-       }
-
-       /*
-        * Before we trumpet to the universe that the session we're looking
-        * for actually exists, check first to make sure it's still there.
-        */
-       if (TheSession != NULL) {
-               if (kill(TheSession->webcit_pid, 0)) {
-                       printf("   Session is *DEAD* !!\n");
-                       remove_session(TheSession, 1);
-                       TheSession = NULL;
-               }
+               pthread_mutex_unlock(&SessionListMutex);
        }
 
        /*
@@ -348,130 +265,65 @@ void *context_loop(int sock)
         */
        if (TheSession == NULL) {
                printf("Creating a new session\n");
-               locate_host(browser_host, sock);
-               TheSession = (struct wc_session *)
-                   malloc(sizeof(struct wc_session));
-               TheSession->session_id = GenerateSessionID();
-               pipe(TheSession->inpipe);
-               pipe(TheSession->outpipe);
-               pthread_mutex_init(&TheSession->critter, NULL);
-
-               pthread_mutex_lock(&MasterCritter);
+               TheSession = (struct wcsession *)
+                       malloc(sizeof(struct wcsession));
+               memset(TheSession, 0, sizeof(struct wcsession));
+               TheSession->wc_session = GenerateSessionID();
+               pthread_mutex_init(&TheSession->SessionMutex, NULL);
+
+               pthread_mutex_lock(&SessionListMutex);
                TheSession->next = SessionList;
                SessionList = TheSession;
-               pthread_mutex_unlock(&MasterCritter);
-
-               sprintf(str_session, "%d", TheSession->session_id);
-               f = fork();
-               if (f > 0)
-                       TheSession->webcit_pid = f;
-
-               fflush(stdout);
-               fflush(stdin);
-               if (f == 0) {
-
-                       /* Hook stdio to the ends of the pipe we're using */
-                       dup2(TheSession->inpipe[0], 0);
-                       dup2(TheSession->outpipe[1], 1);
-
-                       /* Close the ends of the pipes that we're not using */
-                       close(TheSession->inpipe[1]);
-                       close(TheSession->outpipe[0]);
-
-                       /* Close the HTTP socket in this pid; don't need it */
-                       close(sock);
-
-                       /* Run the actual WebCit session */
-                       execlp("./webcit", "webcit", str_session, defaulthost,
-                              defaultport, browser_host, browser, NULL);
-
-                       /* Simple page to display if exec fails */
-                       printf("HTTP/1.0 404 WebCit Failure\n\n");
-                       printf("Server: %s\n", SERVER);
-                       printf("X-WebCit-Session: close\n");
-                       printf("Content-type: text/html\n");
-                       printf("Content-length: 76\n");
-                       printf("\n");
-                       printf("<HTML><HEAD><TITLE>Error</TITLE></HEAD><BODY>\n");
-                       printf("execlp() failed: %s</BODY></HTML>\n", strerror(errno));
-                       exit(0);
-               } else {
-                       /* Close the ends of the pipes that we're not using */
-                       close(TheSession->inpipe[0]);
-                       close(TheSession->outpipe[1]);
-               }
+               pthread_mutex_unlock(&SessionListMutex);
        }
 
-       /* 
-        * Send the request to the appropriate session...
-        */
-       lock_session(TheSession);
-       TheSession->lastreq = time(NULL);
-       printf("   Writing %d lines of command\n", num_lines);
-       printf("%s\n", &req[0][0]);
-       for (a = 0; a < num_lines; ++a) {
-               write(TheSession->inpipe[1], &req[a][0], strlen(&req[a][0]));
-               write(TheSession->inpipe[1], "\n", 1);
-       }
-       printf("   Writing %d bytes of content\n", ContentLength);
-       while (ContentLength > 0) {
-               a = ContentLength;
-               if (a > sizeof buf)
-                       a = sizeof buf;
-               if (!client_read(sock, buf, a))
-                       goto end;
-               if (write(TheSession->inpipe[1], buf, a) != a)
-                       goto end;
-               ContentLength -= a;
-       }
 
        /*
-        * ...and get the response.
+        *
+        * FIX ... check session integrity here before continuing
+        *
         */
-       printf("   Reading response\n");
-       ContentLength = 0;
-       do {
-               gets0(TheSession->outpipe[0], buf);
-               write(sock, buf, strlen(buf));
-               write(sock, "\n", 1);
-               if (!strncasecmp(buf, "Content-length: ", 16))
-                       ContentLength = atoi(&buf[16]);
-               if (!strcasecmp(buf, "X-WebCit-Session: close")) {
-                       CloseSession = 1;
-               }
-       } while (strlen(buf) > 0);
 
-       printf("   Reading %d bytes of content\n", ContentLength);
 
-       while (ContentLength--) {
-               read(TheSession->outpipe[0], buf, 1);
-               write(sock, buf, 1);
-       }
+
+       /*
+        * Bind to the session
+        */
+       pthread_mutex_lock(&TheSession->SessionMutex);
+       pthread_setspecific(MyConKey, (void *)TheSession);
+       TheSession->lastreq = time(NULL);
+       TheSession->http_sock = sock;
+
+       /* 
+        * Perform the WebCit transaction
+        */
+       fprintf(stderr, "Transaction: %s\n", req->line);
+       session_loop(req);
+       fprintf(stderr, "Returned from transaction loop\n");
 
        /*
         * If the last response included a "close session" directive,
         * remove the context now.
         */
        if (CloseSession) {
-               remove_session(TheSession, 1);
+               /*  FIX   remove_session(TheSession, 1);   */
        } else {
-end:           unlock_session(TheSession);
+
+               pthread_mutex_unlock(&TheSession->SessionMutex);
        }
-       free(req);
 
+       /* Free the request buffer */
+       while (req != NULL) {
+               hptr = req->next;
+               free(req);
+               req = hptr;
+       }
 
        /*
-        * Now our HTTP connection is done.  It would be relatively easy
-        * to support HTTP/1.1 "persistent" connections by looping back to
-        * the top of this function.  For now, we'll just close.
+        * Now our HTTP connection is done.  Close the socket and exit this
+        * function, so the worker thread can handle a new HTTP connection.
         */
        printf("   Closing socket %d ... ret=%d\n", sock,
               lingering_close(sock));
-
-       /*
-        * The thread handling this HTTP connection is now finished.
-        * Instead of calling pthread_exit(), just return. It does the same
-        * thing, and supresses a compiler warning.
-        */
-       return NULL;
+       return;
 }
index 3bb3554b9b6d93a726c9397e1eec7d9dba9ad484..5f139fdf54f6b9d6c9ec6af6b5418462330579d2 100644 (file)
@@ -1,12 +1,24 @@
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
 
 /*
  * Pack all session info into one easy-to-digest cookie.  Healthy and delicious!
index 56c4ceebe9f4522aa250595bbf358c65a3fec5a4..3e8ebc61759aad0858036b71fff771e80cc8d341 100644 (file)
@@ -1,13 +1,24 @@
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
-#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
 #include <errno.h>
-#include <time.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
-
 
 void display_graphics_upload(char *description, char *check_cmd, char *uplurl)
 {
@@ -19,7 +30,7 @@ void display_graphics_upload(char *description, char *check_cmd, char *uplurl)
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -93,7 +104,7 @@ void select_floor_to_edit_pic(void)
 {
        int a;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
index fba5d88476663d1d677a59e0bf1e9be8b70f1438..87d1385aa092735be140ee9d199950a567386597 100644 (file)
@@ -2,16 +2,30 @@
  * locate the originating host
  */
 
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/socket.h>
-#include <netinet/in.h>
+#include <sys/time.h>
 #include <limits.h>
+#include <netinet/in.h>
 #include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
+#include "webcit.h"
+
+
+
 
 void locate_host(char *tbuf, int client_socket)
 {
index 8713620f46809bc4f9b270c6f9c48d69182f4aa8..0cdc6ebc5bfdc5d8a21908e7b486a9982f7744ec 100644 (file)
@@ -1,15 +1,31 @@
 /* $Id$ */
 
+
+
+
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
-#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
 #include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
 
 
 /* 
@@ -191,7 +207,7 @@ void embed_advanced_menu(void)
  */
 void display_main_menu(void)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        embed_main_menu();
        wDumpContent(2);
@@ -200,7 +216,7 @@ void display_main_menu(void)
 
 void display_advanced_menu(void)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        embed_advanced_menu();
        embed_main_menu();
@@ -213,7 +229,7 @@ void display_advanced_menu(void)
  */
 void display_generic(void)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770077><TR><TD>");
@@ -253,7 +269,7 @@ void do_generic(void)
                return;
        }
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        serv_printf("%s", bstr("g_cmd"));
@@ -316,7 +332,7 @@ void display_menubar(int as_single_page) {
        char buf[256];
 
        if (as_single_page) {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(0);
                wprintf("<HTML>\n"
                        "<HEAD>\n"
index 0af37486a4b4669a5fdb1da3407819107825fcda..7966e9c41a4af771101654aaca3f53900e989fc7 100644 (file)
@@ -1,12 +1,31 @@
+
+
+
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
-#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
 #include <errno.h>
-#include <time.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
 
 char reply_to[512];
 long msgarr[1024];
@@ -221,7 +240,7 @@ void readloop(char *oper)
        int a;
        int nummsgs;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\"><CENTER><B>%s - ", WC->wc_roomname);
@@ -274,7 +293,7 @@ void post_message(void)
        char buf[256];
        static long dont_post = (-1L);
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\">");
@@ -339,7 +358,7 @@ void display_enter(void)
        long now;
        struct tm *tm;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<FACE=\"Arial,Helvetica,sans-serif\">");
@@ -408,7 +427,7 @@ void confirm_delete_msg(void)
 
        msgid = atol(bstr("msgid"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
@@ -440,7 +459,7 @@ void delete_msg(void)
 
        msgid = atol(bstr("msgid"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        if (!strcasecmp(bstr("yesno"), "Yes")) {
@@ -469,7 +488,7 @@ void confirm_move_msg(void)
 
        msgid = atol(bstr("msgid"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
@@ -517,7 +536,7 @@ void move_msg(void)
 
        msgid = atol(bstr("msgid"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        if (!strcasecmp(bstr("yesno"), "Move")) {
index 91c15b9dcbdef9b0119cd410ab40f45a9f99cc83..5782c5a7269f178ea6ca19e28157277e8682e67f 100644 (file)
@@ -5,16 +5,30 @@
  * messages -- in the case of WebCit, a form containing uploaded files.
  */
 
+
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
-#include "mime_parser.h"
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
 
 
 
index 010fec575e532ac728188923b62eba46332c7791..6b2d763cdfc960fdd5ba22bc10f60d1a1bbe36c9 100644 (file)
@@ -1,12 +1,31 @@
+
+
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
+
 
 struct sharelist {
        struct sharelist *next;
@@ -22,7 +41,7 @@ void display_edit_node(void)
 
        strcpy(node, bstr("node"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -67,7 +86,7 @@ void display_netconf(void)
        char buf[256];
        char node[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -111,7 +130,7 @@ void display_confirm_unshare(void)
        char node[256];
        char sroom[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -139,7 +158,7 @@ void display_confirm_delete_node(void)
 {
        char node[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -168,7 +187,7 @@ void delete_node(void)
        serv_puts(buf);
        serv_gets(buf);
        if (buf[0] == '1') {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
                server_to_text();
                wprintf("<A HREF=\"/display_netconf\">Back to menu</A>\n");
@@ -191,7 +210,7 @@ void unshare(void)
        serv_puts(buf);
        serv_gets(buf);
        if (buf[0] == '1') {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
                server_to_text();
                wprintf("<A HREF=\"/display_netconf\">Back to menu</A>\n");
@@ -206,7 +225,7 @@ void unshare(void)
 void display_add_node(void)
 {
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -242,7 +261,7 @@ void add_node(void)
                serv_puts(buf);
                serv_gets(buf);
                if (buf[0] == '1') {
-                       printf("HTTP/1.0 200 OK\n");
+                       wprintf("HTTP/1.0 200 OK\n");
                        output_headers(1);
                        server_to_text();
                        wprintf("<A HREF=\"/display_netconf\">Back to menu</A>\n");
@@ -266,7 +285,7 @@ void display_share(void)
 
        strcpy(node, bstr("node"));
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -346,7 +365,7 @@ void share(void)
                serv_puts(buf);
                serv_gets(buf);
                if (buf[0] == '1') {
-                       printf("HTTP/1.0 200 OK\n");
+                       wprintf("HTTP/1.0 200 OK\n");
                        output_headers(1);
                        server_to_text();
                        wprintf("<A HREF=\"/display_netconf\">Back to menu</A>\n");
index 828b934527113cc0a54af53121aef4b0e964eb5b..51611c2ea5eea55568f2dd58b36c5a095fdedf60 100644 (file)
@@ -1,16 +1,26 @@
 /* $Id$ */
 
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
 
 /*
  * display the form for paging (x-messaging) another user
@@ -20,7 +30,7 @@ void display_page(void)
        char buf[256];
        char user[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
@@ -70,7 +80,7 @@ void page_user(void)
        char sc[256];
        char buf[256];
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        strcpy(recp, bstr("recp"));
@@ -102,7 +112,7 @@ void page_user(void)
 void do_chat(void)
 {
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
index bf47eaa509d18f57c955ccd05d5b70304771d88a..e4ec0bc72e701df27c3484aec9438b516f53da66 100644 (file)
@@ -1,15 +1,33 @@
 /* $Id$ */
 
+
+#include <ctype.h>
 #include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
+
+
+
 
 /*
  * This struct holds a list of rooms for <G>oto operations.
@@ -232,7 +250,7 @@ void list_all_rooms_by_floor(void)
 
        load_floorlist();
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE width=100% border><TR><TH>Floor</TH>");
@@ -279,7 +297,7 @@ void list_all_rooms_by_floor(void)
  */
 void zapped_list(void)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\" SIZE=+1 COLOR=\"FFFFFF\"");
@@ -391,7 +409,7 @@ void gotoroom(char *gname, int display_name)
 
 
        if (display_name) {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                 printf("Pragma: no-cache\n");
                 printf("Cache-Control: no-store\n");
                output_headers(0);
@@ -629,7 +647,7 @@ void display_editroom(void)
        er_floor = extract_int(&buf[4], 4);
 
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
@@ -946,7 +964,7 @@ void display_entroom(void)
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
@@ -1028,7 +1046,7 @@ void entroom(void)
 void display_private(char *rname, int req_pass)
 {
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
@@ -1091,7 +1109,7 @@ void goto_private(void)
                display_private(bstr("gr_name"), 1);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("%s\n", &buf[4]);
        wDumpContent(1);
@@ -1104,7 +1122,7 @@ void goto_private(void)
  */
 void display_zap(void)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
@@ -1171,7 +1189,7 @@ void confirm_delete_room(void)
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
index 750ec7d2f4fbb0506731b82c37ab98580dabef70..174172a8f53e60cd4a65b156d007c9fa8ceeb35e 100644 (file)
@@ -1,14 +1,33 @@
 /* $Id$ */
 
+
+
 #include <ctype.h>
 #include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
+
+
 
 struct serv_info serv_info;
 
index e178a1733486fa9277a0ae71a968112f4105676a..568b0e4e47bf39785bd4f1e49404069c72f24a75 100644 (file)
@@ -3,15 +3,30 @@
  *
  */
 
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
 
 
 void display_siteconfig(void)
@@ -19,7 +34,7 @@ void display_siteconfig(void)
        char buf[256];
        int i;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        serv_printf("CONF get");
index 526068129cbb6abfb789d43713b0934097450436..fed1603cd7862f539d9076db2e05a41dcc5d2ccd 100644 (file)
@@ -1,12 +1,32 @@
+
+
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
+
+
+
 
 /*
  * display the form for editing something (room info, bio, etc)
@@ -23,7 +43,7 @@ void display_edit(char *description, char *check_cmd,
                display_error(&buf[4]);
                return;
        }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
@@ -60,7 +80,7 @@ void save_edit(char *description, char *enter_cmd, int regoto)
        char buf[256];
 
        if (strcmp(bstr("sc"), "Save")) {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
                wprintf("Cancelled.  %s was not saved.<BR>\n", description);
                wDumpContent(1);
@@ -78,7 +98,7 @@ void save_edit(char *description, char *enter_cmd, int regoto)
        if (regoto) {
                smart_goto(WC->wc_roomname);
        } else {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
                wprintf("%s has been saved.\n", description);
                wDumpContent(1);
index d7ec10712e545c5abecb64f565c4911529e45ff4..50a9b299efb607ddf6c2c3da583ed2a0bc776d74 100644 (file)
@@ -6,21 +6,32 @@
  * $Id$
  */
 
+
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
+#include <sys/wait.h>
 #include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
 #include <netinet/in.h>
-#include <arpa/inet.h>
 #include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
 #include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
 
+
+
+
+
 char server_is_local = 0;
 
 #ifndef INADDR_NONE
index 13fb0334259d325f97c430554baba3ce2fda306d..3754ac4df8af7f0a2fe074f2492408706e0d27c9 100644 (file)
@@ -2,11 +2,32 @@
  * tools.c -- Miscellaneous routines 
  */
 
-#include <stdio.h>
+
+
+#include <ctype.h>
 #include <stdlib.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
 
+
+
+
 char *safestrncpy(char *dest, const char *src, size_t n)
 {
        if (dest == NULL || src == NULL) {
@@ -100,7 +121,7 @@ long extract_long(char *source, long int parmnum)
  */
 int haschar(st, ch)
 char st[];
-int ch;
+char ch;
 {
        int a, b;
        b = 0;
index d710ca5e91ad7ed89a4d73d570fff94905349553..44e60a056691a284844374bccd57ee5309bb6a41 100644 (file)
@@ -1,13 +1,26 @@
+#include <ctype.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
-#include <time.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
 
 struct namelist {
        struct namelist *next;
@@ -36,7 +49,7 @@ void userlist(void)
                        strcpy(bptr->name, buf);
                        bio = bptr;
                }
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        serv_puts("LIST");
@@ -101,7 +114,7 @@ void showuser(void)
        char buf[256];
        int have_pic;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
 
index 10819551a92fabfbad9d91e0515dafd897dab479..78646ffe03af7045f5c4e2025334e5086700902d 100644 (file)
@@ -8,19 +8,29 @@
  * $Id$
  */
 
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
-#include <ctype.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
 #include <errno.h>
-#include <sys/stat.h>
 #include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
-#include "mime_parser.h"
+
+
 
 int TransactionCount = 0;
 char *ExpressMessages = NULL;
@@ -30,9 +40,6 @@ char *ExpressMessages = NULL;
  */
 int fake_frames = 0;
 
-struct webcontent *wlist = NULL;
-struct webcontent *wlast = NULL;
-
 struct urlcontent *urlstrings = NULL;
 
 static const char *defaulthost = DEFAULT_HOST;
@@ -40,8 +47,6 @@ static const char *defaultport = DEFAULT_PORT;
 
 
 
-struct wcsession *WC = NULL;   /* FIX take this out when multithreaded */
-
 void unescape_input(char *buf)
 {
        int a, b;
@@ -158,40 +163,18 @@ char *bstr(char *key)
 void wprintf(const char *format,...)
 {
        va_list arg_ptr;
-       struct webcontent *wptr;
-
-       wptr = (struct webcontent *) malloc(sizeof(struct webcontent));
-       wptr->next = NULL;
-       if (wlist == NULL) {
-               wlist = wptr;
-               wlast = wptr;
-       } else {
-               wlast->next = wptr;
-               wlast = wptr;
-       }
+       char wbuf[1024];
 
        va_start(arg_ptr, format);
-       vsprintf(wptr->w_data, format, arg_ptr);
+       vsprintf(wbuf, format, arg_ptr);
        va_end(arg_ptr);
-}
-
-int wContentLength(void)
-{
-       struct webcontent *wptr;
-       int len = 0;
-
-       for (wptr = wlist; wptr != NULL; wptr = wptr->next) {
-               len = len + strlen(wptr->w_data);
-       }
 
-       return (len);
+       write(WC->http_sock, wbuf, strlen(wbuf));
 }
 
+
 /*
- * wDumpContent() takes all the stuff that's been queued up using
- * the wprintf() and escputs() functions, and sends it out to the browser.
- * By queuing instead of transmitting as it's generated, we're able to
- * calculate a Content-length: header.
+ * wDumpContent() wraps up an HTTP session, closes tags, etc.
  *
  * print_standard_html_footer should be set to 0 to transmit only, 1 to
  * append the main menu and closing tags, or 2 to
@@ -199,8 +182,6 @@ int wContentLength(void)
  */
 void wDumpContent(int print_standard_html_footer)
 {
-       struct webcontent *wptr;
-
        if (fake_frames) {
                wprintf("<CENTER><FONT SIZE=-1>"
                        "<TABLE border=0 width=100%><TR>"
@@ -228,17 +209,8 @@ void wDumpContent(int print_standard_html_footer)
                }
                wprintf("</BODY></HTML>\n");
        }
-       printf("Content-type: text/html\n");
-       printf("Content-length: %d\n", wContentLength());
-       printf("\n");
-
-       while (wlist != NULL) {
-               fwrite(wlist->w_data, strlen(wlist->w_data), 1, stdout);
-               wptr = wlist->next;
-               free(wlist);
-               wlist = wptr;
-       }
-       wlast = NULL;
+
+
 }
 
 
@@ -309,37 +281,6 @@ void urlescputs(char *strbuf)
 
 
 
-/*
- * Get a line of text from the webserver (which originally came from the
- * user's browser), checking for sanity etc.
- */
-char *getz(char *buf)
-{
-       int e = 0;
-
-       bzero(buf, 256);
-
-       /* If fgets() fails, it's because the webserver crashed, so kill off
-        * the session too.
-        */
-       if (fgets(buf, 256, stdin) == NULL) {
-               e = errno;
-               fprintf(stderr, "webcit: exit code %d (%s)\n",
-                       e, strerror(e));
-               fflush(stderr);
-               exit(e);
-               
-       /* Otherwise, strip out nonprintables and resume our happy day.
-        */
-       } else {
-               while ((strlen(buf) > 0) && (!isprint(buf[strlen(buf) - 1])))
-                       buf[strlen(buf) - 1] = 0;
-               return buf;
-       }
-}
-
-
-
 /*
  * Output all that important stuff that the browser will want to see
  *
@@ -355,22 +296,25 @@ void output_headers(int print_standard_html_head)
        static char *unset = "; expires=28-May-1971 18:10:00 GMT";
        char cookie[256];
 
-       printf("Server: %s\n", SERVER);
-       printf("Connection: close\n");
+       wprintf("Content-type: text/html\n");
+       wprintf("Server: %s\n", SERVER);
+       wprintf("Connection: close\n");
 
        if (print_standard_html_head > 0) {
-               printf("Pragma: no-cache\n");
-               printf("Cache-Control: no-store\n");
+               wprintf("Pragma: no-cache\n");
+               wprintf("Cache-Control: no-store\n");
        }
        stuff_to_cookie(cookie, WC->wc_session, WC->wc_username,
                        WC->wc_password, WC->wc_roomname);
        if (print_standard_html_head == 2) {
-               printf("X-WebCit-Session: close\n");
-               printf("Set-cookie: webcit=%s\n", unset);
+               wprintf("X-WebCit-Session: close\n");
+               wprintf("Set-cookie: webcit=%s\n", unset);
        } else {
-               printf("Set-cookie: webcit=%s\n", cookie);
+               wprintf("Set-cookie: webcit=%s\n", cookie);
        }
 
+       wprintf("\n");
+
        if (print_standard_html_head > 0) {
                wprintf("<HTML><HEAD><TITLE>");
                escputs(serv_info.serv_humannode);
@@ -462,36 +406,32 @@ void output_static(char *what)
        sprintf(buf, "static/%s", what);
        fp = fopen(buf, "rb");
        if (fp == NULL) {
-               printf("HTTP/1.0 404 %s\n", strerror(errno));
-               output_headers(0);
-               printf("Content-Type: text/plain\n");
-               sprintf(buf, "%s: %s\n", what, strerror(errno));
-               printf("Content-length: %d\n", strlen(buf));
-               printf("\n");
-               fwrite(buf, strlen(buf), 1, stdout);
+               wprintf("HTTP/1.0 404 %s\n", strerror(errno));
+               wprintf("Content-Type: text/plain\n");
+               wprintf("\n");
+               wprintf("Cannot open %s: %s\n", what, strerror(errno));
        } else {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(0);
 
                if (!strncasecmp(&what[strlen(what) - 4], ".gif", 4))
-                       printf("Content-type: image/gif\n");
+                       wprintf("Content-type: image/gif\n");
                else if (!strncasecmp(&what[strlen(what) - 4], ".txt", 4))
-                       printf("Content-type: text/plain\n");
+                       wprintf("Content-type: text/plain\n");
                else if (!strncasecmp(&what[strlen(what) - 4], ".jpg", 4))
-                       printf("Content-type: image/jpeg\n");
+                       wprintf("Content-type: image/jpeg\n");
                else if (!strncasecmp(&what[strlen(what) - 5], ".html", 5))
-                       printf("Content-type: text/html\n");
+                       wprintf("Content-type: text/html\n");
                else
-                       printf("Content-type: application/octet-stream\n");
+                       wprintf("Content-type: application/octet-stream\n");
 
                fstat(fileno(fp), &statbuf);
                bytes = statbuf.st_size;
-               printf("Content-length: %ld\n", (long) bytes);
+               wprintf("Content-length: %ld\n", (long) bytes);
                printf("\n");
                while (bytes--) {
-                       putc(getc(fp), stdout);
+                       wprintf("%c", getc(fp) );
                }
-               fflush(stdout);
                fclose(fp);
        }
 }
@@ -509,11 +449,11 @@ void output_image()
        serv_gets(buf);
        if (buf[0] == '2') {
                bytes = extract_long(&buf[4], 0);
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(0);
-               printf("Content-type: image/gif\n");
-               printf("Content-length: %ld\n", (long) bytes);
-               printf("\n");
+               wprintf("Content-type: image/gif\n");
+               wprintf("Content-length: %ld\n", (long) bytes);
+               wprintf("\n");
 
                while (bytes > (off_t) 0) {
                        thisblock = (off_t) sizeof(xferbuf);
@@ -524,7 +464,7 @@ void output_image()
                        if (buf[0] == '6')
                                thisblock = extract_long(&buf[4], 0);
                        serv_read(xferbuf, (int) thisblock);
-                       fwrite(xferbuf, thisblock, 1, stdout);
+                       write(WC->http_sock, xferbuf, thisblock);
                        bytes = bytes - thisblock;
                        accomplished = accomplished + thisblock;
                }
@@ -532,13 +472,11 @@ void output_image()
                serv_puts("CLOS");
                serv_gets(buf);
        } else {
-               printf("HTTP/1.0 404 %s\n", strerror(errno));
+               wprintf("HTTP/1.0 404 %s\n", strerror(errno));
                output_headers(0);
-               printf("Content-Type: text/plain\n");
-               sprintf(buf, "Error retrieving image\n");
-               printf("Content-length: %d\n", strlen(buf));
-               printf("\n");
-               fwrite(buf, strlen(buf), 1, stdout);
+               wprintf("Content-Type: text/plain\n");
+               wprintf("\n");
+               wprintf("Error retrieving image\n");
        }
 
 }
@@ -549,7 +487,7 @@ void output_image()
  */
 void convenience_page(char *titlebarcolor, char *titlebarmsg, char *messagetext)
 {
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=%s><TR><TD>", titlebarcolor);
        wprintf("<FONT SIZE=+1 COLOR=\"FFFFFF\"");
@@ -628,7 +566,10 @@ void upload_handler(char *name, char *filename, char *encoding,
 }
 
 
-void session_loop(char *browser_host, char *user_agent)
+/*
+ * Entry point for WebCit transaction
+ */
+void session_loop(struct httprequest *req)
 {
        char cmd[256];
        char action[256];
@@ -637,6 +578,9 @@ void session_loop(char *browser_host, char *user_agent)
        int ContentLength = 0;
        char ContentType[512];
        char *content;
+       struct httprequest *hptr;
+       char browser_host[256];
+       char user_agent[256];
 
        /* 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.
@@ -657,32 +601,38 @@ void session_loop(char *browser_host, char *user_agent)
        WC->upload_length = 0;
        WC->upload = NULL;
 
-       if (getz(cmd) == NULL)
-               return;
+       hptr = req;
+       if (hptr == NULL) return;
+
+       strcpy(cmd, hptr->line);
+       hptr = hptr->next;
        extract_action(action, cmd);
 
-       do {
-               if (getz(buf) == NULL)
-                       return;
+       while (hptr != NULL) {
+               strcpy(buf, hptr->line);
+               hptr = hptr->next;
 
                if (!strncasecmp(buf, "Cookie: webcit=", 15)) {
                        strcpy(cookie, &buf[15]);
                        cookie_to_stuff(cookie, NULL,
                                      c_username, c_password, c_roomname);
                }
-               if (!strncasecmp(buf, "Content-length: ", 16)) {
+               else if (!strncasecmp(buf, "Content-length: ", 16)) {
                        ContentLength = atoi(&buf[16]);
                }
-               if (!strncasecmp(buf, "Content-type: ", 14)) {
+               else if (!strncasecmp(buf, "Content-type: ", 14)) {
                        strcpy(ContentType, &buf[14]);
                }
-       } while (strlen(buf) > 0);
+               else if (!strncasecmp(buf, "User-agent: ", 12)) {
+                       strcpy(user_agent, &buf[12]);
+               }
+       }
 
        ++TransactionCount;
 
        if (ContentLength > 0) {
                content = malloc(ContentLength + 1);
-               fread(content, ContentLength, 1, stdin);
+               read(WC->http_sock, content, ContentLength);
 
                content[ContentLength] = 0;
 
@@ -707,7 +657,7 @@ void session_loop(char *browser_host, char *user_agent)
                        cmd[a] = 0;
                }
        /*
-        * If we're not WC->connected to a Citadel server, try to hook up the
+        * If we're not connected to a Citadel server, try to hook up the
         * connection now.  Preference is given to the host and port specified
         * by browser cookies, if cookies have been supplied.
         */
@@ -723,6 +673,7 @@ void session_loop(char *browser_host, char *user_agent)
 
                WC->connected = 1;
                serv_gets(buf); /* get the server welcome message */
+               locate_host(browser_host, WC->http_sock);
                get_serv_info(browser_host, user_agent);
        }
        check_for_express_messages();
@@ -919,7 +870,7 @@ void session_loop(char *browser_host, char *user_agent)
        } else if (!strcasecmp(action, "display_menubar")) {
                display_menubar(1);
        } else if (!strcasecmp(action, "diagnostics")) {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
 
                wprintf("TransactionCount is %d<BR>\n", TransactionCount);
@@ -948,43 +899,3 @@ void session_loop(char *browser_host, char *user_agent)
                WC->upload_length = 0;
        }
 }
-
-int main(int argc, char *argv[])
-{
-
-       char browser[256];
-       int bd;
-
-       if (argc != 6) {
-               fprintf(stderr,
-                       "webcit: usage error (argc must be 6, not %d)\n",
-                       argc);
-               return 1;
-       }
-
-       WC = (struct wcsession *) malloc(sizeof(struct wcsession));
-       memset(WC, 0, sizeof(struct wcsession));
-
-
-
-       WC->wc_session = atoi(argv[1]);
-       defaulthost = argv[2];
-       defaultport = argv[3];
-
-       strcpy(WC->wc_username, "");
-       strcpy(WC->wc_password, "");
-       strcpy(WC->wc_roomname, "");
-
-       /* Clear out serv_info and temporarily set the value of serv_humannode
-        * to a default value, because it'll be used in HTML page titles
-        */
-       memset(&serv_info, 0, sizeof(serv_info));
-       strcpy(serv_info.serv_humannode, "WebCit");
-
-       strcpy(browser, argv[5]);
-       bd = browser_braindamage_check(browser);
-
-       while (1) {
-               session_loop(argv[4], browser);
-       }
-}
index a831ec92f9aba7fd86e5fad7811c485ed7c3937c..0c5ae0732076f1a4a33e4d1073a6b306bf9988a6 100644 (file)
@@ -3,10 +3,10 @@
 #define SLEEPING       180     /* TCP connection timeout */
 #define WEBCIT_TIMEOUT 900     /* WebCit session timeout */
 #define PORT_NUM       2000    /* port number to listen on */
-#define SERVER         "WebCit v2.01"  /* who's in da house */
+#define SERVER         "WebCit v2.50"  /* who's in da house */
 #define DEVELOPER_ID   0
 #define CLIENT_ID      4
-#define CLIENT_VERSION 201
+#define CLIENT_VERSION 250
 #define DEFAULT_HOST   "localhost"
 #define DEFAULT_PORT   "504"
 #define LB             (1)
 #define QR_MAILBOX     16384   /* Set if this is a private mailbox */
 
 
-/* Browser braindamage check values */
-enum {
-       B_NO,
-       B_YES,
-       B_ASK
-};
-
-
-struct webcontent {
-       struct webcontent *next;
-       char w_data[256];
+struct httprequest {
+       struct httprequest *next;
+       char line[256];
 };
 
 struct urlcontent {
@@ -66,8 +58,15 @@ struct serv_info {
        int serv_ok_floors;
 };
 
+
+
+/*
+ * One of these is kept for each active Citadel session.
+ * HTTP transactions are bound to one at a time.
+ */
 struct wcsession {
-       int wc_session;
+        struct wcsession *next;                /* Linked list */
+       int wc_session;                 /* WebCit session ID */
        char wc_username[256];
        char wc_password[256];
        char wc_roomname[256];
@@ -76,8 +75,8 @@ struct wcsession {
        int axlevel;
        int is_aide;
        int is_room_aide;
+       int http_sock;
        int serv_sock;
-       struct serv_info serv_info;
        unsigned room_flags;
        char ugname[128];
        long uglsn;
@@ -85,14 +84,133 @@ struct wcsession {
        char *upload;
        int new_mail;
        int need_vali;
+        pthread_mutex_t SessionMutex;   /* mutex for exclusive access */
+        time_t lastreq;                        /* Timestamp of most recent HTTP */
 };
 
-extern struct wcsession *WC;
+
+
+#define WC ((struct wcsession *)pthread_getspecific(MyConKey))
+extern pthread_key_t MyConKey;
 
 struct serv_info serv_info;
 extern char floorlist[128][256];
 extern char *axdefs[];
 
-void stuff_to_cookie(char *, int, char *, char *, char *);
-void cookie_to_stuff(char *, int *, char *, char *, char *);
+
+void stuff_to_cookie(char *cookie, int session,
+                       char *user, char *pass, char *room);
+void cookie_to_stuff(char *cookie, int *session,
+                       char *user, char *pass, char *room);
 void locate_host(char *, int);
+void become_logged_in(char *, char *, char *);
+void do_login(void);
+void display_login(char *mesg);
+void do_welcome(void);
+void do_logout(void);
+void display_main_menu(void);
+void display_advanced_menu(void);
+void list_all_rooms_by_floor(void);
+void slrp_highest(void);
+void gotonext(void);
+void ungoto(void);
+void get_serv_info(char *, char *);
+int connectsock(char *host, char *service, char *protocol);
+void serv_gets(char *strbuf);
+void serv_puts(char *string);
+void whobbs(void);
+void fmout(FILE * fp);
+void wDumpContent(int);
+void serv_printf(const char *format,...);
+char *bstr(char *key);
+char *urlesc(char *);
+void urlescputs(char *);
+void output_headers(int);
+void wprintf(const char *format,...);
+void extract(char *dest, char *source, int parmnum);
+int extract_int(char *source, int parmnum);
+void output_static(char *what);
+void escputs(char *strbuf);
+void url(char *buf);
+void escputs1(char *strbuf, int nbsp);
+long extract_long(char *source, long int parmnum);
+void dump_vars(void);
+void embed_main_menu(void);
+void serv_read(char *buf, int bytes);
+int haschar(char *, char);
+void readloop(char *oper);
+void text_to_server(char *ptr);
+void display_enter(void);
+void post_message(void);
+void confirm_delete_msg(void);
+void delete_msg(void);
+void confirm_move_msg(void);
+void move_msg(void);
+void userlist(void);
+void showuser(void);
+void display_page(void);
+void page_user(void);
+void do_chat(void);
+void display_private(char *rname, int req_pass);
+void goto_private(void);
+void zapped_list(void);
+void display_zap(void);
+void zap(void);
+void display_error(char *);
+void display_success(char *);
+void display_entroom(void);
+void entroom(void);
+void display_editroom(void);
+void editroom(void);
+void server_to_text(void);
+void save_edit(char *description, char *enter_cmd, int regoto);
+void display_edit(char *description, char *check_cmd,
+                 char *read_cmd, char *save_cmd);
+void gotoroom(char *gname, int display_name);
+void confirm_delete_room(void);
+void delete_room(void);
+void validate(void);
+void display_graphics_upload(char *, char *, char *);
+void do_graphics_upload(char *upl_cmd);
+void serv_read(char *buf, int bytes);
+void serv_gets(char *strbuf);
+void serv_write(char *buf, int nbytes);
+void serv_puts(char *string);
+void serv_printf(const char *format,...);
+void load_floorlist(void);
+void select_floor_to_edit_pic(void);
+void display_reg(int);
+void register_user(void);
+void display_changepw(void);
+void changepw(void);
+void display_edit_node(void);
+void display_netconf(void);
+void display_confirm_unshare(void);
+void display_confirm_delete_node(void);
+void delete_node(void);
+void unshare(void);
+void display_add_node(void);
+void add_node(void);
+void display_share(void);
+void share(void);
+void terminate_session(void);
+void edit_me(void);
+void display_siteconfig(void);
+void siteconfig(void);
+void display_generic(void);
+void do_generic(void);
+void display_menubar(int);
+void embed_room_banner(char *);
+void smart_goto(char *);
+void ExpressMessageCat(char *);
+void worker_entry(void);
+void session_loop(struct httprequest *);
+void mime_parser(char *content,
+                 int ContentLength,
+                 char *ContentType,
+                 void (*CallBack)
+                  (char *cbname,
+                   char *cbfilename,
+                   char *cbencoding,
+                   void *cbcontent,                                                                char *cbtype,                                                                   size_t cblength)
+);
index 3a00ac3735fbb8eac59b29f01b9c81b1593e259a..ce0c9159d81eedd63b903838fd8e2f778d14869e 100644 (file)
@@ -44,11 +44,18 @@ int vsnprintf(char *buf, size_t max, const char *fmt, va_list argp);
 int msock;                     /* master listening socket */
 extern void *context_loop(int);
 extern void *housekeeping_loop(void);
-extern pthread_mutex_t MasterCritter;
+extern pthread_mutex_t SessionListMutex;
+extern pthread_key_t MyConKey;
+
+
+
+
 
 const char *defaulthost = DEFAULT_HOST;
 const char *defaultport = DEFAULT_PORT;
 
+pthread_mutex_t AcceptQueue;
+
 /*
  * This is a generic function to set up a master socket for listening on
  * a TCP port.  The server shuts down if the bind fails.
@@ -230,9 +237,6 @@ void start_daemon(int do_close_stdio)
  */
 int main(int argc, char **argv)
 {
-       struct sockaddr_in fsin;        /* Data for master socket */
-       int alen;               /* Data for master socket */
-       int ssock;              /* Descriptor for master socket */
        pthread_t SessThread;   /* Thread descriptor */
        pthread_attr_t attr;    /* Thread attributes */
        int a, i;               /* General-purpose variables */
@@ -264,12 +268,21 @@ int main(int argc, char **argv)
                        defaultport = argv[optind];
        }
        /* Tell 'em who's in da house */
-       printf("WebCit version 2.01\n");
-       printf("Copyright (C) 1996-1999.  All rights reserved.\n\n");
+       fprintf(stderr, SERVER "\n"
+               "Copyright (C) 1996-1999.  All rights reserved.\n\n");
 
        if (chdir(WEBCITDIR) != 0)
                perror("chdir");
 
+        /*
+         * Set up a place to put thread-specific data.
+         * We only need a single pointer per thread - it points to the
+         * wcsession struct to which the thread is currently bound.
+         */
+        if (pthread_key_create(&MyConKey, NULL) != 0) {
+                fprintf(stderr, "Can't create TSD key: %s\n", strerror(errno));
+        }
+
        /*
         * Bind the server to our favorite port.
         * There is no need to check for errors, because ig_tcp_server()
@@ -280,9 +293,8 @@ int main(int argc, char **argv)
        printf("Listening on socket %d\n", msock);
        signal(SIGPIPE, SIG_IGN);
 
-       pthread_mutex_init(&MasterCritter, NULL);
-
-
+       pthread_mutex_init(&SessionListMutex, NULL);
+       pthread_mutex_init(&AcceptQueue, NULL);
 
        /*
         * Start up the housekeeping thread
@@ -294,35 +306,57 @@ int main(int argc, char **argv)
 
 
 
-       /* 
-        * Endless loop.  Listen on the master socket.  When a connection
-        * comes in, create a socket, a context, and a thread.
-        */
-       while (1) {
+       /* FIX make this variable */
+       for (i=0; i<10; ++i) {
+
+               /* set attributes for the new thread */
+               pthread_attr_init(&attr);
+               pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+               /* now create the thread */
+               if (pthread_create(&SessThread, &attr,
+                               (void *(*)(void *)) worker_entry, NULL)
+                   != 0) {
+                       printf("webcit: can't create thread: %s\n",
+                              strerror(errno));
+               }
+       }
+
+       /* now become a worker thread too */
+       worker_entry();
+       pthread_exit(NULL);
+}
+
+
+/*
+ * Entry point for worker threads
+ */
+void worker_entry(void) {
+       int ssock;
+       struct sockaddr_in fsin;
+       int alen;
+       int i = 0;
+       int time_to_die = 0;
+
+       do {
+               /* Only one thread can accept at a time */
+               pthread_mutex_lock(&AcceptQueue);
                ssock = accept(msock, (struct sockaddr *) &fsin, &alen);
+               pthread_mutex_unlock(&AcceptQueue);
+
                printf("New connection on socket %d\n", ssock);
                if (ssock < 0) {
                        printf("webcit: accept() failed: %s\n",
-                              strerror(errno));
+                       strerror(errno));
                } else {
                        /* Set the SO_REUSEADDR socket option */
                        i = 1;
                        setsockopt(ssock, SOL_SOCKET, SO_REUSEADDR,
-                                  &i, sizeof(i));
-
-                       /* set attributes for the new thread */
-                       pthread_attr_init(&attr);
-                       pthread_attr_setdetachstate(&attr,
-                                               PTHREAD_CREATE_DETACHED);
-
-                       /* now create the thread */
-                       if (pthread_create(&SessThread, &attr,
-                                       (void *(*)(void *)) context_loop,
-                                          (void *) ssock)
-                           != 0) {
-                               printf("webcit: can't create thread: %s\n",
-                                      strerror(errno));
-                       }
+                               &i, sizeof(i));
+                       context_loop(ssock);
                }
-       }
+
+       } while (!time_to_die);
+
+       pthread_exit(NULL);
 }
index c71ce66a4895376065aaab0b412b93f80000fd8b..8afc9d081470f0f214c856908ed0e8de29265b86 100644 (file)
@@ -1,16 +1,34 @@
 /* $Id$ */
 
+
+
+
+#include <ctype.h>
 #include <stdlib.h>
-#ifdef HAVE_UNISTD_H
 #include <unistd.h>
-#endif
 #include <stdio.h>
+#include <fcntl.h>
 #include <signal.h>
 #include <sys/types.h>
-#include <ctype.h>
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <limits.h>
+#include <netinet/in.h>
+#include <netdb.h>
 #include <string.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <pthread.h>
+#include <signal.h>
 #include "webcit.h"
-#include "child.h"
+
+
+
+
+
+
 
 struct whouser {
        struct whouser *next;
@@ -31,7 +49,7 @@ void whobbs(void)
        char buf[256], sess, user[256], room[256], host[256];
        int foundit;
 
-       printf("HTTP/1.0 200 OK\n");
+       wprintf("HTTP/1.0 200 OK\n");
        output_headers(1);
 
        wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=007700><TR><TD>");
@@ -150,7 +168,7 @@ void terminate_session(void)
                        display_error(&buf[4]);
                }
        } else {
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
                wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=770000><TR><TD>");
                wprintf("<FONT FACE=\"Arial,Helvetica,sans-serif\" SIZE=+1 COLOR=\"FFFFFF\"<B>Confirm session termination");
@@ -199,7 +217,7 @@ void edit_me(void)
                whobbs();
        } else {
 
-               printf("HTTP/1.0 200 OK\n");
+               wprintf("HTTP/1.0 200 OK\n");
                output_headers(1);
 
                wprintf("<TABLE WIDTH=100% BORDER=0 BGCOLOR=000077><TR><TD>");
diff --git a/webcit/wildmat.c b/webcit/wildmat.c
deleted file mode 100644 (file)
index f060ac8..0000000
+++ /dev/null
@@ -1,201 +0,0 @@
-/* $Source$
-
- * $Revision$
- *
- * wildmat.c - simple regular expression pattern matching routines 
- *
- * DESCRIPTION 
- *
- *     These routines provide simple UNIX style regular expression matching.  
- *     They were originally written by Rich Salz, the comp.sources.unix 
- *     moderator for inclusion in some of his software.  These routines 
- *     were released into the public domain and used by John Gilmore in 
- *     USTAR. 
- *
- * AUTHORS 
- *
- *     Mark H. Colburn, NAPS International (mark@jhereg.mn.org) 
- *     John Gilmore (gnu@hoptoad) 
- *     Rich Salz (rs@uunet.uu.net) 
- *
- *
- * Sponsored by The USENIX Association for public distribution. 
- *
- * Copyright (c) 1989 Mark H. Colburn.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice is duplicated in all such 
- * forms and that any documentation, advertising materials, and other 
- * materials related to such distribution and use acknowledge that the 
- * software was developed * by Mark H. Colburn and sponsored by The 
- * USENIX Association. 
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Log$
- * Revision 1.3  1999/06/08 02:01:29  ajc
- *         * Session no longer locks up when an express message is cancelled
- *         * The default Citadel server is now "localhost" instead of uncnsrd
- *         * Added some documentation
- *
- * Revision 1.2  1999/06/03 03:48:52  ajc
- *         * Ditched the frames mode completely.  It wasn't working properly in,
- *           among other places, IE 5.  Die, Bill, Die.
- *
- * Revision 1.1  1999/03/07 03:09:55  ajc
- *         * wildmat.c, braindamage.c: added
- *
- * Revision 1.1  88/12/23  18:02:41  mark
- * Initial revision
- * 
- */
-
-/* Includes */
-
-#include <stdlib.h>
-#include <unistd.h>
-#include <stdio.h>
-
-
-
-/* Function Prototypes */
-
-#ifdef __STDC__
-static int star(char *, char *);
-#else                          /* !__STDC__ */
-static int star();
-#endif                         /* __STDC__ */
-
-
-/*
- * star - handle trailing * in a regular expression 
- *
- * DESCRIPTION
- *
- *     Star is used to match filename expansions containing a trailing
- *     asterisk ('*').  Star call wildmat() to determine if the substring
- *     passed to it is matches the regular expression.
- *
- * PARAMETERS 
- *
- *     char *source    - The source string which is to be compared to the 
- *                       regular expression pattern. 
- *     char *pattern   - The regular expression which we are supposed to 
- *                       match to. 
- *
- * RETURNS 
- *
- *     Returns non-zero if the entire source string is completely matched by 
- *     the regular expression pattern, returns 0 otherwise. This is used to 
- *     see if *'s in a pattern matched the entire source string. 
- *
- */
-
-#ifdef __STDC__
-
-static int star(char *source, char *pattern)
-#else
-
-static int star(source, pattern)
-char *source;                  /* source operand */
-char *pattern;                 /* regular expression to match */
-
-#endif
-{
-       while (!wildmat(source, pattern)) {
-               if (*++source == '\0') {
-                       return (0);
-               }
-       }
-       return (1);
-}
-
-
-/*
- * wildmat - match a regular expression 
- *
- * DESCRIPTION
- *
- *     Wildmat attempts to match the string pointed to by source to the 
- *     regular expression pointed to by pattern.  The subset of regular 
- *     expression syntax which is supported is defined by POSIX P1003.2 
- *     FILENAME EXPANSION rules.
- *
- * PARAMETERS 
- *
- *     char *source    - The source string which is to be compared to the 
- *                       regular expression pattern. 
- *     char *pattern   - The regular expression which we are supposed to 
- *                       match to. 
- *
- * RETURNS 
- *
- *     Returns non-zero if the source string matches the regular expression 
- *     pattern specified, returns 0 otherwise. 
- *
- */
-
-#ifdef __STDC__
-
-int wildmat(char *pattern, char *source)
-#else
-
-int wildmat(pattern, source)
-char *pattern;                 /* regular expression to match */
-char *source;                  /* source operand */
-
-#endif
-{
-       int last;               /* last character matched */
-       int matched;            /* !0 if a match occurred */
-       int reverse;            /* !0 if sense of match is reversed */
-
-       for (; *pattern; source++, pattern++) {
-               switch (*pattern) {
-               case '\\':
-                       /* Literal match with following character */
-                       pattern++;
-                       /* FALLTHRU */
-               default:
-                       if (*source != *pattern) {
-                               return (0);
-                       }
-                       continue;
-               case '?':
-                       /* Match anything. */
-                       if (*source == '\0') {
-                               return (0);
-                       }
-                       continue;
-               case '*':
-                       /* Trailing star matches everything. */
-                       return (*++pattern ? star(source, pattern) : 1);
-               case '[':
-                       /* [^....] means inverse character class. */
-                       if ((reverse = pattern[1]) == '^') {
-                               pattern++;
-                       }
-                       for (last = 0400, matched = 0;
-                       *++pattern && *pattern != ']'; last = *pattern) {
-                               /* This next line requires a good C compiler. */
-                               if (*pattern == '-'
-                               ? *source <= *++pattern && *source >= last
-                                   : *source == *pattern) {
-                                       matched = 1;
-                               }
-                       }
-                       if (matched == reverse) {
-                               return (0);
-                       }
-                       continue;
-               }
-       }
-
-       /*
-        * For "tar" use, matches that end at a slash also work. --hoptoad!gnu 
-        */
-       return (*source == '\0' || *source == '/');
-}