[alt.sources] Here it is -- CHAT V1.7

karl@ddsw1.UUCP (Karl Denninger) (12/15/87)

By popular demand....

Here it is -- System V Chat (this is shareware, hit 'n' now if offended with
this; and no flames please!).

It's been checked out and works on Xenix and Microport (Xenix requires some
hacks since there is no 'inittab').

You know what to do with this.... there is a README file...


#!/bin/sh
# shar:	Shell Archiver
#	Run the following text with /bin/sh to create:
#	Makefile
#	README
#	chat.1
#	chat.h
#	client.c
#	decl.h
#	funcs.c
#	server.c
sed 's/^X//' << 'SHAR_EOF' > Makefile
X#
X# Makefile for Chat 
X#
X# See the README file -- this should be ok for most users.
X#
X
XCC=cc
XCFLAGS= -g  
XLDFLAGS= -g -o
XINC_DEP=/usr/include/stdio.h\
X	/usr/include/sys/types.h\
X	/usr/include/sys/stat.h\
X	/usr/include/fcntl.h\
X	/usr/include/signal.h\
X	/usr/include/setjmp.h\
X	/usr/include/pwd.h\
X	/usr/include/termio.h\
X	/usr/include/sys/file.h\
X	/usr/include/memory.h\
X	chat.h\
X	decl.h
XFILES=	client.o\
X	funcs.o
X
Xall: chat comserver
X
Xchat: $(INC_DEP) $(FILES)
X	$(CC) $(FILES) $(LDFLAGS) chat
X
Xcomserver: $(INC_DEP) server.o funcs.o
X	$(CC) server.o funcs.o $(LDFLAGS) comserver 
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > README
X
X******************************************************************
X
X		CHAT	- Multiuser chat program
X
X******************************************************************
X
X
XPlease read this entire file through before attempting to install 'CHAT'.
XThis file contains important information about the package, installation,
Xand other programs available from MCS.
X
X
XCHAT is a product of and Copyright 1987 by Macro Computer Solutions, Inc.
X
XThis package is distributed under what is known as the 'Shareware' concept. 
X
XShareware is a concept where software authors make programs available to the
Xpublic at no direct cost.  The user sometimes receives source code, more
Xoften not.  The authors request that if you find the software useful and 
Xin fact do use it, that you make a small contribution to them for their
Xefforts.  This contribution is voluntary (no police will call on you if you
Xfail to help out).  Of course, your conscience will haunt you for the rest
Xof your life!  Helping us and others like us out in this endeavor will
Xinsure a continuing flow of software like this!
X
XThe suggested donation for this package is $29.00 per executing CPU.  In 
Xreturn for your donation, your name will be added to an electronic mailing 
Xlist -- and you will receive, via email, notices of updates and improvements 
Xwhich you may obtain from us at no additional cost.  Please mail your 
Xdonations to:
X
X		Macro Computer Solutions, Inc.
X		415 S.E. Garfield
X		Mundelein, IL  60060
X		Attn: Chat Shareware
X
X		Make sure to include a path for Email from ihnp4.
X		Confirmation of your contribution will be returned via
X		Email in order to check the path back to you. 
X
X
XYou are encouraged to copy, distribute, give away, port, and otherwise make
Xavailable this software to others, providing that you follow these rules:
X	
X	1) You provide the entire 'shar' file or the complete contents
X	   thereof, including this file.  It is permissible to include 
X	   ported versions or other modifications to others as well.
X	2) You retain our notice(s) on the package, if any are present.
X	3) You acknowledge that this software is freely available 
X	   at no charge from other sources if you should charge a
X	   distribution or media fee.
X
XIt is permissible to charge a copying fee for including CHAT on a
Xdistribution tape or other media, but you should contact MCS if you have 
Xany questions regarding the reasonableness of your actions.
X
X
XPORTING and INSTALLATION
X========================
X
XYou absolutely need NAMED PIPES (System III and later)
X
XYou will need:
X
X	1) A group you can use for CHAT, with access to a directory.
X	2) Root access.
X
XEdit 'chat.h'.  Specifically, you need to indicate where you want the files
Xbuilt.  This is specified as 'CHATDIR'.
X
XEdit the Makefile if you want, it's probably ok for most people.
X
XType 'make' (cross fingers, pray, etc.).
X
XCopy 'comserver' to a public directory, make it SGID your group, executable
Xby 'root' and the group only.
X
XCopy 'chat' to a public directory, make it SGID your group, executable by world.
X
XCopy (and optionally format with nroff -man) the manual page (chat.1)
X
XOk, now, the tricky part.  You need to add 'comserver' to 'inittab', as if
Xit was a 'getty'.  What you want, for System V machines, is:
X
Xx0:234:respawn:/u/lbin/comserver >/dev/null 2>&1
X
Xsomewhere in your 'inittab' file.  If you are not on System V, get it to run
X(and re-submit when it dies) somehow, a script file running off the startup
Xfiles is ok, just as long as 'comserver' can restart -- it will die and
Xrestart (intentionally) every time the *last* person in a chat leaves.
X
XWith this in place, and an 'init q' typed to sync things, you should be in
Xbusiness.  Type 'chat' and verify that it works as expected.  You should see
Xa message indicating 'Connection' to the server, then a 'welcome' message.
X
XNote that the capacity of this version is 15 users, which is due to the
Xopen-file limit and rather sparse, but high-performance approach to the
Xproblem.  For most small systems this is not an important limitation.  Users
Xwill be notified if 'chat' if currently full, and asked to try later.
X
XThe pipe files from the server are set to NDELAY.  This will keep the
Xserver from hanging if a user should shell escape for a while or otherwise
Xnot be reading his/her end of the pipe.  Note that the user who has stopped
Xtheir copy of 'chat' can and will lost responses in this circumstance, but 
Xno other harm should occur.  As the capacity of a pipe is at least 4096
Xcharacters, you would need to be gone for quite a while (about 100 lines
Xworth) before this becomes a concern.
X
XProblems, corrections, enhancements, etc. welcome!
X
X
X
X
XCHAT is a part of our multi-user conferencing solution for Unix.  If you are
Xinterested in the remainder of what we have to offer, including menuing, 
Xa multisite conferencing system, and new user registration, please contact 
XMCS using the information below.  These other packages are available
Xcommercially in both source and binary format, and in general will run on
Xmost System V machines.  The complete system can be seen by dialing one of
Xthe modem numbers below, public access is available to all 24 hours a day.
X
X
X
XThanks -- and enjoy!
X
XKarl Denninger
XMacro Computer Solutions, Inc.
X	
X...ihnp4!ddsw1!karl
XVoice: (312) 566-8910
XModem: (312) 566-8909, (312) 566-8911, or (312) 566-8912
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > chat.1
X.TH CHAT 1 "Macro Computer Solutions"
X.SH NAME
Xchat \- Chat in real-time with other users
X.SH SYNOPSIS
X.B chat
X.SH DESCRIPTION
X.I Chat
Xis a advanced server-based program utilizing named pipes to provide simple
Xyet effective communication between multiple users.  The chat system can
Xaccomodate up to 15 simultaneous users communicating at one time.
X
XWhen you enter CHAT, you are 'on the air' with the other users who are
Xrunning CHAT.  Chat is always willing to accept a line of input from you
Xwhich is either (1) a shell escape, (2) a command to CHAT, or (3) a line of
Xtext to show to everyone else.
X
XAny line beginning with "!" is a shell escape, and the remainder of the line
Xwill be passed to the shell for interpretation.
X
XA line beginning with "/" is a command.  The following commands are known to
Xthe CHAT program:
X
X/?	\- Get assistance.  This shows you the internal help for CHAT.
X
X/e	\- Toggle echo.  Controls the echo of lines to your screen.
X
X/k	\- Kills a user in CHAT.  Should be used with discretion.
X
X/n	\- Set aliased name - changes your name in CHAT.
X
X/p	\- Sends a private message to another user in CHAT.
X
X/s	\- Shows CHAT status and logged in users
X
X/t	\- Sends a message to any logged in user.
X
X/w	\- Same as /s
X
X/h	\- Same as /?
X
X.sp 1
XSpecial characters:
X.sp 1
X<CTRL>X and <CTRL>U	\- Delete current line, display [Cancelled].
X
X<CTRL>H			\- Backspace.
X
XA line which does not begin with either of these two characters is
Xconsidered a data line and is sent to all the other connected terminals.
XAll lines wrap at 68 characters.  If you are using a command such as '/p' or
X'/t', the prefix will be kept 'sticky' so you can send multi-line private
Xmessages without worrying about the line breaks.
X
X.SH SECURITY
X
XCHAT uses named pipes for all data transmission, thus, there is no record of
Xthe conversation kept inside of CHAT.  Users who wish to record their
Xconversations in CHAT are on their own.
X
XIn general, you can consider messages passed via '/p' secure.  '/t' uses a
Xsystem command and as such is a less secure method of passing sensitive
Xinformation between users.
X
XThe /k command can be restricted if the Site Administrator desires.
XGenerally speaking, misuse of this command will prompt most administrators
Xto restrict it's use.  Users should keep use of this command to emergencies
Xand genuine need.
X
XIn it's current form, it is impossible for a user to mask who he/she really
Xis.  It is possible, however, for a user to deliberately confuse the issue
Xby adopting another's name, etc... The offender will be obvious on a status
Xdisplay.
X
X.SH COPYRIGHT
X
XCHAT is Copyrighted 1987 by Macro Computer Solutions, Inc. and available 
Xto the public as a 'sharware' program.
X
XThe suggested donation for this package is $29.00 per executing CPU.
X
XCHAT may be freely redistributed providing:
X
XYou clearly state that this code is available at no cost from other sources.
XYou provide the entire contents of the original SHAR file.
XYou retain any copyright or other notices on the package.
X
XIf you wish to include this source or object derived from this source on a
Xtape archive of several programs, or otherwise distribute it as a part of a
Xcollection, please let us know so we can keep you current with the latest
Xversions and information!
X
X.SH AUTHOR
X
XCreated September 1987 at Macro Computer Solutions, Inc.
X.sp 1
X415 S.E. Garfield
X.sp 1
XMundelein, IL  60060
X.sp 1
X+1 312 566-8910
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > chat.h
X/*	chat.h	- include file of definitions for chat */
X
X#include	<stdio.h>
X#include	<fcntl.h>
X#include	<errno.h>
X#include	<signal.h>
X#include	<string.h>
X#include	<pwd.h>
X#include	<sys/types.h>
X#include	<sys/utsname.h>
X#include	<sys/stat.h>
X#include	<memory.h>
X#include	<time.h>
X#include	<termio.h>
X#include	<utmp.h>
X
X#define	CHATDIR	"/u/guest/bbs/"		/* Base chat directory */
X#define	LINESIZ		132		/* Line size */
X
X/* System declarations (why the system cannot include these...) */
X
Xextern 	long 	time();			/* System should declare this! */
Xextern 	struct 	passwd *getpwuid();	/* Declare passwd lookup function */
Xextern	char	*malloc();		/* Memory allocation	*/
Xextern	char	*getenv();		/* Environment get */
Xextern	long	lseek();		/* Lseek returns long */
X
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > client.c
X/*	Client party program	*/
X
X#include	"chat.h"
X#include	"decl.h"
X
Xchar	filen[132];
Xint	echo = 0;
Xstruct	termio	oldbuf, tbuf;
X
Xgetline(line)
Xchar	*line;
X
X{
X
X	int	ch;
X	int	x, y;
X	int	flags;
X	int	index = 1;
X	static	char	line2[80] = {0};
X	char	tmpx[80], tmpy[80];
X
X	if (strlen(line2) != 0) {
X		printf("> %s", line2);
X		fflush(stdout);
X		strcpy(line, line2);
X		index = strlen(line2);
X		line2[0] = 0;
X		goto readmore;
X	}
X	alarm(1);
X	if ((ch = getchar()) == EOF)  {
X		alarm(0);
X		return(0);
X	}
X	if ((ch == 24) || (ch == 21)) {
X		puts("\n[Cancelled]");
X		alarm(0);
X		return(0);
X	}
X	if ((ch == 13) || (ch == 10)) return(0);
X	if ((ch < 32) || (ch > 126)) return(0);
X	line2[0] = 0;
X	line[0] = ch;
X	if (echo == 0) {
X		printf("> %c",ch);
X		fflush(stdout);
X	}
X
Xreadmore:;
X
X	alarm(30);				/* 30 seconds on the line */
X	x = 0;
X	while (index < 68) {			/* We get up to 68 chars */
X		if (index != 0) x = -1; else x = 0;
X		ch = getchar();			/* Get one */
X		if (ch == EOF) {		/* If EOF.... */
X			line[index] = 0;
X			puts("");
X			x = 0;
X			break;
X		}
X		if ((ch == 24) || (ch == 21)) {	/* Cancel request... */
X			puts("\n[Cancelled]");
X			alarm(0);
X			return(0);
X		}
X		if ((ch == 13) || (ch == 10)) {	/* End of line */
X			line[index] = 0;
X			if (echo == 0) puts("");
X			alarm(0);
X			if (index == 0) return(0);
X			return(-1);
X		}
X		if (ch == 8) {			/* Backspace */
X			if (index > 0) {	/* Do if anything here */
X				if (echo == 0) {
X					putchar(ch);
X					putchar(32);
X					putchar(ch);
X					fflush(stdout);
X				}
X				index--;
X			}
X			continue;
X		}
X		if ((ch < 32) || (ch > 126)) continue;	/* Do nothing */
X		line[index++] = ch;		/* Add the character */
X		if (echo == 0) {
X			putchar(ch);
X			fflush(stdout);
X		}
X	}					/* Falling off end... */
X	x = -1;					/* Init return code */
X	if (index == 68) {			/* Look for break location */
X		index--;
X		y = line[index--];		/* Get last character */
X		while ((index > 0) && (y != ' ')) {	/* Find last space */
X			if (echo == 0) {		/* Do we echo?? */
X				putchar(8);
X				putchar(32);		/* Cover thy spaces! */
X				putchar(8);
X			}
X			y = line[index--];		/* Check next back */
X		}
X		if (index == 0) return(-1);		/* No break, send it */
X		index++;				/* Break at next */
X		line[index] = 0;			/* Store break */
X		ch = line[1];
X		if (ch >= 'a') ch = tolower(ch);	/* Make lower case */
X		if ((line[0] == '/') && ((ch == 'p') || (ch == 't'))) {
X			sprintf(tmpx, "%s", &line[2]);
X			sscanf(tmpx, " %[!-~]", tmpy);	/* Get name */
X			strncpy(line2, line, 2);
X			line2[2] = 0;
X			strcat(line2, tmpy);		/* Add name */
X			strcat(line2, " ");
X			strcat(line2, &line[index + 1]);
X		} else 
X			strcpy(line2, &line[index + 1]);/* Copy rest.. */
X		x = strlen(line2);			/* Get length */
X		if (x == 0) x = -1;			/* Return length */
X		if (echo == 0) puts("");		/* New line */
X	}
X	alarm(0);					/* No alarms please */
X	return(x);					/* Exit w/status */
X}
X
X/*	And here we find a variety of signal catching routines.
X
X	catch() exists only to satisfy the alarm call requirements.
X
X	The rest are exits of various kinds, some forced by external
X	circumstances, others requested by either the daemon or the user.
X
X*/
X
Xcatch()
X{
X	signal(SIGALRM, catch);
X	return;
X}
X
Xservdied()
X{
X	puts("[Communications Server disconnect]");
X	die1();
X}
X
Xsamename()
X{
X	puts("Only one chat per user id allowed!");
X	die1();
X}
X
Xtoss()
X{
X	puts("You have been blown out of chat by another user!");
X	die1();
X}
X
Xfull()
X{
X	puts("Chat is full, please try later");
X	die1();
X}
X
Xdie1()
X{
X	puts("Bye-bye");
X	unlink(filen);
X	ioctl(0,TCSETAW,&oldbuf);
X	exit(0);
X}
X
X/*	This is it... not many comments, but then again this is
X	pretty simple code... Shouldn't be hard to understand..
X
X*/
X
Xmain()
X{
X	char	temp[132];
X	char	line[132], line2[132];
X	char	victim[20], msg[80];
X	int	out;
X	int	cp;
X	FILE	*ttynq;
X	int	fid, wr;
X	char	key;
X	int	x;
X	struct	passwd	*psw;
X	struct utmp *ptr, *user, *getutent();
X	char	name[20];
X	char	cmd[5];
X
X	umask(0117);
X	psw = getpwuid(getuid());
X	strcpy(name, psw->pw_name);
X	printf("Welcome to Chat V1.7, %s\n", name);
X	puts("Type /h for help");
X	puts("");
X	strcpy(cmd,"w");			/* Base command */
X	signal(SIGALRM,catch);
X	signal(SIGQUIT, toss);
X	signal(SIGINT, die1);			/* Catch signals */
X	signal(SIGUSR1, full);
X	signal(SIGUSR2, samename);
X	signal(SIGPIPE, servdied);
X	out = 0;
X	strcpy(line, CHATDIR);
X	strcat(line, "pipe");
X	strcpy(temp, "mknod ");			/* Make me a pipe! */
X	strcat(temp, line);
X	strcat(temp, itoa(getpid()));
X	strcat(temp, " p");
X	if (system(temp) != 0) {
X		puts("Pipe failure!");
X		exit();
X	}
X	ioctl(0,TCGETA,&tbuf);
X	ioctl(0,TCGETA,&oldbuf);
X	tbuf.c_lflag &= ~(ICANON|ECHO|ISIG);
X	tbuf.c_cc[4] = 1;			/* CBREAK mode */
X	tbuf.c_cc[5] = 1;
X	ioctl(0,TCSETAW,&tbuf);
X	strcpy(temp, CHATDIR);
X	strcat(temp, "pipe");
X	strcat(temp, itoa(getpid()));
X	strcpy(filen, temp);
X	if ((wr = open(line, O_WRONLY|O_NDELAY)) == -1) {
X		puts("I can't find the Communications Server... Please try later.");
X		ioctl(0,TCSETAW,&oldbuf);
X		exit(1);
X	}
X	sprintf(line, "%d o %s >%s\n", getpid(), name, name);
X	write(wr, line, LINESIZ);		/* Write one buffer. */
X	alarm(10);
X	fid = 0;				/* Make pipe id impossible */
X	fid = open(temp, O_RDONLY);		/* Open pipe for reading */
X	if (fid <= 0) {
X		puts("The server seems to have died...");
X		ioctl(0,TCSETAW,&oldbuf);	/* Leave if no server */
X		exit(1);
X	}
X	setgid(getgid());			/* Turn off permissions */
X	setuid(getuid());			/* We have the files open */
X	alarm(0);				/* Cancel outstanding alarm */
X	sprintf(temp, "%d %s %s >%s\n",getpid(), "s", name, "test");
X	write(wr, temp, LINESIZ);
X	while (out == 0) {			/* While still scanning */
X		alarm(1);			/* Interrupt in one second */
X		while (read(fid, temp, LINESIZ) == LINESIZ) {
X			stripj(temp);		/* Read/print while available */
X			puts(temp);		/* Get next line */
X			alarm(1);		/* Reset alarm */
X		}
X		if (getline(line) != 0) {	/* Did we get user input? */
X			if (*line == '!') {	/* Shell escape */
X				ioctl(0,TCSETAW,&oldbuf);
X				alarm(0);	/* Turn off alarm(s)	*/
X				system(&line[1]);	/* Protected below... */
X				while ((wait() != -1) || (errno != ECHILD));;
X				ioctl(0,TCSETAW,&tbuf);
X				puts("!");
X				continue;
X			}
X			if (*line == '/') {	/* Command request... */
X				switch(line[1]) {
X					case '?':
X					case 'h':	/* Help */
X					case 'H':
X						puts("System V Chat V1.7");
X						puts("Copyright 1987 MCS/Karl Denninger");
X						puts("Not-for-profit distribution authorized\n");
X						puts("!cmd - Execute Unix command");
X						puts("/?   - Same as (help)");
X						puts("/e   - Echo (toggle)");
X						puts("/h   - Print this help");
X						puts("/k   - Kill a chatting user");
X						puts("/n   - Set aliased name");
X						puts("/p   - Send a private msg");
X						puts("/q   - Quit chatting");
X						puts("/s   - Show system and chat users");
X						puts("/t   - Tell a user something");
X						puts("/w   - Equivalent to /s");
X						puts("\nControl chars: CTRL-X = cancel line");
X						puts("               CTRL-H = backspace\n");
X						puts("To enter a response just type\n");
X						break;
X					case 'n':
X					case 'N':
X						if (sscanf(&line[2], " %[!-~ ]", victim) == 1) {
X							sprintf(temp, "%d n %s >%s\n", getpid(), name, victim);
X							write(wr, temp, LINESIZ);
X						} else puts("Requires alias");
X						break;
X					case 'p':	/* Private message */
X					case 'P':
X						if (sscanf(&line[2], " %s %[!-~ ]", victim, msg) == 2) {
X							sprintf(temp, "%d %s %s >%s\n",getpid(), "p", victim, msg);
X							write(wr, temp, LINESIZ);
X						} else puts("Requires user and message");
X						break;
X					case 'q':	/* Exit from CHAT */
X					case 'Q':
X						sprintf(temp, "%d q %s >%s\n",getpid(), name, "[Departed from chat]");
X						write(wr, temp, LINESIZ);
X						ioctl(0,TCSETAW,&oldbuf);
X						die1();
X						break;
X					case 'e':	/* Echo toggle */
X					case 'E':		
X						if (echo == 1) {
X							puts("Echo on");
X							echo = 0;
X						} else {
X							echo = 1;
X							puts("Echo off");
X						}
X						break;
X					case 't':	/* Tell someone */
X					case 'T':
X						if (sscanf(&line[2], " %s %[!-~ 	]",victim, msg) < 2) {
X							puts("Requires victim and message");
X							break;
X						}
X						x = 0;
X						setutent();	/* Find user */
X						while ((ptr = getutent()) != NULL)   {
X							if (strncmp(ptr->ut_user, victim, (strlen (victim) -1)) == 0)   {
X								user = ptr;
X								x = 1;
X								break;
X							}
X						}
X						if ( !x)   {
X							printf ("User is not logged on\n");
X							break;
X						}
X						strcpy (temp, "/dev/");
X						strcat (temp, user->ut_line);
X						alarm(10);
X						if ((ttynq = fopen (temp, "w")) == NULL)   {
X							printf ("User %s has disabled writes\n", user->ut_user);
X						} else {
X							fclose (ttynq);
X							printf ("Sending to %s: %s\n", victim, msg);
X							fflush (stdout);
X							strcpy (temp, "echo \"\n;;From ");
X							strcat (temp, name);
X							strcat (temp, ": ");
X							strcat (temp, msg);
X							strcat (temp, " \" >/dev/");
X							strcat (temp, user->ut_line);
X							alarm(10);
X							system (temp);
X						}
X						alarm(0);
X						break;
X					case 'k':	/* Request kill */
X					case 'K':
X						sprintf(temp, "%d %s %s >%s\n",getpid(), "k", &line[2], "test");
X						write(wr, temp, LINESIZ);
X						break;
X					case 'w':	/* Show who is here */
X					case 's':
X					case 'W':
X					case 'S':
X						system("who");
X						puts("");
X						sprintf(temp, "%d %s %s >%s\n",getpid(), "s", name, "test");
X						write(wr, temp, LINESIZ);
X						break;
X					default:	/* Bad command */
X						puts("Unknown command, try '/h'");
X				}
X			} else {		/* Otherwise send the line */
X				sprintf(temp, "%d %s %s >%s\n", getpid(), cmd, name, line);
X				write(wr, temp, LINESIZ);
X			}
X		}
X	}
X}
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > decl.h
X
X/* Our functions used here */
X
Xextern	char	*itoa();
Xextern	long 	getsize();
Xextern 	char 	*capitalize();
Xextern 	void 	openfile();
Xextern	FILE	*popen();
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > funcs.c
X/*	functions!		*/
X
X#include	"chat.h"
X
X
X/*	Itoa		- convert integer to ascii */
Xchar	*itoa(number)
Xint	number;
X{
Xstatic	char	temp[11];
Xint	x;
X	
X	for (x=0; x<9; x++) temp[x]=0;
X	do {
X		temp[x] = (number % 10) + 48;		/* Place character.. */
X		number = number / 10;
X		x--;
X	} while (number != 0);
X	temp[10]=0; x++;
X	return((char *) &temp[x]);
X}
X
Xkill_mask(file, mask, string)
Xchar	*file;
Xchar	*mask;
Xchar	*string;
X{
X
X	FILE	*fid1, *fid2;
X	char	temp[80];
X	int	deleted = 0;
X	char	test[80];
X
X	if ((fid1=fopen(file, "r")) == NULL) {
X		die("Cannot open file for killstring");
X	}
X	unlink(file);
X	if ((fid2=fopen(file, "w")) == NULL) {
X		die("Oh crap -- lost original file!!");
X	}
X	while (fgets(temp, 80, fid1) != NULL) {
X		stripj(temp);
X		if (sscanf(temp, mask, test) == 1) {
X			if (strcmp(test, string) != 0) {
X				fputs(temp, fid2);
X				fputc(10, fid2);
X			} else deleted++;
X		} else puts("Gack!  Invalid file format - groking file!");
X	}
X	fclose(fid1);
X	fclose(fid2);
X	return(deleted);
X}
X
Xkillstring(file, mask)
Xchar	*file;
Xchar	*mask;
X{
X
X	FILE	*fid1, *fid2;
X	char	temp[80];
X	int	deleted = 0;
X	char	test[80];
X
X	if ((fid1=fopen(file, "r")) == NULL) {
X		die("Cannot open file for killstring");
X	}
X	unlink(file);
X	if ((fid2=fopen(file, "w")) == NULL) {
X		die("Oh crap -- lost original file!!");
X	}
X	while (fgets(temp, 80, fid1) != NULL) {
X		stripj(temp);
X		if (strcmp(temp, mask) != 0) {
X			fputs(temp, fid2);
X			fputc(10, fid2);
X		}
X		else
X			deleted++;
X	}
X	fclose(fid1);
X	fclose(fid2);
X	return(deleted);
X}
X
Xtlc(line)
Xchar	*line;
X{
Xint	x=0, y;
X
X	for (x=0;x <= 80;x++) {
X		y = *(line+x);
X		if (y == 0) break;
X		if ((y > 63) && (y < 91)) *(line+x) = y + 32;
X	}
X	return;
X}
X
Xdie(line)
Xchar	*line;
X
X{
X	printf("%s\n", line);
X	exit(1);
X}
X
X
X/*	Stripj	- strip line of ^j's...	*/
Xstripj(ptr)
Xchar	*ptr;
X{
Xint	x;
X	
X	for (x=0; x < 80; x++) {
X		if (*(ptr+x) == 10) *(ptr+x) = 0;
X		if ((*(ptr+x) <= 31) && (*(ptr+x) != 0)) *(ptr+x) = 32;
X		if (*(ptr+x) > 126) *(ptr+x) = 32;
X	}
X	return;
X}
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > server.c
X/*	Server.c	- server process */
X
X#include	"chat.h"
X#include	"decl.h"
X
Xstruct	termio	tbuf, oldbuf;
X
Xdie1()
X{
X	exit(1);
X}
X
Xmain()
X{
X	
X	FILE	*fid2;
X	char	temp[132];
X	char	savename[21];
X	char	names[400];
X	char	alias[400];
X	int	pids[20];
X	int	fids[20], fid;
X	int	count = 0;
X	char	cmd[5];
X	char	name[40], nm[40];
X	char	msg[132];
X	int	pid;
X	char	tmp[132];
X	int	x, y, z, out;
X	int	keep = 0;
X
X	puts("[Comserver V1.7]");
X	strcpy(tmp, "mknod ");
X	strcat(tmp, CHATDIR);
X	strcat(tmp, "pipe p");
X	system(tmp);
X	strcpy(tmp, CHATDIR);
X	strcat(tmp, "pipe");
X	chown(tmp, geteuid(), getegid());
X	chmod(tmp, 0660);
X	fid = open(tmp, O_RDONLY);
X	while (read(fid, tmp, LINESIZ) == LINESIZ) {
X	strcpy(temp, tmp);
X	signal(SIGPIPE,SIG_IGN);		/* Ignore writes on pipes */
X	if (sscanf(temp, " %d %s %s >%[!-~ 	]",&pid,cmd,name,msg) >= 2) {
X		puts(temp);
X		switch (*cmd) {
X			case 'k':		/* Kill user */
X				x = 0;
X				while (x < count) {
X					if (pids[x] == pid) {
X						out = fids[x];
X						break;
X					}
X					x++;
X				}
X				strcpy(tmp, CHATDIR);
X				strcat(tmp, "CHAT.sus");
X				y = 0;			/* Flag no match */
X				if ((fid2 = fopen(tmp, "r")) != NULL) {
X					while (fgets(tmp, 20, fid2) != NULL) {
X						stripj(tmp);
X						if (strcmp(tmp, &names[x*20]) == 0) {
X							y++;
X							break;
X						}
X					}
X					fclose(fid2);
X					if (y == 0) {
X						sprintf(tmp, "[Comserver]: Insufficient privilege\n");
X						write(out, tmp, LINESIZ);
X						break;
X					}
X				}
X				x = 0;
X				while (x < count) {
X					if (strcmp(&names[x*20], name) == 0) {
X						kill(pids[x], SIGQUIT);
X						sprintf(tmp, "[Comserver]: Killed %s\n", name);
X						write(out, tmp, LINESIZ);
X						y = x;
X						strcpy(tmp, CHATDIR);
X						strcat(tmp, "pipe");
X						strcat(tmp, itoa(pids[x]));
X						unlink(tmp);
X						break;
X					}
X					x++;
X				}
X				if (x == count) {
X					sprintf(tmp, "No user: %s\n", name);
X					write(out, tmp, LINESIZ);
X				}
X				break;
X			case 'p':		/* Send private message */
X				x = 0;
X				while (x < count) {
X					if (pids[x] == pid) {
X						strcpy(tmp, &names[20*x]);
X						out = fids[x];
X						break;
X					}
X					x++;
X				}
X				x = 0;
X				while (x < count) {
X					if (strcmp(&names[x*20], name) == 0) {
X						sprintf(temp, "Prv from [%s]: %s\n", tmp, msg);
X						write(fids[x], temp, LINESIZ);
X						sprintf(tmp, "Prv sent to %s\n", name);
X						write(out, tmp, LINESIZ);
X						break;
X					}
X					x++;
X				}
X				if (x == count) {
X					sprintf(temp, "User not in chat: %s\n", name);
X					write(out, temp, LINESIZ);
X				}
X				break;
X			case 's':		/* Request for status */
X				x = 0;
X				printf("Send status to %d\n",pid);
X				while (x < count)  {
X					printf("Pid: %d and %d\n", pids[x], pid);
X					if (pids[x] == pid) {
X						y = fids[x];
X						break;
X					}
X					x++;
X				}
X				if (x == count) break;	/* Invalid */
X				x = 0;
X				printf("Sending via fid %d\n",y);
X				sprintf(tmp, "Users (Alias)");
X				write(y, tmp, LINESIZ);
X				while (x < count) {
X					if (strcmp(&names[x*20], &alias[x*20]) == 0)
X						sprintf(tmp, "%s\n",&names[x*20]);
X					else
X						sprintf(tmp, "%s (%s)\n",&names[x*20], &alias[x*20]);
X						
X					write(y, tmp, LINESIZ);
X					x++;
X				}
X				sprintf(tmp, " ");
X				write(y, tmp, LINESIZ);
X				break;
X			case 'o':	/* Open a new channel */
X				x = 0;
X				while (x < count) {	/* Only one per name */
X					if (strcmp(name, &names[x*20]) == 0) {
X						kill(pid, SIGUSR2);
X						break;
X					}
X					x++;
X				}
X				if (x != count) break;
X				if (count > 15) {
X					kill(pid, SIGUSR1);	/* Special */
X					x = 0;
X					sprintf(tmp, "[Comserver]: Full, refused %s\n", name);
X					while (x < count) {
X						write(fids[x++], tmp, LINESIZ);
X					}
X					
X					break;
X				}
X				printf("Opening channel: %d\n",pid);
X				strcpy(tmp, CHATDIR);
X				strcat(tmp, "pipe");
X				strcat(tmp, itoa(pid));
X				strcpy(&names[count*20],name);
X				strcpy(&alias[count*20],name);
X				if ((fids[count] = open(tmp,O_WRONLY)) < 0) {
X					puts("Gack! Pipe failure! (someone will be disappointed!)");
X					break;
X				}
X				x = fcntl(fids[count], F_GETFL, 0);
X				fcntl(fids[count], F_SETFL, x |= O_NDELAY);
X				pids[count] = pid;
X				count++;
X				x = 0;
X				printf("Added pid %d\n",pids[count - 1]);
X				sprintf(tmp, "[Connected to Comserver V1.7]\n");
X				write(fids[count - 1], tmp, LINESIZ);
X				sprintf(tmp, "[Comserver]: Welcome, %s\n",name);
X				while (x < count) {
X					write(fids[x++], tmp, LINESIZ);
X				}
X				break;
X			case 'n':	/* Change name (alias) */
X				x = 0;
X				while (x < count) {
X					if (pid == pids[x]) break;
X					x++;
X				}
X				if (x == count) break;	/* Bad request */
X				printf("Alias: %s to %s\n", &names[x*20], msg);
X				strncpy(&alias[x*20], msg, 20);
X				alias[(x*20)+19] = 0;
X				sprintf(tmp, "[Comserver]: %s aliased to (%s)\n", &names[x*20], &alias[x*20]);
X				write(fids[x], tmp, LINESIZ);
X				break;
X			case 'q':	/* Kill a user */
X				x = 0;
X				while (x < count) {
X					if (pid == pids[x]) break;
X					x++;
X				}
X				if (x == count) {
X					puts("Bad quit request");
X					break;	/* Bad request */
X				}
X				printf("Leaving: %s (%d left)\n",&names[x*20],(count - 1));
X				strcpy(temp, CHATDIR);
X				strcat(temp, "pipe");
X				strcat(temp, itoa(pid));
X				unlink(temp);		/* Remove pipe file */
X				strcpy(savename, &names[20*x]);
X				y = x;
X				while (y < count) {
X					pids[y] = pids[y + 1];
X					fids[y] = fids[y + 1];
X					strcpy(&names[y*20], &names[(y+1)*20]);
X					strcpy(&alias[y*20], &alias[(y+1)*20]);
X					y++;
X				}
X				count--;		/* Fall through */
X			case 'w':	/* Write a message */
X				x = 0;
X				while (x < count) {
X					if (pid == pids[x]) break;
X					x++;
X				}
X				if (x != count) strcpy(savename, &alias[x*20]);
X				printf("Write message: %s %s\n",savename, msg);
X				sprintf(tmp, "%s: %s\n",savename, msg);
X				savename[0] = 0;	/* Clear name */
X				x = 0;
X				while (x < count) {
X					if ((write(fids[x], tmp, LINESIZ) == -1) && (errno = EPIPE)) {
X						y = x;
X						z = pids[x];
X						strcpy(nm, &names[x*20]);
X						while (y < count) {
X							fids[y] = fids[y+1];
X							pids[y] = pids[y+1];
X							strcpy(&names[y*20],&names[(y + 1)*20]);
X							strcpy(&alias[y*20], &alias[(y+1)*20]);
X							y++;
X						}
X						count--;
X						y = 0;
X						strcpy(tmp, CHATDIR);
X						strcat(tmp, "pipe");
X						strcat(tmp, itoa(z));
X						unlink(tmp);
X						sprintf(tmp, "[Comserver]: %s disappears in a puff of smoke!\n",nm);
X						while (y < count) {
X							write(fids[y++],tmp,LINESIZ);
X						}
X						x--;
X					}
X					x++;
X				}
X				break;
X			default:
X				x = 0;
X				while (x < count) {
X					if (pids[x] == pid) {
X						y = fids[x];
X						break;
X					}
X					x++;
X				}
X				if (x == count) break;	/* Invalid */
X				sprintf(tmp, "Illegal server request\n");
X				write(y, tmp, LINESIZ);
X		}
X	}
X	}
X}
SHAR_EOF
exit
-- 

