v16i003: Multi-user conference system, Part03/05

Rich Salz rsalz at uunet.uu.net
Tue Sep 13 06:08:11 AEST 1988


Submitted-by: Keith Gabryelski <ucsd!elgar!ag>
Posting-number: Volume 16, Issue 3
Archive-name: conf2/part03

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	confprnt.c
#	confrots.c
#	confrw.c
export PATH; PATH=/bin:$PATH
if test -f 'confprnt.c'
then
	echo shar: will not over-write existing file "'confprnt.c'"
else
cat << \SHAR_EOF > 'confprnt.c'
#include "conf.h"

jmp_buf glenv, cvenv;

#define	BACKCHAR() {if (expand8bit && !isascii(*(lp-1)))         \
			(void)fputs("\b \b", stdout);              \
		    if (expandctrl && iscntrl(toascii(*(lp-1)))) \
			(void)fputs("\b \b", stdout);              \
		    (void)fputs("\b \b", stdout); --lp;}

unsigned linelen, col = 0;

my_intr(sig)
int sig;
{
    longjmp(glenv, sig);
}

save_intr(sig)
int sig;
{
    longjmp(cvenv, sig);
}

fputchar(c)
int c;
{
    (void)putchar(c);
}

printmess(stream, constr, usr, tty, mess, length)
char *constr, *usr, *tty, *mess;
unsigned length;
FILE *stream;
{
    register char *ptr = constr;
    register int c;

    while (c = *ptr++)
    {
	switch(c)
	{
	    case '%':
		switch(c = *ptr++)
		{
		    case 'T':
			visprnt(cuser.cu_tty, stream);
			break;

		    case 't':
			visprnt(tty, stream);
			break;

		    case 'N':
			visprnt(cuser.cu_cname, stream);
			break;

		    case 'n':
			visprnt(usr, stream);
			break;

		    case 'm':
			messptr(mess, stream, length);
			break;

		    case '\0':
			(void)putc('%', stream);
			--ptr;
			break;

		    default:
			(void)putc('%', stream);
		    case '%':
			(void)putc(c, stream);
			break;
		}
		break;

	    default:
		(void)putc(c, stream);
		break;
	}
    }

    (void)fflush(stream);
}

messptr(mess, stream, length)
char *mess;
unsigned length;
FILE *stream;
{
    register char *ptr = mess;

    while (length--)
	dispchar(*ptr++, stream, NOVIS);

    (void)fflush(stream);
}

visprnt(mess, stream)
char *mess;
FILE *stream;
{
    register char *ptr = mess;

    while (*ptr)
	dispchar(*ptr++, stream, VIS);

    (void)fflush(stream);
}

vislen(mess)
register char *mess;
{
    register int length = 0;

    while (*mess)
    {
	if (!isascii(*mess) && expand8bit)
	    length += 2;
	if (iscntrl(*mess) && expandctrl)
	    ++length;
	++length;
	++mess;
    }

    return length;
}

dispchar(c, stream, flag)
int c;
FILE *stream;
int flag;
{
    int wasmeta = FALSE;

    if (!isascii(c) && !expand8bit)
    {
	(void)putc(c, stream);
	return;
    }

    if (!isascii(c))
    {
	(void)putc('~', stream);
	c = toascii(c);
	wasmeta = TRUE;
    }

    if (iscntrl(c) && expandctrl)
    {
	switch (c)
	{
	    case DEL:
		(void)fputs("^?", stream);
		break;

	    case '\n':
	    case TAB:
		if (!wasmeta && !(flag&VIS))
		{
		    (void)putc(c, stream);
		    break;
		}

	    default:
		(void)putc('^', stream);
		(void)putc(c|'@', stream);
		break;
	}
    }
    else
	(void)putc(c, stream);
}

