home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume28
/
yapp
/
part03
/
conf.c
next >
Wrap
C/C++ Source or Header
|
1994-05-29
|
21KB
|
660 lines
/* 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);
}