Karl Denninger				UUCP : ...ihnp4!ddsw1!karl
Macro Computer Solutions		Dial : +1 (312) 566-8911 (300-1200)
"Quality solutions at a fair price"	Voice: +1 (312) 566-8910 (24 hrs)

rsalz@bbn.com (Rich Salz) (12/16/87)

>...  This contribution is voluntary (no police will call on you if you
>fail to help out).  Of course, your conscience will haunt you for the rest
>of your life!...
>...  In 
>return for your donation, your name will be added to an electronic mailing 
>list...
>		Make sure to include a path for Email from ihnp4.

Guess the author(s) have no conscience, or they'd be bothered by the
fact that they are using other people's modems and phone bills to make
money.

And just to make this posting more than a snipe attack, let me point out
that there are three SysV chat programs in the FREE comp.sources.unix
archives -- via pipes, via fifo's.  Contact your nearest archive site,
or e-mail me for a list of them.
	/r$
-- 
For comp.sources.unix stuff, mail to sources@uunet.uu.net.

tr@wind.bellcore.com (tom reingold) (12/16/87)

In article <262@papaya.bbn.com> rsalz@bbn.com (Rich Salz) writes:
$ Guess the author(s) have no conscience, or they'd be bothered by the
$ fact that they are using other people's modems and phone bills to make
$ money.
$ 
$ And just to make this posting more than a snipe attack, let me point out
$ that there are three SysV chat programs in the FREE comp.sources.unix
$ archives -- via pipes, via fifo's.  Contact your nearest archive site,
$ or e-mail me for a list of them.
$ 	/r$
$ -- 
$ For comp.sources.unix stuff, mail to sources@uunet.uu.net.