char *
getline()
{
    int c;
    char *line = mymalloc(PAGESIZ);
    int tmplen, len = PAGESIZ;
    char *lp = line;

    if (c = setjmp(glenv))
    {
	(void)alarm(0);
	(void)signal(SIGALRM, my_intr);
	(void)signal(SIGINT, SIG_IGN);

	switch(c)
	{
	    case SIGINT:
		dispchar(ichar, stdout, NOVIS);
		(void)putchar('\n');
		break;
	}

	free(line);
	return NULL;
    }

    (void)signal(SIGALRM, my_intr);
    (void)signal(SIGINT, my_intr);

    (void)alarm(1);
    read(0, lp, 1);
    (void)alarm(0);

    do
    {
	if (lineinput) switch(*lp)
	{
	    case CR:
	    case LF:
		if (lp == line)
		{
		    free(line);
		    return NULL;
		}
		*lp = '\0';
		linelen = lp - line;
		return line;

	    default:
		lp++;
	    	break;
	}
	else switch(*lp)
	{
	    case BS:
	    case DEL:
		if (lp > line)
		    {BACKCHAR();}
		else
		    (void)putchar(BELL);

		(void)fflush(stdout);

		if (lp == line)
		{
		    free(line);
		    return NULL;
	        }
		break;

	    case CR:
	    case LF:
		(void)putchar('\n');

		if (lp == line)
		{
		    free(line);
		    return NULL;
		}
		*lp = '\0';
		linelen = lp - line;
		return line;

	    case CTRL('L'):
		if (cls == NULL)
		    puts("^L\n");
		else
		    tputs(cls, lines, fputchar);

		messptr(line, stdout, (unsigned)(lp-line));

		if (lp == line)
		{
		    free(line);
		    return NULL;
		}
		break;

	    case CTRL('R'):
		*lp = '\0';
		(void)puts("^R");

		messptr(line, stdout, (unsigned)(lp-line));

		if (lp == line)
		{
		    free(line);
		    return NULL;
		}
		break;

	    case CTRL('U'):
		while (lp > line)
		    BACKCHAR();

		(void)fflush(stdout);
		free(line);
		return NULL;

	    case CTRL('V'):
		if (c = setjmp(cvenv))
		{
		    switch(c)
		    {
			case SIGINT:
			    *lp = ichar;
			    break;

			case SIGQUIT:
			    *lp = qchar;
			    break;
		    }
		}
		else
		{
		    (void)signal(SIGINT, save_intr);
		    (void)signal(SIGQUIT, save_intr);

		    if (read(0, lp, 1) != 1)
		    {
			free(line);		/* some sort of read error */
			return NULL;
		    }
		}

		(void)signal(SIGINT, my_intr);
		(void)signal(SIGQUIT, fatal);
		dispchar(*lp++, stdout, NOVIS);
		(void)fflush(stdout);
		break;

	    case CTRL('W'):
		while ((lp > line) && isspace(*(lp-1)))
		    BACKCHAR();   /* ditch the post word white space */

		while ((lp > line) && !isspace(*(lp-1)))
		    BACKCHAR(); /* someday a cool worderizer */

		(void)fflush(stdout);

		if (lp == line)
		{
		    free(line);
		    return NULL;
		}
		break;

	    case CTRL('D'):	/* default must follow this case */
		if (lp == line)
		{
		    (void)puts(":quit");
		    nice_exit(0);
		}
				/* if not first character, do default: */
	    default:
		dispchar(*lp++, stdout, NOVIS);
		(void) fflush(stdout);
	    	break;
	}

	if ((tmplen = lp - line) >= len )
	{
	    line = myrealloc(line, (unsigned)(len += PAGESIZ));
	    lp = line + tmplen;
	}

    } while(read(0, lp, 1));

    free(line);
    return NULL;	/* error while reading -- punt */
}

colprnt(word, pad)
char *word;
int pad;
{
    if (col+pad > columns-1)
    {
	if (!columns)
	{
	    visprnt(word, stdout);
	    (void)putchar('\n');
	}
	else
	{
	    col = pad;
	    (void)putchar('\n');
	    visprnt(word, stdout);
	    (void)printf("%-*s", pad-vislen(word), " ");
	}
    }
    else
    {
	col += pad;
	visprnt(word, stdout);
	(void)printf("%-*s", pad-vislen(word), " ");
    }
}

