home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume26 / tulp-3.0.3 / part02 / lc.c < prev    next >
C/C++ Source or Header  |  1993-04-15  |  12KB  |  551 lines

  1. /*-------------------------------------------------------------------------
  2.  *  Listserv - Unix Mailing List manager (sub-set of FRECP's
  3.  *             Bitnet Listserv tool.
  4.  *
  5.  *  Copyright (C) 1991,1992  Kimmo Suominen, Christophe Wolfhugel
  6.  *
  7.  *  Please read the files COPYRIGHT and AUTHORS for the extended
  8.  *  copyrights refering to this file.
  9.  *
  10.  *  This program is free software; you can redistribute it and/or modify
  11.  *  it under the terms of the GNU General Public License as published by
  12.  *  the Free Software Foundation; either version 1, or (at your option)
  13.  *  any later version.
  14.  *
  15.  *  This program is distributed in the hope that it will be useful,
  16.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  17.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  18.  *  GNU General Public License for more details.
  19.  *
  20.  *  You should have received a copy of the GNU General Public License
  21.  *  along with this program; if not, write to the Free Software
  22.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  23.  *----------------------------------------------------------------------*/
  24.  
  25. static char rcsid[] = "@(#)$Id: lc.c,v 1.22 93/03/02 22:40:31 wolf Exp $";
  26.  
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include <limits.h>
  31. #include <sys/param.h>
  32. #include <sys/types.h>
  33. #include <signal.h>
  34. #include <sys/stat.h>
  35. #include <dirent.h>
  36. #include <sys/times.h>
  37. #include "conf.h"
  38. #include "ext.h"
  39. #include "l.h"
  40. #include "lp.h"
  41. #include "str.h"
  42. #include "popen.h"
  43. #include "messages.h"
  44. #ifdef FAKESYSLOG
  45. # include "fakesyslog.h"
  46. #else
  47. # include <syslog.h>
  48. #endif
  49.  
  50. FILE *l;
  51. char adrs[MAXLINE];
  52. static char cmd[MAXLINE + 1];
  53.  
  54. struct kword {
  55.   char k[4];
  56.   void (*job)();
  57. };
  58.  
  59. void help(), list(), review(), subscribe(), signoff(), listindex(),
  60.      getFile(), addUser(), delUser();
  61.  
  62. struct kword kw[] = { "hel", help,
  63.                       "lis", list,
  64.                       "rev", review,
  65.                       "sub", subscribe,
  66.                       "sig", signoff,
  67.                       "uns", signoff,
  68.                       "ind", listindex,
  69.                       "get", getFile,
  70.                       "add", addUser,
  71.                       "del", delUser,
  72.                       "",  NULL };
  73.  
  74. /*
  75.  * Spawn return message MTA
  76.  */
  77.  
  78. FILE *getMTA(char *recipient)
  79. {
  80.   FILE *mta;
  81.  
  82. #ifdef ADD_REQUEST
  83.   sprintf(cmd,"%s -flistserv-request %s",SENDMAIL,recipient);
  84. #else
  85.   sprintf(cmd,"%s %s",SENDMAIL,recipient);
  86. #endif
  87.   mta = l_popen(cmd,"w");
  88.   fprintf(mta, versFrom);
  89. #ifdef ADD_SENDER
  90.   fprintf(mta, versSender);
  91. #endif
  92.   return(mta);
  93. }
  94.  
  95. /*
  96.  *  HELP
  97.  */
  98.  
  99. void help()
  100. {
  101.   FILE *f,*h;
  102.  
  103.   strlwr(buf);
  104.   syslog(LOG_INFO,"HELP to %s",From);
  105.   h=getMTA(adrs);
  106.   fprintf(h,TULP_HDRHELP(From));
  107.   f=fopen("helpfile","r");
  108.   while (fgets(buf, sizeof(buf), f) != NULL)
  109.     fputs(buf,h);
  110.   fclose(f);
  111.   l_pclose(h);
  112. }
  113.  
  114.  
  115. /*
  116.  *  LIST
  117.  */
  118.  
  119. void list()
  120. {
  121.   FILE *f,*h;
  122.  
  123.   syslog(LOG_INFO,"LIST to %s",From);
  124.   h=getMTA(adrs);
  125.   fprintf(h,TULP_HDRLIST(From));
  126.   f=fopen("lists","r");
  127.   while (fgets(buf, sizeof(buf) ,f) != NULL) {
  128.     if (buf[0] == '#') continue;
  129.     strtok(buf,",");
  130.     fprintf(h,"%-15s  * %s\n",buf,strtok(NULL,"\n"));
  131.   } /* endwhile */
  132.   fclose(f);
  133.   l_pclose(h);
  134. }
  135.  
  136.  
  137. /*
  138.  *  REVIEW list
  139.  */
  140.  
  141. void review()
  142. {
  143.   FILE *h;
  144.   char *s;
  145.  
  146.   s=strtok(NULL," \t\n"); strlwr(s);
  147.   syslog(LOG_INFO,"REV '%s' to %s",s,From);
  148.   if (s == NULL)
  149.     fprintf(l,TULP_SYNTAX);
  150.   else
  151.     if (ReadUserList(s) == -1)
  152.       fprintf(l,TULP_NOSUCHLIST);
  153.     else {
  154.       h=getMTA(adrs);
  155.       fprintf(h,TULP_HDRREV(From,s));
  156.       RewindCommentList();
  157.       RewindUserList();
  158.       while (GetComment(buf) != NULL)
  159.     fprintf(h,"%s\n",buf);
  160.       if (!IsOwner(From) && (strcasecmp(GetReview(), "owner") == 0
  161.        || (strcasecmp(GetReview(),"private") == 0 && !IsUser(From))))
  162.     fprintf(l,TULP_REVPRIVATE);
  163.       else
  164.     while (GetUser(buf) != NULL) {
  165.       strtok(buf,"(");
  166.       buf[strlen(buf)-1]=0;
  167.       fprintf(h,"%-40s %s\n",buf,strtok(NULL,")\n"));
  168.     } /* endwhile */
  169.       l_pclose(h);
  170.     } /* endif */
  171.   CloseUserList();
  172. }
  173.  
  174.  
  175. /*
  176.  *  SUBSCRIBE list first last
  177.  */
  178.  
  179. void subscribe()
  180. {
  181.   FILE *f,*h;
  182.   char *s1,*s2;
  183.  
  184.   s1=strtok(NULL," \n");
  185.   strlwr(s1);
  186.   s2=strtok(NULL,"\n");
  187.   syslog(LOG_INFO,"SUB '%s' from %s",s1,From);
  188.   if (s1 == NULL || s2 == NULL)
  189.     fprintf(l,TULP_SYNTAX);
  190.   else {
  191.     if (ReadUserList(s1) == -1)
  192.       fprintf(l,TULP_NOSUCHLIST);
  193.     else {
  194.       RewindUserList();
  195.       RewindOwnerList();
  196.       if (strcasecmp(GetSubscription(),"closed") == 0)
  197.     fprintf(l,TULP_SUBCLOSED);
  198.       else
  199.     if (strcasecmp(GetSubscription(),"owner") == 0) {
  200.       fprintf(l,TULP_SUBFORWARDED);
  201.       rcpt[0]=0;
  202.       while (GetOwner(cmd) != NULL) {
  203.         strcat(rcpt,strtok(cmd," \t\r\n"));
  204.         strcat(rcpt," ");
  205.       } /* endwhile */
  206.       sprintf(cmd,"%s %s",SENDMAIL,rcpt);
  207.       f=l_popen(cmd,"w");
  208.       fprintf(f,TULP_SUBREQUEST(adrs,s1,s2));
  209.       l_pclose(f);
  210.     } else {
  211.       sprintf(cmd,"%s (%s)",adrs,s2);
  212.       switch (AddUser(cmd)) {
  213.       case 0:
  214.         h=getMTA(adrs);
  215.         fprintf(h,TULP_HDRWELCOME(From,s1));
  216.         strcat(s1,".w");
  217.         f=fopen(s1,"r");
  218.         while (fgets(buf, sizeof(buf), f) != NULL)
  219.           fputs(buf,h);
  220.         fclose(f);
  221.         l_pclose(h);
  222.         break;
  223.       case 1:
  224.         fprintf(l,TULP_SUBALREADY);
  225.         break;
  226.       } /* endsw */
  227.       WriteUserList();
  228.     } /* endif */
  229.     } /* endif */
  230.     CloseUserList();
  231.   } /* endif */
  232. }
  233.  
  234.  
  235. /*
  236.  *  SIGNOFF list
  237.  */
  238.  
  239. void signoff()
  240. {
  241.   FILE *f;
  242.   char *s;
  243.  
  244.   s=strtok(NULL," \t\n");
  245.   strlwr(s);
  246.   syslog(LOG_INFO,"SIG '%s' from %s",s,From);
  247.   if (s == NULL)
  248.     fprintf(l,TULP_SYNTAX);
  249.   else
  250.     if (ReadUserList(s) == -1)
  251.       fprintf(l,TULP_NOSUCHLIST);
  252.     else {
  253.       RewindOwnerList();
  254.       rcpt[0]=0;
  255.       while (GetOwner(cmd) != NULL) {
  256.     strcat(rcpt,strtok(cmd," "));
  257.     strcat(rcpt," ");
  258.       } /* endwhile */
  259.       sprintf(cmd,"%s %s",SENDMAIL,rcpt);
  260.       f=l_popen(cmd,"w");
  261.       if (DelUser(adrs) == -1) {
  262.     fprintf(f,TULP_SIGFAILED(adrs,s));
  263.     fprintf(l,TULP_NOTONLIST);
  264.       } else {
  265.     fprintf(f,TULP_SIGSUCCESS(adrs,s));
  266.     fprintf(l,TULP_SIGDONE);
  267.       }
  268.       l_pclose(f);
  269.       WriteUserList();
  270.       CloseUserList();
  271.     } /* endif */
  272. }
  273.  
  274. /*
  275.  *  INDEX list
  276.  */
  277.  
  278. void listindex()
  279. {
  280. #define MAX_FILES  640
  281.   static char files[MAX_FILES][64+1], swp[64+1];
  282.   FILE *h;
  283.   char *s;
  284.   int i,j,noFiles;
  285.   DIR *dirp;
  286.   struct dirent *de;
  287.   struct stat st;
  288.  
  289.   s=strtok(NULL,"\n");
  290.   strlwr(s);
  291.   syslog(LOG_INFO,"IND %s from %s",s,From);
  292.   if (s == NULL || s[0] == '/' || s[0] == '~' || strstr(s,"..") != NULL)
  293.     fprintf(l,TULP_SYNTAX);
  294.   else {
  295.     if (ReadUserList(s) != -1 && (strcasecmp(GetSend(),"public") != 0
  296.      || strcasecmp(GetReview(), "public") != 0)
  297.     && !IsUser(From) && !IsOwner(From))
  298.       fprintf(l,TULP_NOTONLIST);
  299.     else {
  300.       if (chdir(s) == -1) fprintf(l,TULP_NONESTORED);
  301.       else {
  302.     h=getMTA(adrs);
  303.     fprintf(h,TULP_HDRINDEX(From,s));
  304.     dirp=opendir(".");
  305.     noFiles=0;
  306.     while (noFiles < MAX_FILES && (de=readdir(dirp)) != NULL)
  307.       if (de->d_name[0] != '.')
  308.         strcpy(files[noFiles++],de->d_name);
  309.     closedir(dirp);
  310.     for (i=0; i < noFiles-1; i++) {
  311.       for (j=i+1; j < noFiles; j++) {
  312.         if (strcmp(files[j],files[i]) < 0) {
  313.           strcpy(swp,files[i]);
  314.           strcpy(files[i],files[j]);
  315.           strcpy(files[j],swp);
  316.         } /* endif */
  317.       } /* endfor */
  318.     } /* endfor */
  319.     for (i=0; i < noFiles; i++) {
  320.       stat(files[i],&st);
  321.       if (st.st_mode & S_IFDIR) strcat(files[i],"/");
  322.       fprintf(h,"%-40s %10ld  %s",files[i],st.st_size,ctime(&st.st_mtime));
  323.     } /* endif */
  324.     chdir(TULPDIR);
  325.     if (noFiles == 0) fprintf(l,TULP_INDNOFILES);
  326.     l_pclose(h);
  327.       } /* endif */
  328.     } /* endif */
  329.     CloseUserList();
  330.   } /* endif */
  331. }
  332.  
  333. /*
  334.  *  GET list file
  335.  */
  336.  
  337. void getFile()
  338. {
  339.   FILE *f,*h;
  340.   char *s,*t;
  341.  
  342.   s=strtok(NULL," ");
  343.   t=strtok(NULL," \n");
  344.   strlwr(s);
  345.   strlwr(t);
  346.   syslog(LOG_INFO,"GET %s %s from %s",
  347.      (s == NULL) ? " " : s, (t == NULL) ? " " : t, From);
  348.   if (ReadUserList(s) != -1 && (strcasecmp(GetSend(),"public") != 0
  349.    || strcasecmp(GetReview(), "public") != 0)
  350.    && !IsUser(From) && !IsOwner(From))
  351.     fprintf(l,TULP_NOTONLIST);
  352.   else {
  353.     if (chdir(s) == -1) fprintf(l,TULP_NONESTORED);
  354.     else {
  355.       if (strstr(t,"..") != NULL || *t == '/' || *t == '~') *t=0;
  356.       f=fopen(t,"r");
  357.       if (f == NULL) fprintf(l,TULP_GETNOSUCHFILE);
  358.       else {
  359.     h=getMTA(adrs);
  360.     fprintf(h,TULP_HDRGET(From,s,t));
  361.     while (fgets(buf, sizeof(buf), f) != NULL)
  362.       fputs(buf,h);
  363.     fclose(f);
  364.     l_pclose(h);
  365.       } /* endif */
  366.       chdir(TULPDIR);
  367.     } /* endif */
  368.   } /* endif */
  369.   CloseUserList();
  370. }
  371.  
  372. /*
  373.  *  ADD list user@host.foo.bar First Last
  374.  */
  375.  
  376. void addUser()
  377. {
  378.   FILE *f,*h;
  379.   char *s,*t,*u;
  380.  
  381.   s=strtok(NULL," \n");
  382.   t=strtok(NULL," \n");
  383.   u=strtok(NULL,"\n"); 
  384.   strlwr(s);
  385.   syslog(LOG_INFO,"ADD '%s' %s from %s",s,t,From);
  386.   if (s == NULL || t == NULL || u == NULL)
  387.     fprintf(l,TULP_SYNTAX);
  388.   else
  389.     if (ReadUserList(s) == -1)
  390.       fprintf(l,TULP_NOSUCHLIST);
  391.     else {
  392.       RewindUserList();
  393.       RewindOwnerList();
  394.       if (!IsOwner(From))
  395.     fprintf(l,TULP_NOTOWNER);
  396.       else {
  397.     h=getMTA(t);
  398.     sprintf(cmd,"%s (%s)",t,u);
  399.     switch (AddUser(cmd)) {
  400.     case 0:
  401.       fprintf(h,TULP_HDRWELCOME(cmd,s));
  402.       fprintf(h,TULP_ADDBY(cmd,s,From));
  403.       strcat(s,".w");
  404.       f=fopen(s,"r");
  405.       while (fgets(buf, sizeof(buf),f) != NULL)
  406.         fputs(buf,h);
  407.       fclose(f);
  408.       fprintf(l,TULP_ADDSUCCESS);
  409.       break;
  410.     case 1:
  411.       fprintf(h,TULP_SUBUPDATED(cmd,s,From));
  412.       fprintf(l,TULP_ADDALREADY);
  413.       break;
  414.     } /* endsw */
  415.     l_pclose(h);
  416.       } /* endif */
  417.       WriteUserList();
  418.       CloseUserList();
  419.     }
  420. }
  421.  
  422. /*
  423.  *  DELETE list user@host.foo.bar
  424.  */
  425.  
  426. void delUser()
  427. {
  428.   FILE *h;
  429.   char *s1,*s2;
  430.  
  431.   s1=strtok(NULL," \n");
  432.   s2=strtok(NULL," \n");
  433.   strlwr(s1);
  434.   syslog(LOG_INFO,"DEL '%s' %s from %s",s1,s2,From);
  435.   if (s1 == NULL || s2 == NULL)
  436.     fprintf(l,TULP_SYNTAX);
  437.   else
  438.     if (ReadUserList(s1) == -1)
  439.       fprintf(l,TULP_NOSUCHLIST);
  440.     else {
  441.       RewindUserList();
  442.       RewindOwnerList();
  443.       if (!IsOwner(From))
  444.     fprintf(l,TULP_NOTOWNER);
  445.       else
  446.     if (!IsUser(s2))
  447.       fprintf(l,TULP_DELNOTONLIST);
  448.     else {
  449.       sprintf(cmd,"%s",s2);
  450.       switch (DelUser(cmd)) {
  451.       case 0:
  452.         h=getMTA(s2);
  453.         fprintf(h,TULP_DELREMOVED(s2,s1,From));
  454.         l_pclose(h);
  455.         fprintf(l,TULP_DELSUCCESS);
  456.         break;
  457.       case -1:
  458.         fprintf(l,TULP_DELINCONSISTENT);
  459.         break;
  460.       } /* endsw */
  461.     } /* endif */
  462.       WriteUserList();
  463.       CloseUserList();
  464.     } /* endif */
  465. }
  466.  
  467.  
  468. int doCmd()
  469. {
  470.   int i;
  471.   char s[4];
  472.  
  473.   if (buf[0] == '\n') return(0);
  474.   strncpy(s,strtok(buf," "),3);
  475.   s[3]='\0';
  476.   strlwr(s);
  477.   for (i=0; kw[i].k[0] != 0; i++)
  478.     if (strncmp(kw[i].k,s,3) == 0) {
  479.       kw[i].job();
  480.       return(0);
  481.     }
  482.   return(-1);
  483. }
  484.  
  485. void listservCmd()
  486. {
  487.    int done, noCmd;
  488.    char cmd[256];
  489.    FILE *f;
  490. #ifdef CPUTYPE
  491.    struct tms t;
  492.    long tt;
  493.  
  494.    times(&t); tt=t.tms_stime+t.tms_utime+t.tms_cstime+t.tms_cutime;
  495. #endif
  496.  
  497.    noCmd = 0;
  498.    done  = 0;
  499.    strcpy(adrs, From); strtok(adrs, " ");
  500.    l = getMTA(adrs);
  501.    fprintf(l, TULP_HDROUTPUT(From));
  502.    f = fopen("msg", "r");
  503.    buf[0] = 0;
  504.    while (fgets(buf, sizeof(buf), f) != NULL && buf[0] != '\n')
  505.     buf[0]=0;
  506.    if (buf[0] == 0)
  507.       fprintf(l, TULP_NOBODY);
  508.    else {
  509.       while (!done && fgets(buf, sizeof(buf) - 3, f) != NULL) {
  510.          if (strncasecmp(buf, "quit", 4) == 0
  511.          || strncasecmp(buf, "end", 3) == 0
  512.          || strncasecmp(buf, "stop", 4) == 0
  513.          || buf[0] == '-') {
  514.         fprintf(l, "> %s",buf);
  515.         fprintf(l, TULP_EXITING);
  516.             break;
  517.          } /* endif */
  518. #ifdef SHUTDOWN
  519.          if (strcmp(SHUTDOWN, buf) == 0) {
  520.         syslog(LOG_INFO, "Shutdown by %s", From);
  521.         done = 1;  /* this is clean */
  522.         noCmd++;
  523.         continue;
  524.          } /* endif */
  525. #endif
  526.          if (buf[0] != '\n') {
  527.          fprintf(l,"> %s",buf);
  528.         if (doCmd() == -1)
  529.            fprintf(l,TULP_SAYWHAT);
  530.         else {
  531.            noCmd++;
  532.            fprintf(l,TULP_OKAY);
  533.         } /* endif */
  534.          } /* endif */
  535.       } /* endwhile */
  536.    } /* endif */
  537.    if (noCmd == 0) {
  538.       fprintf(l,TULP_NOCOMMANDS);
  539.       syslog(LOG_INFO,"no commands from",From);
  540.       mailMsg("listman","No commands");
  541.    } /* endif */
  542.    fclose(f);
  543.    unlink("msg");
  544. #ifdef CPUTYPE
  545.    times(&t);
  546.    tt=(t.tms_stime+t.tms_utime+t.tms_cstime+t.tms_cutime)-tt;
  547.    fprintf(l,TULP_TOTAL((float)tt/HZ,CPUTYPE));
  548. #endif
  549.    l_pclose(l);
  550. }
  551.