[alt.sources] UnixChat Part 1/2

ml@brumuc.bru.sub.org (Marc Laukien) (01/22/91)

This is another chat utility for Unix. It's tested with XENIX 2.3.2
and Interactive Unix 2.2.

The source is Public Domain, so you can copy or modify it, or do with
it whatever you want.

#!/bin/sh
# This is UnixChat, a shell archive (shar 3.32)
# made 01/22/1991 15:13 UTC by local@brumuc
# Source directory /usr2/local/chat/XChat_V2.9
#
# existing files WILL be overwritten
#
# This is part 1 of a multipart archive                                    
# do not concatenate these parts, unpack them in order with /bin/sh        
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   5964 -rw------- ch/init.c
#   5543 -rw------- ch/input.c
#   3277 -rw------- ch/main.c
#   5685 -rw------- ch/comm.c
#   5572 -rw------- ch/utility.c
#   2887 -rw------- ch/output.c
#   3358 -rw------- ch/menu.c
#   3234 -rw------- ch/invite.c
#   1792 -rw------- ch/grep.c
#   2912 -rw------- cm/init.c
#   5033 -rw------- cm/int.c
#   2689 -rw------- cm/main.c
#   2311 -rw------- cm/comm.c
#   3456 -rw------- ch/lex.l
#   3789 -rw------- ch/ch.h
#   1318 -rw------- cm/cm.h
#    745 -rw------- hdrs/ipc.h
#    889 -rw------- hdrs/std.h
#   1269 -rw------- def.german
#   1212 -rw------- def.english
#    885 -rw------- help.german
#    835 -rw------- help.english
#    231 -rw------- menu.german
#    231 -rw------- menu.english
#     27 -rw------- super.user
#     38 -rw------- name.list
#     11 -rw------- guest.list
#    633 -rw------- README.ger
#    610 -rw------- README.eng
#   6399 -rw------- Makefile
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
if test -r shar3_seq_.tmp; then
	echo "Must unpack archives in sequence!"
	next=`cat shar3_seq_.tmp`; echo "Please unpack part $next next"
	exit 1
fi
# ============= ch/init.c ==============
if test ! -d 'ch'; then
    echo "x - creating directory ch"
    mkdir 'ch'
