darcy@druid.uucp (D'Arcy J.M. Cain) (10/10/90)
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@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@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@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@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@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@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@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@druid) | D'Arcy Cain Consulting | MS-DOS: The Andrew Dice Clay West Hill, Ontario, Canada | of operating systems. + 416 281 6094 |
water@wheaton.UUCP (Paul Waterman) (10/12/90)
In article <1990Oct10.141259.11468@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes: >>from: darcy@druid.uucp (D'Arcy J.M. Cain) > >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. There's just one problem - chat.h isn't included in the shar. Chat would probably be easier to compile if we could get it too. - Paul -- .------------------------------------------------. Paul Waterman | But I thought you said STRAITjackets and ties! | water@wheaton.UUCP `------------------------------------------------' voice: (708) 260-5877
vreed@sandstorm.Berkeley.EDU (Vincent Reed) (10/23/90)
To: darcy@druid.uucp Subject: Re: Multi-user chat program Newsgroups: alt.sources In-Reply-To: <1990Oct10.141259.11468@druid.uucp> Organization: ucb Cc: Bcc: I grabbed your Multi-User Chat to use on our system, but we are missing a few of the header files necessary. Could you please send me your stdlib.h process.h and getopt.h header files? The copies of these we do have seem to be program specific. I'm posting this to the net because I was unable to get mail directly to you. THanx in Advance. VInce Reed vreed@ocf.berkeley.edu ucbvax!ocf!vreed
darcy@druid.uucp (D'Arcy J.M. Cain) (10/24/90)
In article <1990Oct22.172500.26286@agate.berkeley.edu> vreed@sandstorm.Berkeley.EDU (Vincent Reed) writes: >I grabbed your Multi-User Chat to use on our system, but we are missing a few >of the header files necessary. Could you please send me your stdlib.h process.h >and getopt.h header files? The copies of these we do have seem to be program >specific. I'm posting this to the net because I was unable to get mail >directly to you. > I assumed these were ANSI standard header files but except for stdlib.h I can't find mention of them in my K&R2. On my system, stdlib.h is just a link to unistd.h. That file is obviously OS specific so I try to avoid it. I can't send you a copy because it is copyright AT&T. Your best bet is to remove the include directive for this and see what prototypes you are missing. I would think that getopt.h would be obvious from the name but here it is: ------------------------- getopt.h ------------------------------- /* declarations for getopt */ #ifndef _GETOPT_H #define _GETOPT_H extern int getopt(int argc, char **argv, const char *opts); extern int optind, opterr; extern char *optarg; #endif ------------------------ end of getopt.h ---------------------------- The file process.h holds mainly prototypes fork() and exec() calls as well as wait(). I have built up this file from various files and although I have modified it to an unrecognizable form I hesitate to send out the whole thing. Here are the relevant prototypes: ---------------------------- process.h ------------------------------- /* process.h */ #ifndef _PROCESS_H #define _PROCESS_H int execlp(const char *path, const char *arg0, ...); int fork(void); int getpid(void); int system(const char *command); int wait(int *stat_loc); #endif --------------------------- end of process.h ------------------------- Was I wrong to assume that these files would be available under a standard compiler? BTW: This belongs in alt.sources.d where followups are directed. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | I support gun control. West Hill, Ontario, Canada | Let's start with the government! + 416 281 6094 |
dilvish@anasaz.UUCP (Dilvish the Damned) (10/24/90)
Could someone please mail me the entire multi-user chat program. It appears I missed it when I was on vacation and we can't ftp from here (sigh). Thanks Dilvish You can mail me at: {asuvax,mcdphx}!anasaz!usp1!dilvish
nab1@rosemary.cs.reading.ac.uk (The Phoenix) (10/24/90)
vreed@sandstorm.Berkeley.EDU (Vincent Reed) writes: >I grabbed your Multi-User Chat to use on our system, but we are missing a few >of the header files necessary. Could you please send me your stdlib.h process.h >and getopt.h header files? The copies of these we do have seem to be program >specific. I'm posting this to the net because I was unable to get mail >directly to you. ... ditto. Maybe you could post them...? - Phoenix ============================= F.N.X ======================================= The Phoenix |These are the voyages of the starship ENTERPRISE, its continuing nab1@csug.cs. |mission: to explore strange, new worlds, to seek out new life & reading.ac.uk|new civilisations; to baldly go where noone has gone before ... ============================= F.N.X ======================================= The Phoenix |These are the voyages of the starship ENTERPRISE, its continuing nab1@csug.cs. |mission: to explore strange, new worlds, to seek out new life & reading.ac.uk|new civilisations; to baldly go where noone has gone before ...
mra@srchtec.UUCP (Michael Almond) (10/25/90)
In article <3091@anasaz.UUCP> dilvish@anasaz.UUCP (Dilvish the Damned) writes: >Could someone please mail me the entire multi-user chat program. It appears >I missed it when I was on vacation and we can't ftp from here (sigh). I'm missing the chat.h file. I tried mailing a message to the original poster/ author of chat, but it bounced. I'm not sure what else I might be missing. Maybe a repost is in order? Thanks. --- Michael R. Almond mra@srchtec.uucp (registered) search technology, inc. emory!stiatl!srchtec!mra Atlanta, Georgia (404) 441-1457 (office) .'.'.'.'.'.'.'.'.'.'.'.'.'. Georgia Tech Alumnus .'.'.'.'.'.'.'.'.'.'.'.'.'.'.'.
darcy@druid.uucp (D'Arcy J.M. Cain) (10/27/90)
In article <286@srchtec.UUCP> mra@srchtec.UUCP (Michael Almond) writes: >In article <3091@anasaz.UUCP> dilvish@anasaz.UUCP (Dilvish the Damned) writes: >>Could someone please mail me the entire multi-user chat program. It appears >>I missed it when I was on vacation and we can't ftp from here (sigh). > >I'm missing the chat.h file. I tried mailing a message to the original poster/ >author of chat, but it bounced. I'm not sure what else I might be missing. > >Maybe a repost is in order? > OK. I want to clean up a few things and then I will repost it. -- D'Arcy J.M. Cain (darcy@druid) | D'Arcy Cain Consulting | I support gun control. West Hill, Ontario, Canada | Let's start with the government! + 416 281 6094 |