terpri()
{
    if (col)
	(void)putchar('\n');
    col = 0;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'confrots.c'
then
	echo shar: will not over-write existing file "'confrots.c'"
else
cat << \SHAR_EOF > 'confrots.c'
#include "conf.h"

int do_who(), do_record(), do_to(), moby_hlp(), wee_hlp();
int shell_it(), do_shout(), do_send(), do_reply(), do_from();
int do_set(), rms(), do_shell(), do_cls(), echo_fn();

FILE *hfp;

static struct
    {
	char *fn_name;
	int (*fn_func)();
	int fn_arg;
    }
    cmdtab[] =
    {
	{ "?", wee_hlp, },
	{ "cls", do_cls, },
	{ "echo", echo_fn, },
	{ "exit", nice_exit, 0, },
	{ "from", do_from, },
	{ "help", moby_hlp, },
	{ "quit", nice_exit, 0, },
	{ "record", do_record, },
	{ "reply", do_reply, },
	{ "ring", do_ring, },
	{ "rms", rms, },
	{ "send", do_send, },
	{ "set", do_set, },
	{ "shell", do_shell, },
	{ "shout", do_shout, },
	{ "to", do_to, },
	{ "version", version, TRUE, },
	{ "who", do_who, 0, },
	{ NULL, }
    }, *cmdptr;

intpret(line)
char *line;
{
    cmdptr = cmdtab;
    line = parsestr(line, (int)linelen, NEXTWORD);

    if (line != NULL)
    {
	for (cmdptr = cmdtab; cmdptr->fn_name != NULL; cmdptr++)
	{
	    if (!strcmp(cmdptr->fn_name, line))
		return (*cmdptr->fn_func)(cmdptr->fn_arg);
	}

	if (confing)
	{
	    (void) fputs("Invalid command: \"", stdout);
	    visprnt(line, stdout);
	    (void) puts("\"  :? for list");
	}
    }
    return FALSE;
}

do_to()
{
    char *ptr, tmp[20];
    int ln;

    if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL)
    {
	if (((ln = atoi(ptr)) < 1) || (ln > MAXCONFLINES))
	{
	    if (confing)
		(void) printf("Invalid line number: %d.\n", ln);

	    return FALSE;
	}
	else
	{
	    if (confing)
	    {
		if (cuser.cu_line == ln)
		    (void) printf("Already on line %d.\n", ln);
		else
		{
		    (void) sprintf(tmp, "To line %d", ln);
		    write_log(INFORM, tmp, (char *)NULL, (unsigned)0,
			      (unsigned)strlen(tmp));

		    (void) sprintf(tmp, "From line %d", cuser.cu_line);
		    clog.f_line = cuser.cu_line = ln;

		    (void) printf("Now on line %d.\n", ln);

		    write_usr();

		    write_log(INFORM, tmp, (char *)NULL, (unsigned)0,
			      (unsigned)strlen(tmp));

		    if (cuser.cu_flags&USER_RECORD)
			write_log(INFORM, "Recording", (char *)NULL,
				  (unsigned)0, (unsigned)strlen("Recording"));
		}
	    }
	    else
	    {
		clog.f_line = cuser.cu_line = ln;
		return TRUE;
	    }
	}
    }
    else
	if (confing)
	    (void) printf("On line %d.\n", cuser.cu_line);
	else
	    return FALSE;

    return TRUE;
}

do_from()
{
    char *ptr;
    int fd;

    if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
    {
	(void)puts("No file name given.");
	return FALSE;
    }

    if ((fd = open(ptr, O_RDONLY)) < 0)
    {
	(void) printf("Couldn't open %s (%s)\n",ptr, puterr(errno));
	return FALSE;
    }
    else
    {
	char *buf;
	unsigned fsiz;
	struct stat stbuf;

	if (fstat(fd, &stbuf) < 0)
	{
	    (void) printf("Coundn't stat %s (%s); aborting.\n", ptr,
			  puterr(errno));
	    (void) close(fd);
	    return FALSE;
	}
	else
	{
	    fsiz = (unsigned int)stbuf.st_size;
	    buf = mymalloc(fsiz);

	    read(fd, buf, fsiz);

	    write_log(NORMAL, buf, (char *)NULL, 0, fsiz);
	    free(buf);
	    (void)close(fd);
	}
    }
    return TRUE;
}


do_who(line)
int line;
{
    int namelen, ttylen, users;
    char *ptr;
    struct whostr **wholist, **whoptr;

    wholist = (struct whostr **)mymalloc(0);

    if (confing && !line)
	if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL)
	    line = atoi(ptr);

    if (line > MAXCONFLINES)
	line = 0;
 
    users = 0;
    namelen = strlen("Name");
    ttylen = strlen("Tty");
    (void) lseek(usr_fd, 0L, 0);
    while(read(usr_fd, (char *)&tuser, (unsigned)sizeof(struct cusrfil)))
    {
	if ((tuser.cu_flags != USER_OFF) &&
	    (!line || (line && (tuser.cu_line == line))))
	{
	    wholist = (struct whostr **)myrealloc(wholist,
		   	 sizeof (struct whostr **)*(users+1));
	    whoptr = (struct whostr **)&wholist[users++];
	    *whoptr = (struct whostr *)mymalloc(sizeof (struct whostr));
	    (void) strcpy((*whoptr)->name, tuser.cu_cname);
	    (void) strcpy((*whoptr)->tty, tuser.cu_tty);
	    (*whoptr)->line = tuser.cu_line;
	    (*whoptr)->flags = tuser.cu_flags;

	    if (strlen((*whoptr)->name) > namelen)
		namelen = strlen((*whoptr)->name);

	    if (strlen((*whoptr)->tty) > ttylen)
		ttylen = strlen((*whoptr)->tty);
	}

    }

    wholist = (struct whostr **)myrealloc(wholist,
			sizeof (struct whostr **)*(users+1));
    wholist[users] = (struct whostr *)NULL;

    if (!users)
    {
	if (line)
	    (void) printf("No users on line %d.\n", line);
	else
	    (void) printf("No users on %s.\n", progname);
    }
    else
    {
	char prefix;
	namelen += TABAGE;
	ttylen += TABAGE;
	whoptr = wholist;

	if (line)
	{
	    (void) printf(" %-*s%-*s\n", namelen, "Name", ttylen, "Tty");
	    while (*whoptr != (struct whostr *)NULL)
	    {
		if ((*whoptr)->flags&USER_RECORD)
		    prefix = '*';
		else
		    prefix = ' ';

		(void) printf("%c%-*s%-*s\n", prefix, namelen, (*whoptr)->name,
		    ttylen, (*whoptr)->tty);
		whoptr++;
	    }
	}
	else
	{
	    (void) printf(" %-*s%-*s%s\n", namelen, "Name", ttylen, "Tty", "Line");
	    while (*whoptr != (struct whostr *)NULL)
	    {
		if ((*whoptr)->flags&USER_RECORD)
		    prefix = '*';
		else
		    prefix = ' ';

		(void) printf("%c%-*s%-*s%d\n",prefix,namelen,(*whoptr)->name,
		    ttylen, (*whoptr)->tty, (*whoptr)->line);
		whoptr++;
	    }
	}
	whoptr = wholist;
	while (*whoptr != (struct whostr *)NULL)
	    free(*whoptr++);
    }
    free(wholist);