If you want to plug the software you distribute, then why do you
want to question the morality of software with the same function?
Just because it is shareware doesn't it make it more wasteful of
modems and phone bills.  Besides, not everyone logged in to
systems are in through phone lines.

Tom Reingold                    INTERNET:       tr@bellcore.bellcore.com
Bell Communications Research    UUCP:           rutgers!bellcore!tr
435 South St room 2L350         SOUNDNET:       (201) 829-4622 [work]
Morristown, NJ 07960                            (201) 287-2345 [home]

dkovar@lf-server-2.BBN.COM (David Kovar) (12/17/87)

In article <4309@bellcore.bellcore.com> tr@wind.UUCP (tom reingold) writes:
>In article <262@papaya.bbn.com> rsalz@bbn.com (Rich Salz) writes:
>$ Guess the author(s) have no conscience, or they'd be bothered by the
>$ fact that they are using other people's modems and phone bills to make
>$ money.
>$ 
>$ And just to make this posting more than a snipe attack, let me point out
>$ that there are three SysV chat programs in the FREE comp.sources.unix
>$ archives -- via pipes, via fifo's.  Contact your nearest archive site,
>$ or e-mail me for a list of them.
>$ 	/r$
>$ -- 
>$ For comp.sources.unix stuff, mail to sources@uunet.uu.net.
>
>If you want to plug the software you distribute, then why do you
>want to question the morality of software with the same function?
>Just because it is shareware doesn't it make it more wasteful of
>modems and phone bills.  Besides, not everyone logged in to
>systems are in through phone lines.
>
>Tom Reingold                    INTERNET:       tr@bellcore.bellcore.com

