Multi-user chat program
D'Arcy J.M. Cain
darcy at druid.uucp
Thu Oct 11 00:12:59 AEST 1990
This is the multi user chat program what I mentioned in comp.unix.questions
last week. Since the requests for it have been high I am posting it here
instead of mailing it individually to everyone who asked for it.
#!/bin/sh
# This is a shell archive (shar 3.10)
# made 08/21/1990 14:40 UTC by darcy at druid
# Source directory /usr/darcy/work/Chat
#
# existing files will NOT be overwritten
#
# This shar contains:
# length mode name
# ------ ---------- ------------------------------------------
# 9136 -r--r--r-- chat.c
# 3908 -r--r--r-- chatter.c
# 1568 -r--r--r-- chc_msg.c
# 2327 -r--r--r-- chs_msg.c
# 537 -r-xr--r-- lchat
# 682 -r-xr-xr-x chatyell
# 2516 -r--r--r-- chat.readme
# 520 -r--r--r-- chat.make
#
touch 2>&1 | fgrep '[-amc]' > /tmp/s3_touch$$
if [ -s /tmp/s3_touch$$ ]
then
TOUCH=can
else
TOUCH=cannot
fi
rm -f /tmp/s3_touch$$
# ============= chat.c ==============
if test -f chat.c; then echo "File chat.c exists"; else
echo "x - extracting chat.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > chat.c &&
X/*
X
Xchat
XWritten by D'Arcy J.M. Cain
XAll rights reserved
X
XThis is the front end to the chatter program. It is run by any number
Xof users who wish to communicate conference style with each other. The
Xchatter program serves each user.
X
XPermission is hereby granted to freely copy and redistribute this
Xsoftware, provided that the author is clearly credited in all
Xcopies and derivations. This software is provided ``As Is'' and
Xwithout any express or implied warranties.
X
X*/
X
X#include <stdio.h>
X#include <stdlib.h>
X#include <string.h>
X#include <curses.h>
X#include <signal.h>
X#include <process.h>
X#include <getopt.h>
X#include <ctype.h>
X#include <errno.h>
X#include "chat.h"
X
Xchar chat_rcsid[] = "$Id: chat.c,v 1.1 90/08/19 19:03:22 darcy Exp $";
X
X#ifndef NO_CHG_NAME
Xstatic char *options = "hn:f:";
X#else
Xstatic char *options = "hf:";
X#endif
X
Xstatic FILE *cap_file = NULL;
Xstatic WINDOW *disp, *inp;
X
X#ifdef HALFDELAY_BROKEN
Xint chat_suspended = 0;
X#endif
X
Xvoid cleanup(void) /* come here on just about any signal */
X{
X while (chk_q()) /* clean up your own mess */
X ;
X
X if (cap_file != NULL)
X fclose(cap_file);
X
X chc_send("x");
X
X mvwprintw(inp, 1, 1, "%-77s", " So long... It's been nice chatting");
X wrefresh(disp); /* display any leftovers */
X wrefresh(inp); /* display polite message */
X
X delwin(disp);
X delwin(inp);
X endwin();
X ch_close();
X exit(0);
X}
X
Xvoid disp_str(char *str) /* add latest string to list just above box */
X{
X scroll(disp); /* make room for it first */
X mvwprintw(disp, LINES - 5, 0, "%s", str);
X
X if (cap_file != NULL) /* save to file if it is open */
X fprintf(cap_file, "%s\n", str);
X}
X
Xstatic int need_to_refresh = 0;
X
Xint chk_q(void)
X{
X char msgbuf[256];
X
X if (ch_get(msgbuf))
X {
X disp_str(msgbuf); /*let user know what chatter has to say */
X
X if (*msgbuf == 'e') /* is chatter telling us to get lost? */
X {
X wrefresh(disp); /* display anything pending */
X cleanup(); /* take the Big Sleep */
X }
X
X need_to_refresh = -1;
X return(1); /* let caller know */
X }
X
X return(0); /* nothing happened */
X}
X
X#ifndef NO_SH_ESC
Xstatic void run_command(char *s)
X{
X int status, pid, w, tty;
X void (*istat)(), (*qstat)();
X
X if ((tty = open("/dev/tty", 2)) == -1)
X {
X fprintf(stderr, "Can't open /dev/tty\n");
X return;
X }
X
X if ((pid = fork()) == 0)
X {
X close(0); dup(tty);
X close(1); dup(tty);
X close(1); dup(tty);
X close(tty);
X execlp("sh", "sh", (*s ? "-c" : NULL), s, NULL);
X exit(0); /* note: We don't care about failure here */
X }
X
X close(tty);
X istat = signal(SIGINT, SIG_IGN);
X qstat = signal(SIGQUIT, SIG_IGN);
X
X while ((w = wait(&status)) != pid)
X if ((w == -1) && (errno != EINTR))
X break;
X
X signal(SIGINT, istat);
X signal(SIGQUIT, qstat);
X}
X#endif
X
Xvoid help(void)
X{
X WINDOW *w;
X int k;
X static char *help_msg[] = {
X "CHAT - multi user conference utility",
X "Written by D'Arcy J.M. Cain (darcy at druid.uucp)",
X "Copyright 1990 - All rights reserved",
X "$Revision: 1.1 $\b " + 1,
X "",
X "chat commands consist of a slash (/) followed by a command",
X " ? this Help screen",
X#ifndef NO_SH_ESC
X " ! shell Escape",
X#endif
X " c Change channel i.e: \"/c3\" - change to channel 3",
X " Note: \"/c*\" will change to first empty channel",
X " h Same as ?",
X#ifndef NO_CHG_NAME
X " n change Name to following string",
X#endif
X " r Redraw screen",
X#ifndef NO_SHOW_USERS
X " s Show current users using chat",
X#endif
X " x eXit from chat",
X "",
X " Hit a key to continue ..."
X };
X#define HELP_SZ (sizeof(help_msg)/sizeof(char *))
X
X w = newwin(HELP_SZ + 3, 71, 1, 3); /* get a new window */
X box(w, 0, 0); /* and box it */
X
X for (k = 0; k < HELP_SZ; k++) /* display the help screen */
X mvwprintw(w, k + 1, 3, "%s", help_msg[k]);
X
X wrefresh(w); /* show the screen */
X
X while (wgetch(w) == ERR)
X ; /* wait for keystroke */
X
X delwin(w); /* clear the window */
X touchwin(disp); /* update display window */
X wrefresh(disp); /* get everything back in sync */
X wrefresh(inp);
X}
X
Xint main(int argc, char **argv)
X{
X int c;
X char entry[512], *ptr = NULL, *ptr1, msgbuf[256];
X
X if ((ptr1 = ch_init()) != NULL)
X {
X perror(ptr1);
X return(1);
X }
X
X /* curses stuff */
X initscr();
X nonl();
X noecho();
X cbreak();
X#ifndef HALFDELAY_BROKEN
X halfdelay(20);
X#endif
X
X /* make sure we always exit through cleanup */
X signal(SIGINT, cleanup);
X signal(SIGABRT, cleanup);
X signal(SIGQUIT, cleanup);
X signal(SIGKILL, cleanup);
X signal(SIGTERM, cleanup);
X
X disp = newwin(LINES - 4, COLS, 0, 0); /* conversation window */
X idlok(disp, TRUE);
X scrollok(disp, TRUE);
X
X inp = newwin(3, COLS, LINES - 4, 0); /* input window */
X box(inp, 0, 0);
X
X mvwprintw(inp, 1, 1, "-> "); /* prompt string */
X
X while ((c = getopt(argc, argv, options)) != -1)
X {
X switch (c)
X {
X case '?':
X default:
X sprintf(entry, "%s: Invalid option %c", argv[0], c);
X disp_str(entry);
X
X case 'h':
X sprintf(entry,
X#ifndef NO_CHG_NAME
X "Usage: %s [-h] [-c channel] [-n name] [-f file]",
X#else
X "Usage: %s [-h] [-c channel] [-f file]",
X#endif
X argv[0]);
X disp_str(entry);
X cleanup();
X break;
X
X#ifndef NO_CHG_NAME
X case 'n':
X ptr = optarg;
X break;
X#endif
X
X case 'f':
X if ((cap_file = fopen(optarg, "a")) == NULL)
X {
X sprintf(entry, "Can't open log file: %s", SYS_ERRLIST);
X cleanup();
X }
X break;
X }
X }
X
X disp_str("chat - multi user conferencing utility"); /* signon string */
X disp_str("Written by D'Arcy J.M. Cain");
X disp_str("Copyright 1990 by D'Arcy J.M. Cain - All rights reserved");
X disp_str("$Revision: 1.1 $\b " + 1);
X disp_str("");
X
X /* open chat link */
X ch_init();
X sprintf(entry, "o%s", (ptr == NULL) ? cuserid(NULL) : ptr);
X chc_send(entry);
X sleep(1); /* messages are not FIFO */
X
X disp_str("Enter /h or /? for help");
X disp_str("");
X wrefresh(disp);
X
X ptr = entry;
X chc_send("s"); /* get list of current users */
X
X for (;;) /* loop till the cows come home */
X {
X while (chk_q())
X ;
X
X if (need_to_refresh)
X wrefresh(disp); /* refresh display if necessary*/
X
X wrefresh(inp); /* refresh this to place cursor */
X
X if ((c = wgetch(inp)) != ERR); /* if got a character (not timed out) */
X {
X if (c == 4)
X cleanup(); /* end of session ? */
X
X if (c == '\r') /* end of line ? */
X {
X *ptr = 0;
X
X if (*entry == '/') /* command? */
X {
X switch (entry[1])
X {
X case '?': /* request for help */
X case 'h':
X help();
X break;
X
X#ifndef NO_SH_ESC
X case '!': /* shell escape */
X ptr = entry + 2;
X while (isspace(*ptr))
X ptr++;
X
X#ifdef HALFDELAY_BROKEN
X chat_suspended = 1;
X#endif
X endwin();
X run_command(ptr);
X printf("\n[Press 'Enter' to continue ...]");
X
X while (gets(entry) == NULL)
X ;
X
X doupdate();
X#ifdef HALFDELAY_BROKEN
X chat_suspended = 0;
X#endif
X break;
X#endif
X
X case 'l': /* redraw screen */
X case 'r':
X clearok(disp, TRUE); /* update display window */
X clearok(inp, TRUE); /* update input window */
X wrefresh(disp); /* redraw both windows */
X wrefresh(inp);
X clearok(disp, FALSE); /* reset display window */
X clearok(inp, FALSE); /* reset input window */
X break;
X
X#ifndef NO_CHG_NAME
X case 'n': /* these are passed to chatter */
X#endif
X#ifndef NO_SHOW_USERS
X case 's':
X#endif
X case 'c':
X ptr = entry + 2;
X while (isspace(*ptr))
X ptr++;
X sprintf(msgbuf, "%c%s", entry[1], ptr);
X chc_send(msgbuf);
X break;
X
X case 'x': /* exit from chat */
X case 'q': /* for Dennis Breckenridge :-) */
X cleanup();
X break;
X
X default:
X beep();
X }
X }
X else if (*entry) /* else send it if not blank */
X {
X sprintf(msgbuf, "m%s", entry);
X chc_send(msgbuf);
X }
X
X ptr = entry; /* reset input box */
X mvwprintw(inp, 1, 1, "%77s", "");
X mvwprintw(inp, 1, 1, "-> ");
X }
X else if (c == '\b') /* take care of backspaces */
X {
X if (ptr != entry)
X {
X wprintw(inp, "\b \b");
X ptr--;
X }
X }
X else if (c == '\t') /* expand tabs */
X {
X ptr1 = ptr + 8 - ((ptr - entry) % 8);
X while (ptr != ptr1)
X {
X *(ptr++) = ' ';
X waddch(inp, ' ');
X }
X }
X else if ((c >= ' ') && (c < 0x7f)) /* otherwise if printable */
X {
X if ((ptr - entry) > 62) /* time for word wrap? */
X {
X *(ptr++) = c; /* don't lose latest char */
X *ptr = 0; /* terminate string */
X
X while (!isspace(*ptr)) /* find latest space */
X {
X if (--ptr == entry) /* special case - no spaces */
X {
X ptr += strlen(entry);
X *(ptr + 2) = 0;
X break;
X }
X }
X
X *(ptr++) = 0; /* change space to zero */
X sprintf(msgbuf, "m%s", entry);
X chc_send(msgbuf);
X strcpy(entry, ptr); /* change string to leftover */
X ptr = entry + strlen(entry);
X mvwprintw(inp, 1, 1, "%77s", ""); /* clear input box */
X mvwprintw(inp, 1, 1, "-> %s", entry); /* print string */
X }
X else
X waddch(inp, (*(ptr++) = c)); /* print character */
X }
X }
X }
X}
SHAR_EOF
chmod 0444 chat.c || echo "restore of chat.c fails"
if [ $TOUCH = can ]
then
touch -am 0820223590 chat.c
fi
fi
# ============= chatter.c ==============
if test -f chatter.c; then echo "File chatter.c exists"; else
echo "x - extracting chatter.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > chatter.c &&
X/*
X
Xchatter
Xserver process for multi-user chat
XWritten by D'Arcy J.M. Cain
XWest Hill, Ontario
Xdarcy at druid.UUCP
XAll rights reserved
X
XThis is the server for the chat program. It handles various
Xrequests and sends messages to the users of chat.
X
XPermission is hereby granted to freely copy and redistribute this
Xsoftware, provided that the author is clearly credited in all
Xcopies and derivations. This software is provided ``As Is'' and
Xwithout any express or implied warranties.
X
X*/
X
X#include <stdio.h>
X#include <signal.h>
X#include <string.h>
X#include <stdlib.h>
X#include <sys/types.h>
X#include <ctype.h>
X#include <errno.h>
X#include "chat.h"
X
Xchar chatter_rcsid[] = "$Id: chatter.c,v 1.1 90/08/19 19:03:46 darcy Exp $";
X
X#define MAX_CHATTERS 32
XCHATTER u[MAX_CHATTERS];
X
Xchar progname[64];
X
Xvoid cleanup(int sig) /* exit through here always */
X{
X ch_close();
X fprintf(stderr, "\nchatter exiting\n");
X exit(sig);
X}
X
X/* open message queue */
Xvoid init(void)
X{
X char *p;
X
X if ((p = ch_init()) != NULL)
X {
X fprintf(stderr, "%s: %s\n", progname, p);
X exit(1);
X }
X}
X
Xvoid main(int argc, char **argv)
X{
X int k, u_id;
X char ch, msgbuf[512], message[256];
X
X strcpy(progname, argv[0]);
X
X /* all trap everything to go through cleanup */
X signal(SIGINT, cleanup);
X signal(SIGABRT, cleanup);
X signal(SIGKILL, cleanup);
X signal(SIGTERM, cleanup);
X
X init();
X
X /* reset all channels */
X for (k = 0; k < MAX_CHATTERS; k++)
X u[k].channel = 0;
X
X for (;;) /* till the stars fall from the sky */
X {
X while ((u_id = ch_get(msgbuf)) == -1)
X ;
X
X if (u[u_id].channel == 0)
X u[u_id].channel = '0';
X
X ch = u[u_id].channel;
X
X switch (*msgbuf)
X {
X case 'o': /* open a chat channel */
X strcpy(u[u_id].logname, msgbuf + 1);
X sprintf(msgbuf, "[%-12.12s] Joining Chat", u[u_id].logname);
X
X /* advise the chat world of newcomer */
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u[k].channel)
X ch_send(msgbuf, k);
X
X break;
X
X
X case 'x': /* user exiting from chat */
X sprintf(msgbuf, "[%-12.12s] Leaving Chat", u[u_id].logname);
X
X /* check each user */
X for (k = 0; k < MAX_CHATTERS; k++)
X {
X if (k == u_id) /* this user */
X u[k].channel = 0;
X else if (u[k].channel) /* other user */
X if (u[k].channel == ch) /* same channel */
X ch_send(msgbuf, k);
X }
X
X ch_send(NULL, u_id); /* remove user from list */
X break;
X
X case 'c': /* change channel */
X if (isascii(msgbuf[1])) /* only allow ASCII */
X {
X if (msgbuf[1] == '*')
X {
X int c = '0';
X
X while (isascii(c))
X {
X if (c == '*')
X continue;
X
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u[k].channel == c)
X k = MAX_CHATTERS + 1;
X
X if (k == MAX_CHATTERS)
X {
X u[u_id].channel = c;
X sprintf(msgbuf,
X "[%-12.12s] switched to channel %c",
X u[u_id].logname, c);
X
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u[k].channel)
X ch_send(msgbuf, k);
X
X break;
X }
X
X c++;
X }
X
X break;
X }
X
X u[u_id].channel = msgbuf[1];
X sprintf(msgbuf, "[%-12.12s] switched to channel %c",
X u[u_id].logname, u[u_id].channel);
X
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u[k].channel)
X ch_send(msgbuf, k);
X }
X
X break;
X
X case 's': /* show users */
X for (k = 0; k < MAX_CHATTERS; k++)
X {
X if (u[k].channel)
X {
X sprintf(msgbuf, "[%-12.12s] is on channel %c",
X u[k].logname, u[k].channel);
X ch_send(msgbuf, u_id);
X }
X }
X
X break;
X
X case 'n': /* change user's display name */
X if (msgbuf[1])
X strcpy(u[u_id].logname, msgbuf + 1);
X break;
X
X case 'm': /* send a message */
X msgbuf[64] = 0;
X sprintf(message, "[%-12.12s] %s",
X u[u_id].logname, msgbuf + 1);
X
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u[k].channel == ch)
X ch_send(message, k);
X
X break;
X }
X }
X}
SHAR_EOF
chmod 0444 chatter.c || echo "restore of chatter.c fails"
if [ $TOUCH = can ]
then
touch -am 0820223590 chatter.c
fi
fi
# ============= chc_msg.c ==============
if test -f chc_msg.c; then echo "File chc_msg.c exists"; else
echo "x - extracting chc_msg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > chc_msg.c &&
X/*
Xchc_msg
X
Xsupport routines for chat client - message IPC version
XWritten by D'Arcy J.M. Cain
XWest Hill, Ontario
Xdarcy at druid.UUCP
XAll rights reserved
X
XThis module is linked with chat to implement a message based
Xversion of chat.
X
XPermission is hereby granted to freely copy and redistribute this
Xsoftware, provided that the author is clearly credited in all
Xcopies and derivations. This software is provided ``As Is'' and
Xwithout any express or implied warranties.
X
X*/
X
X#include <signal.h>
X#include <sys/ipc.h>
X#include <sys/msg.h>
X#include <string.h>
X#include <process.h>
X#include "chat.h"
X
Xchar chc_msg_rcsid[] = "$Id: chc_msg.c,v 1.1 90/08/19 19:03:55 darcy Exp $";
X
X#define KEY 0x63
X
Xstatic struct msgbuf sndbuf, rcvbuf;
Xstatic int q;
Xstatic long my_pid;
X
X#ifdef HALFDELAY_BROKEN
Xstatic void checker(int sig)
X{
X extern int chat_suspended;
X
X if (!chat_suspended)
X while (chk_q())
X ;
X
X sigset(SIGALRM, checker);
X alarm(2);
X}
X#endif
X
X/* open message queue */
Xchar *ch_init(void)
X{
X if ((q = msgget(KEY, 0666)) == -1)
X return("Can't open chat queue");
X
X#ifdef HALFDELAY_BROKEN
X checker(0); /* set up timer */
X#endif
X my_pid = getpid();
X return(NULL);
X}
X
Xint ch_close(void) /* exit through here always */
X{
X /* nothing to do in message IPC version */
X return(0);
X}
X
Xvoid chc_send(char *s) /* send message to chatter */
X{
X sndbuf.mtype = 1L;
X strcpy(sndbuf.mtext, s);
X msgsnd(q, &sndbuf, 256, 0);
X}
X
X/* don't block */
Xint ch_get(char *s)
X{
X if (msgrcv(q, &rcvbuf, 256, my_pid, IPC_NOWAIT) > 0)
X {
X strcpy(s, rcvbuf.mtext);
X return(1);
X }
X
X return(0);
X}
X
SHAR_EOF
chmod 0444 chc_msg.c || echo "restore of chc_msg.c fails"
if [ $TOUCH = can ]
then
touch -am 0820223590 chc_msg.c
fi
fi
# ============= chs_msg.c ==============
if test -f chs_msg.c; then echo "File chs_msg.c exists"; else
echo "x - extracting chs_msg.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > chs_msg.c &&
X/*
Xchs_msg
X
Xsupport routines for chatter - message IPC version
XWritten by D'Arcy J.M. Cain
XWest Hill, Ontario
Xdarcy at druid.UUCP
XAll rights reserved
X
XThis module is linked with chatter to implement a message IPC based
Xversion of chatter.
X
XPermission is hereby granted to freely copy and redistribute this
Xsoftware, provided that the author is clearly credited in all
Xcopies and derivations. This software is provided ``As Is'' and
Xwithout any express or implied warranties.
X
X*/
X
X#include <signal.h>
X#include <sys/ipc.h>
X#include <sys/msg.h>
X#include <string.h>
X#include "chat.h"
X
Xchar chs_msg_rcsid[] = "$Id: chs_msg.c,v 1.1 90/08/19 19:04:32 darcy Exp $";
X
X#define KEY 0x63
X
Xstatic struct msgbuf sndbuf, rcvbuf;
Xstatic struct msqid_ds msqid;
Xstatic int q;
X
Xstatic long u_pid[MAX_CHATTERS];
X
Xstatic int get_u(long i)
X{
X int k;
X
X for (k = 0; k < MAX_CHATTERS; k++)
X if (u_pid[k] == i)
X return(k);
X
X return(-1);
X}
X
X/* open message queue */
Xchar *ch_init(void)
X{
X if ((q = msgget(KEY, 0666 | IPC_CREAT)) == -1)
X return("Chat queue in use");
X
X return(NULL);
X}
X
Xint ch_close(void) /* exit through here always */
X{
X /* remove chat message queue */
X return(msgctl(q, IPC_RMID, NULL));
X}
X
Xvoid ch_send(char *s, int id) /* send message to user */
X{
X if (s == NULL)
X u_pid[id] = 0;
X else if (u_pid[id])
X {
X sndbuf.mtype = u_pid[id];
X strcpy(sndbuf.mtext, s);
X msgsnd(q, &sndbuf, 256, 0);
X }
X}
X
X/* block until a message is received */
Xint ch_get(char *s)
X{
X int u;
X
X /* check for dead process */
X for (u = 0; u < MAX_CHATTERS; u++)
X {
X if (u_pid[u])
X {
X if ((kill(u_pid[u], 0)) /* && (errno == ESRCH) */ )
X /* We shouldn't have to test */
X /* for ESRCH since that is */
X /* only theoretical return */
X {
X while (msgrcv(q, &rcvbuf, 256, u_pid[u], IPC_NOWAIT) != -1)
X ;
X
X /* simulate a close command */
X strcpy(s, "x");
X u_pid[u] = 0;
X return(u);
X }
X }
X }
X
X if (msgrcv(q, &rcvbuf, 256, 1L, 0) == -1)
X return(-1);
X
X /* set up various variables from message */
X strcpy(s, rcvbuf.mtext);
X msgctl(q, IPC_STAT, &msqid);
X
X if ((u = get_u(msqid.msg_lspid)) == -1)
X {
X if ((u = get_u(0L)) == -1)
X {
X strcpy(sndbuf.mtext, "e2 Chatter table full");
X sndbuf.mtype = msqid.msg_lspid;
X msgsnd(q, &sndbuf, 256, 0);
X return(-1);
X }
X else
X u_pid[u] = msqid.msg_lspid;
X }
X
X return(u);
X}
X
SHAR_EOF
chmod 0444 chs_msg.c || echo "restore of chs_msg.c fails"
if [ $TOUCH = can ]
then
touch -am 0820223590 chs_msg.c
fi
fi
# ============= lchat ==============
if test -f lchat; then echo "File lchat exists"; else
echo "x - extracting lchat (Text)"
sed 's/^X//' << 'SHAR_EOF' > lchat &&
X:
X# $Id: lchat,v 1.1 90/08/19 19:06:00 darcy Exp $
X# This script calls chat with some arguments. Set LOGFILE equal to
X# a log file to capture your session to. Set REALNAME to the name
X# to display on the output.
X
X# If a user's name is entered, chat is called via chatyell which
X# sends a message to the named user to run chat before running chat.
X
XLOGFILE=/usr/darcy/chat.log
XREALNAME="D'Arcy"
X
Xecho "\n`date`" >> $LOGFILE
X
Xif [ $# = 0 ]
Xthen
X chat -n $REALNAME -f $LOGFILE
Xelse
X chatyell $1 -n $REALNAME -f $LOGFILE $2 $3 $4 $5
Xfi
X
SHAR_EOF
chmod 0544 lchat || echo "restore of lchat fails"
if [ $TOUCH = can ]
then
touch -am 0820223690 lchat
fi
fi
# ============= chatyell ==============
if test -f chatyell; then echo "File chatyell exists"; else
echo "x - extracting chatyell (Text)"
sed 's/^X//' << 'SHAR_EOF' > chatyell &&
X:
X# chatyell tells someone to join the chat.
X# Written by D'Arcy J.M. Cain
X# $Id: chatyell,v 1.1 90/08/19 19:05:45 darcy Exp $
X
Xif [ $# -lt 1 ]
Xthen
X echo "Usage: chatyell user"
Xelse
X# The following test isn't perfect. If you want to chat
X# with user bill and he is not logged in but billy is then
X# the test shows bill as logged in. I'm sure there is a
X# really easy way to find out if someone is logged in but
X# I just don't happen to know it.
X if [ `who | awk "/$1/ {print \$1}" | wc -l` != 0 ]
X then
X write $1 <<- END_ECHO
X $LOGNAME wants to chat with you.
X Type chat at the prompt
X END_ECHO
X chat $2 $3 $4 $5 $6 $7 $8 $9
X else
X echo "$1 not currently logged on"
X fi
Xfi
SHAR_EOF
chmod 0555 chatyell || echo "restore of chatyell fails"
if [ $TOUCH = can ]
then
touch -am 0820223690 chatyell
fi
fi
# ============= chat.readme ==============
if test -f chat.readme; then echo "File chat.readme exists"; else
echo "x - extracting chat.readme (Text)"
sed 's/^X//' << 'SHAR_EOF' > chat.readme &&
Xchat
X====
X
XWritten by D'Arcy J.M. Cain 1990
X(darcy at cain)
XAll rights reserved
X
XPermission is hereby granted to freely copy and redistribute this
Xsoftware, provided that the author is clearly credited in all
Xcopies and derivations. This software is provided ``As Is'' and
Xwithout any express or implied warranties.
X
XChat allows more than one user on a system to be involved
Xin a conference via their terminal. It consists of a foreground
Xpart and a background part.
X
Xchatter is the background process. It looks for messages from
Xother processes and sends messages to them. It should be put into
Xinittab so that it always restarts.
X
Xchat is the front end and is the program run by users wishing to
Xjoin or start a chat. In chat, lines starting with / are commands.
Xenter /? or /h for a list of commands
X
XTo call chat simply enter chat from the command line. Various
Xoptions are available and are accessed by adding '-x' to the command
Xwhere x is one of the following letters:
X
Xh Displays a usage message instead of running the program.
Xn Takes the following name and uses it instead of login name.
Xf Takes the following file and keeps a log of the conversation in it.
X
XExample:
X
Xchat -n "D'Arcy" -f chat.log
X
XThis starts chat, sets up the name as D'Arcy, opens the file chat.log
Xand keeps a record of the chat in it. Note that the quotes around
XD'Arcy are only neccessary because of the apostrophe.
X
XThe n option can be set from within the program as well.
X
XMove chat.make to Makefile and run make to create the programs.
X
X
XChat Wish List:
X
XThese are a few things that I hope to add to chat later. If you can
Xthink of other enhancements please let me know.
X
X- A TLI version. I have made a small start on this but if anyone wants
X to give it a try, go ahead. Use the ???_msg.c files as models. You
X should be able to write ???_tli.c files that just link into the other
X files without changing them.
X
X- A monitor program. This is mostly a matter of deciding what it should
X do. One idea would be to print the name of the user any time there was
X any activity from the chatter. This could be monitored in any way one
X chooses. A simplistic method would be to run the monitor program in
X background and allow it to interupt the user each time there was any
X activity. Of course there are other possibilities. On my system, for
X example, I would put it in background and pipe it to a program that
X displays the name on the LED's on my front panel.
X
X
XEnjoy.
XD'Arcy J.M. Cain
X(darcy at druid)
X
SHAR_EOF
chmod 0444 chat.readme || echo "restore of chat.readme fails"
if [ $TOUCH = can ]
then
touch -am 0820223690 chat.readme
fi
fi
# ============= chat.make ==============
if test -f chat.make; then echo "File chat.make exists"; else
echo "x - extracting chat.make (Text)"
sed 's/^X//' << 'SHAR_EOF' > chat.make &&
X# Makefile for chat
X# Written by D'Arcy J.M. Cain
X# $Id: chat.make,v 1.1 90/08/21 10:40:17 darcy Exp $
X#
X
X# So far only message based method supported.
XMETHOD=msg
X
Xall: chat chatter
X
Xchatter: chatter.o chs_$(METHOD).o
X $(CC) $(CFLAGS) chatter.o chs_$(METHOD).o $(LDFLAGS) -o chatter
X
Xchat: chat.o chc_$(METHOD).o
X $(CC) $(CFLAGS) chat.o chc_$(METHOD).o $(LDFLAGS) -lcurses -o chat
X
Xchat.o: chat.c chat.h
X
Xchatter.o: chatter.c chat.h
X
Xchc_$(METHOD).o: chc_$(METHOD).c chat.h
X
Xchs_$(METHOD).o: chs_$(METHOD).c chat.h
SHAR_EOF
chmod 0444 chat.make || echo "restore of chat.make fails"
if [ $TOUCH = can ]
then
touch -am 0821104090 chat.make
fi
fi
exit 0
--
D'Arcy J.M. Cain (darcy at druid) |
D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay
West Hill, Ontario, Canada | of operating systems.
+ 416 281 6094 |
More information about the Alt.sources
mailing list