/*    if (!confing)
 *	(void) close(usr_fd);
 */
    fflush(stdout);

    return TRUE;
}

do_record()
{
    char *ptr;

/* check to see if filename will screw log/user file */

    if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
    {
	if (cuser.cu_flags&USER_RECORD)
	{
	    (void)fclose(rec_fp);
	    cuser.cu_flags &= ~USER_RECORD;
	    write_usr();
	    if (confing)
	    {
		write_log(INFORM, "Recording OFF", (char *)NULL, (unsigned)0,
		    (unsigned)strlen("Recording OFF"));
		(void)fputs("Recording OFF.\n", stdout);
	    }
	    return FALSE;
	}
	else
	    ptr = recfile;
    } 

    if (cuser.cu_flags&USER_RECORD)
	(void) fclose(rec_fp);

    if ((rec_fp = fopen(ptr, "a")) == (FILE *)NULL)
    {
	(void) fputs("Couldn't open ", stdout);
	messptr(ptr, stdout, (unsigned)strlen(ptr));
	(void) printf(" (%s).\n", puterr(errno));

	if (cuser.cu_flags&USER_RECORD)
	{
	    cuser.cu_flags &= ~USER_RECORD;
	    if (confing)
	    {
		write_log(INFORM, "Recording OFF", (char *)NULL, (unsigned)0,
		    (unsigned)strlen("Recording OFF"));
		(void) printf("Recording OFF\n");
	    }
	}
    }
    else
    {
	if (confing)
	{
	    if (cuser.cu_flags&USER_RECORD)
		(void)fputs("Changing record file to ", stdout);
	    else
		(void)fputs("Recording to file ", stdout);

	    (void) printf("%s.\n", ptr);
	    write_log(INFORM, "Recording ON", (char *)NULL, (unsigned)0,
		(unsigned)strlen("Recording ON"));
	}

	cuser.cu_flags |= USER_RECORD;
    }

    write_usr();
    return TRUE;
}

wee_hlp()
{
    char *ptr;

    if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
    {
	int tmp, len=0;
	cmdptr = cmdtab;

	for (cmdptr = cmdtab; cmdptr->fn_name != NULL; cmdptr++)
	    if ((tmp = strlen(cmdptr->fn_name)) > len)
		len = tmp;
	
	len += TABAGE;

	for (cmdptr = cmdtab; cmdptr->fn_name != NULL; cmdptr++)
	    colprnt(cmdptr->fn_name, len);

	terpri();

	return TRUE;
    }
    else
    {
	char *word;
	int c;

	if ((hfp = fopen(CONFHELP, "r")) == (FILE *)NULL)
	    (void)printf("Couldn't open help file %s (%s).\n",
		CONFHELP, puterr(errno));
	else
	{
	    while ((word = getword()) != NULL)
		if (!strcmp(word+1, ptr))
		{
		    (void)fputs(word, stdout);
		    while(((c = getc(hfp)) != EOF) && (c != '\n'))
			(void)putchar(c);

		    (void)putchar('\n');
		    (void)fclose(hfp);
		    return TRUE;
		}

	    (void) printf("Command not found: %s\n", ptr);
	}
    }
    (void)fclose(hfp);
    return FALSE;
}