The point is that someone is making money by distributing software via
USENET. USENET is built on mostly Unix systems talking to each other mostly
by leased or normal phone lines. To transfer the shareware from one
system to another costs someone who is not the author nor the user money.
In effect, the author is getting free a free advertising and distribution
network as other people are paying the cost of those services for him.
This is against the intent, at the very least, of USENET. (And, when it
gets on on ARPANET or MILNET it's *really* against the intent.)


-----------------------------------------------------------------------------
David C. Kovar                                               DKovar@BBN.COM

  It's fairly obvious that Corwin is around. Corwin will show up when he
is good and ready, and is quite good at hiding otherwise. Searching for
him makes no sense if he doesn't want to be found, and if he wants to be
found he'll surface on his own.
-----------------------------------------------------------------------------

lvc@tut.cis.ohio-state.edu (Lawrence V. Cipriani) (12/17/87)

Not to pick nits but you don't need the second semicolon here.

client.c line 262
	while ((wait() != -1) || (errno != ECHILD));;
-- 
	Larry Cipriani AT&T Network Systems at
	cbosgd!osu-cis!tut!lvc Ohio State University

webber@brandx.rutgers.edu (Webber) (12/17/87)

In article <417@ddsw1.UUCP>, karl@ddsw1.UUCP (Karl Denninger) writes:
> ...
> Here it is -- System V Chat (this is shareware, hit 'n' now if offended with
> this; and no flames please!).

Given that there are people who are intent on abusing the net by posting
shareware, which will inevitably cause the people being abused to flame,
they should at least have the sense to redirect followups to alt.flame.
Indeed, the source should probably have been posted there as well.

----- BOB (webber@athos.rutgers.edu ; rutgers!athos.rutgers.edu!webber)

sob@academ.UUCP (Stan Barber) (12/17/87)

In article <4309@bellcore.bellcore.com> tr@wind.UUCP (tom reingold) writes:
>In article <262@papaya.bbn.com> rsalz@bbn.com (Rich Salz) writes:
>$ Guess the author(s) have no conscience, or they'd be bothered by the
>$ fact that they are using other people's modems and phone bills to make
>$ money.
>$ 
>$ And just to make this posting more than a snipe attack, let me point out
>$ that there are three SysV chat programs in the FREE comp.sources.unix
>$ archives -- via pipes, via fifo's.  Contact your nearest archive site,
>$ or e-mail me for a list of them.
>$ 	/r$
>$ -- 
>$ For comp.sources.unix stuff, mail to sources@uunet.uu.net.
>
>If you want to plug the software you distribute, then why do you
>want to question the morality of software with the same function?
>Just because it is shareware doesn't it make it more wasteful of
>modems and phone bills.  Besides, not everyone logged in to
>systems are in through phone lines.
>
>Tom Reingold                    INTERNET:       tr@bellcore.bellcore.com

Tom,

Ron is not "plugging" the software he distributes. That software is archived
by many sites and published by more than one moderator. He is calling 
attention to an old usenet custom of not making money off the network.
I know there has been considerable debate over the use of the network for
shareware distribution, so I won't attempt to start-up that battle again.

The fact that Karl used the alt.sources newsgroup for the distribution
indicates that he is aware of the concern over this practice and he chose
the best group he could think of in which to post. Ron seems to disagree
strongly with Karl's choice and so Ron offers an alternative. 

Also, should Karl's code travel over certain transmission systems (i.e.
ARPANET), it probably would violate the non-commercial use policy of
that transmission system.

