Party - A multi user rap program for SysV
John C. Sucilla
jcs at tarkus.UUCP
Mon Oct 17 05:00:39 AEST 1988
Theres been quite a few people asking for multi user talk/write type programs
the last few months so I figured I'd let this one out finally.
Have fun...
#!/bin/sh
# shar: Shell Archiver
# Run the following text with /bin/sh to create:
# makefile
# partyhlp
# party.c
sed 's/^X//' << 'SHAR_EOF' > makefile
X# Run the install phase as root
X# The files target only needs to be hit once, the first time you build.
X
XCC=cc
XCFLAGS=-O -DUSG -s -o party
XLCFLAGS=-68010
XINSTALL=/local/bin/
XPFILES=/usr/bbs/
X
Xparty: party.c
X $(CC) $(LCFLAGS) $(CFLAGS) party.c
X chmod 755 party
X
Xinstall: party
X ln $(INSTALL)party $(INSTALL)oparty
X -rm $(INSTALL)party
X mv ./party $(INSTALL)party
X chmod 2711 $(INSTALL)party
X chgrp party $(INSTALL)party
X
Xfiles:
X echo > $(PFILES).party
X echo > $(PFILES).party1
X echo > $(PFILES).party2
X echo > $(PFILES).party3
X echo > $(PFILES).party4
X echo > $(PFILES).party.passwd
X echo > $(PFILES)potd
X chmod 664 $(PFILES).party*
X chmod 660 $(PFILES).party4 $(PFILES).party.passwd
X echo "All files created, edit $(PFILES).party.passwd to set a password"
X
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > partyhlp
XThings typed in here are saved in a file. Please
Xuse your common sense...
X
XPARTY help:
Xq Exit the party program
X! Unix shell escape
X% Party Console
X i = Invite a user to party
X m = Send a one line message to user
X n = Change name
X p = Join a different party
X r = Read file into party
X s = Scroll back and read again
X t = Toggle this message off/on
X w = Who is on the system
X? This message
Xh This message
X(space) enter a response.
SHAR_EOF
sed 's/^X//' << 'SHAR_EOF' > party.c
X/* John "C". Sucilla's party hack.
X * This Party program is based on the single process party
X * by Jan Wolter which was a rewrite of Marcus's PD party.
X * Thanks for the original version(s) Jan and Marcus!
X *
X * You should define either VER7 or USG to compile.
X * I have no idea if it will still compile under Version 7 though...
X * It works on my 3B1 (tarkus), a 3B2/300 (chinet) and an AT clown
X * running Microport (igloo).
X *
X * This program remains in the public domain because theres lots
X * of Jan/Marcus code in it.
X **************************************************************************
X * Hacks by John "C". Sucilla ...ihnp4{chinet|nwutb}!jcs:
X * Added "Party Console". Currently, the control center allows the user
X * to:
X *
X * 1) Change his name (silently) in a party. A check is done to verify
X * that the requested new name does not exist in the passwd file.
X * Some people don't like their logname used in vain...
X *
X * 2) Switch from the standard party (/usr/bbs/.party) to one of 4
X * private parties (.party[1-4]). .party4 is accessed thru the
X * password in /usr/bbs/.party.passwd. It is not encrypted.
X *
X * 3) Read file capability added. Limited to 66 lines.
X *
X * 01/Aug/87 - jcs
X * 1) Added "who" command to console.
X *
X * 2) Added "invite" command to console. Echo to the invited user's
X * tty if possible. If not possible, send mail. If they are not
X * logged in, abort.
X *
X * 31/Aug/87 - jcs
X * 1) Added support for the SHELL environment variable so Korn Shell
X * users can use thier alias's. If SHELL is not set, it uses /bin/sh.
X * 2) Added a private message function. A one line message can be sent
X * to another user.
X *
X * 15/Feb/88 - jcs
X * 1) Added the scroll back function.
X *
X * 03/Jul/88 - jcs
X * 1) Added a "MOTD" type function. Party will now print the contents
X * of /usr/bbs/potd if it exists.
X */
X
X#include <stdio.h>
X#include <sys/types.h>
X#include <sys/stat.h>
X#include <fcntl.h>
X#include <signal.h>
X#include <setjmp.h>
X#include <pwd.h>
X#include <utmp.h>
X#ifdef VER7
X#include <sgtty.h>
X#endif
X#ifdef USG
X#include <termio.h>
X#include <ctype.h>
X#endif
X#ifdef EWOULDBLOCK
X#include <sys/file.h> /* 4.2BSD flock */
X#endif
X
X#ifdef TCGETA
Xstruct termio cooked, cbreak;
X#define EOFCHAR (cooked.c_cc[VEOF])
X#define GTTY(fd, st) ioctl(fd, TCGETA, (st))
X#define STTY(fd, st) ioctl(fd, TCSETAF, (st))
X#endif
X
X#ifdef TIOCGETC
Xstruct tchars ctrlchars;
X#define EOFCHAR (ctrlchars.t_eofc)
Xstruct sgttyb cooked, cbreak;
X#define GTTY(fd, st) ioctl(fd, TIOCGETP, (st))
X#define STTY(fd, st) ioctl(fd, TIOCSETN, (st))
X#endif
X
X#ifdef LOCK_EX
X#define LOCK(file) flock(fileno(file), LOCK_EX)
X#define UNLOCK(file) flock(fileno(file), LOCK_UN)
X#else
X#define LOCK(file) fseek(file, 0L, 0), chk_lock(file, 1, -1L)
X#define UNLOCK(file) fseek(file, 0L, 0), chk_lock(file, 0, -1L)
X#endif
X
Xchar *passfile = "/usr/bbs/.party.passwd";
Xchar *partyfile = "/usr/bbs/.party";
Xchar *basename = "/usr/bbs/.";
Xchar *helpfile = "/usr/bbs/partyhlp";
Xchar *potdfile = "/usr/bbs/potd";
Xchar *name[20];
Xchar *VER = "Version 3.3.1";
Xchar id_alg;
Xchar *who_cmd = "who -T";
Xchar *invitation = "echo \"Party or Die!!!\" | mail ";
Xchar progname[14];
X
X#define ON 0
X#define OFF 1
Xint C_FLAG = ON;
X
XFILE *wfd;
Xint rst;
Xjmp_buf jenv;
Xextern int errno;
X
X#define BFSZ 200
Xchar inbuf[BFSZ+24];
X#define buf (inbuf+10)
Xchar *cancel = " XXX\n";
X
Xint alrm(), intr();
Xchar *getlogin(), *malloc(), *ctime(), *fgets(), *strchr();
Xstruct passwd *getpwnam(), *getpwuid();
Xlong lseek(), time();
X
X
Xmain(argc,argv)
Xint argc;
Xchar **argv;
X{
Xregister int n, i;
Xchar ch, *pnl;
Xstruct passwd *pwd;
Xlong now = time((long *)0);
X
X if (!(strcpy (name, getlogin())) || !(pwd = getpwnam(name))
X || pwd->pw_uid != getuid()) {
X if (pwd = getpwuid(getuid()))
X strcpy (name, pwd->pw_name);
X else
X strcpy (name, "(unknown)");
X }
X strcpy(inbuf,name);
X strcat(inbuf,": ");
X
X /* Get ioctl modes */
X errno = 0;
X GTTY(0,&cooked);
X#ifndef TCSETA
X ioctl(0, TIOCGETC, &ctrlchars);
X#endif
X if (errno != 0)
X {
X printf("Input not a tty");
X exit(1);
X }
X cbreak = cooked; /* This works? */
X#ifdef TCSETA
X cbreak.c_lflag &= ~(ECHO | ICANON);
X cbreak.c_cc[VMIN] = 1;
X cbreak.c_cc[VTIME] = 0;
X#else /* else use TIOCGETC v7 */
X cbreak.sg_flags &= ~ECHO;
X cbreak.sg_flags |= CBREAK;
X#endif
X
X /* convert the program name to upper case */
X for (i = 0; argv[0][i] != NULL; i++) {
X progname[i] = toupper (argv[0][i]);
X }
X progname[++i] = NULL;
X
X printf ("Welcome to %s -- %s Type ? for HELP, ", progname, VER);
X printf ("%c for CONSOLE\n", 0x25);
X
X /* Print the Party message of the day if it exists */
X potd ();
X
X /* Put up the signal handlers */
X signal(SIGQUIT,intr);
X signal(SIGINT,intr);
X signal(SIGALRM,alrm);
X
X /* Open partyfile and put in join message */
X if ((wfd = fopen(partyfile,"a")) == NULL)
X {
X printf("Cannot write partyfile %s\n",partyfile);
X exit(1);
X }
X LOCK(wfd);
X fseek(wfd,0L,2);
X fprintf(wfd,"---- %s joining (%.12s)\n",name,ctime(&now)+4);
X fflush(wfd);
X UNLOCK(wfd);
X
X if ((rst = open(partyfile,O_RDONLY)) < 0)
X {
X printf("Cannot read partyfile %s\n",partyfile);
X exit(1);
X }
X
X /* Position read pointer 300 characters from the end of the file */
X if (lseek(rst,-300L,2) < 0)
X {
X /* File isn't that long -- start from begining */
X lseek(rst,0L,0);
X }
X else
X /* Skip forward to a newline */
X while (read(rst,&ch,1) > 0 && ch != '\n')
X ;
X
X /* Get in cbreak/noecho mode */
X STTY(0,&cbreak);
X
X for(;;)
X {
X if ((n = read(rst,buf,BFSZ)) > 0)
X write(1,buf,n);
X else
X {
X alarm(4);
X if (!setjmp(jenv))
X {
X read(0,&ch,1);
X
X alarm(0);
X if (ch == EOFCHAR) intr();
X STTY(0,&cooked);
X switch (ch)
X {
X case '!':
X putc('!',stderr);
X if (fgets(buf,BFSZ,stdin))
X {
X if ((pnl = strchr(buf,'\n'))
X != NULL)
X *pnl = '\0';
X usystem(buf);
X fputs("!\n",stderr);
X }
X else
X fputs(cancel,stderr);
X STTY(0,&cbreak);
X break;
X case 'q':
X intr();
X break;
X case '?':
X case 'h':
X help();
X break;
X case '%':
X control();
X STTY(0, &cbreak);
X break;
X default:
X putc ('>', stderr);
X putc (' ', stderr);
X fputs (ch, stderr);
X if (fgets(buf,BFSZ,stdin))
X {
X if (buf[0] != '\0')
X {
X LOCK(wfd);
X fseek(wfd,0L,2);
X fputs(inbuf,wfd);
X fflush(wfd);
X UNLOCK(wfd);
X }
X else
X fputs(cancel,stderr);
X }
X else
X fputs(cancel,stderr);
X STTY(0,&cbreak);
X break;
X }
X }
X }
X }
X}
X
Xalrm()
X{
X signal(SIGALRM,alrm);
X longjmp(jenv,1);
X}
X
Xintr()
X{
Xlong now = time((long *)0);
X
X alarm(0);
X
X signal(SIGINT,SIG_IGN);
X signal(SIGQUIT,SIG_IGN);
X
X LOCK(wfd);
X fseek(wfd,0L,2);
X fprintf(wfd,"---- %s leaving (%.12s)\n",name,ctime(&now)+4);
X fflush(wfd);
X UNLOCK(wfd);
X printf("---- %s leaving (%.12s)\n",name,ctime(&now)+4);
X STTY(0,&cooked);
X exit(0);
X}
X
X
Xusystem(cmd)
Xchar *cmd;
X{
Xint cpid, wpid, status;
Xint (*old_intr)(), (*old_quit)();
Xchar *myshell[20];
X
X if ((cpid = fork ()) == 0) {
X setuid(getuid());
X setgid(getgid());
X strcpy (myshell, getenv ("SHELL"));
X if (myshell[0] == NULL) {
X strcpy (myshell, "/bin/sh");
X }
X execl(myshell,"sh","-c",cmd,(char *)0);
X exit(-1);
X }
X old_intr = signal(SIGINT,SIG_IGN);
X old_quit = signal(SIGQUIT,SIG_IGN);
X while ((wpid = wait(&status)) != cpid && wpid != -1)
X ;
X signal(SIGINT,old_intr);
X signal(SIGQUIT,old_quit);
X}
X
Xhelp()
X{
Xregister int hf;
Xregister int n;
X
X if ((hf = open(helpfile,0)) < 0)
X fprintf(stderr,"Cannot open help file %s\n",helpfile);
X else
X {
X while((n = read(hf,buf,BFSZ)) > 0)
X write(1,buf,n);
X close(hf);
X }
X
X}
X
X
X#ifndef LOCK_EX
X/* Keep calling locking() until it works */
X
Xchk_lock(file,request,size)
XFILE *file;
Xint request;
Xlong size;
X{
X/* register int i = 5;
X *
X * while (locking(fileno(file), request, size) && i--)
X * sleep(1);
X */
X}
X#endif
X
X/*
X * This is the Party Console function.
X */
X
Xcontrol()
X{
Xint i, n, chelp;
Xchar nname[20];
Xchar myname[20];
Xstruct passwd *pwd;
X
X if (C_FLAG == ON) {
X printf("Party Console\n");
X help_cntrl();
X }
X printf("\ncmd: ");
X
X rewind(stdin);
X chelp = getc(stdin);
X
X switch (chelp) {
X case 'n':
X nname[0] = '\0';
X printf ("Your new name: ");
X rewind (stdin);
X fgets (nname,80,stdin);
X if (nname[0] != '\n') {
X
X for (n = 1; n <= strlen(nname); n++) {
X if (nname[n] == '\n') {
X nname[n] = '\0';
X break;
X }
X }
X
X /*
X * Look for control or escapes in name, they can
X * can be used to look like a valid user.
X */
X
X for (n = 0; n < (strlen(nname)); n++) {
X if (nname[n] < 0x20 || nname[n] > 0x7e) {
X printf("Illegal char in name\n");
X return(1);
X }
X }
X
X } else {
X /* None given -- use real name */
X }
X
X /*
X * Test the requested name against valid users.
X * If a match is found, deny the change.
X */
X
X pwd = getpwnam (nname);
X strcpy (myname, getlogin ());
X
X /*
X * Blow up if name exists in passwd file and is
X * not my name.
X */
X
X if ((strcmp (nname, pwd->pw_name) == 0) &&
X (strcmp (myname, nname) != 0)) {
X printf ("Sorry, name is reserved\n");
X break;
X }
X
X if (strcmp (myname, nname) == 0) {
X name[0] = NULL;
X inbuf[0] = NULL;
X strcpy (name,nname);
X strcpy (inbuf,nname);
X strcat (inbuf,": ");
X break;
X } else {
X name[0] = NULL;
X inbuf[0] = NULL;
X strcpy (name,nname);
X strcpy (inbuf,nname);
X strcat (inbuf,": ");
X break;
X }
X case 'h':
X case '?':
X fflush (stdin);
X fflush (stdout);
X fflush (stderr);
X help_cntrl ();
X break;
X case 'p':
X fflush (stdin);
X fflush (stdout);
X fflush (stderr);
X private_party ();
X break;
X case 'r':
X read_file ();
X fflush (stdout);
X fflush (stderr);
X break;
X case 'w':
X who ();
X break;
X case 'i':
X invite ();
X break;
X case 'm':
X p_message();
X break;
X case 't':
X fflush (stdin);
X fflush (stdout);
X fflush (wfd);
X if (C_FLAG == ON)
X C_FLAG = OFF;
X else
X C_FLAG = ON;
X break;
X case 's':
X scrollback ();
X break;
X default:
X printf ("Input error, returning to party...\n");
X return;
X }
X}
X
X/*
X * Help for Party Console.
X */
X
Xhelp_cntrl()
X{
X printf ("i = Invite a user to party\n");
X printf ("m = Send a one line message to user\n");
X printf ("n = Change name\n");
X printf ("p = Join a different party\n");
X printf ("r = Read file into party\n");
X printf ("s = Scroll back and read again\n");
X printf ("t = Toggle this message off/on\n");
X printf ("w = Who is on the system\n");
X}
X
X/*
X * This function will read a file into the party file.
X */
X
Xread_file()
X{
XFILE *rfile;
Xchar ifname[255];
Xchar fname[255];
Xchar fbuff[81];
Xint LIMIT = 66; /* Limit is 66 limes */
Xint line_cnt = 0;
X
X rewind (stdin);
X printf ("File: ");
X gets (ifname);
X /* adjust */
X strncpy (fname, ifname, (sizeof(ifname) -1));
X
X if ((rfile = fopen (fname,"r")) == NULL) {
X printf ("Can't open: %s\n",fname);
X return;
X }
X
X fprintf (wfd,"\nFILE: %s entered by %s\n", fname, name);
X
X while (fgets (fbuff,80,rfile) != NULL) {
X line_cnt++;
X if (line_cnt == LIMIT) {
X printf ("Input file size exceeded...\n");
X line_cnt = 0;
X break;
X } else {
X fprintf (wfd,"%s", fbuff);
X }
X }
X
X fflush (wfd);
X fclose (rfile);
X
X}
X
X/*
X * This function will switch us out of the current party and into
X * a new one thru a call to align().
X */
X
Xprivate_party()
X{
Xint c;
Xchar new_table[8], pass[15];
Xchar p4pass[15];
XFILE *pfile;
X
X printf("File to party in (0 (standard) or 1-4): ");
X rewind(stdin);
X c = getc(stdin);
X fflush (stdin);
X switch(c) {
X case '0':
X strcpy (new_table, "party"); /* Standard party file */
X align(new_table);
X break;
X case '1':
X strcpy (new_table, "party1");
X align(new_table);
X break;
X case '2':
X strcpy (new_table, "party2");
X align(new_table);
X break;
X case '3':
X strcpy (new_table, "party3");
X align (new_table);
X break;
X case '4':
X rewind (stdin);
X strcpy (pass, getpass ("Password: "));
X fflush (stdin);
X if ((pfile = fopen (passfile, "r")) == NULL) {
X printf ("Can't open: %s\n", passfile);
X return;
X }
X fgets (p4pass, 14, pfile);
X fclose (pfile);
X if (strncmp (pass, p4pass, (strlen (p4pass) -1)) == 0) {
X strcpy (new_table, "party4");
X align (new_table);
X } else {
X printf ("Attempt failed. Returning to party...\n");
X }
X break;
X default:
X printf("\nInput error, returning to old party...\n\n");
X break;
X }
X}
X
X/*
X * This function takes care of everything that needs to be modified for
X * a party file switch.
X */
X
Xalign(table)
Xchar *table;
X{
Xregister int n;
Xchar ch, *pnl;
Xchar *pfile[80];
Xstruct passwd *pwd;
Xlong now = time((long *)0);
X
X name[0] = NULL;
X inbuf[0] = NULL;
X pfile[0] = NULL;
X /* Set up path to the new party file */
X strcpy (pfile, basename);
X strcat (pfile, table);
X /* Get user info */
X if (!(strcpy (name, getlogin())) || !(pwd = getpwnam(name))
X || pwd->pw_uid != getuid()) {
X if (pwd = getpwuid(getuid()))
X strcpy (name, pwd->pw_name);
X else
X strcpy (name, "(unknown)");
X }
X strcpy(inbuf,name);
X strcat(inbuf,": ");
X
X fprintf(wfd,"---- %s has moved to %s\n", name, table);
X fprintf(stderr,"\nEntering %s!\n\n", table);
X
X /* close old partyfile */
X fclose(wfd);
X
X /* Open partyfile and put in join message */
X if ((wfd = fopen(pfile,"a")) == NULL)
X {
X printf("Can't write partyfile %s\n",pfile);
X exit(1);
X }
X fseek(wfd,0L,2);
X fprintf(wfd,"---- %s joining (%s) (%.12s)\n",name,table,ctime(&now)+4);
X fflush(wfd);
X
X if ((rst = open(pfile,O_RDONLY)) < 0)
X {
X printf("Cannot read partyfile %s\n",pfile);
X exit(1);
X }
X
X /* Position read pointer 300 characters from the end of the file */
X if (lseek(rst,-300L,2) < 0) {
X /* File isn't that long -- start from begining */
X lseek(rst,0L,0);
X } else
X /* Skip forward to a newline */
X while (read(rst,&ch,1) > 0 && ch != '\n') ;
X}
X
X/*
X * Display who is currently logged in
X */
X
Xwho()
X{
XFILE *pnt;
Xchar *in[81];
X
X rewind (stdin);
X if ((pnt = popen (who_cmd, "r")) == NULL) {
X printf ("Can't get users, popen() failed.\n");
X return;
X }
X
X while (fgets (in, 80, pnt) != NULL) {
X printf ("%s", in);
X }
X pclose (pnt);
X}
X
X/*
X * Invite a user into party using a canned message
X */
X
Xinvite()
X{
XFILE *pnt;
XFILE *user_tty;
Xchar *User[20];
Xchar *message[100];
Xchar *write_buf[40];
Xchar *theirtty;
Xchar tmp[512];
Xstruct utmp *ptr, *user, *getutent();
Xvoid setutent();
Xint found;
X
X found = 0;
X rewind (stdin);
X message[0] = NULL;
X tmp[0] = NULL;
X write_buf[0] = NULL;
X User[0] = NULL;
X printf ("User: ");
X fgets (User, 19, stdin);
X
X setutent();
X while ((ptr = getutent()) != NULL) {
X if (strncmp(ptr->ut_user, User, (strlen (User) -1)) == 0) {
X user = ptr;
X found = 1;
X break;
X }
X }
X
X if (!found) {
X printf ("User is not logged on\n");
X return;
X }
X
X strcpy (tmp, "/dev/");
X strcat (tmp, user->ut_line);
X if ((user_tty = fopen (tmp, "w")) == NULL) {
X printf ("%s has disabled messages\n", user->ut_user);
X /* Cant write, so mail it... */
X strcpy (message, invitation);
X strcat (message, User);
X printf ("Sending mail to %s\n", user->ut_user);
X if ((pnt = popen (message, "r")) == NULL) {
X printf ("Can't invite user, popen() failed.\n");
X return;
X }
X pclose (pnt);
X } else {
X fclose (user_tty);
X printf ("Inviting: /dev/%s (%s)\n", user->ut_line,
X user->ut_user);
X fflush (stdout);
X strcpy (write_buf, "echo \"From ");
X strcat (write_buf, name);
X strcat (write_buf, ": Party or Die!!\"");
X strcat (write_buf, "");
X strcat (write_buf, " > /dev/");
X strcat (write_buf, user->ut_line);
X system (write_buf);
X return;
X }
X}
X
X/*
X * Send a one line private message to another user.
X */
X
Xp_message()
X{
XFILE *user_tty;
Xchar *User[20];
Xchar *m_buff[80];
Xchar *write_buf[40];
Xchar tmp[512];
Xstruct utmp *ptr, *user, *getutent();
Xvoid setutent();
Xint found;
X
X found = 0;
X rewind (stdin);
X tmp[0] = NULL;
X write_buf[0] = NULL;
X User[0] = NULL;
X printf ("User: ");
X fgets (User, 19, stdin);
X rewind (stdin);
X
X setutent();
X while ((ptr = getutent()) != NULL) {
X if (strncmp(ptr->ut_user, User, (strlen (User) -1)) == 0) {
X user = ptr;
X found = 1;
X break;
X }
X }
X
X if ( !found) {
X printf ("User is not logged on\n");
X return (1);
X }
X
X printf ("Message: ");
X fgets (m_buff, 79, stdin);
X strcpy (tmp, "/dev/");
X strcat (tmp, user->ut_line);
X if ((user_tty = fopen (tmp, "w")) == NULL) {
X printf ("%s has disabled messages, aborted\n", user->ut_user);
X return (1);
X } else {
X fclose (user_tty);
X printf ("Message sent to: /dev/%s (%s)\n", user->ut_line,
X user->ut_user);
X strcpy (write_buf, "echo \"From ");
X strcat (write_buf, name);
X strcat (write_buf, ": ");
X strcat (write_buf, m_buff);
X strcat (write_buf, "\"");
X strcat (write_buf, " > /dev/");
X strcat (write_buf, user->ut_line);
X fflush (stdout);
X sleep (1);
X system (write_buf);
X return;
X }
X}
X
Xscrollback ()
X{
Xint c, i, n, lines, orst, s_flg, q_flg;
Xchar *inp[6];
Xchar ch;
X
X printf ("Number of lines to review: ");
X
X rewind (stdin);
X fgets (inp, 5, stdin);
X c = atoi (inp);
X fflush (stdin);
X if (c == 0) c = 20;
X
X /* Save previous location */
X orst = rst;
X
X /* Reverse seek c lines */
X for ( i = 1; i <= c;) {
X if (lseek (rst, -1L, 1) < 0) {
X lseek (rst, 0L, 0);
X break;
X }
X if (read (rst, &ch, 1) > 0 && ch == '\n') {
X i++;
X }
X lseek (rst, -1L, 1);
X }
X
X /* Seek forward to EOF and print each line */
X i = q_flg = s_flg = 0;
X while ((n = read (rst, buf, BFSZ)) > 0) {
X i++;
X if (i == 5) {
X i = 0;
X if (s_flg == 0) {
X printf ("\nMore (q=quit, c=continuous): ");
X c = getc (stdin);
X switch (c) {
X case 'q':
X q_flg = 1;
X break;
X case 'c':
X s_flg = 1;
X break;
X default:
X break;
X }
X fflush (stdin);
X }
X }
X if (q_flg == 1)
X break;
X else
X write (1, buf, n);
X }
X rst = orst;
X lseek (rst, 0L, 2);
X printf ("\n------------- review completed ------------\n");
X}
X
X/* This function prints the Party Message Of The Day */
Xpotd()
X{
XFILE *potdf;
Xchar *pbuf[81];
X
X if ((potdf = fopen(potdfile, "r")) == NULL) {
X return;
X }
X
X while ((fgets (pbuf, 80, potdf)) != NULL)
X fputs (pbuf, stdout);
X
X fclose (potdf);
X}
X
SHAR_EOF
exit
--
John "C". Sucilla, A silicon based life form.
{att,chinet,ddsw1}!tarkus!jcs
You have a better idea? Now's the time..
More information about the Alt.sources
mailing list