]> code.citadel.org Git - citadel.git/commitdiff
Pre-caching proxy.
authorArt Cancro <ajc@citadel.org>
Thu, 17 Sep 1998 17:28:49 +0000 (17:28 +0000)
committerArt Cancro <ajc@citadel.org>
Thu, 17 Sep 1998 17:28:49 +0000 (17:28 +0000)
citadel/proxy.c

index c2390a8c407375a0e61f30feed622b83910c2298..e7853ccdba29a35f7d9f7fea8b2e46ea6bd1e73f 100644 (file)
 #include <errno.h>
 #include "citadel.h"
 
+struct RoomList {
+       struct RoomList *next;
+       char roomname[32];
+       };
+
+struct MsgList {
+       struct MsgList *next;
+       long msgnum;
+       };
+
+
+/*
+ * num_parms()  -  discover number of parameters...
+ */
+int num_parms(char *source)
+{
+        int a;
+        int count = 1;
+
+        for (a=0; a<strlen(source); ++a)
+                if (source[a]=='|') ++count;
+        return(count);
+        }
+
+
+/*
+ * extract()  -  extract a parameter from a series of "|" separated...
+ */
+void extract(char *dest, char *source, int parmnum)
+{
+        char buf[256];
+        int count = 0;
+        int n;
+
+        n = num_parms(source);
+
+        if (parmnum >= n) {
+                strcpy(dest,"");
+                return;
+                }
+        strcpy(buf,source);
+        if ( (parmnum == 0) && (n == 1) ) {
+                strcpy(dest,buf);
+                return;
+                }
+
+        while (count++ < parmnum) do {
+                strcpy(buf,&buf[1]);
+                } while( (strlen(buf)>0) && (buf[0]!='|') );
+        if (buf[0]=='|') strcpy(buf,&buf[1]);
+        for (count = 0; count<strlen(buf); ++count)
+                if (buf[count] == '|') buf[count] = 0;
+        strcpy(dest,buf);
+        }
+
+
+
+
+
+
+
 void logoff(int code) {
        exit(code);
        }
 
 