Shareware is such a nice idea on the surface, but seems to be so much
more complex underneath.


-- 
Stan	     uucp:{killer,rice,hoptoad}!academ!sob     Opinions expressed here
Olan         domain:sob@tmc.edu                            are ONLY mine &
Barber       CIS:71565,623   BBS:(713)790-9004               noone else's.

allbery@ncoast.UUCP (Brandon Allbery) (12/18/87)

As quoted from <672@brandx.rutgers.edu> by webber@brandx.rutgers.edu (Webber):
+---------------
| In article <417@ddsw1.UUCP>, karl@ddsw1.UUCP (Karl Denninger) writes:
| > Here it is -- System V Chat (this is shareware, hit 'n' now if offended with
| > this; and no flames please!).
| 
| Given that there are people who are intent on abusing the net by posting
| shareware, which will inevitably cause the people being abused to flame,
| they should at least have the sense to redirect followups to alt.flame.
| Indeed, the source should probably have been posted there as well.
+---------------

Given that it was posted to ALT.SOURCES, I'd suggest that complaints about
shareware are at best misdirected and at worst utterly unwarranted.  There
is no policy statement on shareware in alt.sources; there is no *policy*,
it's militant anarchy.  In other words, stuff it!
-- 
Brandon S. Allbery		      necntc!ncoast!allbery@harvard.harvard.edu
 {hoptoad,harvard!necntc,cbosgd,sun!mandrill!hal,uunet!hnsurg3}!ncoast!allbery
			Moderator of comp.sources.misc

