home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume13
/
conf
/
part01
/
conf.c
next >
Wrap
C/C++ Source or Header
|
1988-03-13
|
11KB
|
487 lines
/*
* conf - An interactive multi-user chat program.
*
* conf Copyright (c) 1986, 1987 by Keith Gabryelski
*
* Conf is quasi-public domain software; it may be used and copied
* freely and may be modified to suit the indivuals needs as long
* as:
*
* [1] It is not sold.
* [2] It is not made part of any licensed product.
* [3] This header and others like it are not modified or removed.
* [4] You allow others to use and copy without charge.
*
* without expressed written permission from the original
* author (Keith Gabryelski).
*
*
*/
#include "conf.h"
char *progname; /* program name (argv[0]) */
char *logname, *homedir;
int log_rfd, log_wfd, usr_fd;
long ourplace;
FILE *rec_fp;
int confing = FALSE;
char pubkey[MAXPASSWORDLEN], curkey[MAXPASSWORDLEN];
char pubblock[MAXPASSWORDLEN*8], curblock[MAXPASSWORDLEN*8];
char pubpass[MAXPASSWORDLEN], curpass[MAXPASSWORDLEN];
char replyname[MAXNAMELEN] = "";
char replytty[MAXTTYLEN+1] = ""; /* there is a reason for the + 1
although I have forgotten it
right now, I'm sure it should
be there.
*/
char *wrdata;
unsigned wdlen=0;
struct cusrfil cuser, tuser;
struct clogfil clog, tlog;
#ifdef SYSV
struct termio term, saveterm;
#endif SYSV
#ifdef BSD
struct tchars chrstr;
struct sgttyb ktty;
int ttyflags;
#endif BSD
char ichar = CTRL(C); /* interrupt character */
char qchar = CTRL(\\); /* quit character */
jmp_buf env;
int columns = DEF_COLUMNS, lines = DEF_LINES;
int banner = TRUE, seeme = TRUE, informe = FALSE, warncrypt = TRUE;
int autowho = FALSE, lineinput = FALSE, beep = FALSE, askdump = TRUE;
int expand8bit = TRUE, expandctrl = TRUE;
char *cls, *pager, *shell, *normform, *lineform, *shoutform, *sendform;
char *informform, *recfile;
my_int()
{
longjmp(env, 1);
}
main(argc, argv)
int argc;
char *argv[];
{
char *ptr, *word, *line;
int num, x, old_umask;
struct passwd *pt;
/* set up some pointers to interesting stuff */
wrdata = mymalloc(wdlen = PAGESIZ);
progname = *argv++; argc--;
cuser.cu_line = 1;
cuser.cu_flags = USER_ON;
cuser.cu_procid = getpid();
pt = getpwuid(getuid());
if ((ptr = getlogin()) == NULL)
if ((ptr = pt->pw_name) == NULL)
ptr = "???"; /* can't figure this guy out */
logname = mymalloc((unsigned)(strlen(ptr)+1));
(void) strcpy(logname, ptr);
(void) strcpy(cuser.cu_cname, ptr);
(void) strcpy(cuser.cu_tty, ((ptr= strrchr(ttyname(0), '/')) ? ptr+1 : "tty??"));
homedir = mymalloc((unsigned)(strlen(pt->pw_dir)+1));
(void) strcpy(homedir, pt->pw_dir);
zbuf(pubkey, MAXPASSWORDLEN);
(void)strncpy(pubkey, DEF_KEY, MAXPASSWORDLEN);
zbuf(curkey, MAXPASSWORDLEN);
(void)strncpy(curkey, DEF_KEY, MAXPASSWORDLEN);
cls = mymalloc((unsigned)(strlen(DEF_CLS)+1));
(void) strcpy(cls, DEF_CLS);
normform = mymalloc((unsigned)(strlen(DEF_FORM_NORM)+1));
(void) strcpy(normform, DEF_FORM_NORM);
sendform = mymalloc((unsigned)(strlen(DEF_FORM_SEND)+1));
(void) strcpy(sendform, DEF_FORM_SEND);
shoutform = mymalloc((unsigned)(strlen(DEF_FORM_SHOUT)+1));
(void) strcpy(shoutform, DEF_FORM_SHOUT);
informform = mymalloc((unsigned)(strlen(DEF_FORM_INFORM)+1));
(void) strcpy(informform, DEF_FORM_INFORM);
lineform = mymalloc((unsigned)(strlen(DEF_FORM_LINE)+1));
(void) strcpy(lineform, DEF_FORM_LINE);
pager = mymalloc((unsigned)(strlen(DEF_PAGER)+1));
(void) strcpy(pager, DEF_PAGER);
shell = mymalloc((unsigned)(strlen(DEF_SHELL)+1));
(void) strcpy(shell, DEF_SHELL);
recfile = mymalloc((unsigned)(strlen(DEF_RECFILE)+1));
(void) strcpy(recfile, DEF_RECFILE);
gettcap(); /* get termcap stuff */
getrc(); /* get some defaults from rc file */
getopts(); /* get some defaults from environment */
while (word = *argv++, argc--)
{
if (*word == '-')
{
word++;
while (*word != '\0')
{
switch(*word++)
{
case 'l':
if (*word == '\0')
{
if (!argc)
{
(void)printf("%s: -l switch specified without a conference line number\n",
progname);
usage();
}
word = *argv++; --argc;
}
num = atoi(word);
if ((num < 1) || (num > MAXCONFLINES))
{
(void)printf("%s: invalid conference line number: %d\n",
progname, num);
usage();
}
cuser.cu_line = num;
*word = '\0';
break;
case 's':
if (*word == '\0')
{
if (!argc)
{
(void)fprintf(stderr, "%s: -s specified without a parameter\n", progname);
usage();
}
word = *argv++; --argc;
}
if ((x = setopts(parsestr(word, strlen(word), NEXTWORD))) != FOUNDOPT)
{
char *errmess;
if (x == AMBIGUOUS)
errmess = "Ambiguous";
else
errmess = "Invalid";
(void)fprintf(stderr, "%s: %s -s parameter: %s\n",
progname, errmess, word);
usage();
}
*word = '\0';
break;
case 'w':
(void) do_who(0);
(void) exit(0);
default:
(void)fprintf(stderr, "%s: invalid parameter '%c'\n",
progname, *(word-1));
usage();
}
}
}
else
(void) do_ring(word);
}
/* by this point, all parameters/options have been parsed */
confing = TRUE;
makepass(pubkey, pubblock, pubpass);
makepass(curkey, curblock, curpass);
clog.f_line = cuser.cu_line;
clog.f_usrlen = strlen(cuser.cu_cname) + 1;
clog.f_ttylen = strlen(cuser.cu_tty) + 1;
old_umask = umask(0);
if ((usr_fd = open(CONFUSERS, O_RDWR|O_CREAT, FILEMASK)) < 0)
{
(void)fprintf(stderr, "%s: couldn't open %s (%s)\n", progname,
CONFUSERS, puterr(errno));
(void) exit(-1);
}
(void)lseek(usr_fd, 0L, 0);
#ifdef SYSV
lockf(usr_fd, F_LOCK, 0L); /* lock user file */
#endif SYSV
#ifdef BSD
flock(usr_fd, LOCK_EX);
#endif BSD
ourplace = lseek(usr_fd, 0L, 1);
while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
sizeof(struct cusrfil))
if (tuser.cu_flags == USER_OFF)
break;
else
ourplace = lseek(usr_fd, 0L, 1);
(void)lseek(usr_fd, ourplace, 0);
write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));
#ifdef SYSV
(void)lseek(usr_fd, 0L, 0);
lockf(usr_fd, F_ULOCK, 0L);
#endif SYSV
#ifdef BSD
flock(usr_fd, LOCK_UN);
#endif BSD
if ((log_wfd = open(CONFLOG, O_WRONLY|O_CREAT|O_APPEND, FILEMASK)) < 0)
{
(void)fprintf(stderr,"%s: couldn't create/open %s for writing(%s)\n",
progname, CONFLOG, puterr(errno));
(void) exit(-1);
}
(void) umask(old_umask);
if ((log_rfd = open(CONFLOG, O_RDONLY)) < 0)
{
(void)fprintf(stderr,"%s: couldn't open %s for reading (%s)\n",
progname, CONFLOG, puterr(errno));
(void) exit(-1);
}
/* any fatal errors pass this point must do a nice_exit(status) */
(void)lseek(log_rfd, 0L, 2);
write_log(INFORM, "Login", (char *)NULL, 0, (unsigned)strlen("Login"));
#ifdef SYSV
(void) ioctl(0, TCGETA, &term);
saveterm=term;
if (!(term.c_lflag&ECHO))
lineinput = TRUE;
ichar = term.c_cc[VINTR];
qchar = term.c_cc[VQUIT];
term.c_iflag &= ~(ICRNL);
term.c_lflag &= ~(ICANON|ECHO);
term.c_cc[VEOF] = 1;
term.c_cc[VEOL] = 0;
(void) ioctl(0, TCSETAW, &term);
#endif SYSV
#ifdef BSD
gtty(0, &ktty);
ttyflags = ktty.sg_flags;
if (!(ttyflags&ECHO))
lineinput = TRUE;
ktty.sg_flags |= CBREAK;
ktty.sg_flags &= ~ECHO;
stty(0, &ktty);
(void) ioctl(0, TIOCGETC, &chrstr);
ichar = chrstr.t_intrc;
qchar = chrstr.t_quitc;
#endif BSD
(void)signal(SIGINT, SIG_IGN);
(void)signal(SIGQUIT, fatal);
(void)signal(SIGHUP, nice_exit);
(void)signal(SIGTERM, nice_exit);
(void)signal(SIGILL, fatal);
(void)signal(SIGTRAP, fatal);
(void)signal(SIGIOT, fatal);
(void)signal(SIGEMT, fatal);
(void)signal(SIGFPE, fatal);
(void)signal(SIGBUS, fatal);
(void)signal(SIGSEGV, fatal);
(void)signal(SIGSYS, fatal);
(void)signal(SIGPIPE, fatal);
if (banner)
(void) version(FALSE);
if (autowho)
{
(void) printf("Currently on %s:\n\n", progname);
(void) do_who(0);
(void) putchar('\n');
}
(void)printf("login user %s (%s) on conference line %d\n",
cuser.cu_cname, cuser.cu_tty, cuser.cu_line);
if (setjmp(env))
{
(void)signal(SIGINT, my_int);
dispchar(ichar, stdout, NOVIS);
(void)putchar('\n');
(void)lseek(log_rfd, 0L, 2);
}
else
(void)signal(SIGINT, my_int);
forever
{
read_log();
line = getline();
(void)signal(SIGINT, my_int);
if (line != NULL)
{
if ((*line == ':') && (*(line+1) != ':'))
{
if (*(line+1) == '!')
keep_shell(line+2);
else
{
--linelen;
(void) intpret(line+1);
}
}
else
{
if (*line == ':')
write_log(NORMAL, line+1, (char *)NULL, 0, linelen-1);
else
write_log(NORMAL, line, (char *)NULL, 0, linelen);
}
free(line);
}
}
}
nice_exit(status)
int status;
{
make_nice(TRUE);
(void)signal(SIGALRM, SIG_DFL);
(void)signal(SIGINT, SIG_DFL);
(void)signal(SIGQUIT, SIG_DFL);
(void)signal(SIGHUP, SIG_DFL);
(void)signal(SIGTERM, SIG_DFL);
(void)signal(SIGILL, SIG_DFL);
(void)signal(SIGTRAP, SIG_DFL);
(void)signal(SIGIOT, SIG_DFL);
(void)signal(SIGEMT, SIG_DFL);
(void)signal(SIGFPE, SIG_DFL);
(void)signal(SIGBUS, SIG_DFL);
(void)signal(SIGSEGV, SIG_DFL);
(void)signal(SIGSYS, SIG_DFL);
(void)signal(SIGPIPE, SIG_DFL);
(void) exit(status);
}
make_nice(status)
int status;
{
int c, rotten_egg; /* last one out ... */
(void)alarm(0);
if (status)
write_log(INFORM,"Logout",(char *)NULL,0, (unsigned)strlen("Logout"));
if (cuser.cu_flags&USER_RECORD)
(void)fclose(rec_fp);
cuser.cu_flags = USER_OFF;
write_usr();
(void)lseek(usr_fd, 0L, 0);
#ifdef SYSV
lockf(usr_fd, F_LOCK, 0L); /* lock user file */
#endif SYSV
#ifdef BSD
flock(usr_fd, LOCK_EX);
#endif BSD
rotten_egg = TRUE;
while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
sizeof(struct cusrfil))
if (tuser.cu_flags != USER_OFF)
{
c = kill(tuser.cu_procid, 0);
if ((!c) || ((c < 0) && (errno != ESRCH)))
rotten_egg = FALSE;
}
if (rotten_egg)
{
if (unlink(CONFLOG) < 0)
(void)printf("%s: couldn't remove %s (%s)\n", progname, CONFLOG,
puterr(errno));
if (unlink(CONFUSERS) < 0)
(void)printf("%s: couldn't remove %s (%s)\n", progname, CONFUSERS,
puterr(errno));
}
#ifdef SYSV
(void)lseek(usr_fd, 0L, 0);
lockf(usr_fd, F_ULOCK, 0L);
#endif SYSV
#ifdef BSD
flock(usr_fd, LOCK_UN);
#endif BSD
(void)close(usr_fd);
(void)close(log_rfd);
(void)close(log_wfd);
#ifdef SYSV
(void) ioctl(0, TCSETAW, &saveterm);
#endif SYSV
#ifdef BSD
ktty.sg_flags = ttyflags;
stty(0, &ktty);
#endif BSD
}
usage()
{
(void)fprintf(stderr, "usage: %s [-w][-s switchname][-l line-number]\n",
progname);
(void) exit(-1);
}