home *** CD-ROM | disk | FTP | other *** search
- /* CONF.C */
- static char sccsid[] = "@(#)conf.c 1.2 94/01/20 (c)1993 thalerd";
- /* PHASE 1: Conference Subsystem
- Be able to enter/exit the program, and move between conferences
- Commands: join, next, quit, source
- Files: rc files, cflist, login, logout, bull
- */
-
- #include <stdio.h>
- #include <string.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <time.h>
- #include <pwd.h> /* for participants */
- #include "config.h"
- #include "struct.h"
- #include "globals.h"
- #include "conf.h"
- #include "lib.h"
- #include "joq.h"
- #include "sum.h"
- #include "item.h"
- #include "range.h"
- #include "macro.h"
- #include "system.h"
- #include "change.h"
- #include "sep.h"
- #include "xalloc.h"
- #include "driver.h" /* for source */
- #include "stats.h" /* for get_config */
-
- /******************************************************************************/
- /* PROCESS COMMAND LINE ARGUMENTS */
- /******************************************************************************
- Function: join(char *conference, short idx, int force)
- Called by: command, main
- Arguments: cf name or conference # to join, force flag
- Returns:
- Calls: source() for CONF/rc and WORK/.cfrc files
- cat() for login
- get_idx to find cf name in conflist
- Description:
- *******************************************************************************/
- #define O_JOIN 0x0002
- char /* RETURNS: 1 on success, 0 else */
- join(conf, force) /* ARGUMENTS: */
- char *conf; /* Conference name to join */
- int force; /* Force Observe/join flags */
- {
- char buff[MAX_LINE_LENGTH];
- struct stat st;
- time_t t1;
- char **config;
-
- /* Initialize st_new structure */
- st_new.outp = st_glob.outp;
- st_new.inp = st_glob.inp;
- st_new.mailsize = st_glob.mailsize;
- st_new.listtime = st_glob.listtime;
- st_new.c_security = st_new.i_current = st_new.c_status = 0;
- st_new.sumtime = 0;
- #ifdef NEWS
- st_new.c_article = 0;
- #endif
- strcpy(st_new.fullname, st_glob.fullname);
-
- /* Check for existence */
- if (!conf) return 0;
- joinidx=get_idx(conf,conflist,maxconf);
- if (joinidx<0) {
- printf("Cannot access conference %s.\n",conf);
- return 0;
- }
- if(flags & O_DEBUG) printf("join: %hd dir=%s\n",joinidx,conflist[joinidx].location);
-
- /* Read in config file */
- if (!(config=get_config(joinidx)))
- return 0;
-
- /* Pass security checks */
- if (xsizeof(config)>CF_SECURITY)
- st_new.c_security=atoi(config[CF_SECURITY]);
- #ifdef NEWS
- if (xsizeof(config)<=CF_NEWSGROUP)
- st_new.c_security &= ~CT_NEWS;
- #endif
- if (!checkpoint(joinidx,st_new.c_security)) {
- if (st_new.c_security & CT_READONLY)
- force |= O_READONLY;
- else {
- return 0;
- }
- }
-
- /* Do stuff with WORK/.name.cf */
- sprintf(buff,"%s/%s",work,config[CF_PARTFILE]);
- if (flags & O_DEBUG) printf("join: Partfile=%s\n",buff);
- if (stat(buff,&st)) { /* Not a member */
- if (!((flags|force) & O_OBSERVE)) {
-
- /* Main JOQ cmd loop */
- mode = M_JOQ;
- if ((force & O_JOIN) || (status & S_MOTIF)) {
- sprintf(buff,"You are being automatically registered in %s\n",
- conflist[joinidx].location);
- wputs(buff);
- command("join",0);
- } else {
- printf("You are not a member of %s\nDo you wish to:",
- conflist[joinidx].location);
- while (mode==M_JOQ && get_command(NULL));
- }
-
- if (status & S_QUIT) {
- printf("registration aborted (didn't leave)\n");
- status &= ~S_QUIT;
- return 0;
- }
- }
- t1 = (time_t)0;
- } else {
- t1 = st.st_mtime; /* last time .*.cf was touched */
- }
- if (flags & O_DEBUG) printf("join: t1=%x\n",t1);
-
- if (confidx>=0) leave(0,(char**)0);
-
- memcpy(&st_glob,&st_new,sizeof(st_new));
-
- confidx =joinidx; /* passed all security checks */
- if (xsizeof(config)>CF_FWLIST)
- fw = explode(config[CF_FWLIST],",");
- else
- fw = 0;
- read_part(config[CF_PARTFILE],part,&st_glob,confidx);
-
- /* Set status */
- if ((flags|force) & O_OBSERVE)
- st_glob.c_status |= CS_OBSERVER;
- if ((flags|force) & O_READONLY)
- st_glob.c_status |= CS_NORESPONSE;
-
- /* Allow FW to be specified by login or by UID */
- sprintf(buff,"%d",uid);
- if (searcha(login,fw,0)>=0 || searcha(buff,fw,0)>=0 || uid==geteuid())
- st_glob.c_status |= CS_FW;
- if (flags & O_DEBUG) printf("join: Status=%hd\n",(short)status);
-
- st_glob.sumtime = 0;
- refresh_sum(0,confidx,sum,part,&st_glob);
-
- /* Source CONF/rc file and WORK/.cfrc files */
- if (flags & O_SOURCE) {
- mode = M_SANE;
- source(conflist[confidx].location,"rc");
- /* mode = M_OK;
- source(work,".cfrc");
- */
- }
-
- /* Display login file */
- sepinit(IS_START|IS_ITEM);
- /*printf("PARTTIME=%d\n",st_glob.parttime);*/
- confsep("linmsg",confidx,&st_glob,part,0);
- check_mail(1);
-
- /* Source WORK/.cfrc files */
- if (flags & O_SOURCE) {
- mode = M_OK;
- source(work,".cfrc");
- }
- return 1;
- }
-
- /******************************************************************************/
- /* FIND INDEX OF NAME IN AN ASSOCIATIVE LIST */
- /******************************************************************************/
- short /* RETURNS: -1 on error, else index of elt in list */
- get_idx(elt,list,size) /* ARGUMENTS: */
- char *elt; /* String to match */
- assoc_t *list; /* List of elements to search */
- short size; /* Number of elements in the list */
- {
- short i;
-
- for (i=1; i<size && !match(elt,list[i].name); i++);
- return (i<size)? i : -1;
- }
-
- /******************************************************************************/
- /* PROCESS COMMAND LINE ARGUMENTS */
- /******************************************************************************
- Function: leave
- Called by: command
- Arguments:
- Returns:
- Calls: cat() for logout
- Description:
- *******************************************************************************/
- int /* RETURNS: error flag */
- leave(argc,argv) /* ARGUMENTS: (none) */
- int argc;
- char **argv;
- {
- char **config;
- if (flags & O_DEBUG) printf("leave: %hd\n",confidx);
- if (confidx<0) return 1; /* (noconf) */
-
- if (!argc || argv[0][0]!='a') { /* not "abort" */
-
- /* Display logout */
- /* more(conflist[confidx].location,"logout"); */
- sepinit(IS_START|IS_ITEM);
- confsep("loutmsg",confidx,&st_glob,part,0);
-
- /* Write participation file unless observing */
- if (!(st_glob.c_status & CS_OBSERVER)) {
- if (!(config = get_config(confidx)))
- return 1;
- write_part(config[CF_PARTFILE]);
- }
- }
-
- /* Free config info */
- xfree(fw);
-
- st_glob.sumtime = 0;
- st_glob.c_status = 0; /* |= CS_OTHERCONF; */
-
- confidx = -1;
- undefine(DM_SANE);
-
- /* Re-source system rc file */
- mode = M_SUPERSANE;
- source(bbsdir,"rc");
- mode = M_OK;
-
- return (!argc || argv[0][0]!='a');
- }
-
- /******************************************************************************/
- /* CHECK A LIST OF CONFERENCES FOR NEW ITEMS */
- /******************************************************************************/
- int /* RETURNS: (nothing) */
- check(argc,argv) /* ARGUMENTS: */
- int argc; /* Number of arguments */
- char **argv; /* Argument list */
- {
- int i;
- char **list,*cfname,sec,buff[MAX_LINE_LENGTH],**fw;
- short size,idx,all=0,count=0,argidx=1;
- partentry_t part2[MAX_ITEMS],*part3;
- sumentry_t sum2[MAX_ITEMS];
- status_t *st,st_temp;
- struct stat stt;
- char **config;
- long force;
-
- /* Check for before/since dates */
- st_glob.since = st_glob.before = 0;
- if (argc>argidx) {
- if (match(argv[argidx],"si_nce")
- || match(argv[argidx],"S=")) {
- st_glob.since = since(argc,argv,&argidx);
- argidx++;
- } else if (match(argv[argidx],"before")
- || match(argv[argidx],"B=")) {
- st_glob.before = since(argc,argv,&argidx);
- argidx++;
- }
- }
-
- if (argc>argidx) { /* list given by user */
- size = argc-argidx;
- list = argv+argidx;
- } else if (argv[0][0]=='l') { /* use conflist */
- all = 1;
- size = maxconf-1;
- } else { /* use .cflist */
- refresh_list();
- size = xsizeof(cflist);
- list = cflist;
- }
-
- sepinit(IS_START);
- for (i=0; i<size && !(status & S_INT); i++) {
- force = 0;
- idx=(all)? i+1 : get_idx(list[i],conflist,maxconf);
- cfname = (all)? compress(conflist[idx].name) : list[i];
- if (idx<0 || !(config=get_config(idx))) {
- printf("Cannot access conference %s.\n",cfname);
- continue;
- }
-
- /* Pass security checks */
- sec=(xsizeof(config)>CF_SECURITY)? atoi(config[CF_SECURITY]) : 0;
- #ifdef NEWS
- if (xsizeof(config)<=CF_NEWSGROUP)
- sec &= ~CT_NEWS;
- #endif
- if (!checkpoint(idx,sec)) {
- if (sec & CT_READONLY) {
- force |= O_READONLY;
- } else {
- continue;
- }
- }
-
- /* if (idx==confidx) */
- if (!strcmp(conflist[idx].location,conflist[confidx].location)) {
- refresh_sum(0,confidx,sum,part,&st_glob);
- st = &st_glob;
- part3=part;
- } else {
- st = &st_temp;
- #ifdef NEWS
- st->c_article = 0;
- #endif
- read_part(config[CF_PARTFILE],part2,st,idx); /* Read in partfile */
-
- /* Initialize c_status */
- st->c_status = 0;
- sprintf(buff,"%d",uid);
- if (xsizeof(config)>CF_FWLIST)
- fw = explode(config[CF_FWLIST],",");
- else
- fw = 0;
- if (searcha(login,fw,0)>=0 || searcha(buff,fw,0)>=0 || uid==geteuid())
- st->c_status |= CS_FW;
- else
- st->c_status &= ~CS_FW;
- xfree(fw);
- if ((flags|force) & O_OBSERVE)
- st->c_status |= CS_OBSERVER;
- else
- st->c_status &= ~CS_OBSERVER;
- if ((flags|force) & O_READONLY)
- st->c_status |= CS_NORESPONSE;
- else
- st->c_status &= ~CS_NORESPONSE;
-
- sprintf(buff,"%s/%s",work,config[CF_PARTFILE]);
- st->parttime = (stat(buff,&stt))? 0 : stt.st_mtime;
- st->c_security = (xsizeof(config)>CF_SECURITY)?
- atoi(config[CF_SECURITY]) : 0;
-
- /* Read in sumfile */
- get_status(st,sum2,part2,idx);
- part3=part2;
- }
- st->c_security = sec;
-
- if ((!st_glob.before || st->sumtime < st_glob.before)
- && (st_glob.since <= st->sumtime)) {
- st->count = (++count);
- sepinit(IS_ITEM);
- if (argc<2 && current==i) sepinit(IS_CFIDX);
- confsep((argv[0][0]=='l')?"listmsg":"checkmsg",idx,st,part3,0);
- }
- }
- return 1;
- }
-
- /******************************************************************************/
- /* ADVANCE TO NEXT CONFERENCES WITH NEW ITEMS */
- /******************************************************************************/
- int /* RETURNS: (nothing) */
- do_next(argc,argv) /* ARGUMENTS: */
- int argc; /* Number of arguments */
- char **argv; /* Argument list */
- { /* LOCAL VARIABLES: */
- char **config,
- buff[MAX_LINE_LENGTH];
- char sec; /* Conference's security type */
- short idx;
- partentry_t part2[MAX_ITEMS];
- sumentry_t sum2[MAX_ITEMS];
- status_t st;
- struct stat stt;
-
- if (argc>1) {
- printf("Bad parameters near \"%s\"\n",argv[1]);
- return 2;
- }
-
- refresh_list(); /* make sure .cflist is current */
- for (; current+1 < xsizeof(cflist) && !(status & S_INT); current++) {
- idx=get_idx(cflist[current+1],conflist,maxconf);
- if (idx<0 || !(config=get_config(idx))) {
- printf("Cannot access conference %s.\n",cflist[current+1]);
- continue;
- }
-
- /* Check security */
- sec=(xsizeof(config)>CF_SECURITY)? atoi(config[CF_SECURITY]) : 0;
- #ifdef NEWS
- if (xsizeof(config)<=CF_NEWSGROUP)
- sec &= ~CT_NEWS;
- #endif
- if (!(sec & CT_READONLY) && !checkpoint(idx,sec))
- continue;
-
- /* if (idx==confidx) */
- if (!strcmp(conflist[idx].location,conflist[confidx].location)) {
- refresh_sum(0,confidx,sum,part,&st_glob);
- if (st_glob.i_newresp || st_glob.i_brandnew) {
- join(cflist[++current],0);
- return 1;
- }
- } else {
- read_part(config[CF_PARTFILE],part2,&st,idx); /* Read in partfile */
- sprintf(buff,"%s/%s",work,config[CF_PARTFILE]);
- st.parttime = (stat(buff,&stt))? 0 : stt.st_mtime;
- st.c_security = (xsizeof(config)>CF_SECURITY)?
- atoi(config[CF_SECURITY]) : 0;
- #ifdef NEWS
- st.c_article = 0;
- #endif
- get_status(&st,sum2,part2,idx); /* Read in sumfile */
- st.sumtime = 0;
- if (st.i_newresp || st.i_brandnew) {
- join(cflist[++current],0);
- return 1;
- }
- }
- printf("No new items in %s\n",cflist[current+1]);
- }
- printf("No more conferences left.\n");
- return 2;
- }
-
- /******************************************************************************/
- /* RESIGN FROM (UNJOIN) THE CURRENT CONFERENCE */
- /******************************************************************************/
- int /* RETURNS: (nothing) */
- resign(argc,argv) /* ARGUMENTS: */
- int argc; /* Number of arguments */
- char **argv; /* Argument list */
- {
- char buff[MAX_LINE_LENGTH];
- char **config;
-
- if (argc>1) {
- printf("Bad parameters near \"%s\"\n",argv[1]);
- return 2;
- }
- if (st_glob.c_status & CS_OBSERVER) {
- printf("But you don't belong to this conference!\n");
- return 1;
- }
- if (get_yes("Are you sure you wish to resign? ")) {
- if (!(config = get_config(confidx)))
- return 1;
- sprintf(buff,"%s/%s",work,config[CF_PARTFILE]);
- rm(buff,SL_USER);
- st_glob.c_status |= CS_OBSERVER;
- printf("You are now just an observer.\n");
- }
- return 1;
- }
-
- /******************************************************************************/
- /* DETERMINE IF USER IS ALLOWED TO JOIN A CONFERENCE */
- /******************************************************************************/
- char /* RETURNS: 1 if passed, 0 if failed */
- checkpoint(idx,sec) /* ARGUMENTS: */
- short idx; /* Conference # to checkpoint */
- char sec; /* Conference's security type */
- {
- char **password,**ulst,osec;
- char buff[MAX_LINE_LENGTH];
-
- /* Do Security checks */
- osec = sec;
- sec &= CT_BASIC;
- if (sec==CT_PRESELECT || sec==CT_PARANOID) {
- if (!(ulst=grab_file(conflist[idx].location,"ulist",GF_WORD|GF_IGNCMT)))
- return 0;
- sprintf(buff,"%d",uid);
- if (searcha(login,ulst,0)<0 && searcha(buff,ulst,0)<0) {
- if (!(osec & CT_READONLY))
- printf("Access failed for %s\n", compress(conflist[idx].name));
- xfree(ulst);
- return 0;
- }
- } else ulst=0;
- if (sec==CT_PASSWORD || sec==CT_PARANOID) {
- if (!(password=grab_file(conflist[idx].location,"secret",0))) {
- xfree(ulst);
- return 0;
- }
- if (xsizeof(password)>0) {
- printf("Password for %s: ",compress(conflist[idx].name));
- if (strcmp(get_password(),password[0])) {
- printf("UNK: Invalid password.\n");
- xfree(password);
- xfree(ulst);
- return 0;
- }
- }
- xfree(password);
- }
- xfree(ulst);
- return 1;
- }
-
- /******************************************************************************/
- /* GET INFORMATION ON CONFERENCE PARTICIPANTS */
- /******************************************************************************/
- int /* RETURNS: (nothing) */
- participants(argc,argv) /* ARGUMENTS: */
- int argc; /* Number of arguments */
- char **argv; /* Argument list */
- {
- char **ulst,**namestr,
- **config;
- struct passwd *pwd;
- struct stat st;
- short j,all=0,dump=0;
- time_t tparttime;
- uid_t tuid;
- char tlogin[L_cuserid];
- char tfullname[MAX_LINE_LENGTH];
- char twork[MAX_LINE_LENGTH];
- char buff[MAX_LINE_LENGTH];
- char file[MAX_LINE_LENGTH],file2[MAX_LINE_LENGTH];
-
- /* Save user info */
- tuid = uid; strcpy(tlogin,login);
- strcpy(tfullname,st_glob.fullname); strcpy(twork,work);
- tparttime = st_glob.parttime;
- st_glob.count = 0;
-
- if (argc>1) { /* User list specified */
- ulst = xalloc(argc-1,sizeof(char *));
- for (j=1; j<argc; j++)
- ulst[j-1] = xstrdup(argv[j]);
- } else {
- sprintf(file,"%s/ulist",conflist[confidx].location);
- if
- (!(ulst=grab_file(conflist[confidx].location,"ulist",GF_WORD|GF_SILENT|GF_IGNCMT))) {
- all = 1;
- setpwent();
- } else if (!((st_glob.c_security & CT_BASIC)==CT_PRESELECT
- || (st_glob.c_security & CT_BASIC)==CT_PARANOID)) {
- dump=1;
- sprintf(file2,"%s/ulist.tmp",conflist[confidx].location,"ulist");
- }
- }
-
- open_pipe();
-
- /* Process items */
- sepinit(IS_START);
- confsep("partmsg",confidx,&st_glob,part,0);
-
- for (j=0; !(status & S_INT); j++) {
- if (all) {
- if (!(pwd = getpwent())) break;
- } else {
- if (j>=xsizeof(ulst)) break;
- if (isdigit(ulst[j][0]))
- pwd = getpwuid((uid_t)atoi(ulst[j]));
- else
- pwd = getpwnam(ulst[j]);
- if (!pwd) {
- printf(" User %s not found\n",ulst[j]);
- if (dump) {
- xfree(ulst[j]);
- ulst[j] = 0;
- dump = 2;
- }
- continue;
- }
- }
-
- if (!(config = get_config(confidx)))
- return 1;
-
- sprintf(work,"%s/.cfdir",pwd->pw_dir);
- sprintf(buff,"%s/%s",work,config[CF_PARTFILE]);
- if (stat(buff,&st)) {
- strcpy(work,pwd->pw_dir);
- sprintf(buff,"%s/%s",work, config[CF_PARTFILE]);
- if (stat(buff,&st)) {
- if (dump) { /* someone resigned or deleted a part file */
- xfree(ulst[j]);
- ulst[j] = 0;
- dump = 2;
- }
- fprintf(st_glob.outp,"User %s not a member\n",pwd->pw_name);
- fflush(st_glob.outp);
- continue;
- }
- }
- uid = pwd->pw_uid;
- strcpy(login, pwd->pw_name);
- namestr=explode(pwd->pw_gecos,expand("gecos",DM_VAR));
- strcpy(st_glob.fullname,namestr[0]);
- xfree(namestr);
- st_glob.parttime = st.st_mtime;
- st_glob.count++;
- sepinit(IS_ITEM);
- confsep("partmsg",confidx,&st_glob,part,0);
-
- if (all) {
- sprintf(buff,"%s\n",login);
- write_file(file,buff);
- }
- }
- sepinit(IS_CFIDX);
- confsep("partmsg",confidx,&st_glob,part,0);
-
- if (dump==2) { /* reset ulist file */
- for (j=0; j<xsizeof(ulst); j++) {
- if (ulst[j]) {
- sprintf(buff,"%s\n",ulst[j]);
- if (!write_file(file2,buff)) {
- dump=3;
- break;
- }
- }
- }
- }
- if (dump==2)
- if (rename(file2,file)) error("renaming ",file);
-
- if (all) endpwent();
- else xfree(ulst);
-
- /* Restore user info */
- uid = tuid;
- strcpy(login,tlogin);
- strcpy(st_glob.fullname,tfullname);
- st_glob.parttime = tparttime;
- strcpy(work,twork);
-
- return 1;
- }
-
- void
- log(idx,str)
- short idx;
- char *str;
- {
- char buff[MAX_LINE_LENGTH],
- file[MAX_LINE_LENGTH],
- timestamp[MAX_LINE_LENGTH];
- time_t t;
-
- sprintf(file, "%s/log", conflist[idx].location);
- time(&t);
- strcpy(timestamp,ctime(&t)+4);
- timestamp[20]='\0';
- sprintf(buff,"%s %s %s\n", timestamp, login, str);
- write_file(file, buff);
- }
-