tr@wind.bellcore.com (tom reingold) (12/18/87)

In article <4309@bellcore.bellcore.com> I write:
$ If you want to plug the software you distribute, then why do you want
$ to question the morality of software with the same function?  Just
$ because it is shareware doesn't it make it more wasteful of modems
$ and phone bills.  Besides, not everyone logged in to systems are in
$ through phone lines.

And then, in article <3314@tut.cis.ohio-state.edu> Bob Sutterfield
writes:
$ The complaint doesn't concern single users' dialup (or whatever)
$ access to the system on which they will run the software; nor with
$ people distributing new software that performs the same function as
$ existing function; nor even with the author asking for money for the
$ new software.
$ 
$ Rather the complaint is with author's use of many other sites'
$ (sometimes expensive) UUCP phone links and /usr/spool disk space to
$ distribute the software from which he hopes to reap financial gain.
$ Though that may be the custom on other networks, it is not considered
$ kosher in Usenet-land.
$ 
$ For example, the fact that our site feeds and is fed alt.* does not
$ tacitly imply that the State of Ohio wishes to support software
$ development efforts at a company in Illinois.

Ok, I get it now.  And now that you point it out to me that way,
I agree 100%.  And I sent a message to this effect to Rich Salz,
the person who posted the original objection.

Tom Reingold                    INTERNET:       tr@bellcore.bellcore.com
Bell Communications Research    UUCP:           rutgers!bellcore!tr
435 South St room 2L350         SOUNDNET:       (201) 829-4622 [work]
Morristown, NJ 07960                            (201) 287-2345 [home]

soley@well.UUCP (Norman Soley) (12/19/87)

Please correct me if I'm wrong. I gather from the things I read about the 
altnet that THE RULES ARE DIFFERENT and that anyone who wishes
to be sticky about the usenet rules shouldn't carry alt groups. YES or NO?