home *** CD-ROM | disk | FTP | other *** search
- /*-------------------------------------------------------------------------
- * Listserv - Unix Mailing List manager (sub-set of FRECP's
- * Bitnet Listserv tool.
- *
- * Copyright (C) 1991,1992 Kimmo Suominen, Christophe Wolfhugel
- *
- * Please read the files COPYRIGHT and AUTHORS for the extended
- * copyrights refering to this file.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 1, or (at your option)
- * any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *----------------------------------------------------------------------*/
-
- static char rcsid[] = "@(#)$Id: lc.c,v 1.22 93/03/02 22:40:31 wolf Exp $";
-
- #include <stdio.h>
- #include <string.h>
- #include <unistd.h>
- #include <limits.h>
- #include <sys/param.h>
- #include <sys/types.h>
- #include <signal.h>
- #include <sys/stat.h>
- #include <dirent.h>
- #include <sys/times.h>
- #include "conf.h"
- #include "ext.h"
- #include "l.h"
- #include "lp.h"
- #include "str.h"
- #include "popen.h"
- #include "messages.h"
- #ifdef FAKESYSLOG
- # include "fakesyslog.h"
- #else
- # include <syslog.h>
- #endif
-
- FILE *l;
- char adrs[MAXLINE];
- static char cmd[MAXLINE + 1];
-
- struct kword {
- char k[4];
- void (*job)();
- };
-
- void help(), list(), review(), subscribe(), signoff(), listindex(),
- getFile(), addUser(), delUser();
-
- struct kword kw[] = { "hel", help,
- "lis", list,
- "rev", review,
- "sub", subscribe,
- "sig", signoff,
- "uns", signoff,
- "ind", listindex,
- "get", getFile,
- "add", addUser,
- "del", delUser,
- "", NULL };
-
- /*
- * Spawn return message MTA
- */
-
- FILE *getMTA(char *recipient)
- {
- FILE *mta;
-
- #ifdef ADD_REQUEST
- sprintf(cmd,"%s -flistserv-request %s",SENDMAIL,recipient);
- #else
- sprintf(cmd,"%s %s",SENDMAIL,recipient);
- #endif
- mta = l_popen(cmd,"w");
- fprintf(mta, versFrom);
- #ifdef ADD_SENDER
- fprintf(mta, versSender);
- #endif
- return(mta);
- }
-
- /*
- * HELP
- */
-
- void help()
- {
- FILE *f,*h;
-
- strlwr(buf);
- syslog(LOG_INFO,"HELP to %s",From);
- h=getMTA(adrs);
- fprintf(h,TULP_HDRHELP(From));
- f=fopen("helpfile","r");
- while (fgets(buf, sizeof(buf), f) != NULL)
- fputs(buf,h);
- fclose(f);
- l_pclose(h);
- }
-
-
- /*
- * LIST
- */
-
- void list()
- {
- FILE *f,*h;
-
- syslog(LOG_INFO,"LIST to %s",From);
- h=getMTA(adrs);
- fprintf(h,TULP_HDRLIST(From));
- f=fopen("lists","r");
- while (fgets(buf, sizeof(buf) ,f) != NULL) {
- if (buf[0] == '#') continue;
- strtok(buf,",");
- fprintf(h,"%-15s * %s\n",buf,strtok(NULL,"\n"));
- } /* endwhile */
- fclose(f);
- l_pclose(h);
- }
-
-
- /*
- * REVIEW list
- */
-
- void review()
- {
- FILE *h;
- char *s;
-
- s=strtok(NULL," \t\n"); strlwr(s);
- syslog(LOG_INFO,"REV '%s' to %s",s,From);
- if (s == NULL)
- fprintf(l,TULP_SYNTAX);
- else
- if (ReadUserList(s) == -1)
- fprintf(l,TULP_NOSUCHLIST);
- else {
- h=getMTA(adrs);
- fprintf(h,TULP_HDRREV(From,s));
- RewindCommentList();
- RewindUserList();
- while (GetComment(buf) != NULL)
- fprintf(h,"%s\n",buf);
- if (!IsOwner(From) && (strcasecmp(GetReview(), "owner") == 0
- || (strcasecmp(GetReview(),"private") == 0 && !IsUser(From))))
- fprintf(l,TULP_REVPRIVATE);
- else
- while (GetUser(buf) != NULL) {
- strtok(buf,"(");
- buf[strlen(buf)-1]=0;
- fprintf(h,"%-40s %s\n",buf,strtok(NULL,")\n"));
- } /* endwhile */
- l_pclose(h);
- } /* endif */
- CloseUserList();
- }
-
-
- /*
- * SUBSCRIBE list first last
- */
-
- void subscribe()
- {
- FILE *f,*h;
- char *s1,*s2;
-
- s1=strtok(NULL," \n");
- strlwr(s1);
- s2=strtok(NULL,"\n");
- syslog(LOG_INFO,"SUB '%s' from %s",s1,From);
- if (s1 == NULL || s2 == NULL)
- fprintf(l,TULP_SYNTAX);
- else {
- if (ReadUserList(s1) == -1)
- fprintf(l,TULP_NOSUCHLIST);
- else {
- RewindUserList();
- RewindOwnerList();
- if (strcasecmp(GetSubscription(),"closed") == 0)
- fprintf(l,TULP_SUBCLOSED);
- else
- if (strcasecmp(GetSubscription(),"owner") == 0) {
- fprintf(l,TULP_SUBFORWARDED);
- rcpt[0]=0;
- while (GetOwner(cmd) != NULL) {
- strcat(rcpt,strtok(cmd," \t\r\n"));
- strcat(rcpt," ");
- } /* endwhile */
- sprintf(cmd,"%s %s",SENDMAIL,rcpt);
- f=l_popen(cmd,"w");
- fprintf(f,TULP_SUBREQUEST(adrs,s1,s2));
- l_pclose(f);
- } else {
- sprintf(cmd,"%s (%s)",adrs,s2);
- switch (AddUser(cmd)) {
- case 0:
- h=getMTA(adrs);
- fprintf(h,TULP_HDRWELCOME(From,s1));
- strcat(s1,".w");
- f=fopen(s1,"r");
- while (fgets(buf, sizeof(buf), f) != NULL)
- fputs(buf,h);
- fclose(f);
- l_pclose(h);
- break;
- case 1:
- fprintf(l,TULP_SUBALREADY);
- break;
- } /* endsw */
- WriteUserList();
- } /* endif */
- } /* endif */
- CloseUserList();
- } /* endif */
- }
-
-
- /*
- * SIGNOFF list
- */
-
- void signoff()
- {
- FILE *f;
- char *s;
-
- s=strtok(NULL," \t\n");
- strlwr(s);
- syslog(LOG_INFO,"SIG '%s' from %s",s,From);
- if (s == NULL)
- fprintf(l,TULP_SYNTAX);
- else
- if (ReadUserList(s) == -1)
- fprintf(l,TULP_NOSUCHLIST);
- else {
- RewindOwnerList();
- rcpt[0]=0;
- while (GetOwner(cmd) != NULL) {
- strcat(rcpt,strtok(cmd," "));
- strcat(rcpt," ");
- } /* endwhile */
- sprintf(cmd,"%s %s",SENDMAIL,rcpt);
- f=l_popen(cmd,"w");
- if (DelUser(adrs) == -1) {
- fprintf(f,TULP_SIGFAILED(adrs,s));
- fprintf(l,TULP_NOTONLIST);
- } else {
- fprintf(f,TULP_SIGSUCCESS(adrs,s));
- fprintf(l,TULP_SIGDONE);
- }
- l_pclose(f);
- WriteUserList();
- CloseUserList();
- } /* endif */
- }
-
- /*
- * INDEX list
- */
-
- void listindex()
- {
- #define MAX_FILES 640
- static char files[MAX_FILES][64+1], swp[64+1];
- FILE *h;
- char *s;
- int i,j,noFiles;
- DIR *dirp;
- struct dirent *de;
- struct stat st;
-
- s=strtok(NULL,"\n");
- strlwr(s);
- syslog(LOG_INFO,"IND %s from %s",s,From);
- if (s == NULL || s[0] == '/' || s[0] == '~' || strstr(s,"..") != NULL)
- fprintf(l,TULP_SYNTAX);
- else {
- if (ReadUserList(s) != -1 && (strcasecmp(GetSend(),"public") != 0
- || strcasecmp(GetReview(), "public") != 0)
- && !IsUser(From) && !IsOwner(From))
- fprintf(l,TULP_NOTONLIST);
- else {
- if (chdir(s) == -1) fprintf(l,TULP_NONESTORED);
- else {
- h=getMTA(adrs);
- fprintf(h,TULP_HDRINDEX(From,s));
- dirp=opendir(".");
- noFiles=0;
- while (noFiles < MAX_FILES && (de=readdir(dirp)) != NULL)
- if (de->d_name[0] != '.')
- strcpy(files[noFiles++],de->d_name);
- closedir(dirp);
- for (i=0; i < noFiles-1; i++) {
- for (j=i+1; j < noFiles; j++) {
- if (strcmp(files[j],files[i]) < 0) {
- strcpy(swp,files[i]);
- strcpy(files[i],files[j]);
- strcpy(files[j],swp);
- } /* endif */
- } /* endfor */
- } /* endfor */
- for (i=0; i < noFiles; i++) {
- stat(files[i],&st);
- if (st.st_mode & S_IFDIR) strcat(files[i],"/");
- fprintf(h,"%-40s %10ld %s",files[i],st.st_size,ctime(&st.st_mtime));
- } /* endif */
- chdir(TULPDIR);
- if (noFiles == 0) fprintf(l,TULP_INDNOFILES);
- l_pclose(h);
- } /* endif */
- } /* endif */
- CloseUserList();
- } /* endif */
- }
-
- /*
- * GET list file
- */
-
- void getFile()
- {
- FILE *f,*h;
- char *s,*t;
-
- s=strtok(NULL," ");
- t=strtok(NULL," \n");
- strlwr(s);
- strlwr(t);
- syslog(LOG_INFO,"GET %s %s from %s",
- (s == NULL) ? " " : s, (t == NULL) ? " " : t, From);
- if (ReadUserList(s) != -1 && (strcasecmp(GetSend(),"public") != 0
- || strcasecmp(GetReview(), "public") != 0)
- && !IsUser(From) && !IsOwner(From))
- fprintf(l,TULP_NOTONLIST);
- else {
- if (chdir(s) == -1) fprintf(l,TULP_NONESTORED);
- else {
- if (strstr(t,"..") != NULL || *t == '/' || *t == '~') *t=0;
- f=fopen(t,"r");
- if (f == NULL) fprintf(l,TULP_GETNOSUCHFILE);
- else {
- h=getMTA(adrs);
- fprintf(h,TULP_HDRGET(From,s,t));
- while (fgets(buf, sizeof(buf), f) != NULL)
- fputs(buf,h);
- fclose(f);
- l_pclose(h);
- } /* endif */
- chdir(TULPDIR);
- } /* endif */
- } /* endif */
- CloseUserList();
- }
-
- /*
- * ADD list user@host.foo.bar First Last
- */
-
- void addUser()
- {
- FILE *f,*h;
- char *s,*t,*u;
-
- s=strtok(NULL," \n");
- t=strtok(NULL," \n");
- u=strtok(NULL,"\n");
- strlwr(s);
- syslog(LOG_INFO,"ADD '%s' %s from %s",s,t,From);
- if (s == NULL || t == NULL || u == NULL)
- fprintf(l,TULP_SYNTAX);
- else
- if (ReadUserList(s) == -1)
- fprintf(l,TULP_NOSUCHLIST);
- else {
- RewindUserList();
- RewindOwnerList();
- if (!IsOwner(From))
- fprintf(l,TULP_NOTOWNER);
- else {
- h=getMTA(t);
- sprintf(cmd,"%s (%s)",t,u);
- switch (AddUser(cmd)) {
- case 0:
- fprintf(h,TULP_HDRWELCOME(cmd,s));
- fprintf(h,TULP_ADDBY(cmd,s,From));
- strcat(s,".w");
- f=fopen(s,"r");
- while (fgets(buf, sizeof(buf),f) != NULL)
- fputs(buf,h);
- fclose(f);
- fprintf(l,TULP_ADDSUCCESS);
- break;
- case 1:
- fprintf(h,TULP_SUBUPDATED(cmd,s,From));
- fprintf(l,TULP_ADDALREADY);
- break;
- } /* endsw */
- l_pclose(h);
- } /* endif */
- WriteUserList();
- CloseUserList();
- }
- }
-
- /*
- * DELETE list user@host.foo.bar
- */
-
- void delUser()
- {
- FILE *h;
- char *s1,*s2;
-
- s1=strtok(NULL," \n");
- s2=strtok(NULL," \n");
- strlwr(s1);
- syslog(LOG_INFO,"DEL '%s' %s from %s",s1,s2,From);
- if (s1 == NULL || s2 == NULL)
- fprintf(l,TULP_SYNTAX);
- else
- if (ReadUserList(s1) == -1)
- fprintf(l,TULP_NOSUCHLIST);
- else {
- RewindUserList();
- RewindOwnerList();
- if (!IsOwner(From))
- fprintf(l,TULP_NOTOWNER);
- else
- if (!IsUser(s2))
- fprintf(l,TULP_DELNOTONLIST);
- else {
- sprintf(cmd,"%s",s2);
- switch (DelUser(cmd)) {
- case 0:
- h=getMTA(s2);
- fprintf(h,TULP_DELREMOVED(s2,s1,From));
- l_pclose(h);
- fprintf(l,TULP_DELSUCCESS);
- break;
- case -1:
- fprintf(l,TULP_DELINCONSISTENT);
- break;
- } /* endsw */
- } /* endif */
- WriteUserList();
- CloseUserList();
- } /* endif */
- }
-
-
- int doCmd()
- {
- int i;
- char s[4];
-
- if (buf[0] == '\n') return(0);
- strncpy(s,strtok(buf," "),3);
- s[3]='\0';
- strlwr(s);
- for (i=0; kw[i].k[0] != 0; i++)
- if (strncmp(kw[i].k,s,3) == 0) {
- kw[i].job();
- return(0);
- }
- return(-1);
- }
-
- void listservCmd()
- {
- int done, noCmd;
- char cmd[256];
- FILE *f;
- #ifdef CPUTYPE
- struct tms t;
- long tt;
-
- times(&t); tt=t.tms_stime+t.tms_utime+t.tms_cstime+t.tms_cutime;
- #endif
-
- noCmd = 0;
- done = 0;
- strcpy(adrs, From); strtok(adrs, " ");
- l = getMTA(adrs);
- fprintf(l, TULP_HDROUTPUT(From));
- f = fopen("msg", "r");
- buf[0] = 0;
- while (fgets(buf, sizeof(buf), f) != NULL && buf[0] != '\n')
- buf[0]=0;
- if (buf[0] == 0)
- fprintf(l, TULP_NOBODY);
- else {
- while (!done && fgets(buf, sizeof(buf) - 3, f) != NULL) {
- if (strncasecmp(buf, "quit", 4) == 0
- || strncasecmp(buf, "end", 3) == 0
- || strncasecmp(buf, "stop", 4) == 0
- || buf[0] == '-') {
- fprintf(l, "> %s",buf);
- fprintf(l, TULP_EXITING);
- break;
- } /* endif */
- #ifdef SHUTDOWN
- if (strcmp(SHUTDOWN, buf) == 0) {
- syslog(LOG_INFO, "Shutdown by %s", From);
- done = 1; /* this is clean */
- noCmd++;
- continue;
- } /* endif */
- #endif
- if (buf[0] != '\n') {
- fprintf(l,"> %s",buf);
- if (doCmd() == -1)
- fprintf(l,TULP_SAYWHAT);
- else {
- noCmd++;
- fprintf(l,TULP_OKAY);
- } /* endif */
- } /* endif */
- } /* endwhile */
- } /* endif */
- if (noCmd == 0) {
- fprintf(l,TULP_NOCOMMANDS);
- syslog(LOG_INFO,"no commands from",From);
- mailMsg("listman","No commands");
- } /* endif */
- fclose(f);
- unlink("msg");
- #ifdef CPUTYPE
- times(&t);
- tt=(t.tms_stime+t.tms_utime+t.tms_cstime+t.tms_cutime)-tt;
- fprintf(l,TULP_TOTAL((float)tt/HZ,CPUTYPE));
- #endif
- l_pclose(l);
- }
-