moby_hlp()
{
    int c, lastnl;
    char *ptr, *word;

    if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
    {
	ptr = mymalloc((unsigned int)(strlen(pager)+1+strlen(CONFHELP) + 1));
	(void)strcpy(ptr, pager);
	(void)strcat(ptr, " ");
	(void)strcat(ptr, CONFHELP);

	(void) shell_it(ptr);
	free(ptr);
	return TRUE;
    }
    else
    {
	if ((hfp = fopen(CONFHELP, "r")) == (FILE *)NULL)
	    (void)printf("Couldn't open help file %s (%s).\n",
		CONFHELP, puterr(errno));
	else
	{
	    while ((word = getword()) != NULL)
		if (!strcmp(word+1, ptr))
		{
		    (void)fputs(word, stdout);
		    lastnl = FALSE;
		    while((c = getc(hfp)) != EOF)
			if (c == '\n')
			{
			    if (lastnl)
			    {
				(void)fclose(hfp);
				return TRUE;
			    }

			    (void)putchar(c);
			    lastnl = TRUE;
			}
			else
			{
			    lastnl = FALSE;
			    (void)putchar(c);
			}
		}

	    (void)printf("Command not found: %s\n", ptr);
	    (void)fclose(hfp);
	}
    }
    return FALSE;
}

char *
getword()
{
    int c;
    static char buf[100];
    char *bp = buf;

    forever
    {
	while (((c = getc(hfp)) != '\n') && (c != EOF)) ;

	if (c == EOF)
	    return NULL;

	if ((c = getc(hfp)) != ':')
	    (void)ungetc(c, hfp);
	else
	{
	    do
	    {
		*bp++ = c;
	    } while (!isspace((c = getc(hfp))));

	    (void)ungetc(c, hfp);
	    *bp = '\0';
	    return buf;
	}
    }
}

do_shell()
{
    if (shell_it(shell) <0)
	(void) puts("!Error");
    else
	(void) puts("!");
}

keep_shell(line)
char *line;
{
    static char *lastcmd;

    if (*line == '!')
    {
	if (lastcmd == NULL)
	{
	    (void)puts("No previous command.");
	}
	else
	{
	    lastcmd = myrealloc(lastcmd, (unsigned)(strlen(lastcmd) + strlen(line+1) +1));
	    (void)strcat(lastcmd, line+1);
	}
    }
    else
    {
	lastcmd = myrealloc(lastcmd, (unsigned)(strlen(line) + 1));
	(void)strcpy(lastcmd, line);
    }

    if (shell_it(lastcmd) <0)
	(void) puts("!Error");
    else
	(void)puts("!");
}

shell_it(line)
char *line;
{
    int status;
#ifdef	SYSV
    (void) ioctl(0, TCSETAW, &saveterm);
#endif	SYSV

#ifdef	BSD
    int tmpflags;

    tmpflags = ktty.sg_flags;
    ktty.sg_flags = ttyflags;
    stty(0, &ktty);
#endif	BSD

    (void)signal(SIGINT, SIG_DFL);

    status = system(line);

    (void)signal(SIGINT, SIG_IGN);

#ifdef	SYSV
    (void) ioctl(0, TCSETAW, &term);
#endif	SYSV

#ifdef	BSD
    ktty.sg_flags = tmpflags;
    stty(0, &ktty);
#endif	BSD

    return status;
}

do_shout()
{
    char *ptr;

    if (!confing)
	return FALSE;

    ptr = parsestr((char *)NULL, 0, THEREST);

    write_log(SHOUT, ptr, (char *)NULL, (unsigned)0, wordlen);
    return TRUE;
}

do_reply()
{
    char *ptr;

    if (!confing)
	return FALSE;

    if (*replytty == '\0')
	(void)puts("No one to reply to.");
    else
    {
	if ((ptr = parsestr((char *)NULL, 0, THEREST)) == NULL)
	    (void)printf("Last send was from %s (%s).\n", replyname, replytty);
	else
	    write_log(SEND, ptr, replytty, (unsigned)(strlen(replytty)+1),
		    wordlen);
    }
    return TRUE;
}