fi
echo "x - extracting ch/init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/init.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Initialisierungen			*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <malloc.h>
X#include <termio.h>
X#include <curses.h>
X#include <term.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include <errno.h>
X#include "ch.h"
X
X/*----------------------------------------------------------------------*/
X/* 	Initialisierungen						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	init()
X{
X	char 	str[STRLEN];
X	FILE 	*fp;			/* fdriptor 	*/
X	int	i;
X
X	if(grep(getlogin(),"super.user"))		/* super-user ?	*/
X		superuser=1;
X
X	if(grep(getlogin(),"guest.list"))		/* gast ?	*/
X	{
X		superuser=0;
X		guest=1;
X	}
X
X	for(i=0;i<10;i++)		/* Funktionstasten loeschen	*/
X		fkey[i]=(char *)0;
X
X	strcpy(cname,getlogin());	/* Chatname holen	*/
X
X	if(!guest)				/* Kein Gast ?		*/
X	{
X		sprintf(str,"userdir/%s",getlogin());
X
X		if((fp=fopen(str,"r"))!=(FILE *)0) /* Userdaten einlesen ? */
X		{
X			while(!feof(fp))
X			{
X				i= -1;
X				do
X					str[++i]=fgetc(fp);	/* einlesen */
X				while(str[i]!='\n' && !feof(fp));
X				str[i]='\0';
X			
X				if(!strncmp("fkey",str,4))/* Funktionstaste ? */
X					chat_pr_fkey(str+4);
X
X				else if(!strncmp("mode",str,4))	/* Modus ? */
X					sscanf(str+4,"%d",&mode);
X
X				else if(!strncmp("name",str,4))	/* Modus ? */
X					sscanf(str+4,"%s",cname);
X			}
X
X			fclose(fp);
X		}
X	}
X
X	if(lang[0]!=0)			/* eigene Sprache ? 	*/
X		lex();			/* Strings einlesen 	*/
X
X	if(strlen(prompt)<2)		/* Prompt zu kurz ? 	*/
X	{
X		fprintf(stderr,"%s: prompt too short in def.%s\n",pname,lang);
X		deinit();
X		exit(2);
X	}
X
X	/* Terminal initialisieren		*/
X
X	setupterm((char *)0,1,(int *)0);	/* Terminfo ein	*/
X
X	ioctl(1,TCGETA,&oterm);		/* termio retten 	*/
X	ioctl(1,TCGETA,&term);		/* termio holen 	*/
X	term.c_cc[VEOF]=1;		/* veraendern 		*/
X	term.c_cc[VEOL]=1;
X	term.c_cc[VINTR]=0;
X	term.c_lflag &= ~(ICANON | ECHO);
X	term.c_iflag &= ~(IXON | IXOFF);
X	ioctl(1,TCSETA,&term);
X
X	terminfo=1;
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Konferenz Initialisierungen					*/
X/*----------------------------------------------------------------------*/
X/*	Return:	1-alles ok	0-Fehler				*/
X/*----------------------------------------------------------------------*/
X
Xint	conf_init()
X
X{
X	char	pass[STRLEN];		/* Password		*/
X	char 	str[STRLEN];
X	FILE 	*fp;			/* Filedeskriptor 	*/
X
X	/* Conf suchen ----------------------------- */
X
X	sprintf(str,"confdir/%s",conf);		/* Konferenz-File	*/
X
X	fp=fopen(str,"r");			/* oeffnen 		*/
X	if(fp == (FILE *)0)			/* Fehler ? 		*/
X	{
X		if(errno==ENOENT)
X		{
X			fprintf(stderr,"%s: no such conference\n",pname);
X			return(0);
X		}
X		else				/* Anderer Fehler 	*/
X			fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X
X		deinit();
X		exit(2);
X	}
X
X	fscanf(fp,"%ld",&key);			/* Messagekey holen 	*/
X	fscanf(fp,"%s",pass);			/* Messagekey holen 	*/
X
X	if(strcmp(pass,pw)!=0 && strcmp(pass,STDPASS)!=0)
X	{				/* Passwort nicht bekannt ?	*/
X		if(superuser)
X			fprintf(stderr,"%s: super-user: password is '%s'\n"
X			,pname,pass);
X
X		if(strcmp(read_string(password),pass))
X		{
X			fprintf(stderr,"%s: wrong password\n",pname,lang);
X			return(0);
X		}
X	}
X	fclose(fp);				/* schliessen 		*/
X
X	/* Ende Conf suchen ---------------------- */
X
X	/* Manager FIFO eroeffnen ---------------- */
X
X	sprintf(str,"fifodir/%ld",key);		/* Pfad fuer FIFO	*/
X
X	fifofd=open(str,O_WRONLY);		/* FIFO oeffnen 	*/
X	if(fifofd== -1)				/* Fehler ? 		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	/* Ende FIFO eroeffnen ------------------- */
X
X	/* eigene FIFO anlegen ------------------------------- */
X
X 	pkey=getpid();				/* Messagekey holen	*/
X	if(pkey== -1)				/* Fehler ?		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X	
X	sprintf(str,"fifodir/%ld",pkey);	/* Pfad fuer FIFO	*/
X
X	if(mknod(str,S_IFIFO | MODE,0)==-1)	/* Anlegen		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	pfifofd=open(str,O_RDONLY | O_NDELAY);	/* FIFO oeffnen 	*/
X	if(pfifofd== -1)			/* Fehler ? 		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	/* Ende eigene FIFO anlegen -------------------------- */
X
X	return(1);
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Deinitialisierungen						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	deinit()
X{
X	char 	str[STRLEN];
X	FILE	*fp;
X	int	i;
X
X	if(terminfo==1)	/* Terminfo an ?	*/
X	{
X		vidattr(0);
X		ioctl(1,TCSETA,&oterm);	/* termio herstellen	*/
X		fflush(stdout);
X		resetterm();
X	}
X
X	conf_deinit();	/* private FIFO loeschen	 */
X
X	if(!guest)		/* Kein Gast ?	*/
X	{
X		sprintf(str,"userdir/%s",getlogin());
X
X		if((fp=fopen(str,"w"))!=(FILE *)0) /* Userdaten schreiben ? */
X		{
X			if(mode != STDMODE)	/* Mode schreiben	*/
X				fprintf(fp,"mode %d\n",mode);
X		
X			if(strcmp(cname,getlogin()))/* Namen schreiben	*/
X				fprintf(fp,"name %s\n",cname);
X		
X			for(i=0;i<10;i++) /* Funktionstasten schreiben	*/
X				if(fkey[i]!=(char *)0)
X					fprintf(fp,"fkey%d %s\n",i,fkey[i]);
X
X			fclose(fp);
X		}
X	}
X
X	chdir(cwd);		/* Directory einstellen	*/
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Konferenz Deinitialisierungen					*/
X/*----------------------------------------------------------------------*/
X
Xvoid	conf_deinit()
X{
X	char 	str[STRLEN];
X	FILE	*fp;
X
X	if(fifofd != -1)
X		give_notice();	/* Abmelden		*/
X
X	/* private FIFO loeschen -------------------- */
X
X	if(pfifofd != -1)
X	{
X		sprintf(str,"fifodir/%ld",pkey);
X		unlink(str);
X
X		close(pfifofd);
X
X		pfifofd= -1;
X	}
X}
SHAR_EOF
$TOUCH -am 0806104890 ch/init.c &&
chmod 0600 ch/init.c ||
echo "restore of ch/init.c failed"
set `wc -c ch/init.c`;Wc_c=$1
if test "$Wc_c" != "5964"; then
	echo original size 5964, current size $Wc_c
fi
# ============= ch/input.c ==============
echo "x - extracting ch/input.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/input.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Input					*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <curses.h>
X#include <ctype.h>
X#include <term.h>
X#include "ch.h"
X
X/* globale Variablen */
X
Xjmp_buf env;		/* Environment */
X
X/*----------------------------------------------------------------------*/
X/* 	Eingabe								*/
X/*----------------------------------------------------------------------*/
X
Xvoid	input()
X{
X	char 	text[STRLEN];
X	char	c;
X
X	if(!conf_init())		/* Konfer. init.	*/
X	{
X		if(menu)
X			menu_key();
X
X		return;
X	}
X
X	announce();			/* Anmelden 		*/
X
X	CLEAR				/* clear screen		*/
X	fflush(stdout);
X
X	puts(start);			/* Hilfe anzeigen	*/
X	puts("");
X	sleep(2);
X	conf_members(conf,'p');
X	puts("");
X
X	do
X	{
X		do
X			input_str(text);	/* einlesen 	*/
X		while(text[0]==0);
X
X		vidattr(0);		/* normale Schrift	*/
X		fflush(stdout);
X
X		c=text[1];		/* Kommando holen	*/
X		if(isupper(c))
X			c=tolower(c);
X
X		if(text[0]!=':')	/* kein Kommando ?	*/
X			pub_msg(text);	/* an den Manager senden*/
X		else if(c==cmds[1])	/* Hilfe ?		*/
X			chat_help();
X		else if(c==cmds[2])	/* wer ist im System ?	*/
X			system(who);
X		else if(c==cmds[3])	/* wer ist in der Konf ?*/
X			conf_members(conf,'p');
X		else if(c==cmds[4])	/* clear	*/
X			CLEAR
X		else if(c==cmds[5])	/* Blitzmeldung	*/
X			message(text+2);
X		else if(c==cmds[6])	/* Einladung		*/
X			invite(text+2);
X		else if(c==cmds[7])	/* Namensaenderung	*/
X			change_name(text+2);
X		else if(c==cmds[8])	/* User rauswerfen	*/
X			kill_user(text+2);
X		else if(c==cmds[9])	/* Nachricht ohne Prompt*/
X			noprompt_msg(text+2);
X		else if(c==cmds[10])	/* Modi 	*/
X			chat_mode(text+2);
X		else if(c==cmds[11])	/* F-Key Programmieren 	*/
X			chat_pr_fkey(text+2);
X		else if(c==cmds[12])	/* F-Key abfragen 	*/
X			chat_fkey(text+2);
X		else if(c!=cmds[0])	/* Fehler	*/
X			printf("%s\n",nocmd);	
X	}
X	while(!(text[0]==':' && c==cmds[0]));	/* Ende ?	*/
X
X	conf_deinit();		/* deinitialisieren	*/
X}
X
X/*----------------------------------------------------------------------*/
X/*	String eingeben							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	input_str(str)
X
Xchar 	*str;		/* Einzugebender String	*/
X{
X	static	char	bsp[] = {BS,' ',BS};	/* Backspace	*/
X
X	char 	c=' ';				/* Kommando	*/
X	char 	prstr[STRLEN];			/* Prompt	*/
X	int 	pos=0;
X	int 	anz=0,an;			/* Anzahl der Messages	*/
X
X	str[0]='\0';		/* loeschen	*/
X
X	sprintf(prstr,"%s%s",cname,prompt);
X
X	if(mode & REVERSE)			/* Revers ?	*/
X		vidattr(A_REVERSE);
X	else
X		vidattr(A_BOLD);
X
X	fputs(prstr,stdout);			/* prstr ausgeben	*/
X	fflush(stdout);
X
X	do
X	{
X		/* ----- Ausgabe -------------------------------------- */
X
X		if(an=output(anz))	/* Messages ausgeben		*/
X		{
X			anz += an;	/* Anzahl der Zeilen gesamt	*/
X
X			if(anz>=lines	/* Zeilenzahl ueberschritten	*/
X					/* Bei keiner Emu: lines=0	*/
X			|| !(mode&JUMP))	/* Jump ein		*/
X			{
X				putchar('\n');	/* 1 Zeile runter	*/
X				anz=0;
X
X				if(mode & REVERSE)	/* Revers ?	*/
X					vidattr(A_REVERSE);
X				else
X					vidattr(A_BOLD);
X
X				fputs(prstr,stdout);	/* prstr ausgeben*/
X				fputs(str,stdout);	/* str ausgeben  */
X				fflush(stdout);
X			}
X			else				/* hochfahren	*/
X			{
X				int	i,len2;
X
X				if(parm_up_cursor!=(char *)0) /* hoch */
X					putp(tparm(parm_up_cursor,anz));
X				else		/* einzeln hoch	*/
X				for(i=0;i<anz;i++)
X					putp(cursor_up);
X
X				len2=strlen(prstr)+strlen(str);
X
X				/* kuerzeren Weg suchen	*/
X				if(2*len2<len)
X				{
X					putchar(RET);	/* Zeilenanfang	*/
X					len=0;
X				}
X
X				if(len<len2)
X				{
X				if(parm_right_cursor!=(char *)0) /* rechts */
X					putp(tparm(parm_right_cursor,len2-len));
X
X				else		/* einzeln rechts	*/
X				for(i=0;i<len2-len;i++)
X					putp(cursor_right);
X				}
X				else if(len>len2)
X				{
X				if(parm_left_cursor!=(char *)0) /* rechts */
X					putp(tparm(parm_left_cursor,len-len2));
X
X				else		/* einzeln rechts	*/
X				for(i=0;i<len-len2;i++)
X					putp(cursor_left);
X				}
X
X				fflush(stdout);
X			}
X		}
X
X		if(an)				/* Messages bekommen ?	*/
X		{
X			if(mode & REVERSE)		/* Revers ?	*/
X				vidattr(A_REVERSE);
X			else
X				vidattr(A_BOLD);
X		}
X
X		/* ----- Eingabe -------------------------------------- */
X
X		if(setjmp(env)==0)		/* Environment sichern	*/
X		{
X			signal(SIGUSR1,interrupt);	/* Int. set.	*/
X			read(0,&c,1);		/* Kommandoabk. einl.	*/
X		}
X		else
X			c=0;
X
X		signal(SIGUSR1,SIG_IGN);	/* Interrupt aus	*/
X
X		if(c==NL || c==RET)		/* Ende der Eingabe	*/
X			break;
X
X		if(c<' ' && c!=BS)
X			c=0;
X
X		if(c)
X		{
X			if(c==BS)		/* loeschen	*/
X			{
X				if(pos>0)
X				{
X					str[--pos]=0;		
X					fputs(bsp,stdout);
X					fflush(stdout);
X				}
X			}
X			else if(c==DEL)	/* alles loeschen	*/
X			{
X				while(pos>0)
X				{
X					str[--pos]=0;		
X					fputs(bsp,stdout);
X				}
X				fflush(stdout);
X			}
X			else if(pos<80-strlen(prstr)-1)/* eingeben	*/
X			{
X				str[pos++]=c;
X				str[pos]=0;	
X				putchar(c);		/* ausgeben	*/
X				fflush(stdout);
X			}
X		}
X
X		if(pos>=80-strlen(prstr)-1)	/* Linewrap	*/
X			break;
X	}
X	FOREVER;
X
X	if(anz)
X	{
X		int	i;
X
X		if(parm_down_cursor!=(char *)0) /* runter */
X			putp(tparm(parm_down_cursor,anz));
X		else		/* einzeln runter	*/
X		for(i=0;i<anz;i++)
X			putp(cursor_down);
X	}
X
X	putchar('\n');
X
X}
X
Xstatic	void	interrupt()
X
X{
X	longjmp(env,1);
X}
SHAR_EOF
$TOUCH -am 0106163691 ch/input.c &&
chmod 0600 ch/input.c ||
echo "restore of ch/input.c failed"
set `wc -c ch/input.c`;Wc_c=$1
if test "$Wc_c" != "5543"; then
	echo original size 5543, current size $Wc_c
fi
# ============= ch/main.c ==============
echo "x - extracting ch/main.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/main.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Hauptprogramm				*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <termio.h>
X#include <string.h>
X#include <stdio.h>
X#include <signal.h>
X#include "ch.h"
X
X/* globale Variablen */
X
Xchar	*pname;				/* Programmname: argv[0]	*/
Xchar	*cwd;				/* Working Directory 		*/
Xchar	conf[STRLEN]="sysconf";		/* Konferenzname 		*/
Xchar	lang[STRLEN]=STDLANG;		/* Sprache 			*/
Xchar	cname[STRLEN];			/* Chatname			*/
X
Xint	len;			/* Laenge der letzten Zeile		*/
X
Xint	mode=STDMODE;		/* Modus				*/
Xint	superuser=0;		/* falls 1: Super-User			*/
Xint	guest=0;		/* falls 1: Gast			*/
Xint	menu=0;			/* falls 1: Menue aufrufen		*/
Xchar	pw[STRLEN]=STDPASS;	/* Passwort				*/
Xchar	*fkey[10];		/* Funktionstasten			*/
X
Xint	terminfo=0;		/* Falls 1: Terminfo ist an		*/
Xstruct	termio	term,oterm;	/* Terminaldaten 			*/
X
Xlong	key= -1;		/* Key der Manager-FIFO 	*/
Xint	fifofd= -1;		/* Manager FIFO fd 		*/
Xlong	pkey= -1;		/* Key der privaten FIFO 	*/
Xint	pfifofd= -1;		/* private FIFO fd 		*/
X
X/*----------------------------------------------------------------------*/
X/* 	Hauptprogramm							*/
X/*----------------------------------------------------------------------*/
X
Xint	main(argc,argv,envp)
X
Xint	argc;
Xchar	*argv[];
Xchar	*envp[];
X{
X	extern char *optarg;
X	extern int  optind,opterr;
X	char ch;
X
X	pname=argv[0];		/* Programmname		*/
X
X	umask(077);		/* Creation-Mask	*/
X
X	cwd=getcwd((char *)0,STRLEN);	/* Directory retten 	*/
X	if(chdir(LIBDIR)== -1)		/* Directory einstellen */
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		exit(2);
X	}
X
X	signal(SIGHUP,interrupt);	/* Interrupt einstellen	*/
X	signal(SIGTERM,interrupt);
X	signal(SIGINT,SIG_IGN);
X	signal(SIGQUIT,SIG_IGN);
X	signal(SIGUSR1,SIG_IGN);	/* Interrupt loeschen	*/
X
X	/* Optionen einlesen *******************************************/
X
X	opterr=1;
X	while((ch=getopt(argc,argv,"mc:l:"))!=EOF)
X		switch(ch)
X		{
X		case 'm':		/* Menue		*/
X			menu=1;
X			break;
X
X		case 'c':		/* andere Konferenz	*/
X			strcpy(conf,optarg);
X			break;
X
X		case 'l':		/* andere Sprache	*/
X			strcpy(lang,optarg);
X			break;
X
X		case '?':		/* Fehler		*/
X			opterr++;
X			break;
X		}
X
X	if(opterr>1)			/* falsche Optionen	*/
X	{
X		fprintf(stderr,
X		"usage: %s [-m] [-c conf] [-l language]\n",pname);
X		deinit();
X		exit(2);
X	}
X	
X	/* Ende Optionen einlesen **************************************/
X
X	if(strlen(conf)>10)		/* Name zu lang ?	*/
X	{
X		fprintf(stderr,"%s: conference name too long\n",pname);
X		exit(2);
X	}
X
X	init();				/* Initialisierungen	*/
X
X	if(menu && !guest)		/* Menue aufrufen ?	*/
X		chat_menu();
X	else
X		input();		/* Eingabeschleife	*/
X
X	deinit();			/* Deinitialisierungen	*/
X	return(0);			/* Tschuess		*/
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Interruptroutine						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	interrupt()
X
X{
X	give_notice();			/* abmelden	*/
X	deinit();
X	puts("");			/* Leerzeile	*/
X	exit(0);
X}
SHAR_EOF
$TOUCH -am 0122160791 ch/main.c &&
chmod 0600 ch/main.c ||
echo "restore of ch/main.c failed"
set `wc -c ch/main.c`;Wc_c=$1
if test "$Wc_c" != "3277"; then
	echo original size 3277, current size $Wc_c
fi
# ============= ch/comm.c ==============
echo "x - extracting ch/comm.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/comm.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Kommunikation				*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <memory.h>
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X#include <fcntl.h>
X#include <errno.h>
X#include "ch.h"
X
Xstruct _msgbuf
X{
X	long	mtype;		/* message type */
X	MSG	mtext;		/* message text */
X};
X
Xstruct _umsgbuf
X{
X	long	mtype;		/* message type */
X	UMSG	mtext;		/* message text */
X};
X
X/*----------------------------------------------------------------------*/
X/* 	User rauswerfen							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	kill_user(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	MSG	msg;			/* Message	*/
X	int	i=0;
X
X	if(!superuser)			/* Kein Super-User ?	*/
X		return;
X
X	while(*text==' ' || *text==TAB)
X		text++;
X
X	while(text[i]!=' ' && text[i]!=TAB && text[i]!='\0')
X		i++;
X
X	if(i>20)			/* nicht zu lang	*/
X		i=20;
X
X	text[i]='\0';			/* beenden		*/
X
X	if(*text!='\0')			/* Text vorhanden ?	*/
X	{
X		msg.pid=getpid();		/* Pfd holen	*/
X		msg.typ=KILL;			/* Messagetyp	*/
X		strcpy(msg.text,text);		/* Messagetext	*/
X
X		send_msg(&msg);
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Namen aendern							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	change_name(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	MSG	msg;			/* Message	*/
X	int	i=0;
X	char	str[STRLEN],str2[STRLEN];
X
X	while(*text==' ' || *text==TAB)
X		text++;
X
X	while(text[i]!=' ' && text[i]!=TAB && text[i]!='\0')
X		i++;
X
X	if(i>20)			/* nicht zu lang	*/
X		i=20;
X
X	text[i]='\0';			/* beenden		*/
X
X	if(*text!='\0')			/* Text vorhanden ?	*/
X	{
X		strcpy(str,getlogin());	/* eigener Name		*/
X		strcpy(str2,text);	/* gewuenschter Name	*/
X
X		for(i=0;str[i]!='\0';i++)	/* klein machen	*/
X			if(isupper(str[i]))
X				str[i]=tolower(str[i]);
X
X		for(i=0;str2[i]!='\0';i++)	/* klein machen	*/
X			if(isupper(str2[i]))
X				str2[i]=tolower(str2[i]);
X
X
X		if(strcmp(str,str2))		/* nicht eigener Name ?	*/
X		{
X		if(grep(text,"name.list"))	/* unzulaessiger Name ?	*/
X			return;
X
X		sprintf(str,"confdir/%s",conf);
X		if(grep(text,str))		/* unzulaessiger Name ?	*/
X			return;
X		}
X
X		msg.pid=getpid();		/* Pfd holen	*/
X		msg.typ=CNAME;			/* Messagetyp	*/
X		strcpy(msg.text,text);		/* Messagetext	*/
X
X		send_msg(&msg);
X
X		strcpy(cname,text);	/* Chatname merken	*/
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Anmelden							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	announce()
X
X{
X	MSG msg;	/* Message 	*/
X
X	msg.pid=getpid();		/* Pfd holen	*/
X	msg.typ=ARRIVAL;		/* Messagetyp 	*/
X	sprintf(msg.text,"%ld %s %s",pkey,getlogin(),cname);
X					/* Key und Name	*/
X	send_msg(&msg);
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Abmelden							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	give_notice()
X
X{
X	MSG	msg;			/* Message	*/
X
X	msg.pid=getpid();		/* Pfd holen	*/
X	msg.typ=DEPARTURE;		/* Messagetyp	*/
X	strcpy(msg.text,getlogin());	/* Name		*/
X
X	send_msg(&msg);
X}
X
X/*----------------------------------------------------------------------*/
X/* 	oeffentliche Message senden					*/
X/*----------------------------------------------------------------------*/
X
Xvoid	pub_msg(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	MSG	msg;			/* Message	*/
X	int	i=0;
X
X	while(text[i]==' ' || text[i]==TAB)
X		i++;
X
X	if(text[i]!='\0')		/* Text vorhanden ?	*/
X	{
X		msg.pid=getpid();		/* Pfd holen	*/
X		msg.typ=MESSAGE;		/* Messagetyp	*/
X		strcpy(msg.text,text);		/* Messagetext	*/
X
X		send_msg(&msg);
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	oeffentliche Message ohne Prompt senden				*/
X/*----------------------------------------------------------------------*/
X
Xvoid	noprompt_msg(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	MSG	msg;			/* Message	*/
X	int	i=0;
X
X	while(text[i]==' ' || text[i]==TAB)
X		i++;
X
X	if(text[i]!='\0')		/* Text vorhanden ?	*/
X	{
X		msg.pid=getpid();		/* Pfd holen	*/
X		msg.typ=NOPROMPT;		/* Messagetyp	*/
X		strcpy(msg.text,text);		/* Messagetext	*/
X
X		send_msg(&msg);
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Message empfangen						*/
X/*----------------------------------------------------------------------*/
X
XUMSG 	*recv_msg()
X{
X	static	UMSG	umsg;		/* Message 		*/
X	int	ret;			/* Return von Read	*/
X
X	ret=read(pfifofd,&umsg,sizeof(UMSG));	/* empfangen	*/
X
X	if(ret== -1)	/* Fehler ?	*/
X	{
X		fprintf(stderr,"%s: %s (recv_msg)\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);		/* Fehler 	*/
X	}
X	else if(ret==0)
X		umsg.typ=EMPTY;		/* leer 	*/
X
X	return(&umsg);			/* Message als Returnwert 	*/
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Message senden							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	send_msg(msg)
X
XMSG	*msg;				/* zu sendende Message 	*/
X{
X	struct	stat	status;		/* Filestatus		*/
X	int	i=0;
X
X	FOREVER
X	{
X		fstat(fifofd,&status);	/* Status holen		*/
X
X		if(status.st_size<MAXBYTES)
X			break;
X
X		if(i++ >= MAXTRYS)
X			return;
X
X		sleep(2);
X	}
X	
X	if(write(fifofd,msg,sizeof(MSG)) == -1)	/* empf */
X	{
X		fprintf(stderr,"%s: %s (send_msg)\n",pname,sys_errlist[errno]);
X		fifofd= -1;		/* FIFO sperren */
X		deinit();
X		exit(2);		/* Fehler */
X	}
X}
SHAR_EOF
$TOUCH -am 0806104890 ch/comm.c &&
chmod 0600 ch/comm.c ||
echo "restore of ch/comm.c failed"
set `wc -c ch/comm.c`;Wc_c=$1
if test "$Wc_c" != "5685"; then
	echo original size 5685, current size $Wc_c
fi
# ============= ch/utility.c ==============
echo "x - extracting ch/utility.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/utility.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Utilities				*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <malloc.h>
X#include <stdio.h>
X#include <curses.h>
X#include <term.h>
X#include <ctype.h>
X#include "ch.h"
X
X/*----------------------------------------------------------------------*/
X/* 	Tastendruck							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	menu_key()
X
X{
X	char	c;
X
X	printf("\n\n%s\n",press_key);
X	read(0,&c,1);		/* einlesen	*/
X}
X
X/*----------------------------------------------------------------------*/
X/* 	String einlesen							*/
X/*----------------------------------------------------------------------*/
X
Xchar	*read_string(pro)
X
Xchar	*pro;			/* Prompt	*/
X{
X	static	char	str[STRLEN];
X	static	char	bsp[] = {BS,' ',BS};	/* Backspace	*/
X	int 	pos=0;
X	char	c;
X
X	str[0]='\0';		/* loeschen	*/
X
X	fputs(pro,stdout);
X
X	if(mode & REVERSE)			/* Revers ?	*/
X		vidattr(A_REVERSE);
X	else
X		vidattr(A_BOLD);
X
X	fflush(stdout);
X
X	FOREVER
X	{
X		read(0,&c,1);		/* Kommandoabk. einl.	*/
X
X		if(c==NL || c==RET)	/* Ende der Eingabe	*/
X			break;
X
X		if(isalnum(c) || c==DEL || c==BS)
X		{
X			if(c==BS)		/* loeschen	*/
X			{
X				if(pos>0)
X				{
X					str[--pos]=0;		
X					fputs(bsp,stdout);
X					fflush(stdout);
X				}
X			}
X			else if(c==DEL)	/* alles loeschen	*/
X			{
X				while(pos>0)
X				{
X					str[--pos]=0;		
X					fputs(bsp,stdout);
X				}
X				fflush(stdout);
X			}
X			else if(pos<14)		/* eingeben	*/
X			{
X				str[pos++]=c;
X				str[pos]=0;	
X				putchar(c);	/* ausgeben	*/
X				fflush(stdout);
X			}
X		}
X	}
X
X	vidattr(A_NORMAL);
X
X	putchar('\n');
X
X	return(str);
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Funktionstasten programmieren					*/
X/*----------------------------------------------------------------------*/
X
Xvoid	chat_pr_fkey(str)
X
Xchar	*str;
X{
X	int	num;
X
X	if(isdigit(*str))	/* abrufen ?	*/
X	{
X		num=(int)*str-(int)'0';
X
X		if(fkey[num]!=(char *)0)	/* programiert ?	*/
X			free(fkey[num]);
X
X		do				/* Anfang suchen	*/
X			str++;
X		while(*str==' ' || *str==TAB);
X
X		if(*str=='\0')			/* loeschen ?		*/
X			fkey[num]=(char *)0;
X		else
X		{
X			fkey[num]=malloc(strlen(str)+1); /* Speichern	*/
X
X			strcpy(fkey[num],str);
X		}
X	}
X	else
X		chat_fkey(str);
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Funktionstasten abrufen						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	chat_fkey(str)
X
Xchar	*str;
X{
X	int	num;
X
X	if(isdigit(*str))	/* abrufen ?	*/
X	{
X		num=(int)*str-(int)'0';
X
X		if(fkey[num]!=(char *)0)	/* programiert ?	*/
X		{
X			char	msg[STRLEN];
X
X			str++;
X			sprintf(msg,"%s%s",fkey[num],str);
X
X			if(mode & REVERSE)	/* Revers ?		*/
X				vidattr(A_REVERSE);
X			else
X				vidattr(A_BOLD);
X
X			printf("%s%s%s\n",cname,prompt,msg);
X			pub_msg(msg);		/* senden		*/
X		}
X	}
X	else			/* alles ausgeben	*/
X		for(num=0;num<10;num++)
X		{
X			printf("f%d='",num);
X			if(fkey[num]!=(char *)0)
X				printf("%s",fkey[num]);
X			printf("'\n");
X		}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Modi-Parser							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	chat_mode(str)
X
Xchar	*str;
X{
X	int	i;
X
X	for(i=0;str[i]!='\0';i++)	/* klein machen	*/
X		if(isupper(str[i]))
X			str[i]=tolower(str[i]);
X
X	for(i=0;str[i]!='\0';i++)
X	{
X		if(str[i]==TAB || str[i]==' ')		/* Space ?	*/
X			continue;
X		else if(!strncmp(str+i,"beep",4))	/* Beep ein ?	*/
X		{
X			i+=3;
X			mode |= BEEPER;
X		}
X		else if(!strncmp(str+i,"nobeep",6))	/* Beep aus ? 	*/
X		{
X			i+=5;
X			mode &= ~BEEPER;
X		}
X		else if(!strncmp(str+i,"jump",4))	/* Scrollen ?	*/
X		{
X			i+=3;
X			mode |= JUMP;
X		}
X		else if(!strncmp(str+i,"nojump",6))	/* Nicht scrollen ? */
X		{
X			i+=5;
X			mode &= ~JUMP;
X		}
X		else if(!strncmp(str+i,"reverse",7))	/* Invers ?	*/
X		{
X			i+=6;
X			mode |= REVERSE;
X		}
X		else if(!strncmp(str+i,"bold",4))	/* Hell ?	*/
X		{
X			i+=3;
X			mode &= ~REVERSE;
X		}
X		else					/* Fehler	*/
X		{
X			puts(nomode);
X			break;
X		}
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Hilfe								*/
X/*----------------------------------------------------------------------*/
X
Xvoid	chat_help()
X
X{
X	FILE	*fp;
X	char 	c;
X
X	if((fp=fopen(help,"r"))==(FILE *)0) /* oeffnen */
X		printf("can't open %s\n",help);
X	else
X	{
X		while(!feof(fp))	/* Ende ? */
X		{
X			c=(char)fgetc(fp);
X
X			if(!feof(fp))
X				putchar(c);
X		}
X
X		fclose(fp);	/* schliessen	*/
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Wer ist in der Konferenz ?					*/
X/*----------------------------------------------------------------------*/
X
Xvoid	conf_members(co,m)
X
Xchar	*co;	/* Konferenz			*/
Xchar	m;	/* Mode: 'p' = Mit Passwort	*/
X{
X	FILE	*fp;
X	char 	str[STRLEN],str2[STRLEN];
X
X	sprintf(str,"confdir/%s",co);	/* Konferenz-File */
X
X	if((fp=fopen(str,"r"))==(FILE *)0) /* oeffnen */
X		printf("can't open %s\n",str);
X	else
X	{
X		fscanf(fp,"%s",str);
X		printf("%s (%s)\n",members,co);
X
X		fscanf(fp,"%s",str);	/* Password	*/
X		if(strcmp(str,STDPASS) && m=='p')
X			printf("%s%s\n",password,str);
X
X		while(!feof(fp))	/* Ende ? */
X		{
X			fscanf(fp,"%s %s",str,str2);
X			if(!feof(fp))
X				printf("%s%c(%s)\n",
X				str,TAB,str2);	/* ausg. */
X		}
X
X		fclose(fp);	/* schliessen	*/
X	}
X}
SHAR_EOF
$TOUCH -am 0806102490 ch/utility.c &&
chmod 0600 ch/utility.c ||
echo "restore of ch/utility.c failed"
set `wc -c ch/utility.c`;Wc_c=$1
if test "$Wc_c" != "5572"; then
	echo original size 5572, current size $Wc_c
fi
# ============= ch/output.c ==============
echo "x - extracting ch/output.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/output.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Output					*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <signal.h>
X#include <curses.h>
X#include <term.h>
X#include "ch.h"
X
X/*----------------------------------------------------------------------*/
X/* 	Ausgabe								*/
X/*----------------------------------------------------------------------*/
X/*	Return: Anzahl der empfangenen Messages				*/
X/*----------------------------------------------------------------------*/
X
Xint	output(anz)
X
Xint	anz;	/* Anzahl der vorzurueckenden Zeilen 	*/
X{
X	UMSG	*msg;
X	int  	ret=0;			/* noch keine Message	*/
X	char	str[STRLEN];
X	int	i;
X
X	signal(SIGUSR1,SIG_IGN);	/* Interrupt loeschen	*/
X
X	do
X	{
X		msg=recv_msg();			/* empfangen	*/
X
X		if(msg->typ != EMPTY && ret==0)	/* Message da ?	*/
X		{
X			if(anz)
X			{
X			int	i;
X
X			if(parm_down_cursor!=(char *)0) /* runter */
X				putp(tparm(parm_down_cursor,anz));
X			else		/* einzeln runter	*/
X			for(i=0;i<anz;i++)
X				putp(cursor_down);
X			}
X
X			vidattr(0);	/* normale Schrift	*/
X		}
X
X		switch(msg->typ)
X		{
X		case MESSAGE:			/* Nachricht 		*/
X			sprintf(str,"\n%s",msg->text);
X			fputs(str,stdout);
X			ret++;			/* 1. Message mehr 	*/
X			break;
X
X		case ARRIVAL:			/* Ankunft 		*/
X			if(mode & BEEPER)
X			sprintf(str,"\n***%c %s %s ***",BELL,msg->text,arr);
X			else
X			sprintf(str,"\n*** %s %s ***",msg->text,arr);
X
X			fputs(str,stdout);
X			ret++;			/* 1. Message mehr 	*/
X			break;
X
X		case DEPARTURE:			/* Verlassen 		*/
X			if(mode & BEEPER)
X			sprintf(str,"\n***%c %s %s ***",BELL,msg->text,dep);
X			else
X			sprintf(str,"\n*** %s %s ***",msg->text,dep);
X
X			fputs(str,stdout);
X			ret++;			/* 1. Message mehr 	*/
X			break;
X
X		case KILL:			/* Rauswurf		*/
X			if(mode & BEEPER)
X			sprintf(str,"\n***%c %s %s ***",BELL,msg->text,fire);
X			else
X			sprintf(str,"\n*** %s %s ***",msg->text,fire);
X
X			fputs(str,stdout);
X			ret++;			/* 1. Message mehr 	*/
X			break;
X
X		case CNAME:			/* Namensaenderung	*/
X		{
X			char	s1[STRLEN],s2[STRLEN];
X
X						/* aufbereiten		*/
X			sscanf(msg->text,"%s %s",s1,s2);
X
X			if(mode & BEEPER)
X			sprintf(str,"\n***%c %s --> %s ***",BELL,s1,s2);
X			else
X			sprintf(str,"\n*** %s --> %s ***",s1,s2);
X
X			fputs(str,stdout);
X			ret++;			/* 1. Message mehr 	*/
X			break;
X		}
X
X		case QUIT:			/* beenden 		*/
X			sprintf(str,"\n");
X			fputs(str,stdout);
X			give_notice();
X			deinit();
X			exit(0);
X			break;
X		}	/* Ende switch */
X
X	}
X	while(msg->typ != EMPTY);		/* leer ? 	*/
X
X	i   = -1;
X	len =  0;
X	while(str[++i]!='\0')
X		if(str[i]!='\n' && str[i]!=BELL)
X			len++;		/* Laenge merken	*/
X	
X	return(ret);
X}
SHAR_EOF
$TOUCH -am 0806103490 ch/output.c &&
chmod 0600 ch/output.c ||
echo "restore of ch/output.c failed"
set `wc -c ch/output.c`;Wc_c=$1
if test "$Wc_c" != "2887"; then
	echo original size 2887, current size $Wc_c
fi
# ============= ch/menu.c ==============
echo "x - extracting ch/menu.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/menu.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Menue					*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include <stdio.h>
X#include <curses.h>
X#include <term.h>
X#include <ctype.h>
X#include "ch.h"
X
Xstatic	void	menu_out();
Xstatic	void	conf_out();
X 
X/*----------------------------------------------------------------------*/
X/* 	Menue								*/
X/*----------------------------------------------------------------------*/
X
Xvoid	chat_menu()
X
X{
X	char 	c;
X	char	str[STRLEN];
X
X	menu_out();
X
X	FOREVER
X	{
X		read(0,&c,1);		/* einlesen	*/
X
X		if(isupper(c))		/* Klein machen	*/
X			c=tolower(c);
X
X		switch(c)
X		{
X		case 'x':		/* Ende ?		*/
X			CLEAR;
X			deinit();
X			exit(0);
X			break;
X
X		case '1':		/* sysconf		*/
X			puts("\n");
X			strcpy(conf,"sysconf");
X
X			strcpy(pw,STDPASS);	/* Password 	*/
X			input();	/* Eingabeschleife	*/
X			menu_out();
X			break;
X
X		case '2':		/* andere Konf.		*/
X			puts("\n");
X			strcpy(conf,read_string(conf_name));
X			puts("\n");
X
X			strcpy(pw,STDPASS);/* Password 		*/
X
X			if(conf[0]!='\0')
X				input();	/* Eingabeschleife	*/
X
X			menu_out();
X			break;
X
X		case '3':		/* Konf. beginnen	*/
X			puts("\n");
X			strcpy(conf,read_string(conf_name));
X			puts("\n");
X
X			if(conf[0]!='\0')
X			{
X				sprintf(str,"%s/chman -c'%s' &",
X				BINDIR,conf);
X				system(str);	/* starten		*/
X				sleep(4);
X
X				strcpy(pw,STDPASS);/* Password 		*/
X				input();	/* Eingabeschleife	*/
X			}
X			menu_out();
X			break;
X
X		case '4':		/* priv Konf. beginnen	*/
X			puts("\n");
X			strcpy(conf,read_string(conf_name));
X			puts("\n");
X			if(conf[0]!='\0')
X			{
X				strcpy(pw,read_string(password));
X	
X				sprintf(str,"%s/chman -c'%s' -p'%s' &",
X				BINDIR,conf,pw);
X				system(str);	/* starten		*/
X				sleep(4);
X	
X				input();	/* Eingabeschleife	*/
X			}
X			menu_out();
X			break;
X
X		case '5':		/* Konferenzen anzeigen	*/
X			conf_out();
X			menu_out();
X			break;
X
X		default:
X			putchar(BELL);
X			fflush(stdout);
X			break;
X		}
X	}
X}
X
Xstatic	void	menu_out()
X
X{
X	char	str[STRLEN];
X	FILE	*fp;
X	char	c;
X
X	CLEAR
X
X	if((fp=fopen(menufile,"r"))==(FILE *)0) /* oeffnen */
X		printf("can't open %s\n",menufile);
X	else
X	{
X		while(!feof(fp))	/* Ende ? */
X		{
X			c=(char)fgetc(fp);
X
X			if(!feof(fp))
X				putchar(c);
X		}
X
X		fclose(fp);	/* schliessen	*/
X	}
X}
X
Xstatic	void	conf_out()
X
X{
X	FILE	*fp;
X	struct	direct	dir;	/* Directory - Struktur		*/
X	char	str[STRLEN];	/* String	*/
X
X	if((fp=fopen("confdir","r"))==(FILE *)0)	/* oeffnen	*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	while(!feof(fp))		/* Ende ?		*/
X	{
X		if(!fread((char *)&dir,sizeof(dir),1,fp)) /* einlesen	*/
X			continue;
X
X		if(dir.d_ino==(ino_t)0)			/* unused ?	*/
X			continue;
X
X		strncpy(str,dir.d_name,DIRSIZ);	/* kopieren		*/
X		str[DIRSIZ]='\0';		/* beenden		*/
X
X		if(str[0]=='.')
X			continue;
X
X		CLEAR;
X		fflush(stdout);
X
X		if(mode & REVERSE)		/* Revers ?		*/
X			vidattr(A_REVERSE);
X		else
X			vidattr(A_BOLD);
X
X		puts(str);			/* Konferenznamen	*/
X
X		vidattr(0);
X
X		conf_members(str,'n');		/* Ausgeben ohne Password */
X
X		menu_key();
X	}
X
X	fclose(fp);
X}
SHAR_EOF
$TOUCH -am 0806102490 ch/menu.c &&
chmod 0600 ch/menu.c ||
echo "restore of ch/menu.c failed"
set `wc -c ch/menu.c`;Wc_c=$1
if test "$Wc_c" != "3358"; then
	echo original size 3358, current size $Wc_c
fi
# ============= ch/invite.c ==============
echo "x - extracting ch/invite.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/invite.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Einladung und Blitzmeldung		*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <utmp.h>
X#include <pwd.h>
X#include <stdio.h>
X#include "ch.h"
X
Xstatic	void	send_to_user();
X
X/*----------------------------------------------------------------------*/
X/* 	Einladung							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	invite(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	int	i;
X	char	name[STRLEN],str[STRLEN];
X
X	FOREVER
X	{
X		while(*text==' ' || *text==TAB)
X			text++;
X
X		i=0;
X		while(*text!=' ' && *text!=TAB && *text!='\0')
X		{
X			name[i++] = *text;
X			text++;
X		}
X
X		if(i==0)		/* Ende ?	*/
X			break;
X
X		name[i++]='\0';		/* beenden	*/
X
X		/* Message an tty senden ----------------- */
X		
X		sprintf(str,"%s (%s)",inv,conf);
X
X		send_to_user(name,str);
X
X		/* Ende an tty senden -------------------- */
X
X		if(*text=='\0')		/* text schon zu ende	?	*/
X			break;
X	}
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Nachricht							*/
X/*----------------------------------------------------------------------*/
X
Xvoid	message(text)
X
Xchar	*text;				/* Messagetext	*/
X{
X	int	i;
X	char	name[STRLEN];
X
X	while(*text==' ' || *text==TAB)
X		text++;
X
X	i=0;
X	while(*text!=' ' && *text!=TAB && *text!='\0')
X	{
X		name[i++] = *text;
X		text++;
X	}
X
X	if(i==0)		/* Ende ?	*/
X		return;
X
X	name[i++]='\0';		/* beenden	*/
X
X	while(*text == ' ' || *text == TAB)
X		text++;
X
X	/* Message an tty senden ----------------- */
X		
X	send_to_user(name,text);
X
X	/* Ende an tty senden -------------------- */
X}
X
Xstatic	void	send_to_user(name,text)
X
Xchar	*name;				/* Username	*/
Xchar	*text;				/* Messagetext	*/
X{
X	char	tty[STRLEN];
X	char	str[STRLEN];
X	char	path[STRLEN];
X	FILE	*fp,*fp2;
X	struct	utmp	ut;	/* UTMP - Struktur	*/
X	struct	passwd	*pwd;	/* Password-Struct	*/
X	int	count=0;
X
X	pwd=getpwnam(name);	/* Password-Struct holen */
X	if(pwd == (struct passwd *)0)
X	{
X		printf(nouser,name);
X		putchar('\n');
X		return;		/* Fehler	*/
X	}
X
X	if((fp=fopen(UTMP_FILE,"r"))==(FILE *)0)	/* oeffnen	*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	while(!feof(fp))		/* Ende ?		*/
X	{
X		if(!fread((char *)&ut,sizeof(ut),1,fp)) /* einlesen	*/
X			continue;
X
X		if(ut.ut_type != USER_PROCESS)	/* Kein User-Prozess ?	*/
X			continue;
X
X		if(strncmp(ut.ut_user,name,8))	/* Falscher User ?	*/
X			continue;
X
X		count++;		/* Einen User mehr gefunden	*/
X
X		strcpy(tty,ut.ut_line);	/* tty kopieren		*/
X		sprintf(path,"/dev/%s",tty);
X
X		if((fp2=fopen(path,"w")) == (FILE *)0)
X		{
X			printf(nomsg,name);
X			putchar('\n');
X			continue;
X		}
X
X		sprintf(str,msg_from,getlogin());	/* senden	*/
X		fprintf(fp2,"\n*** %s ***\n*** %s ***\n",str,text);
X
X		printf("%s [%s]\n",name,tty);		/* bestaetigen	*/
X
X		fclose(fp2);
X	}
X
X	fclose(fp);
X
X	if(!count)		/* Kein User online	*/
X	{
X		printf(not_online,name);
X		putchar('\n');
X	}
X}
X
SHAR_EOF
$TOUCH -am 0806180390 ch/invite.c &&
chmod 0600 ch/invite.c ||
echo "restore of ch/invite.c failed"
set `wc -c ch/invite.c`;Wc_c=$1
if test "$Wc_c" != "3234"; then
	echo original size 3234, current size $Wc_c
fi
# ============= ch/grep.c ==============
echo "x - extracting ch/grep.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ch/grep.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			Chatter V2.9				*/
X/*	                                                                */
X/*	Programmteil:		Grep					*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/dir.h>
X#include <stdio.h>
X#include <ctype.h>
X#include "ch.h"
X
Xstatic	int	str_cmp();
X
X/*----------------------------------------------------------------------*/
X/* 	Grep								*/
X/*----------------------------------------------------------------------*/
X/*	Return:		1-gefunden	0-nicht				*/
X/*----------------------------------------------------------------------*/
X
Xint	grep(str,file)
X
Xchar	*str;			/* String nach dem gesucht wird		*/
Xchar	*file;			/* Filename, in dem gesucht wird	*/
X{
X	FILE	*fp;		/* Filepointer		*/
X	int	ret=0;		/* noch nicht gefunden	*/
X	char	str2[STRLEN];	/* String		*/
X
X	if((fp=fopen(file,"r")) == (FILE *)0)	/* oeffnen		*/
X	{
X		fprintf(stderr,"%s: can't open \"%s\".\n",pname,file);
X		deinit();
X		exit(2);
X	}
X
X	while(!feof(fp))
X	{
X		fscanf(fp,"%s",str2);	/* einlesen	*/
X
X		if(!str_cmp(str,str2))	/* passt ?	*/
X		{
X			ret=1;
X			break;
X		}
X	}
X
X	fclose(fp);
X
X	return(ret);
X}
X
Xstatic	int	str_cmp(s1,s2) /* Eigenes strcmp ohne Gross/Kleinschreibung */
X
Xchar	*s1,*s2;
X{
X	int	i;
X	char	sc1[STRLEN],sc2[STRLEN];
X
X	i = -1;
X	do	/* kopieren (nur kleinschrift)	*/
X	{
X		i++;
X		sc1[i] = s1[i];
X
X		if(isupper(sc1[i]))
X			sc1[i]=tolower(sc1[i]);
X	}
X	while(s1[i] != '\0');
X
X	i = -1;
X	do	/* kopieren (nur kleinschrift)	*/
X	{
X		i++;
X		sc2[i] = s2[i];
X
X		if(isupper(sc2[i]))
X			sc2[i]=tolower(sc2[i]);
X	}
X	while(s2[i] != '\0');
X
X	return(strcmp(sc1,sc2));
X}
SHAR_EOF
$TOUCH -am 0806112690 ch/grep.c &&
chmod 0600 ch/grep.c ||
echo "restore of ch/grep.c failed"
set `wc -c ch/grep.c`;Wc_c=$1
if test "$Wc_c" != "1792"; then
	echo original size 1792, current size $Wc_c
fi
# ============= cm/init.c ==============
if test ! -d 'cm'; then
    echo "x - creating directory cm"
    mkdir 'cm'
fi
echo "x - extracting cm/init.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > cm/init.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			ChatManager V2.9			*/
X/*	                                                                */
X/*	Programmteil:		Initialisierungen			*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <stdio.h>
X#include <fcntl.h>
X#include <errno.h>
X#include "cm.h"
X
X/*----------------------------------------------------------------------*/
X/* 	Initialisierungen						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	init()
X{
X	char	str[STRLEN];
X	int 	fd;				/* Filedeskriptor 	*/
X	int 	i;
X	int	flags;
X
X	for(i=0;i<MAXUSER;i++)			/* alle User loeschen	*/
X		userlist[i].pid= -1;
X
X	/* Conf anlegen ----------------------------- */
X
X	sprintf(str,"confdir/%s",conf);		/* Konferenz-File 	*/
X
X	fd=open(str,O_WRONLY | O_CREAT | O_EXCL,MODE);	/* oeffnen 	*/
X
X	if(fd==-1)				/* schon belegt ?	*/
X	{
X		if(errno==EEXIST)
X		{
X			fprintf(stderr,"%s: conference exists\n",pname);
X			deinit();
X			exit(2);
X		}
X		else				/* Anderer Fehler	*/
X		{
X			fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X			deinit();
X			exit(2);
X		}
X	}
X
X 	key=getpid();				/* Messagekey holen 	*/
X	if(key== -1)				/* Fehler ? 		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X	
X	close(fd);				/* schliessen 		*/
X
X	write_conf();
X	conf_on=1;				/* Konferenz ist an	*/
X
X	/* Ende Conf anlegen -------------------------- */
X
X	/* FIFO anlegen ------------------------------- */
X
X	sprintf(str,"fifodir/%ld",key);		/* Pfad fuer FIFO	*/
X
X	if(mknod(str,S_IFIFO | MODE,0)==-1)	/* Anlegen		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	fifofd=open(str,O_RDWR);		/* FIFO oeffnen 	*/
X	if(fifofd== -1)				/* Fehler ? 		*/
X	{
X		fprintf(stderr,"%s: %s\n",pname,sys_errlist[errno]);
X		deinit();
X		exit(2);
X	}
X
X	/* Ende FIFO anlegen -------------------------- */
X
X	setpgrp();				/* eigene Prozessgruppe	*/
X}
X
X/*----------------------------------------------------------------------*/
X/* 	Deinitialisierungen						*/
X/*----------------------------------------------------------------------*/
X
Xvoid	deinit()
X{
X	char str[STRLEN];	/* String fuer Pfad- und Dateinamen	*/
X	
X	/* File loeschen ---------------------------- */
X	
X	if(conf_on)		/* Konferenz an ?		*/
X	{
X		sprintf(str,"confdir/%s",conf);
X		unlink(str);
X	}
X
X	/* FIFO loeschen -------------------- */
X
X	if(fifofd != -1)
X	{
X		UMSG umsg;
X		int  i;
X
X		umsg.typ=QUIT;		/* Message aufbereiten 	*/
X
X		for(i=0;i<MAXUSER;i++)	/* alle User durchgehen	*/
X			if(userlist[i].pid!= -1)
X				send_msg(&umsg,&userlist[i]);/* senden 	*/
X
X		sprintf(str,"fifodir/%ld",key);
X		unlink(str);
X
X		close(fifofd);
X	}
X
X	chdir(cwd);		/* Directory einstellen 	*/
X}
SHAR_EOF
$TOUCH -am 0806102990 cm/init.c &&
chmod 0600 cm/init.c ||
echo "restore of cm/init.c failed"
set `wc -c cm/init.c`;Wc_c=$1
if test "$Wc_c" != "2912"; then
	echo original size 2912, current size $Wc_c
fi
# ============= cm/int.c ==============
echo "x - extracting cm/int.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > cm/int.c &&
X/*----------------------------------------------------------------------*/
X/*									*/
X/*	Name:			ChatManager V2.9			*/
X/*	                                                                */
X/*	Programmteil:		Messageinterpreter			*/
X/*									*/
X/*	Library:		UNIX V					*/
X/*									*/
X/*	Autor:			Marc Laukien				*/
X/*									*/
X/*----------------------------------------------------------------------*/
X
X#include <stdio.h>
X#include "cm.h"
X
X/*----------------------------------------------------------------------*/
X/* 	Message-Interpreterschleife					*/
X/*----------------------------------------------------------------------*/
X
Xvoid	msg_int()
X
X{
X	MSG	*msg;
X	int	i,j;
X
X	do
X	{
X	msg=recv_msg();			/* Empfangen 		*/
X
X	switch(msg->typ)		/* was fuer ein Typ 	*/
X	{
X	case EMPTY:			/* leer 	*/
X		break;
X
X	case ARRIVAL:			/* neuer User 	*/
X		i=0;
X		while(userlist[i].pid != -1 && i<MAXUSER)
X			i++;		/* freien Platz suchen 	*/
X
X		if(i!=MAXUSER)
X		{
X			sscanf(msg->text,"%ld %s %s",
X			&userlist[i].key,userlist[i].name,
X			userlist[i].cname);
X
X			if(userlist[i].key == -1)	/* Fehler ? 	*/
X			{
X				fprintf(stderr,"%s: %s\n",pname
X				,sys_errlist[errno]);
X				userlist[i].pid = -1;
X			}
X			else
X			{
X			UMSG umsg;
X
X			sprintf(umsg.text,"%s",userlist[i].cname);
X			umsg.typ=ARRIVAL;	/* aufbereiten 		*/
X
X			for(j=0;j<MAXUSER;j++)	/* User durchgehen 	*/
X				if(userlist[j].pid!= -1)/* senden 	*/
X					send_msg(&umsg,&userlist[j]);
X
X			userlist[i].pid = msg->pid;	/* speichern 	*/
X			usernr++;		/* ein User mehr 	*/
X
X			write_conf();	/* Conf-Datei neu anlegen 	*/
X			}
X		}
X		break;
X
X	case DEPARTURE:			/* User geht 		*/
X		i=0;
X		while(userlist[i].pid != msg->pid && i<MAXUSER)
X			i++;		/* Eintrag suchen 	*/
X
X		if(i!=MAXUSER)
X		{
X		UMSG umsg;
X
X		sprintf(umsg.text,"%s",userlist[i].cname);
X		umsg.typ=DEPARTURE;	/* Message aufbereiten	*/
X
X		userlist[i].pid= -1;	/* Daten loeschen	*/
X		usernr--;		/* ein User weniger	*/
X
X		for(j=0;j<MAXUSER;j++)	/* alle User durchgehen		*/
X			if(userlist[j].pid!= -1)	/* senden 	*/
X				send_msg(&umsg,&userlist[j]);
X
X		write_conf();		/* Conf-Datei neu anlegen 	*/
X		}
X		break;
X
X	case MESSAGE:			/* oeffentliche Nachricht	*/
X	case NOPROMPT:
X		i=0;
X		while(userlist[i].pid != msg->pid && i<MAXUSER)
X			i++;		/* Eintrag suchen	*/
X
X		if(i!=MAXUSER)		/* gefunden ?		*/
X		{
X		UMSG umsg;
X
X		if(msg->typ==NOPROMPT)	/* Kein Prompt ?	*/
X			sprintf(umsg.text,"%s%s",userlist[i].cname,msg->text);
X		else
X			sprintf(umsg.text,"%s: %s",userlist[i].cname,msg->text);
X
X		umsg.typ=MESSAGE;	/* Message aufbereiten	*/
X
X		for(j=0;j<MAXUSER;j++)	/* alle User durchgehen	*/
SHAR_EOF
echo "End of UnixChat part 1"
echo "File cm/int.c is continued in part 2"
echo "2" > shar3_seq_.tmp
exit 0
-- 
   /              |    -: Marc Laukien :-     |
  /__             |                           |   _  _           __
 /   \  /_  /  /  |   ml@brumuc.bru.sub.org   |  / \/ |   /  /  /
/____/ /   /__/   | sigma@salyko.doit.sub.org | /     |  /__/  /__