+/* Fetch a message (or check its status in the cache)
+ */
+void fetch_message(long msgnum) {
+       char filename[64];
+       char temp[64];
+       FILE *fp;
+       char buf[256];
+
+       sprintf(filename, "%ld", msgnum);
+
+       if (access(filename, F_OK)==0) {
+               return;                         /* Already on disk */
+               }
+
+       /* The message is written to a file with a temporary name, in
+        * order to avoid another user accidentally fetching a
+        * partially written message from the cache.
+        */
+       sprintf(buf, "MSG0 %ld", msgnum);
+       serv_puts(buf);
+       serv_gets(buf);
+       if (buf[0] != '1') return;
+        sprintf(temp, "%ld.%d", msgnum, getpid());
+        fp = fopen(temp, "w");
+        while (serv_gets(buf), strcmp(buf, "000")) {
+                fprintf(fp, "%s\n", buf);
+                }
+        fclose(fp);
+
+        /* Now that the message is complete, it can be renamed to the
+         * filename that the cache manager will recognize it with.
+         */
+        link(temp, filename);
+        unlink(temp);
+       }
+
+
+/*
+ * This loop pre-fetches lots of messages
+ */
+void do_prefetch() {
+       char buf[256];
+       struct RoomList *rl = NULL;
+       struct RoomList *rlptr;
+       struct MsgList *ml = NULL;
+       struct MsgList *mlptr;
+
+       close(0);
+       close(1);
+       close(2);
+
+
+       serv_gets(buf);
+       if (buf[0] != '2') {
+               exit(0);
+               }
+
+
+       /* Log in (this is kind of arbitrary) */
+       serv_puts("USER cypherpunks");
+       serv_gets(buf);
+       if (buf[0]=='3') {
+               serv_puts("PASS cypherpunks");
+               serv_gets(buf);
+               if (buf[0] != '2') exit(1);
+               }
+       else {
+               serv_puts("NEWU cypherpunks");
+               serv_gets(buf);
+               if (buf[0] != '2') exit(1);
+               serv_puts("SETP cypherpunks");
+               serv_gets(buf);
+               if (buf[0] != '2') exit(1);
+               }
+
+       /* Fetch the roomlist (rooms with new messages only) */
+       serv_puts("LKRN");
+       serv_gets(buf);
+       if (buf[0] != '1') exit(2);
+       while (serv_gets(buf), strcmp(buf, "000")) {
+               rlptr = (struct rlptr *) malloc(sizeof(struct RoomList));
+               rlptr->next = rl;
+               rl = rlptr;
+               extract(rlptr->roomname, buf, 0);
+               }
+
+       /* Go to each room, fetching new messages */
+       while (rl != NULL) {
+               sprintf(buf, "GOTO %s", rl->roomname);
+               serv_puts(buf);
+               serv_gets(buf);
+               if (buf[0]=='2') {
+                       serv_puts("MSGS NEW");
+                       serv_gets(buf);
+                       ml = NULL;
+                       if (buf[0]=='1') {
+                               while (serv_gets(buf), strcmp(buf, "000")) {
+                                       mlptr = (struct mlptr *)
+                                               malloc(sizeof(struct MsgList));
+                                       mlptr->next = ml;
+                                       ml = mlptr;
+                                       mlptr->msgnum = atol(buf);
+                                       }
+                               }
+                       }
+
+               /* Fetch each message */
+               while (ml != NULL) {
+                       fetch_message(ml->msgnum);
+                       mlptr = ml;
+                       ml = ml->next;
+                       free(mlptr);
+                       }
+
+               /* Free the room list pointer */
+               rlptr = rl;
+               rl = rl->next;
+               free(rlptr);
+               }
+
+       /* Now log out. */
+       serv_puts("QUIT");
+       exit(0);
+       }
+
 void do_msg0(char cmd[]) {
-       long msgid;
+       long msgnum;
        char filename[32];
        char temp[32];
        char buf[256];
        FILE *fp;
 
-       msgid = atol(&cmd[5]);
-       sprintf(filename, "%ld", msgid);
+       msgnum = atol(&cmd[5]);
+       sprintf(filename, "%ld", msgnum);
 
        /* If the message is cached, use the copy on disk */
        fp = fopen(filename, "r");
        if (fp != NULL) {
-               printf("%d Cached message %ld:\n", LISTING_FOLLOWS, msgid);
+               printf("%d Cached message %ld:\n", LISTING_FOLLOWS, msgnum);
                while (fgets(buf, 256, fp) != NULL) {
                        buf[strlen(buf)-1]=0;
                        printf("%s\n", buf);
@@ -48,7 +234,7 @@ void do_msg0(char cmd[]) {
 
        /* Otherwise, fetch the message from the server and cache it */
        else {
-               sprintf(buf, "MSG0 %ld", msgid);
+               sprintf(buf, "MSG0 %ld", msgnum);
                serv_puts(buf); 
                serv_gets(buf);
                printf("%s\n", buf);
@@ -61,7 +247,7 @@ void do_msg0(char cmd[]) {
                 * order to avoid another user accidentally fetching a
                 * partially written message from the cache.
                 */
-               sprintf(temp, "%ld.%d", msgid, getpid());
+               sprintf(temp, "%ld.%d", msgnum, getpid());
                fp = fopen(temp, "w");
                while (serv_gets(buf), strcmp(buf, "000")) {
                        printf("%s\n", buf);
@@ -178,6 +364,7 @@ void do_mainloop() {
 
 void main(int argc, char *argv[]) {
        char buf[256];
+       int pid;
 
        /* Create the cache directory.  Ignore any error return, 'cuz that
         * just means it's already there.  FIX... this really should check
@@ -188,7 +375,9 @@ void main(int argc, char *argv[]) {
        /* Now go there */
        if (chdir(CACHE_DIR) != 0) exit(errno);
 
+       pid = fork();
        attach_to_server(argc, argv);
+       if (pid == 0) do_prefetch();
 
        serv_gets(buf);
        strcat(buf, " (VIA PROXY)");