do_send()
{
    char *to, *temp, *lastnam, *cp;
    int found;
    unsigned int tolen = 0;
    unsigned int tp;

    if (!confing)
	return FALSE;

    if ((cp = parsestr((char *)NULL, 0, THEREST)) == NULL)
    {
	(void)puts("No parameters given to send, usage :send usr,/line,:tty,... message");
	return FALSE;
    }

    if (tolen == 0)
	to = mymalloc(tolen = PAGESIZ);

    temp = to;

    do
    {
	while (wordlen && isspace(*cp))
	{
	    --wordlen;
	    cp++;
	}

	lastnam = temp;
	while (wordlen && (isalnum(*cp) || ((lastnam == temp) && (strchr("/:", *cp)))))
	{
	    if (temp - to + 2 >= tolen)
	    {
		tp = temp - to;
		to = myrealloc(to, tolen += PAGESIZ);
		temp = to+tp;
	    }

	    --wordlen;
	    *temp++ = *cp++;
	}
	*temp++ = '\0';

    /* check here for validity of send parameter */

    (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

    found = FALSE;
    switch(*lastnam)
    {
	int num;

	case '/':
	    num = atoi(lastnam+1);
	    if ((num < 1) || (num > MAXCONFLINES))
	    {
		(void)printf("Invalid conference line number: %s\n", lastnam+1);
		temp = lastnam;
		break;
	    }

	    while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
			sizeof(struct cusrfil))
		if ((tuser.cu_flags == USER_ON) && (tuser.cu_line == num))
		    found = TRUE;

	    if (!found)
	    {
		(void)printf("No one is on conference line %d\n", num);
		temp = lastnam;
	    }
	    break;

	case ':':
	    while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
			sizeof(struct cusrfil))
		if ((tuser.cu_flags == USER_ON) && !strcmp(tuser.cu_tty, lastnam+1))
		    found = TRUE;

	    if (!found)
	    {
		(void)printf("No user on %s\n", lastnam+1);
		temp = lastnam;
	    }
	    break;

	default:
	    while (read(usr_fd, (char *)&tuser, sizeof(struct cusrfil)) ==
			sizeof(struct cusrfil))
		if ((tuser.cu_flags == USER_ON) && !strcmp(tuser.cu_cname, lastnam))
		    found = TRUE;

	    if (!found)
	    {
		(void)printf("User %s not logged into %s.\n", lastnam, progname);
		temp = lastnam;
	    }

	    break;
    }

#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 (wordlen)
	    --wordlen;
    } while (wordlen && (*cp++ == ','));

    if (!wordlen)
    {
	(void)puts("No message given to send, usage :send usr,/line,:tty... message");
	return FALSE;
    }

    *temp++ = '\0';

    write_log(SEND, cp, to, (unsigned)(temp-to), wordlen);

    free(to);
    return TRUE;
}

echo_fn()
{
    char *ptr;
    int i;

    while ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL)
	for (i=0; i < wordlen; ++i)
	    dispchar(*ptr++, stdout, NOVIS);

    return TRUE;
}

rms()
{
    (void) sleep(1);		/* small sleep for f/x */
    (void) fputs("root password changed to 'rms'\n", stdout);
    return TRUE;
}

version(lngver)
int lngver;
{
    (void) printf("%s (conference) version %d.%d\n", progname, VERNUM,
		  PATCHLEVEL);
    (void) printf("Written by %s (%s)\n", AUTHOR, ADDRESS);

    if (lngver)
	(void) printf("Special thanks to:\n\t%s\n", THANKS1);

    fflush(stdout);
    return TRUE;
}

do_set()
{
    char *ptr;
    int x;

    ptr = parsestr((char *)NULL, 0, NEXTWORD);

    do
    {
	if ((x = setopts(ptr)) != FOUNDOPT)
	{
	    if (x == AMBIGUOUS)
		(void)fputs("Ambiguos option: \"", stdout);
	    else
		(void)fputs("Invalid option: \"", stdout);

	    messptr(ptr, stdout, wordlen);
	    (void)puts("\";  :set<cr> for list");
	    break;
	}
    } while ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL);

    return TRUE;
}

do_ring(ptr)
char *ptr;
{
    FILE *pp;
    char *tostr = mymalloc((unsigned)(strlen(SENDER)+1+MAXNAMELEN + 1));

    if (confing)
	if ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) == NULL)
	{
	    (void)puts("Must supply a user to :ring.");
	    free(tostr);
	    return FALSE;
	}

    do
    {
	(void)sprintf(tostr, "%s %s", SENDER, ptr);
	if ((pp = popen(tostr, "w")) == (FILE *)NULL)
	{
	    (void)printf("Couldn't popen %s to %s (%s).\n", SENDER, ptr,
		   puterr(errno));
	    free(tostr);
	    return FALSE;
	}
	else
	{
	    (void)fprintf(pp, "Your presence is requested on %s.\n", progname);
	    (void)fprintf(pp, "Please type: %s -l%d at your shell prompt to confernce.\n", progname, cuser.cu_line);

	    (void)pclose(pp);
	}
    } while (confing && ((ptr = parsestr((char *)NULL, 0, NEXTWORD)) != NULL));

    free(tostr);
    return TRUE;
}

do_cls()
{
    (void) fputs(cls, stdout);
    return TRUE;
}
SHAR_EOF
fi # end of overwriting check
if test -f 'confrw.c'
then
	echo shar: will not over-write existing file "'confrw.c'"
else
cat << \SHAR_EOF > 'confrw.c'
#include "conf.h"

