games-request@tekred.TEK.COM (03/02/88)
Submitted by: Jan Wolter <janc@crim.eecs.umich.edu>
Comp.sources.games: Volume 3, Issue 90
Archive-name: cchess/Part05
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 5 (of 5)."
# Contents: def.h reap.c
# Wrapped by billr@tekred on Tue Jan 12 12:09:57 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f def.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"def.h\"
else
echo shar: Extracting \"def.h\" \(10411 characters\)
sed "s/^X//" >def.h <<'END_OF_def.h'
X/* C O R R E S P O N D E N C E C H E S S Version 1.00
X *
X * These are the defines for cchess.
X *
X * (C) Apr 1986 - Jan Dithmar Wolter.
X */
X
Xtypedef char boolean;
X
X/* For lint we always turn on the UNCHAR flag */
X#ifdef lint
X#define UNCHAR
X#endif
X
X#ifdef UNCHAR
Xtypedef short schar;
X#else
Xtypedef char schar;
X#endif
X
X#ifdef USYS_5
X#define index strchr
X#define NODUP2
X#endif
X
X/* SCO seems to have problems with register directives in some situations */
X#ifdef SCO
X#define REGISTER
X#else
X#define REGISTER register
X#endif
X
X/* Handle 4.3bsd as superset of 4.2bsd */
X#ifdef U43BSD
X#define U42BSD
X#endif
X
X/* Fake the 4.2bsd directory routines for non-4.2bsd systems */
X#ifndef U42BSD
X#define DIR FILE
X#define opendir(n) fopen(n,"r")
X#define telldir(f) ftell(f)
X#define seekdir(f,o) fseek(f,o,0)
X#define rewinddir(f) rewind(f)
X#define closedir(f) close(f)
X#endif U42BSD
X
X#define BELL '\007'
X
X#undef TRUE /* Some systems already define these, here or there */
X#undef FALSE
X#define TRUE 1
X#define FALSE 0
X
X/* Code numbers for pieces */
X
X#define WHITE (schar) 1
X#define BLACK (schar) -1
X
X#define SQ (schar) 0 /* Blank Square */
X
X#define WK (schar) 1 /* White King */
X#define WQ (schar) 2 /* White Queen */
X#define WB (schar) 3 /* White Bishop */
X#define WN (schar) 4 /* White Knight */
X#define WR (schar) 5 /* White Rook */
X#define WP (schar) 6 /* White Pawn */
X#define WM (schar) 7 /* White Minister */
X#define WE (schar) 8 /* White Elephant */
X#define WD (schar) 9 /* White Duke */
X#define WJ (schar) 10 /* White Jester */
X#define WH (schar) 11 /* White Maharajah */
X
X#define BK (schar) -1 /* Black King */
X#define BQ (schar) -2 /* Black Queen */
X#define BB (schar) -3 /* Black Bishop */
X#define BN (schar) -4 /* Black Knight */
X#define BR (schar) -5 /* Black Rook */
X#define BP (schar) -6 /* Black Pawn */
X#define BM (schar) -7 /* Black Minister */
X#define BE (schar) -8 /* Black Elephant */
X#define BD (schar) -9 /* Black Duke */
X#define BJ (schar) -10 /* Black Jester */
X#define BH (schar) -11 /* White Maharajah */
X
X#define XX (schar) 99 /* Goofy piece used as place holder */
X
X#define PIECES 11
X
X/* Definition of options in "option" array */
X
X#define OP_COLOR 0 /* Is first player white? */
X#define Firstwhite option[OP_COLOR]
X#define HI_COLOR TRUE
X
X#define OP_PRIVATE 1 /* Is game Private? */
X#define Private option[OP_PRIVATE]
X#define HI_PRIVATE TRUE
X
X#define OP_KIBITZ 2 /* Computer Kibitzing */
X#define Help_me option[OP_KIBITZ]
X#define HI_KIBITZ TRUE
X
X#define OP_GAME 3 /* Major Variant */
X#define Game_type option[OP_GAME]
X#define TY_MIXED 0
X#define TY_CHESS 1
X#define TY_KRIEGSPIEL 2
X#define TY_SHATRANJ 3
X#define TY_COURIER 4
X#define TY_HALFBOARD 5
X#define TY_KARMA 6
X#define TY_RIFLE 7
X#define TY_KAMIKAZI 8
X#define TY_DOUBLE 9
X#define TY_STEAMROLLER 10
X#define TY_PROGRESSIVE 11
X#define TY_MAHARAJAH 12
X#define TY_LOSING 13
X#define TY_CONVERSION 14
X#define HI_GAME 14
X
X#define OP_ROWS 4 /* Board Rows minus 1 */
X#define Rows option[OP_ROWS]
X#define HI_ROWS 7
X
X#define OP_COLS 5 /* Board Columns minus 1 */
X#define Cols option[OP_COLS]
X#define HI_COLS 11
X
X#define OP_BOARD 6 /* Is board uncheckered? */
X#define Plain option[OP_BOARD]
X#define HI_BOARD TRUE
X
X#define OP_NAMES 7 /* Which names for pieces */
X#define Language option[OP_NAMES]
X#define LG_ENGLISH 0 /* English */
X#define LG_PERSIAN 1 /* Persian */
X#define LG_FRENCH 2 /* French */
X#define LG_GERMAN 3 /* German */
X#define HI_NAMES 3
X
X#define OP_VISIB 8 /* Kriegspiel? */
X#define Kriegspiel option[OP_VISIB]
X#define HI_VISIB TRUE
X
X#define OP_CASTLE 9 /* Is castling illegal? */
X#define Oldcastle option[OP_CASTLE]
X#define HI_CASTLE 9
X
X#define OP_DPAWN 10 /* Double pawn move illegal? */
X#define Oldpawn option[OP_DPAWN]
X#define HI_DPAWN TRUE
X
X#define OP_STRIP 11 /* Result if king is stripped */
X#define Stripresult option[OP_STRIP] /* of all his forces: */
X#define RE_DRAW 0 /* Game is a draw */
X#define RE_WIN 1 /* Stripped side wins */
X#define RE_LOSE 2 /* Stripped side loses */
X#define RE_NONE 3 /* Game Continues */
X#define RE_CANCEL 4 /* Game Cancelled */
X#define flip(x) (((x) == RE_WIN) ? RE_LOSE : (((x) == RE_LOSE) ? RE_WIN : x))
X#define HI_STRIP 3
X
X#define OP_STALE 12 /* Result of Stalemate */
X#define Staleresult option[OP_STALE]
X#define HI_STALE 2
X
X#define OP_CAPTURE 13 /* How do pieces capture? */
X#define Capture option[OP_CAPTURE]
X#define CA_NORMAL 0 /* The usual way */
X#define CA_NONE 1 /* Capture not allowed */
X#define CA_RIFLE 2 /* Rifle Chess */
X#define CA_CONVERSION 3 /* Conversion Chess */
X#define CA_KARMA 4 /* Karma Chess */
X#define CA_KAMIKAZI 5 /* Kamikazi Chess */
X#define HI_CAPTURE 5
X
X#define OP_KCAPTURE 14 /* How do kings capture? */
X#define Kcapture option[OP_KCAPTURE]
X#define HI_KCAPTURE 3
X
X#define OP_PROMOTE 15 /* What can you promote to? */
X#define Promotion option[OP_PROMOTE]
X#define PR_QRBN 0 /* Queen/Rook/Bishop/Knight */
X#define PR_MINISTER 1 /* Minister Only */
X#define PR_NONE 2 /* Stays as Pawn */
X#define HI_PROMOTE 2
X
X#define OP_WIMOVES 16 /* Number of pieces moved on */
X#define Winitmoves option[OP_WIMOVES] /* white's first turn */
X#define HI_WIMOVES 127
X
X#define OP_BIMOVES 17 /* Number of pieces moved on */
X#define Binitmoves option[OP_BIMOVES] /* black's first turn */
X#define HI_BIMOVES 127
X
X#define OP_WMOVES 18 /* Number of pieces moved on */
X#define Whitemoves option[OP_WMOVES] /* white's later turns */
X#define MO_PROGRESS 0 /* Move one more than before */
X#define HI_WMOVES 127
X
X#define OP_BMOVES 19 /* Number of pieces moved on */
X#define Blackmoves option[OP_BMOVES] /* black's later turns */
X#define HI_BMOVES 127
X
X#define OP_THRUCHECK 20 /* Can king move thru check? */
X#define Thrucheck option[OP_THRUCHECK] /* (relevant in multimove */
X#define HI_THRUCHECK TRUE /* games only) */
X
X#define OP_WHITEKING 21 /* Piece which can be checked*/
X#define Whiteking option[OP_WHITEKING] /* (must be a unique piece) */
X#define HI_WHITEKING PIECES
X
X#define OP_BLACKKING 22 /* Piece which can be checked*/
X#define Blackking option[OP_BLACKKING] /* (must be a unique piece) */
X#define HI_BLACKKING PIECES
X
X#define OP_MUSTTAKE 23 /* Are captures required? */
X#define Musttake option[OP_MUSTTAKE]
X#define HI_MUSTTAKE TRUE
X
X#define OP_TABIYAT 24 /* Must pieces stay own side */
X#define Tabiyat option[OP_TABIYAT] /* on first turn? */
X#define HI_TABIYAT TRUE
X
X#define OPTIONS 25 /* Number of options defined */
X
X/* King of color c */
X#define Kingtype(c) ((c == WHITE) ? Whiteking : Blackking)
X#define Kingpiece(c) ((c == WHITE) ? Whiteking : -Blackking)
X
X/* Reasons for winning or losing or drawing or cancelling */
X
X#define EV_NOTHING 0 /* Nothing happened */
X#define EV_CHECKMATE 1 /* Checkmate */
X#define EV_STALEMATE 2 /* Stalemate */
X#define EV_FORCES 3 /* Player lost forces */
X#define EV_AGREEMENT 4 /* Players agreed to result */
X#define EV_FIFTYMOVES 5 /* Fifty tame moves */
X#define EV_REPEATED 6 /* Three times repeated position */
X#define EV_FORFIET 7 /* Player forfieted */
X
X/* Maximum size of board - actual size is given by variabls Rows and Cols */
X#define R_SIZE HI_ROWS + 1
X#define C_SIZE HI_COLS + 1
X
X/* Macros to find left, right, top and bottom of board */
X#define lside(c) (((c)==BLACK) ? Cols : 0)
X#define rside(c) (((c)==WHITE) ? Cols : 0)
X#define bside(c) (((c)==BLACK) ? Rows : 0)
X#define tside(c) (((c)==WHITE) ? Rows : 0)
X
X/* Macro to decide if piece p is color c, or if p and c are same color (sign) */
X/* #define coloris(p,c) ((p ^ c) & 0200) not used... */
X
X/* A string of n blanks, n between 0 and BLANK_LEN */
X#define BLANK_LEN 70
X#define blanks(n) (blankstr+BLANK_LEN-(n))
X
X/* Error Codes for bad moves */
X
X#define E_OK 0000 /* no error */
X#define E_MT 0001 /* move from empty square */
X#define E_AF 0002 /* attack on friendly piece */
X#define E_EQ 0003 /* source and destination square are equal */
X#define E_SY 0004 /* Move syntax error */
X#define E_MC 0005 /* Move into Check */
X#define E_NC 0006 /* Pieces in not allowed to capture */
X#define E_MM 0007 /* Check during multiple move */
X#define E_CR 0010 /* A capture was required */
X#define E_CC 0011 /* May not cross center on first move */
X
X#define E_IL 0100 /* Illegal Move */
X#define E_KI 0101 /* Illegal move of King */
X#define E_QI 0102 /* Illegal move of Queen */
X#define E_BI 0103 /* Illegal move of Bishop */
X#define E_NI 0104 /* Illegal move of Knight */
X#define E_RI 0105 /* Illegal move of Rook */
X#define E_PI 0106 /* Illegal move of Pawn */
X#define E_MI 0107 /* Illegal move of Minister */
X#define E_EI 0110 /* Illegal move of Elephant */
X#define E_DI 0111 /* Illegal move of Duke */
X#define E_JI 0112 /* Illegal move of Jester */
X#define E_HI 0113 /* Illegal move of Maharajah */
X
X#define E_CP 0200 /* Illegal castling position */
X#define E_CM 0201 /* Castled moved piece */
X#define E_CT 0202 /* Castled through check */
X
X#define E_MB 0300 /* Blocked move */
X#define E_KB 0301 /* Blocked move of Kamikazi King */
X#define E_QB 0302 /* Blocked move of Queen */
X#define E_BB 0303 /* Blocked move of Bishop */
X#define E_BR 0305 /* Blocked move of Rook */
X#define E_BH 0313 /* Illegal move of Maharajah */
X
X/* Lengths for game transcript file io buffer */
X#define CB_LEN 160 /* Comment buffer length */
X#define MB_LEN CB_LEN+28 /* Move buffer length */
X
X/* Column positions of things inside game transcript files */
X#define C_DAY 0 /* Day of the year that the line was entered */
X#define C_CMD 6 /* Command letter (Move,Draw,Challenge,etc) */
X#define C_MAT 7 /* Check, Stalemate or Mate */
X#define C_MOV 8 /* Move made */
X#define C_FLG 13 /* Is there a comment? */
X#define C_COM 14 /* Comment text */
X
X/*
X * Number of moves after which to apply the fifty move rule. This is set up
X * so it is easy to change to some small number for debugging.
X */
X
X#ifndef MAXTAME
X#define MAXTAME 100
X#endif
X
X/* System 3 and System 5 and everything else uses the signal library */
X
X#define LSIGNAL
X
X/* 4.2bsd uses the sigvec library */
X
X#ifdef U42BSD
X# define UBERK
X# define LSIGVEC
X# undef LSIGSYS
X# undef LSIGNAL
X#endif
X
X/* 4.1bsd uses the sigsys library */
X
X#ifdef U41BSD
X# define UBERK
X# define LSIGSYS
X# undef LSIGVEC
X# undef LSIGNAL
X#endif
END_OF_def.h
if test 10411 -ne `wc -c <def.h`; then
echo shar: \"def.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f reap.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"reap.c\"
else
echo shar: Extracting \"reap.c\" \(9189 characters\)
sed "s/^X//" >reap.c <<'END_OF_reap.c'
X/* CCHESS GAME REAPER Version 1.00 */
X
X/* Note: this reaper is still somewhat experimental */
X
X#include <stdio.h>
X#include <sys/types.h>
X#ifdef U42BSD
X# include <sys/time.h>
X#else
Xlong time();
X#endif
X#include <pwd.h>
X#include <sys/dir.h>
X
X#include "def.h"
Xstruct direct *readdir();
XFILE *upopen();
X
X/* The following determine the reminder schedule:
X * at least sched[0] days after a move was made, the player whose turn
X * it is to move is sent a reminder message.
X * at least sched[n] (n < MAXREM-2) days after a the last reminder,
X * the player whose turn it is to move is sent another reminder.
X * at least sched[MAXREM-2] days after that, both players are sent
X * mail that the game will be deleted within sched[MAXREM-1]
X * days.
X * at least sched[MAXREM-1] days after that, the game is deleted,
X * and both players are informed of the fact.
X *
X * If the second player has not responded to the initial challenge, he is
X * not sent reminders. The game is deleted after SNUBKILL days.
X */
X
X#define MAXREM 4
Xint sched[MAXREM] = {4, 7, 7, 5};
X#define SNUBKILL 7
X
X/* EXAMPLES:
X * To delete games without warning after no moves for a week:
X * #define MAXREM 1
X * int sched[MEXREM] = {7};
X * To warn of deletion after two weeks, and delete 3 days later:
X * #define MAXREM 2
X * int sched[MEXREM] = {14, 3};
X * To remind players once a week for three months and never delete it:
X * #define MAXREM 14
X * int sched[MAXREM] = {7,7,7,7, 7,7,7,7, 7,7,7,7, 15000, 1};
X */
X
Xchar rem_msg[] = "Cchess Reminder";
X
Xlong today, day();
Xchar ids[2][9];
Xint toplay;
Xchar *hisid, *myid;
XFILE *fopen();
Xstruct passwd *getpwuid();
X
Xmain()
X{
XDIR *dfp;
Xstruct direct *dirent;
X
X today = day();
X
X if ((dfp = opendir(CCDIR)) == NULL)
X return(0);
X
X chdir(CCDIR);
X while((dirent = readdir(dfp)) != NULL)
X {
X dofile(dirent->d_name);
X }
X}
X
Xdofile(name)
Xchar *name;
X{
XFILE *fp;
Xchar buf[512];
Xint code,flag=0;
Xint uid1,uid2;
Xstruct passwd *pwbuf;
X
X /* Get the uid's of the players */
X if (sscanf(name,"%d.%d",&uid1,&uid2) != 2)
X return;
X
X /* Read the board to see if a reminder is needed */
X if ((code = readboard(name))==0)
X return;
X
X /* Kill one player games first chance we get */
X if (uid1 == uid2)
X {
X killfile(name);
X return;
X }
X
X /* Look up the login names of the players */
X if ((pwbuf = getpwuid(uid1)) != NULL)
X strcpy(ids[toplay],pwbuf->pw_name);
X else
X flag |= 1;
X
X if ((pwbuf = getpwuid(uid2)) != NULL)
X strcpy(ids[1-toplay],pwbuf->pw_name);
X else
X flag |= 2;
X
X /* If either player's account is gone, kill the game */
X if (flag != 0)
X {
X /* Do something nicer here someday */
X killfile(name);
X return;
X }
X
X hisid = ids[0]; myid = ids[1];
X
X if (code < MAXREM - 1)
X {
X /* Remind the player whose turn it is to move */
X markfile(name);
X sprintf(buf,"It's your turn to move in the cchess game between you and %s.\n",myid);
X mesg(rem_msg,buf);
X }
X else if (code == MAXREM - 1)
X {
X /* Warn both players that time is short */
X markfile(name);
X sprintf(buf,"It's your turn to move in the cchess game between you and %s.\nThe game will be deleted in %d days if no move is made\n",myid,sched[MAXREM-1]);
X mesg(rem_msg,buf);
X
X hisid = ids[1]; myid = ids[0];
X
X sprintf(buf,"%s has not been moving in your cchess game\nThe game will be deleted in %d days if no move is made\n",myid,sched[MAXREM-1]);
X mesg(rem_msg,buf);
X }
X else
X {
X /* Delete the game */
X killfile(name);
X if (code == MAXREM)
X sprintf(buf,
X "The cchess game between you and %s has been deleted.\n",
X myid);
X else
X sprintf(buf,
X "The cchess game %s challenged you to has been deleted.\n",
X myid);
X mesg(rem_msg,buf);
X
X hisid = ids[1]; myid = ids[0];
X
X if (code == MAXREM)
X sprintf(buf,
X "The cchess game between you and %s has been deleted.\n",
X myid);
X else
X sprintf(buf,
X "The cchess game you challenged %s to has been deleted.\n",
X myid);
X mesg(rem_msg,buf);
X }
X}
X
X/* READBOARD
X *
X * Read in the file "name" and toplay=0 if the first named player is the
X * next player, and toplay=1 if the last named player is the next player.
X * It returns the reminder number if a reminder is due, or 0 if not. It
X * returns MAXREM+1 for snubbed games.
X */
X
Xint readboard(name)
Xchar *name;
X{
Xint fw,snubbed;
XFILE *rfp;
Xint reminder;
Xlong date;
Xchar mbuffer[MB_LEN+1];
X
X if ((rfp = fopen(name,"r")) == NULL)
X return(0);
X
X snubbed = 2;
X reminder = 1;
X toplay = 0; /* First player, by definition, does first challenge */
X
X for (;;)
X {
X if (fgets(mbuffer,MB_LEN,rfp)==NULL)
X break;
X date = atol(mbuffer+C_DAY);
X
X switch (mbuffer[C_CMD])
X {
X case 'R':
X reminder++;
X break;
X case 'A':
X /* My move first if Firstwhite */
X toplay = !fw;
X reminder=1;
X snubbed = 0;
X break;
X case 'C': /* players alternate counterchallenges */
X fw = (mbuffer[C_MOV+OP_COLOR] == '1');
X if (snubbed) snubbed--;
X toplay = 1-toplay;
X reminder=1;
X break;
X case 'M': case 'D': case 'K': case 'N': case 'Y': case 'F':
X toplay = 1-toplay;
X case 'P': case 'm': case 'I': case 'V':
X reminder=1;
X break;
X default:
X printf("ccreap: strange code in file %s\n",name);
X fclose(rfp);
X return(0);
X }
X }
X fclose(rfp);
X
X if (snubbed)
X return((today - date > SNUBKILL) ? MAXREM+1 : 0);
X
X if (reminder > MAXREM)
X reminder = MAXREM;
X if (today - date > sched[reminder-1])
X return(reminder);
X else
X return(0);
X}
X
X/* KILLFILE
X *
X * Delete the named game file. If debug, just print a message.
X */
Xkillfile(name)
Xchar *name;
X{
X#ifdef DEBUG
X printf("Delete %s\n",name);
X#else
X unlink(name);
X#endif DEBUG
X}
X
X/* MARKFILE
X *
X * Make a note in the game file that a reminder has been sent.
X */
X
Xmarkfile(name)
Xchar *name;
X{
XFILE *wfp;
X
X if ((wfp = fopen(name,"a")) == NULL)
X return(0);
X fprintf(wfp,"%5ld:R\n",today);
X fclose(wfp);
X}
X
X/**************************************************************************/
X/* The following routines are mostly stolen from cchess */
X/**************************************************************************/
X
X/* DAY()
X *
X * Return today's date, in the form of the number of days since Jan 1, 1970.
X * Actually, the 4.2bsd could use the time() call too, but gettimeofday()
X * seems to be prefered.
X */
X
Xlong day()
X{
X#define SECSPERDAY 86400L
X#ifdef U42BSD
Xstruct timeval tp;
Xstruct timezone tzp;
X gettimeofday(&tp,&tzp);
X return(tp.tv_sec/SECSPERDAY);
X#else
X return(time((long *)0)/SECSPERDAY);
X#endif
X}
X
X/* MESG()
X *
X * Send Mail to the other player. Use the the given text and subject
X * heading. Making this come out right may take some fooling around on
X * any given system.
X */
X
X/* Choose default mailer */
X#ifndef MAILER
X# ifdef U41BSD
X# define MAILER "/etc/delivermail"
X# else
X# ifdef U42BSD
X# define MAILER "/usr/lib/sendmail"
X# else
X# define MAILER "/bin/mail"
X# endif U42BSD
X# endif U41BSD
X#endif MAILER
X
Xmesg(subj,text)
Xchar *subj, *text;
X{
X#ifdef DEBUG
Xprintf("message to %d: %s\n",hisid, text);
X#else
Xchar cmd[60];
XFILE *cmdfd;
X
X sprintf(cmd,"%s %s",MAILER,hisid);
X cmdfd = upopen(cmd,"w");
X
X#ifdef UBERK
X fprintf(cmdfd,"To: %s\n",hisid);
X#endif UBERK
X
X fprintf(cmdfd,"Subject: %s\n\n",subj);
X fprintf(cmdfd,"%s",text);
X
X fclose(cmdfd); /* Don't use pclose -- don't want to wait */
X#endif DEBUG
X}
X
X
X#ifndef U42BSD
X/* READDIR
X *
X * Here we fake 4.2bsd's readdir() command for older bsd's and at&t
X * unixs. The "direct" structure on those systems returned isn't the
X * same the bsd one, but we do ensure that the file name is null
X * terminated. It would be easy enough to add the d_namlen and d_reclen
X * records and extend d_ino to a long named d_fileno, but I don't
X * really need that here.
X */
X
Xstruct direct *readdir(fp)
XDIR *fp;
X{
X/* We allocate one extra byte on the end of the structure for the null */
Xstatic char dent[ sizeof(struct direct) + 1 ];
X
X do
X if (fread(dent,sizeof(struct direct),1,fp) == 0)
X return(NULL);
X while (((struct direct *)dent)->d_ino == 0);
X ((struct direct *)dent)->d_name[DIRSIZ] = '\0';
X return((struct direct *)dent);
X}
X#endif U42BSD
X
X
X/* UPOPEN - Run command on a pipe
X *
X * This is just like the Unix popen() call, except it runs the command
X * with the original user id. This is done for the same reasons mentioned
X * in the usystem routine.
X */
X
XFILE *upopen(cmd,mode)
Xchar *cmd;
XREGISTER char *mode;
X{
Xint p[2];
Xregister int chd_pipe,par_pipe;
XFILE *fdopen();
X#ifdef NODUP2
Xint t;
X#endif NODUP2
X
X /* Make a pipe */
X if (pipe(p)) return((FILE *)0);
X
X /* Choose ends */
X par_pipe = (*mode == 'r') ? p[0] : p[1];
X chd_pipe = (*mode == 'r') ? p[1] : p[0];
X
X switch (fork())
X {
X case 0:
X /* Child - run command */
X close(par_pipe);
X if (chd_pipe != (*mode == 'r'?1:0))
X {
X#ifdef NODUP2
X close(t = (*mode == 'r'?1:0));
X if (fcntl(chd_pipe,F_DUPFD,t) != t)
X {
X printf("Panic: can dup pipe\n");
X exit(1);
X }
X#else
X dup2(chd_pipe,(*mode == 'r'?1:0));
X#endif NODUP2
X close(chd_pipe);
X }
X setuid(getuid());
X setgid(getgid());
X execl("/bin/sh","sh","-c",cmd,NULL);
X exit(1);
X case -1:
X close(chd_pipe);
X close(par_pipe);
X return((FILE *)0);
X default:
X close(chd_pipe);
X return(fdopen(par_pipe,mode));
X }
X}
END_OF_reap.c
if test 9189 -ne `wc -c <reap.c`; then
echo shar: \"reap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 5 \(of 5\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 5 archives.
rm -f ark[1-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0