]> code.citadel.org Git - citadel.git/blobdiff - citadel/netproc.c
* Various changes to begin work on support for MIME messages
[citadel.git] / citadel / netproc.c
index 52dafca1c3815802753f15d52d66fd41520de689..630254b1e1add6fbae6c2165eda3f0a868b090e7 100644 (file)
@@ -2,16 +2,9 @@
  * Citadel/UX Intelligent Network Processor for IGnet/Open networks v3.6
  * Designed and written by Art Cancro @ Uncensored Communications Group
  * See copyright.txt for copyright information
+ * $Id$
  */
 
-/*
- * Specify where netproc should log to, and the mode for opening the file.
- * If you are logging to a file, NPLOGMODE should be a; if you are logging to
- * a device or fifo it should be w.
- */
-#define NPLOGFILE      "./netproc.log" 
-#define NPLOGMODE      "a"
-
 /* How long it takes for an old node to drop off the network map */
 #define EXPIRY_TIME    (2592000L)
 
@@ -37,7 +30,9 @@
 #include <time.h>
 #include <signal.h>
 #include <errno.h>
+#include <syslog.h>
 #include "citadel.h"
+#include "tools.h"
 
 /* A list of users you wish to filter out of incoming traffic can be kept
  * in ./network/filterlist -- messages from these users will be automatically
 struct msglist {
        struct msglist *next;
        long m_num;
-       char m_rmname[20];
+       char m_rmname[ROOMNAMELEN];
        };
 
 struct rmlist {
        struct rmlist *next;
-       char rm_name[20];
+       char rm_name[ROOMNAMELEN];
        long rm_lastsent;
        };
 
@@ -73,29 +68,12 @@ struct syslist {
        char s_name[16];
        char s_type[4];
        char s_nexthop[128];
-       long s_lastcontact;
+       time_t s_lastcontact;
        char s_humannode[64];
        char s_phonenum[32];
        char s_gdom[64];
        };
 
-struct minfo {
-       char A[512];
-       char E[512];
-       long I;
-       char N[512];
-       char O[512];
-       char R[512];
-       long T;
-       char D[512];
-       char C[512];
-       char nexthop[32];
-       char H[512];
-       char S[512];
-       char B[512];
-       char G[512];
-       };
-
 
 void attach_to_server(int argc, char **argv);
 void serv_read(char *buf, int bytes);
@@ -103,8 +81,6 @@ void serv_write(char *buf, int nbytes);
 void get_config(void);
 
 struct filterlist *filter = NULL;
-char roomnames[MAXROOMS][20];
-char roomdirs[MAXROOMS][15];
 struct syslist *slist = NULL;
 
 struct config config;
@@ -133,30 +109,6 @@ void strip_trailing_whitespace(char *buf)
        }
 
 
-/*
- * for performance optimization, netproc loads the list of room names (and
- * their corresponding directory names, if applicable) into a table in memory.
- */
-int load_roomnames(void) {
-       FILE *fp;
-       struct quickroom qbuf;
-       int i;
-
-       fp=fopen("./quickroom","rb");
-       if (fp==NULL) return(1);
-       for (i=0; i<MAXROOMS; ++i) {
-               if (fread((char *)&qbuf,sizeof(struct quickroom),1,fp)!=1)
-                       return(1);
-               strcpy(roomnames[i],qbuf.QRname);
-               if (qbuf.QRflags & QR_DIRECTORY)
-                       strcpy(roomdirs[i],qbuf.QRdirname);
-               else
-                       strcpy(roomdirs[i],config.c_bucket_dir);
-               }
-       fclose(fp);
-       return(0);
-       }
-
 /*
  * we also load the network/mail.sysinfo table into memory, make changes
  * as we learn more about the network from incoming messages, and write
@@ -269,7 +221,7 @@ void setup_special_nodes(void) {
 void rewrite_syslist(void) {
        struct syslist *stemp;
        FILE *newfp;
-       long now;
+       time_t now;
 
        time(&now);
        newfp=fopen("network/mail.sysinfo","w");
@@ -365,6 +317,7 @@ void remove_lockfile(void) {
 void nq_cleanup(int e)
 {
        remove_lockfile();
+       closelog();
        exit(e);
        }
 
@@ -460,7 +413,7 @@ GETSN:      for (stemp=slist; stemp!=NULL; stemp=stemp->next) {
                        }
                }
            }
-       printf("netproc: cannot find system '%s' in mail.sysinfo\n",name);
+       syslog(LOG_ERR, "cannot find system '%s' in mail.sysinfo", name);
        return(-1);
        }
 
@@ -498,12 +451,12 @@ void msgfind(char *msgfile, struct minfo *buffer)
        strcpy(userid,"");
        fp=fopen(msgfile,"rb");
        if (fp==NULL) {
-               fprintf(stderr,"Can't open message file: %s\n",strerror(errno));
+               syslog(LOG_ERR, "can't open message file: %s",strerror(errno));
                return;
                }
        e=getc(fp);
        if (e!=255) {
-               fprintf(stdout,"Incorrect message format\n");
+               syslog(LOG_ERR, "incorrect message format");
                goto END;
                }
        mtype=getc(fp); aflag=getc(fp);
@@ -566,11 +519,11 @@ void ship_to(char *filenm, char *sysnm)   /* send spool file filenm to system sysn
        FILE *sysflfd;
 
 #ifdef DEBUG
-       fprintf(stdout,"netproc: shipping %s to %s\n",filenm,sysnm);
+       syslog(LOG_NOTICE, "shipping %s to %s", filenm, sysnm);
 #endif
        sprintf(sysflnm,"./network/systems/%s",sysnm);
        sysflfd=fopen(sysflnm,"r");
-       if (sysflfd==NULL) fprintf(stdout,"netproc: cannot open %s\n",sysflnm);
+       if (sysflfd==NULL) syslog(LOG_ERR, "cannot open %s", sysflnm);
        fgets(commbuf1,99,sysflfd);
        commbuf1[strlen(commbuf1)-1] = 0;
        fclose(sysflfd);
@@ -580,40 +533,56 @@ void ship_to(char *filenm, char *sysnm)   /* send spool file filenm to system sysn
 
 /*
  * proc_file_transfer()  -  handle a simple file transfer packet
+ *
  */
 void proc_file_transfer(char *tname)
 {      /* name of temp file containing the whole message */
-       char buf[128];
-       char dest_dir[32];
+       char buf[256];
+       char dest_room[ROOMNAMELEN];
+       char subdir_name[256];
        FILE *tfp,*uud;
-       int a,b;
+       int a;
 
-       printf("netproc: processing network file transfer...\n");
-       strcpy(dest_dir,config.c_bucket_dir);
+       syslog(LOG_NOTICE, "processing network file transfer...");
 
        tfp=fopen(tname,"rb");
-       if (tfp==NULL) printf("netproc: cannot open %s\n",tname);
+       if (tfp==NULL) syslog(LOG_ERR, "cannot open %s", tname);
        getc(tfp); getc(tfp); getc(tfp);
        do {
                a=getc(tfp);
                if (a!='M') {
                        fpgetfield(tfp,buf);
-                       if (a=='O') for (b=0; b<MAXROOMS; ++b) {
-                               if (!strcasecmp(buf,roomnames[b]))
-                                       strcpy(dest_dir,roomdirs[b]);
+                       if (a=='O') {
+                               strcpy(dest_room, buf);
                                }
                        }
                } while ((a!='M')&&(a>=0));
        if (a!='M') {
                fclose(tfp);
-               printf("netproc: no message text for file transfer\n");
+               syslog(LOG_ERR, "no message text for file transfer");
                return;
                }
 
-       sprintf(buf,"cd %s/files/%s; exec %s",bbs_home_directory,dest_dir,UUDECODE);
+       strcpy(subdir_name, "---xxx---");
+       sprintf(buf, "GOTO %s", dest_room);
+       serv_puts(buf);
+       serv_gets(buf);
+       if (buf[0]=='2') {
+               extract(subdir_name, &buf[4], 2);
+               if (strlen(subdir_name) == 0) strcpy(subdir_name, "--xxx--");
+               }
+
+       /* Change to the room's directory; if that fails, change to the
+        * bitbucket directory.  Then run uudecode.
+        */
+       sprintf(buf,"(cd %s/files/%s || cd %s/files/%s ) ; exec %s",
+               bbs_home_directory, subdir_name,
+               bbs_home_directory, config.c_bucket_dir,
+               UUDECODE);
+
        uud=(FILE *)popen(buf,"w");
        if (uud==NULL) {
-               printf("netproc: cannot open uudecode pipe\n");
+               syslog(LOG_ERR, "cannot open uudecode pipe");
                fclose(tfp);
                return;
                }
@@ -637,7 +606,7 @@ void bounce(struct minfo *bminfo)
        FILE *bounce;
        char bfilename[64];
        static int bseq = 1;
-       long now;
+       time_t now;
 
        sprintf(bfilename,"./network/spoolin/bounce.%d.%d",getpid(),bseq++);
        bounce = fopen(bfilename,"wb");
@@ -699,8 +668,7 @@ void inprocess(void) {
        sprintf(aaa,"cd %s/network/spoolin; ls",bbs_home_directory);
        ls=popen(aaa,"r");
        if (ls==NULL) {
-               fprintf(stderr,"netproc: could not open dir cmd: %s\n",
-                       strerror(errno));
+               syslog(LOG_ERR, "could not open dir cmd: %s", strerror(errno));
                }
        if (ls!=NULL) {
                do {
@@ -708,20 +676,17 @@ void inprocess(void) {
                        if (ptr!=NULL) sfilename[strlen(sfilename)-1] = 0;
                        } while( (ptr!=NULL)&&((!strcmp(sfilename,"."))
                                 ||(!strcmp(sfilename,".."))));
-               if (ptr!=NULL) printf("netproc: processing %s\n",sfilename);
+               if (ptr!=NULL) syslog(LOG_NOTICE, "processing %s", sfilename);
                pclose(ls);
                }
 
       if (ptr!=NULL) {
        sprintf(pfilename,"%s/network/spoolin/%s",bbs_home_directory,sfilename);
-       fprintf(stderr,"netproc: processing <%s>\n", pfilename);
-       fflush(stderr);
+       syslog(LOG_NOTICE, "processing <%s>", pfilename);
        
        fp = fopen(pfilename, "rb");
        if (fp == NULL) {
-           fprintf(stderr, "netproc: cannot open <%s>: %s\n",
-                       pfilename, strerror(errno));
-           fflush(stderr);
+           syslog(LOG_ERR, "cannot open %s: %s", pfilename, strerror(errno));
            fp = fopen("/dev/null" ,"rb");
            }
                
@@ -733,8 +698,7 @@ NXMSG:      /* Seek to the beginning of the next message */
 
        message = fopen(tname,"wb");    /* This crates the temporary file. */
        if (message == NULL) {
-               fprintf(stderr, "Error creating %s: %s\n",
-                       tname, strerror(errno));
+               syslog(LOG_ERR, "error creating %s: %s", tname,strerror(errno));
                goto ENDSTR;
                }
        putc(255,message);              /* 0xFF (start-of-message) */
@@ -762,23 +726,22 @@ NXMSG:    /* Seek to the beginning of the next message */
        strncpy(recentmsg.RMnodename,minfo.N,9);
        recentmsg.RMnodename[9]=0;
        recentmsg.RMnum=minfo.I;
-       printf("netproc: #%ld fm <%s> in <%s> @ <%s>\n",
+       syslog(LOG_NOTICE, "#%ld fm <%s> in <%s> @ <%s>",
                minfo.I,minfo.A,minfo.O,minfo.N);
        if (strlen(minfo.R)>0) {
-               printf("         to <%s>",minfo.R);
+               syslog(LOG_NOTICE, "     to <%s>",minfo.R);
                if (strlen(minfo.D)>0) {
-                       printf(" @ <%s>",minfo.D);
+                       syslog(LOG_NOTICE, "     @ <%s>",minfo.D);
                        }
-               printf("\n");
                }
-       fflush(stdout);
        if (!strcasecmp(minfo.D,FQDN)) strcpy(minfo.D,NODENAME);
 
        /* this routine updates our info on the system that sent the message */
        stemp = get_sys_ptr(minfo.N);
        if ((stemp == NULL) && (get_sys_ptr(minfo.nexthop) != NULL)) {
                /* add non-neighbor system to map */
-               printf("Adding non-neighbor system <%s> to map\n", slist->s_name);
+               syslog(LOG_NOTICE, "Adding non-neighbor system <%s> to map",
+                       slist->s_name);
                stemp = (struct syslist *)malloc((long)sizeof(struct syslist));
                stemp->next = slist;
                slist = stemp;
@@ -789,7 +752,8 @@ NXMSG:      /* Seek to the beginning of the next message */
                }
        else if ((stemp == NULL) && (!strcasecmp(minfo.N,minfo.nexthop))) {
                /* add neighbor system to map */
-               printf("Adding neighbor system <%s> to map\n", slist->s_name);
+               syslog(LOG_NOTICE, "Adding neighbor system <%s> to map",
+                       slist->s_name);
                sprintf(aaa,"%s/network/systems/%s",bbs_home_directory,minfo.N);
                testfp=fopen(aaa,"r");
                if (testfp!=NULL) {
@@ -815,17 +779,16 @@ NXMSG:    /* Seek to the beginning of the next message */
        /* route the message if necessary */
        if ((strcasecmp(minfo.D,NODENAME))&&(minfo.D[0]!=0)) { 
                a = get_sysinfo_type(minfo.D);
-               printf("netproc: routing message to system <%s>\n",minfo.D);
+               syslog(LOG_NOTICE, "routing message to system <%s>", minfo.D);
                fflush(stdout);
                if (a==M_INTERNET) {
                        if (fork()==0) {
-                               printf("netproc: netmailer %s\n", tname);
+                               syslog(LOG_NOTICE, "netmailer %s", tname);
                                fflush(stdout);
                                execlp("./netmailer","netmailer",
                                        tname,NULL);
-                               printf("netproc: error running netmailer: %s\n",
+                               syslog(LOG_ERR, "error running netmailer: %s",
                                        strerror(errno));
-                               fflush(stdout);
                                exit(errno);
                                }
                        else while (wait(&b)!=(-1));
@@ -868,7 +831,7 @@ NXMSG:      /* Seek to the beginning of the next message */
                serv_puts(buf);
                serv_gets(buf);
                if (buf[0] != '2') {
-                       puts(buf); fflush(stdout);
+                       syslog(LOG_ERR, "%s", buf);
                        sprintf(buf,"GOTO _BITBUCKET_");
                        serv_puts(buf);
                        serv_gets(buf);
@@ -877,7 +840,7 @@ NXMSG:      /* Seek to the beginning of the next message */
                /* Open the temporary file containing the message */
                message = fopen(tname, "rb");
                if (message == NULL) {
-                       fprintf(stderr, "netproc: cannot open %s: %s\n",
+                       syslog(LOG_ERR, "cannot open %s: %s",
                                tname, strerror(errno));
                        unlink(tname);
                        goto NXMSG;
@@ -885,10 +848,8 @@ NXMSG:     /* Seek to the beginning of the next message */
 
                /* Transmit the message to the server */
                sprintf(buf, "ENT3 1|%s|%ld", minfo.R, msglen);
-               printf("< %s\n", buf);
                serv_puts(buf);
                serv_gets(buf);
-               printf("> %s\n", buf);
                if (!strncmp(buf, "570", 3)) {
                        /* no such user, do a bounce */
                        bounce(&minfo);
@@ -900,9 +861,9 @@ NXMSG:      /* Seek to the beginning of the next message */
                        while (msglen > 0L) {
                                bloklen = ((msglen >= 255L) ? 255 : ((int)msglen));
                                if (fread(buf, bloklen, 1, message) < 1) {
-                                       fprintf(stderr, "netproc: error trying to read %d bytes: %s\n",
-                                               bloklen, strerror(errno));
-                                       fflush(stderr);
+                                       syslog(LOG_ERR,
+                                          "error trying to read %d bytes: %s",
+                                          bloklen, strerror(errno));
                                        }
                                serv_write(buf, bloklen);
                                msglen = msglen - (long)bloklen;
@@ -911,8 +872,7 @@ NXMSG:      /* Seek to the beginning of the next message */
                        serv_gets(buf);
                        }
                else {
-                       puts(buf);
-                       fflush(stdout); 
+                       syslog(LOG_ERR, "%s", buf);
                        }
 
                fclose(message);
@@ -938,7 +898,7 @@ int checkpath(char *path, char *sys)        /* Checks to see whether its ok to send */
        strcat(sys2,"!");
 
 #ifdef DEBUG
-       printf("netproc: checkpath <%s> <%s> ... ",path,sys);
+       syslog(LOG_NOTICE, "checkpath <%s> <%s> ... ", path, sys);
 #endif
        for (a=0; a<strlen(path); ++a) {
                if (!strncmp(&path[a],sys2,strlen(sys2))) return(0);
@@ -966,7 +926,7 @@ int ismsgok(long int mpos, FILE *mmfp, char *sysname)
                        }
                }
 #ifdef DEBUG
-       printf("%s\n", ((ok)?"SEND":"(no)") );
+       syslog(LOG_NOTICE, "%s", ((ok)?"SEND":"(no)") );
 #endif
        return(ok);
        }
@@ -1003,7 +963,7 @@ int spool_out(struct msglist *cmlist, FILE *destfp, char *sysname) /* spool list
                                strcpy(curr_rm, cmptr->m_rmname);
                                }
                        else {
-                               fprintf(stderr,"%s\n", buf);
+                               syslog(LOG_ERR, "%s", buf);
                                }
                        }
 
@@ -1022,7 +982,7 @@ int spool_out(struct msglist *cmlist, FILE *destfp, char *sysname) /* spool list
                                }
                        }
                else {                                  /* or print the err */
-                       fprintf(stderr, "%s\n", buf);
+                       syslog(LOG_ERR, "%s", buf);
                        }
                fclose(mmfp);
        
@@ -1118,7 +1078,7 @@ void outprocess(char *sysname) /* send new room messages to sysname */
                serv_puts(buf);
                serv_gets(buf);
                if (buf[0]!='2') {
-                       fprintf(stderr, "%s\n", buf);
+                       syslog(LOG_ERR, "%s", buf);
                        }
                else {
                        sprintf(buf, "MSGS GT|%ld", rmptr->rm_lastsent);
@@ -1145,7 +1105,7 @@ void outprocess(char *sysname) /* send new room messages to sysname */
                                        }
                                }
                        else {          /* print error from "msgs all" */
-                               fprintf(stderr, "%s\n", buf);
+                               syslog(LOG_ERR, "%s", buf);
                                }
                        }
                }
@@ -1155,18 +1115,15 @@ void outprocess(char *sysname) /* send new room messages to sysname */
                ++outgoing_msgs;
                cmptr2 = cmptr2->next;
                }
-       printf("netproc: %d messages to be spooled to %s\n",
+       syslog(LOG_NOTICE, "%d messages to be spooled to %s",
                outgoing_msgs,sysname);
-       fflush(stdout);
 
 /*
  * Spool out the messages, but only if there are any.
  */
-       fflush(stdout);
        if (outgoing_msgs!=0) outgoing_msgs=spool_out(cmlist,tempflfp,sysname);
-       printf("netproc: %d messages actually spooled\n",
+       syslog(LOG_NOTICE, "%d messages actually spooled",
                outgoing_msgs);
-       fflush(stdout);
 
 /*
  * Deallocate list of spooled messages.
@@ -1180,8 +1137,7 @@ void outprocess(char *sysname) /* send new room messages to sysname */
 /*
  * Rewrite system file and deallocate room list.
  */
-       printf("Spooling...\n");
-       fflush(stdout);
+       syslog(LOG_NOTICE, "Spooling...");
        sysflfp=fopen(sysflnm,"w");
        fprintf(sysflfp,"%s\n",shiptocmd);
        for (rmptr=crmlist; rmptr!=NULL; rmptr=rmptr->next)  
@@ -1210,16 +1166,16 @@ void np_attach_to_server(void) {
        char portname[8];
        char *args[] = { "netproc", "localhost", NULL, NULL } ;
 
-       printf("Attaching to server...\n");
+       syslog(LOG_NOTICE, "Attaching to server...");
        sprintf(portname, "%d", config.c_port_number);
        args[2] = portname;
        attach_to_server(3, args);
        serv_gets(buf);
-       printf("%s\n",&buf[4]);
+       syslog(LOG_NOTICE, "%s", &buf[4]);
        sprintf(buf,"IPGM %d", config.c_ipgm_secret);
        serv_puts(buf);
        serv_gets(buf);
-       printf("%s\n",&buf[4]);
+       syslog(LOG_NOTICE, "%s", &buf[4]);
        if (buf[0]!='2') {
                cleanup(2);
                }
@@ -1230,38 +1186,39 @@ void np_attach_to_server(void) {
 /*
  * main
  */
-void main(int argc, char **argv)
+int main(int argc, char **argv)
 {
        char allst[32];
        FILE *allfp;
        int a;
+       int import_only = 0;    /* if set to 1, don't export anything */
 
-
+       openlog("netproc", LOG_PID, LOG_USER);
        strcpy(bbs_home_directory, BBSDIR);
 
        /*
         * Change directories if specified
         */
-       if (argv > 0) for (a=1; a<argc; ++a) {
+       for (a=1; a<argc; ++a) {
                if (!strncmp(argv[a], "-h", 2)) {
                        strcpy(bbs_home_directory, argv[a]);
                        strcpy(bbs_home_directory, &bbs_home_directory[2]);
                        home_specified = 1;
                        }
+               else if (!strcmp(argv[a], "-i")) {
+                       import_only = 1;
+                       }
                else {
-                       fprintf(stderr, "netproc: usage: netproc [-hHomeDir]\n");
+                       fprintf(stderr, "netproc: usage: ");
+                       fprintf(stderr, "netproc [-hHomeDir] [-i]\n");
                        exit(1);
                        }
                }
 
        get_config();
 
-       /* write all messages to the log from this point onward */
-       freopen(NPLOGFILE,NPLOGMODE,stdout);
-       freopen(NPLOGFILE,NPLOGMODE,stderr);
-
        if (set_lockfile()!=0) {
-               fprintf(stderr,"netproc: lock file exists: already running\n");
+               syslog(LOG_NOTICE, "lock file exists: already running");
                cleanup(1);
                }
 
@@ -1270,29 +1227,31 @@ void main(int argc, char **argv)
        signal(SIGHUP,cleanup);
        signal(SIGTERM,cleanup);
 
-       printf("netproc: started.  pid=%d\n",getpid());
+       syslog(LOG_NOTICE, "started.  pid=%d", getpid());
        fflush(stdout);
        np_attach_to_server();
        fflush(stdout);
 
-       if (load_roomnames()!=0) fprintf(stdout,"netproc: cannot load rooms\n");
-       if (load_syslist()!=0) fprintf(stdout,"netproc: cannot load sysinfo\n");
+       if (load_syslist()!=0) syslog(LOG_ERR, "cannot load sysinfo");
        setup_special_nodes();
 
        inprocess();    /* first collect incoming stuff */
 
-       allfp=(FILE *)popen("cd ./network/systems; ls","r");
-       if (allfp!=NULL) {
-               while (fgets(allst,32,allfp)!=NULL) {
-                       allst[strlen(allst)-1] = 0;
-                       outprocess(allst);
+       if (import_only != 1) {
+               allfp=(FILE *)popen("cd ./network/systems; ls","r");
+               if (allfp!=NULL) {
+                       while (fgets(allst,32,allfp)!=NULL) {
+                               allst[strlen(allst)-1] = 0;
+                               outprocess(allst);
+                               }
+                       pclose(allfp);
                        }
-               pclose(allfp);
+               /* import again in case anything new was generated */
+               inprocess();
                }
 
-       inprocess();    /* incoming again in case anything new was generated */
        rewrite_syslist();
-       printf("netproc: processing ended.\n");
+       syslog(LOG_NOTICE, "processing ended.");
        cleanup(0);
+       return 0;
        }
-