read_log()
{
    char *ptr, *p;
    char rduser[MAXNAMELEN], rdtty[MAXTTYLEN];
    int tous, toline;

    while (read(log_rfd, (char *)&tlog, (unsigned)sizeof(struct clogfil)) ==
	sizeof(struct clogfil))
    {
	switch(tlog.type)
	{
	    case NORMAL:
		if (tlog.f_line == cuser.cu_line)
		{
		    if (tlog.messlen > wdlen)
			wrdata = myrealloc(wrdata, wdlen = tlog.messlen);

		    read(log_rfd, rduser, tlog.f_usrlen);
		    read(log_rfd, rdtty, tlog.f_ttylen);
		    read(log_rfd, wrdata, tlog.messlen);

		    if (!seeme && !strcmp(rdtty, cuser.cu_tty))
			break;

		    if (beep)
			(void)putchar(BELL);

		    printmess(stdout, normform, rduser, rdtty,
			    wrdata, tlog.messlen);

		    if (cuser.cu_flags&USER_RECORD)
			printmess(rec_fp, normform, rduser, rdtty,
				wrdata, tlog.messlen);
		}
		else
		    (void)lseek(log_rfd, (long)(tlog.f_usrlen + tlog.f_ttylen +
			tlog.messlen), 1);
		break;

	    case SEND:
		read(log_rfd, rduser, tlog.f_usrlen);
		read(log_rfd, rdtty, tlog.f_ttylen);

		ptr = mymalloc(tlog.t_utlen);
		read(log_rfd, ptr, tlog.t_utlen);
		read(log_rfd, wrdata, tlog.messlen);

		p = ptr;
		toline = tous = FALSE;
		do
		{
		    switch(*p)
		    {
			case '/':
			    if (atoi(p+1) == cuser.cu_line)
			    toline = TRUE;
			    break;

			case ':':
			    if (!strcmp(p+1, cuser.cu_tty))
				tous = TRUE;
			    break;

			default:
			    if (!strcmp(p, cuser.cu_cname))
				tous = TRUE;
			    break;
		    }
		    
		    while (*p++) ;  /* to next name */
		} while (*p);       /* while another name exists */

		free(ptr);

		if (tous)
		{
		    if (beep)
			(void)putchar(BELL);

		    printmess(stdout, sendform, rduser, rdtty,
			wrdata, tlog.messlen);

		    if (cuser.cu_flags&USER_RECORD)
			printmess(rec_fp, sendform, rduser, rdtty,
				wrdata, tlog.messlen);

		    (void)strcpy(replytty, rdtty);
		    replytty[strlen(replytty)] = '\0'; /* extra nul 4 send*/
		    (void)strcpy(replyname, rduser);
		}

		if (toline)
		{
		    if (beep)
			(void)putchar(BELL);

		    printmess(stdout, lineform, rduser, rdtty,
			    wrdata, tlog.messlen);

		    if (cuser.cu_flags&USER_RECORD)
			printmess(rec_fp, lineform, rduser, rdtty,
				wrdata, tlog.messlen);
		}
		break;

	    case SHOUT:
		read(log_rfd, rduser, tlog.f_usrlen);
		read(log_rfd, rdtty, tlog.f_ttylen);
		read(log_rfd, wrdata, tlog.messlen);

		if (beep)
		    (void)putchar(BELL);

		printmess(stdout, shoutform, rduser, rdtty, wrdata,
			tlog.messlen);

		if (cuser.cu_flags&USER_RECORD)
		    printmess(rec_fp, shoutform, rduser, rdtty,
			    wrdata, tlog.messlen);
		break;

	    case INFORM:
		if (tlog.f_line == cuser.cu_line)
		{
		    if (tlog.messlen > wdlen)
			wrdata = myrealloc(wrdata, wdlen = tlog.messlen);

		    read(log_rfd, rduser, tlog.f_usrlen);
		    read(log_rfd, rdtty, tlog.f_ttylen);
		    read(log_rfd, wrdata, tlog.messlen);

		    if (!informe && !strcmp(rdtty, cuser.cu_tty))
			break;

		    if (beep)
			(void)putchar(BELL);

		    printmess(stdout, informform, rduser, rdtty,
			    wrdata, tlog.messlen);

		    if (cuser.cu_flags&USER_RECORD)
			printmess(rec_fp, informform, rduser,
				rdtty,wrdata, tlog.messlen);
		}
		else
		{
		    (void)lseek(log_rfd, (long)(tlog.f_usrlen + tlog.f_ttylen +
			tlog.messlen), 1);

#ifdef DEBUG1
		    (void)puts("flushin' this inform...");
		    (void)printf("f_line = %d, cu_line = %d.\n", 
			tlog.f_line, cuser.cu_line);
#endif DEBUG1
		}
		break;

	    default:
		/* ignore invalid type lseek to end */
#ifdef	DEBUG0
		(void)printf("invalid type (0x%x)\n",tlog.type);
#endif	DEBUG0
		(void)lseek(log_rfd, 0L, 2);
		break;
	}
    }
}

write_log(type, message, user, userlen, siz)
int type;
unsigned int userlen, siz;
char *message, *user;
{
    static char *wrbuf;
    static unsigned wblen=0;
    unsigned wrlen;

    clog.type = type;
    clog.messlen = siz;
    clog.t_utlen = userlen;

    switch(type)
    {
	case NORMAL:
	    wrlen = sizeof(struct clogfil) + clog.f_usrlen + clog.f_ttylen +
		    clog.messlen;

	    if (wrlen > wblen)
		wrbuf = myrealloc(wrbuf, wblen = wrlen);

	    /* move data into wrbuf */
	    cpystr(wrbuf, (char *)&clog, (unsigned)sizeof(struct clogfil));

	    strcpy(wrbuf+sizeof(struct clogfil), cuser.cu_cname);
	    strcpy(wrbuf+sizeof(struct clogfil)+clog.f_usrlen, cuser.cu_tty);
	    cpystr(wrbuf+sizeof(struct clogfil)+clog.f_usrlen+
		   clog.f_ttylen, message, clog.messlen);

	    write(log_wfd, wrbuf, wrlen);
	    break;

	case SEND:
	    wrlen = sizeof(struct clogfil) + clog.f_usrlen + clog.f_ttylen +
		clog.t_utlen + clog.messlen;

	    if (wrlen > wblen)
		wrbuf = myrealloc(wrbuf, wblen = wrlen);

	    /* move data into wrbuf */

	    cpystr(wrbuf, (char *)&clog, sizeof(struct clogfil));
	    (void)strcpy(wrbuf+sizeof(struct clogfil), cuser.cu_cname);
	    (void)strcpy(wrbuf+sizeof(struct clogfil)+clog.f_usrlen,
			 cuser.cu_tty);
	    cpystr(wrbuf+sizeof(struct clogfil)+clog.f_usrlen+clog.f_ttylen,
		   user, clog.t_utlen);

	    cpystr(wrbuf+sizeof(struct clogfil)+clog.f_usrlen+
		   clog.f_ttylen+clog.t_utlen, message, clog.messlen);

	    write(log_wfd, wrbuf, wrlen);
	    break;

	case SHOUT:
	    wrlen = sizeof(struct clogfil) + clog.f_usrlen + clog.f_ttylen +
		    clog.messlen;

	    if (wrlen > wblen)
		wrbuf = myrealloc(wrbuf, wblen = wrlen);

	    /* move data into wrbuf */


	    cpystr(wrbuf, (char *)&clog, sizeof(struct clogfil));
	    (void)strcpy(wrbuf+sizeof(struct clogfil), cuser.cu_cname);
	    (void)strcpy(wrbuf+sizeof(struct clogfil)+clog.f_usrlen,
			 cuser.cu_tty);
	    cpystr(wrbuf+sizeof(struct clogfil)+clog.f_usrlen+clog.f_ttylen,
		   message, clog.messlen);

	    write(log_wfd, wrbuf, wrlen);
	    break;

	case INFORM:
	    wrlen = sizeof(struct clogfil) + clog.f_usrlen + clog.f_ttylen +
		    clog.messlen;

	    if (wrlen > wblen)
		wrbuf = myrealloc(wrbuf, wblen = wrlen);

	    /* move data into wrbuf */

	    cpystr(wrbuf, (char *)&clog, (unsigned)sizeof(struct clogfil));
	    (void)strcpy(wrbuf+sizeof(struct clogfil), cuser.cu_cname);
	    (void)strcpy(wrbuf+sizeof(struct clogfil)+clog.f_usrlen,
			 cuser.cu_tty);
	    cpystr(wrbuf+sizeof(struct clogfil)+clog.f_usrlen+clog.f_ttylen,
		   message, clog.messlen);

	    write(log_wfd, wrbuf, wrlen);
	    break;

#ifdef	DEBUG0
	default:
	    (void)printf("warning .. Bogus type, no write (type = %d)\n", type);
	    break;
#endif	DEBUG0
    }
}

write_usr()
{
    (void)lseek(usr_fd, ourplace, 0);

#ifdef	SYSV
    lockf(usr_fd, F_LOCK, (long)sizeof(struct cusrfil));
#endif	SYSV

#ifdef	BSD
    flock(usr_fd, LOCK_EX);
#endif	BSD

    write(usr_fd, (char *)&cuser, sizeof(struct cusrfil));

#ifdef	SYSV
    (void)lseek(usr_fd, ourplace, 0);
    lockf(usr_fd, F_ULOCK, (long)sizeof(struct cusrfil));
#endif	SYSV

#ifdef	BSD
    flock(usr_fd, LOCK_UN);
#endif	BSD
}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0
-- 
  "If green is all there is to be, then green is good enough for me" - ktf
[  Keith   ]  UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag
[Gabryelski]  INET: ag at elgar.cts.com                 ARPA: elgar!ag at ucsd.edu

-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.



More information about the Comp.sources.unix mailing list