[comp.unix.admin] sources for opermenu

sfreed@triton.unm.edu (Steven Freed CIRT) (06/17/91)

Part 2 of the sources to opermenu. See part one for a description.

#! /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 2 (of 2)."
# Contents:  mdi/getnamevalue.c src/Makefile src/backup.c src/dump_io.c
#   src/execute.c src/externs.c src/failed_dump.c src/get_fsystem.c
#   src/init.c src/line_to_vec.c src/mtaccess.c src/ps_open.c
#   src/reroute_printer.c src/set_date.c src/setdate.c
# Wrapped by sfreed@triton.unm.edu on Fri Jun 14 18:00:59 1991
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'mdi/getnamevalue.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'mdi/getnamevalue.c'\"
else
echo shar: Extracting \"'mdi/getnamevalue.c'\" \(1402 characters\)
sed "s/^X//" >'mdi/getnamevalue.c' <<'END_OF_FILE'
X#include "mdi.h"
X#include <strings.h>
X#include <ctype.h>
X
X_mdi_getnamevalue(name, value, in)
char **name, **value;
XFILE *in;
X{
X	 char line[MAX_STR], *comment, *name_end, *value_start;
X	 char *malloc();
X	 int len;
X	 extern int debug;
X
X	 *name = NULL;
X
X	 do {
X		if (fgets(line, MAX_STR, in) == NULL)
X			return EOF;
X		line[strlen(line)-1] = '\0';
X		if (debug)
X			printf("read: '%s'\n", line);
X		if ((comment = index(line, '#')) != NULL)
X			*comment = '\0';
X		if (!line[0])
X			continue;
X		if ((name_end = index(line, '=')) == NULL) {
X			fprintf(stderr, "Warning: no '=' on line '%s'\n", 
X				line);
X			continue;
X		}
X
X		value_start = name_end + 1;
X		name_end--;
X
X		/* don't hang on to white space before the = */
X		while (isspace(*name_end))
X			name_end--;
X		name_end++; /* loop above goes too far */
X		len = name_end - line;
X		if (len < 0) {
X			fprintf(stderr, "Internal error, len %d < 0!", len);
X			fprintf(stderr, " on line '%s'\n", line);
X			continue;
X		}
X		*name = malloc((unsigned)(len + 1));
X		if (*name == NULL) {
X			fprintf(stderr, "Unable to malloc for getinfo!\n");
X			return EOF;
X		}
X		(void) strncpy(*name, line, len);
X		(*name)[len] = '\0';
X
X		/* don't hang on to white space after the = */
X		for ( ; isspace(*value_start); value_start++)
X			;
X		len = strlen(value_start);
X		*value = malloc((unsigned)(len+1));
X		(void)strcpy(*value, value_start);
X	} while (*name == NULL);
X	
X	return NULL;
X}
END_OF_FILE
if test 1402 -ne `wc -c <'mdi/getnamevalue.c'`; then
    echo shar: \"'mdi/getnamevalue.c'\" unpacked with wrong size!
fi
# end of 'mdi/getnamevalue.c'
fi
if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile'\"
else
echo shar: Extracting \"'src/Makefile'\" \(2393 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
X#
X# Makefile for opermenu
X#
X# Each file contains the subroutine named.  The only exception is
X# "externs.c", which contains all of the external declarations.
X#
OBJS = backup.o dequeue.o externs.o games.o is_a_tty.o last_backup.o\
X	list_ps.o main.o main_menu.o oper_kill.o run.o\
X	send_mail.o show_queue.o shutdown.o talk.o log_dump.o\
X	atoo.o init.o wall.o mtaccess.o in.o getans.o\
X	set_ids.o match.o set_date.o ps_open.o line_to_vec.o\
X	get_level.o get_fsystem.o get_tdrive.o \
X	get_printername.o printer_menu.o printers.o lpc_cmd.o\
X	printer_down.o set_sigs.o naughty.o dump_io.o do_dump.o \
X	attend_dump.o printer_up.o reroute_printer.o failed_dump.o\
X	list_printers.o known_printer.o kill_end_spaces.o
X
SRCS = backup.c dequeue.c externs.c games.c is_a_tty.c last_backup.c\
X	list_ps.c main.c main_menu.c oper_kill.c run.c\
X	send_mail.c show_queue.c shutdown.c talk.c log_dump.c\
X	atoo.c init.c wall.c mtaccess.c in.c getans.c\
X	set_ids.c match.c set_date.c ps_open.c line_to_vec.c\
X	get_level.c get_fsystem.c get_tdrive.c \
X	get_printername.c printer_menu.c printers.c lpc_cmd.c\
X	printer_down.c set_sigs.c naughty.c dump_io.c do_dump.c \
X	attend_dump.c printer_up.c reroute_printer.c failed_dump.c\
X	list_printers.c known_printer.c kill_end_spaces.c
X
X# This is where the executable is to be placed when everything is done.
BINDIR = /usr/staff/oper/bin
X
X# Location of the machine dependent information library
MDIDIR = ./mdi
MDILIB = -lmdi
X
X# if -DDEBUG is below then things like shotdown dont actually do their
X# stuff.  they just print what they would have done.
X# Also, you may need to define a few types:
X#CFLAGS = -O -Duid_t="u_short"
CFLAGS = -O -Duid_t=int
X
oper: ${P} $(OBJS)
X	cc -oO oper $(OBJS) $(MDILIB)
X
X$(OBJS): defs.h
X
X$(SRCS) defs.h:
X	co $@
X
X$(MDILIB): /tmp
X	cd $(MDIDIR) ; make
X
clean:
X	rm -f *.o oper
X
install: oper
X	install -o root -g operations -m 4750 -s oper $(BINDIR)
X
X# test is used to test a new version without bothering the one in
X# BINDIR.  All protections, etc are set up properly.
test: oper
X	strip oper
X	chown root oper
X	chgrp operations oper
X	chmod 6755 oper
X
lint:
X	lint -xh *.c > Lint.out
X
X# shar: $(SRCS) Mdi.shar defs.h
shar: $(SRCS) defs.h
X	shar Makefile $(SRCS) defs.h lib > Oper.shar
X	@echo You will need to make the file Mdi.shar also.
X
Mdi.shar: $(MDIDIR)/Mdi.shar
X	cp $(MDIDIR)/Mdi.shar Mdi.shar
X
X$(MDIDIR)/Mdi.shar: /tmp
X	cd $(MDIDIR) ; make shar
END_OF_FILE
if test 2393 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
# end of 'src/Makefile'
fi
if test -f 'src/backup.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/backup.c'\"
else
echo shar: Extracting \"'src/backup.c'\" \(2367 characters\)
sed "s/^X//" >'src/backup.c' <<'END_OF_FILE'
X/*
X   backup: start a backup running.  This includes finding out from the
X	   system what filesystems are available, and if necessary, what
X	   tape drives are available.  Selecting a valid filesystem (and
X	   tape drive) is required.
X*/
X
X#include "defs.h"
X#include <sys/file.h>
X
void
backup()
X{
X	extern int oper_uid, errno;
X	extern struct tapedrive *tapelist[];
X	extern int ntapedrives;
X	extern struct tapedrive *get_tdrive();
X	char cmd[MAX_STR], fsystem[MAX_STR], tape_name[MAX_STR];
X	char answer[MAX_STR], host[MAX_STR];
X	int level;
X	extern int tape_len;	/* default tape length, see externs.c */
X	char *tape_len_s;	/* string for new tape length, from getinfo */
X	int remote;
X	char tmach[MAX_STR];
X	struct tapedrive *drive;
X	char *dump_opt;
X
X	printf("Backup\n\n");
X
X	if (gethostname(host, MAX_STR) < 0) {
X		perror("Get host name in backup");
X		return;
X	}
X
X	level = get_level();
X
X	if ( get_fsystem(fsystem) == 0 )
X		return;
X
X	if ( (drive=get_tdrive()) == (struct tapedrive *) NULL ) {
X		fprintf( stderr,"oper:  couldn't figure out where to dump.\n" );
X		return;
X	}
X
X	tape_len = 2300;			/* in feet */
X 	tape_len_s = getinfo( "TAPE_LENGTH" );
X	if ( tape_len_s != (char *) NULL )
X		if ( atoi(tape_len_s) > 0 ) {
X			printf( "Using %d, not %d, for tape length in feet.\n",
X				atoi(tape_len_s), tape_len );
X			tape_len = atoi( tape_len_s );
X		} else
X			printf( "%s %d %s.\n",
X				"Munged new tape length; using default of",
X				tape_len, "feet" );
X		
X	if ( strncmp(host, drive->td_host, strlen(drive->td_host)))
X		sprintf( tape_name, "%s:%s", drive->td_host, drive->td_drive );
X	else
X		strcpy( tape_name, drive->td_drive );
X
X	sprintf( cmd, "%s %d%susfd %d %s %d %s",
X	    drive->td_dumpprog, level, drive->td_flags, tape_len, tape_name,
X	    drive->td_density, fsystem );
X
X	printf( "%s\n",cmd );
X
X#ifndef DEBUG
X	/* testing the below; KLI
X		ken, don't forget about 'dump_opt'...
X	do_dump( cmd, fsystem, host, tmach, tdrive );
X	*/
X	system(cmd);
X#endif  DEBUG
X
X	getans("\nWas the dump successful? ", "y/n/yes/no", answer);
X	if (strcmp(answer, "no") == 0 || strcmp(answer, "n") == 0) {
X		if (remote) {
X			failed_dump( "oper reports [r]dump failing.", cmd );
X			printf( "A message has been mailed to DOC.\n" );
X			printf( "Please write up an I.R.  Thanks!\n\n" );
X		}
X		else {
X			printf("Please beep DOC and inform them that the\n");
X			printf("backup failed.\n\n");
X		}
X	}
X}
END_OF_FILE
if test 2367 -ne `wc -c <'src/backup.c'`; then
    echo shar: \"'src/backup.c'\" unpacked with wrong size!
fi
# end of 'src/backup.c'
fi
if test -f 'src/dump_io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dump_io.c'\"
else
echo shar: Extracting \"'src/dump_io.c'\" \(1784 characters\)
sed "s/^X//" >'src/dump_io.c' <<'END_OF_FILE'
X/*
X   dump_io: setup the pipeline between us and the dump program.  we have
X   two pipelines, one for reading from dump and one for writing to
X   dump.
X
X   Kenneth Ingham
X*/
X
X#include "defs.h"
X
X#define in	0
X#define out	1
X#define err	2
X
X#define p_read	0
X#define p_write	1
X
dump_io(cmd, to_dump, from_dump)
char *cmd;
int *to_dump, *from_dump;
X{
X	int pipe_in[2], pipe_out[2]; /* in & out are relative to child */
X	char *args[MAX_ARGS];
X	extern char **environ;
X
X	if (pipe(pipe_out) == -1) {
X		printf("Unable to open output pipe to dump pgm!\n");
X		perror("oper menu pipe");
X		exit(1);
X	}
X	if (pipe(pipe_in) == -1) {
X		fprintf(stderr, "Unable to open input pipe to dump pgm!\n");
X		perror("oper menu pipe");
X		exit(1);
X	}
X
X	switch (fork()) { 
X		case -1: /* error */
X			perror("oper menu dump");
X			exit(1);
X		case 0: /* child */
X			close(in);
X			if (dup(pipe_in[p_read]) != in) {
X				printf("Weird thigs in muddville!\n");
X				perror("oper menu dup");
X				exit(1);
X			}
X			close(pipe_in[p_read]);
X
X			close(out);
X			if (dup(pipe_out[p_write]) != in) {
X				printf("Weirder things have %s",
X					"never been seen in muddville!\n");
X				perror("oper menu dup");
X				exit(1);
X			}
X
X			/* 
X			   note that stdout & stderr are both going down
X			   the same pipe
X			*/
X			close(err);
X			if (dup(pipe_out[p_write]) != in) {
X				printf("You wouldn't believe %s",
X					"how weird things are in muddville.\n");
X				perror("oper menu dup");
X				exit(1);
X			}
X			close(pipe_out[p_write]);
X
X			line_to_vec(cmd, args, " ");
X			if (execve("dump", args, environ) == -1) {
X				perror("oper menu dump fork");
X				exit(1);
X			}
X			/*NOTREACHED*/
X		default: /* parent */
X			close(pipe_out[p_write]);
X			close(pipe_in[p_read]);
X			*to_dump = pipe_in[p_write];
X			*from_dump = pipe_out[p_read];
X			break;
X	}
X}
END_OF_FILE
if test 1784 -ne `wc -c <'src/dump_io.c'`; then
    echo shar: \"'src/dump_io.c'\" unpacked with wrong size!
fi
# end of 'src/dump_io.c'
fi
if test -f 'src/execute.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/execute.c'\"
else
echo shar: Extracting \"'src/execute.c'\" \(1593 characters\)
sed "s/^X//" >'src/execute.c' <<'END_OF_FILE'
X/*
X   execute: execute the command typed in by the operator.  All that is
X   here is a switch statement, selecting amongst the definitions in
X   'cmds.h'.  
X   
X   Note that 'cmds.h' must correspond to the descriptions given in 'externs.c'.
X*/
X
X#include "defs.h"
X#include "cmds.h"
X
execute(cmd)
int cmd;
X{
X	extern int n_choices;
X
X	switch(cmd) {
X		case IBM_LOG:
X			ibm_log();
X			break;
X		case HASP_LOG:
X			hasp_log();
X			break;
X		case ACCOUNTING:
X			accounting();
X			break;
X		case LAST_BACKUP:
X			last_backup();
X			break;
X		case LPC:
X			lpc();
X			break;
X		case QUIT:
X			return;
X		case GAMES:
X			games();
X			break;
X		case BERKNET:
X			berknet();
X			break;
X		case RJE:
X			rje();
X			break;
X		case FREE:
X			free_space();
X			break;
X		case IDLE:
X			main_menu();
X			break;
X		case SHOW_QUEUE:
X			show_queue();
X			break;
X		case SHUTDOWN:
X			shutdown();
X			break;
X		case LIST_PS:
X			list_ps();
X			break;
X		case KILL:
X			oper_kill();
X			break;
X		case WHO:
X			who();
X			break;
X		case TALK:
X			talk();
X			break;
X		case WALL:
X			wall();
X			break;
X		case READ_MAIL:
X			read_mail();
X			break;
X		case SEND_MAIL:
X			send_mail();
X			break;
X		case MOTD:
X			motd();
X			break;
X		case PASSWD:
X			passwd();
X			break;
X		case BACKUP:
X			backup();
X			break;
X		case PLOT:
X			plot();
X			break;
X		case DEQUEUE:
X			dequeue();
X			break;
X		case MTACCESS:
X			mtaccess();
X			break;
X		case FCLEAR:
X			fclear();
X			break;
X		case DATE:
X			setdate();
X			break;
X		case 0: /* just pressing return */
X			main_menu();
X			break;
X		default:
X			printf("Unknown command.  A command is an integer between 1 and %d.",n_choices);
X			break;
X	}
X}
END_OF_FILE
if test 1593 -ne `wc -c <'src/execute.c'`; then
    echo shar: \"'src/execute.c'\" unpacked with wrong size!
fi
# end of 'src/execute.c'
fi
if test -f 'src/externs.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/externs.c'\"
else
echo shar: Extracting \"'src/externs.c'\" \(2586 characters\)
sed "s/^X//" >'src/externs.c' <<'END_OF_FILE'
X/*
X   externs: external variables for the oper program live here.
X*/
X#include "defs.h"
X
X#define FREE_PGM	"/bin/df"
X#define OBSOLETE	"/bin/echo This option is obsolete"
X#define MAIL_PGM	"/usr/ucb/mail"
X#define MOTD_PGM	"/usr/local/bin/post"
X#define PASSWD_PGM	"/bin/passwd"
X#define WHO_PGM		"/bin/who"
X
void shutdown(), list_ps(), oper_kill(), show_queue(), dequeue();
void talk(), wall(), send_mail(), last_backup(), backup(), plot();
void games(), ibm_log(), hasp_log(), mtaccess(), set_date(), main_menu();
void printers(), lpc_cmd(), printer_down(), printer_up(),reroute();
void exit();
X
struct cmd_st cmds[] = {
X{ "Exit this procedure.",		exit,		PROC,	NULL },
X{ "System shutdown procedure.",		shutdown,	PROC,	NULL },
X{ "List processes.",			list_ps,	PROC,	NULL },
X{ "Kill a process.",			oper_kill,	PROC,	NULL },
X{ "Play with the printers.",		printers,	PROC,	NULL },
X{ "List users.",			NULL,		RUN,	WHO_PGM },
X{ "Talk to a user.",			talk,		PROC,	NULL },
X{ "Send a message to all users.",	wall,		PROC,	NULL },
X{ "Send mail.",				send_mail,	PROC,	NULL },
X{ "Read mail.",				NULL,		RUN,	MAIL_PGM },
X{ "Edit the message of the day.",	NULL,		SYSTEM,	MOTD_PGM },
X{ "Change the password for oper.",	NULL,		RUN,	PASSWD_PGM },
X{ "Show free space on disks.",		NULL,		RUN,	FREE_PGM },
X{ "Show last dump dates.",		last_backup,	PROC,	NULL },
X{ "Run disk to tape backups.",		backup,		PROC,	NULL },
X{ "Change the status of the games.",	NULL,		RUN,	OBSOLETE },
X{ "Run Accounting.",			NULL,		RUN,	OBSOLETE },
X{ "Set mag tape access.",		mtaccess,	PROC,	NULL },
X{ "Reset the date.",			set_date,	PROC,	NULL },
X{ "Reroute a printer.",			reroute,	PROC,	NULL },
X{ "Redisplay this menu.",		main_menu,	PROC,	NULL },
X{ NULL,					NULL,		NULL,	NULL }
X};
int ncmds = -1;
X
X/* commands for the printer menu */
struct pcmd_st pcmds[] = {
X	{ "Show printer status.",		lpc_cmd,	"status" },
X	{ "Show the print queue.",		show_queue,	NULL },
X	{ "Remove a printout from the queue.",	dequeue,	NULL },
X	{ "Take a printer down.",		printer_down,	NULL },
X	{ "Bring a printer up.",		printer_up,	NULL },
X	{ "Restart a printer.",			lpc_cmd,	"restart" },
X	{ "Terminate printing on a printer & bring it down.",lpc_cmd,"abort"},
X	{ NULL,					NULL,		NULL }
X};
int npcmds = -1;
X
int pid = -9;
X
char *tapenames[] = {
X	"/dev/nrmt0h",
X	"/dev/nrmt0l",
X	"/dev/rmt0h",
X	"/dev/rmt0l"
X};
int n_tapes = sizeof(tapenames) / sizeof(char *);
X
int uid, gid, oper_uid;
X
char *lpc_pgm;
int remote_managed;
char *remote_mgr;
X
int tape_len = 2300;	/* each reel of backup tape defaults to 2300 feet */
X
struct tapedrive tapelist[25];
int ntapedrives = 0;
END_OF_FILE
if test 2586 -ne `wc -c <'src/externs.c'`; then
    echo shar: \"'src/externs.c'\" unpacked with wrong size!
fi
# end of 'src/externs.c'
fi
if test -f 'src/failed_dump.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/failed_dump.c'\"
else
echo shar: Extracting \"'src/failed_dump.c'\" \(1718 characters\)
sed "s/^X//" >'src/failed_dump.c' <<'END_OF_FILE'
X/*
X   failed_dump: the dump failed.  do whatever we should about it.
X   Currently this means sending a letter to DOC (obtained from getinfo).
X
X   Kenneth Ingham
X*/
X
X#include "defs.h"
X
failed_dump(errmsg, details)
char *errmsg;
char *details;
X{
X	extern FILE *popen();
X	extern char *remote_mgr;
X	FILE *mail;
X	char *mail_pgm;
X	char cmd[MAX_STR], host[MAX_STR], *ctime(), *doc;
X	long tval, time();
X
X	gethostname(host, MAX_STR);
X	doc = getinfo("DOC");
X	if (doc == (char *) NULL) {
X		printf( "%s\n%s.\n",
X			"Unable to obtain mail address for DOC;  Please",
X			"write an IR and send mail to 'doc' on a CIRT machine");
X		return;
X	}
X
X	mail_pgm = getinfo("MAIL_PGM");
X	if (mail_pgm == (char *) NULL) {
X		printf( "%s\n%s.\n",
X			"Unable to locate the mail program;  Please",
X			"write an IR and send mail to 'doc' on a CIRT machine");
X		return;
X	}
X
X	sprintf( cmd, "%s %s", mail_pgm, doc, remote_mgr );
X	
X	if ( mail_pgm == (char *) NULL || (mail = popen(cmd, "w")) == NULL ) {
X		printf("Unable to send mail to person on call to inform\n");
X		printf("them of the failed dump.  Please send mail to\n");
X		printf("'%s' from a different machine informing them\n",doc);
X		printf("that the dumps on %s failed.\n\n", host);
X	}
X	else {
X		tval = time((long *)0);
X
X		fprintf( mail, "%s\n%s '%s'.\n%s '%s'.\n",
X		    "Dear Doc,",
X		    "  It appears that remote dumps are failing on host", host,
X		    "The error message reads", errmsg );
X
X		if ( details != (char *) NULL )
X		    fprintf( mail, "Some details: '%s'.\n", details );
X
X		fprintf( mail, "%s %s.\n%s\n%s\n\n%s\n",
X		    "This message *automatically* generated at", ctime(&tval),
X		    "Have fun looking into this...",
X		    "Later,",
X		    "  Oper-Menu" );
X
X		pclose(mail);
X	}
X}
END_OF_FILE
if test 1718 -ne `wc -c <'src/failed_dump.c'`; then
    echo shar: \"'src/failed_dump.c'\" unpacked with wrong size!
fi
# end of 'src/failed_dump.c'
fi
if test -f 'src/get_fsystem.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/get_fsystem.c'\"
else
echo shar: Extracting \"'src/get_fsystem.c'\" \(2054 characters\)
sed "s/^X//" >'src/get_fsystem.c' <<'END_OF_FILE'
X/*
X   get_fsystem: read fstab to find out what filesystems are on the system.
X   ignore /tmp and all systems whose names do not begin with /.
X
X   it seems much easier to use getfsent...  The only thing that will
X   have to happen is that 'n_systems' will have to be adjusted after
X   all the filesystems have been found so that the original code that
X   inquires of the user the desired filesystem will still work.
X
X  fixed the check for dumpable file systems to make sure partitions
X  is not a swap partitioni, using fs_type == "sw". this is more robust
X  than checking the directory on which a fs is mounted for first char == '/'
X  -- mike, 11/20/88.
X */
X
X#include "defs.h"
X
extern char *index();
X
get_fsystem(fsystem)
char *fsystem;
X{
X	char ans[MAX_STR];
X	char *gets();
X	int i, f_system;
X	char filesystem[50][MAX_STR];
X	int n_systems = -1;
X	struct fstab *fsent;
X
X	setfsent();
X	while ( (fsent=getfsent()) != (struct fstab *) NULL )
X
X		if ( (strcmp(fsent->fs_file, "/tmp") != 0) &&
X				(strcmp(fsent->fs_type, "sw") != 0) &&
X				(*(fsent->fs_spec) == '/') &&
X				(index(fsent->fs_spec, '@') == (char *) NULL) ){
X			n_systems++;
X			sprintf( filesystem[n_systems], "%-20.20s  %s",
X						fsent->fs_spec, fsent->fs_file );
X		}
X	endfsent();
X	if ( n_systems == -1 ) {
X		fprintf( stderr, "Hmmm... No filesystems to dump.\n" );
X		fprintf( stderr, "You'll want to tell someone about this.\n" );
X		return( 0 );
X	}
X/*
X* Here is said adjustment:
X*/
X	n_systems++;
X
X	/* print available filesystems and get user's selection of filesystem */
X	do {
X		putchar( '\n' );
X		for (i=0; i<n_systems; i++)
X			printf("%d    %s\n",i,filesystem[i]);
X		printf("\nEnter number of filesystem: ");
X		gets(ans);
X		f_system = atoi(ans);
X	} while (f_system < 0 || f_system >= n_systems);
X
X	/* 
X	   now that they have specified which filesystem, change the
X	   space to null so that we don't pass the name of the filesystem
X	   to dump also.
X	*/
X	for (i=0; filesystem[f_system][i] != ' '; i++) 
X		;
X	filesystem[f_system][i] = '\0';
X
X	strcpy(fsystem, filesystem[f_system]);
X	return( 1 );
X}
END_OF_FILE
if test 2054 -ne `wc -c <'src/get_fsystem.c'`; then
    echo shar: \"'src/get_fsystem.c'\" unpacked with wrong size!
fi
# end of 'src/get_fsystem.c'
fi
if test -f 'src/init.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/init.c'\"
else
echo shar: Extracting \"'src/init.c'\" \(2768 characters\)
sed "s/^X//" >'src/init.c' <<'END_OF_FILE'
X#include "defs.h"
X
init()
X{
X	extern int remote_managed;
X	extern char *remote_mgr;
X	extern struct tapedrive tapelist[];
X	extern int ntapedrives;
X	char host[MAX_STR];
X	char *targets, *colon, *comma, *index();
X	int density;
X
X	/*
X	   look for a remote manager for this machine.  If there is one
X	   then this machine must be remotely managed.  If not, then it
X	   must be a local machine.
X	*/
X	remote_mgr = getinfo("REMOTE_MGR");
X	if (remote_mgr != NULL)
X		remote_managed = True;
X	else
X		remote_managed = False;
X
X	set_ids();
X	set_sigs();
X
X	if ( (targets=getinfo(TAPELIST)) == (char *) NULL ) {
X	    fprintf( stderr, "oper:  %s.\n",
X		  "warning: found no tape drives for 'dump'" );
X	    ntapedrives = 0;
X	} else
X	    for ( ntapedrives=0; ; ++ntapedrives ) {
X
X		if ( targets != (char *) NULL && *targets != '\0' ) {
X		    colon = index( targets, ':' );
X		    if ( colon != (char *) NULL )
X			*colon = '\0';
X		    else
X			colon = targets + strlen(targets) - 1;
X		} else
X		    break;
X
X		if ( targets == (char *) NULL || *targets == (char) NULL ||
X			(comma=index(targets, ',')) == (char *) NULL ) {
X		    fprintf( stderr, "oper: bad tape format string '%s'.\n",
X								targets );
X		    break;
X		}
X		*comma = (char) NULL;
X		strcpy( tapelist[ntapedrives].td_host, targets );
printf("td_host '%s'\n", tapelist[ntapedrives].td_host);
X		targets = comma + 1;
X
X		if ( targets == (char *) NULL || *targets == (char) NULL ||
X			(comma=index(targets, ',')) == (char *) NULL ) {
X		    fprintf( stderr, "oper: bad tape format string '%s'.\n",
X								targets );
X		    break;
X		}
X		*comma = (char) NULL;
X		strcpy( tapelist[ntapedrives].td_drive, targets );
printf("td_drive '%s'\n", tapelist[ntapedrives].td_drive);
X		targets = comma + 1;
X
X		if ( targets == (char *) NULL || *targets == (char) NULL ||
X			(comma=index(targets, ',')) == (char *) NULL ) {
X		    fprintf( stderr, "oper: bad tape format string '%s'.\n",
X								targets );
X		    break;
X		}
X		if ( (density=atoi(targets)) == 0 )
X		    fprintf(stderr,"oper: warning: drive %s's density is %d.\n",
X				tapelist[ntapedrives].td_drive, density );
X		tapelist[ntapedrives].td_density = density;
X/* printf("td_density '%d'\n", tapelist[ntapedensitys].td_density); */
X		targets = comma + 1;
X
X		if ( targets == (char *) NULL || *targets == (char) NULL ||
X			(comma=index(targets, ',')) == (char *) NULL ) {
X		    fprintf( stderr, "oper: bad tape format string '%s'.\n",
X								targets );
X		    break;
X		}
X		*comma = (char) NULL;
X		strcpy( tapelist[ntapedrives].td_dumpprog, targets );
X/*printf("td_dumpprog '%s'\n", tapelist[ntapedumpprogs].td_dumpprog); */
X		targets = comma + 1;
X
X		if ( targets != (char *) NULL && *targets != (char) NULL )
X		    strcpy( tapelist[ntapedrives].td_flags, targets );
X		targets = colon + 1;
X	    }
X
X}
END_OF_FILE
if test 2768 -ne `wc -c <'src/init.c'`; then
    echo shar: \"'src/init.c'\" unpacked with wrong size!
fi
# end of 'src/init.c'
fi
if test -f 'src/line_to_vec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/line_to_vec.c'\"
else
echo shar: Extracting \"'src/line_to_vec.c'\" \(1508 characters\)
sed "s/^X//" >'src/line_to_vec.c' <<'END_OF_FILE'
X/*
X   line_to_vec: take a string and separates it into a vector of strings.
X
X   Assumptions:
X
X   Arguments:
X	   line: line to split.
X	   vec:	split line.
X	   splits: array of characters on which to split.
X
X   Global data used:
X	none.
X   
X   Local variables:
X	i, j, k: loop indices.
X	len: length of 'line'.
X	name: current entry in the vector we are building.
X	sub: subscript into rpairs of the char we are looking for to
X		match the one in rpairs that we found a moment.
X
X   Author:
X	Kenneth Ingham
X
X   Date:
X	Thu Sep  5 13:59:21 MDT 1985
X*/
X
X#include "defs.h"
X
char lpairs[] = "'\"";
char rpairs[] = "'\"";
X
line_to_vec(line, vec, splits)
char line[], *vec[], splits[];
X{
X	register int i, j, k;
X	int len, sub;
X	char name[MAX_STR];
X	char *malloc(), *strcpy();
X
X	len = strlen(line);
X	for (i=0, j=0, k=0; i<len; i++) {
X		if ((sub = cmatch(line[i], lpairs, strlen(lpairs))) != -1) {
X			if (i > 0 && !isspace(line[i-1]) && i < len) {
X				name[k] = '\0';
X				vec[j] = malloc((unsigned)strlen(name) + 1);
X				strcpy(vec[j],name);
X				j++;
X				k = 0;
X			}
X			i++;
X			while (line[i] != rpairs[sub] && line[i]) {
X				name[k] = line[i];
X				i++; k++;
X			}
X		}
X		else if (index(splits, line[i]) != 0) {
X			name[k] = '\0';
X			vec[j] = malloc((unsigned)strlen(name) + 1);
X			strcpy(vec[j],name);
X			j++;
X			k = 0;
X			while (index(splits, line[i]) != 0)
X				i++;
X			if (line[i]) i--;
X		}
X		else 
X			name[k++] = line[i];
X	}
X	name[k] = '\0';
X	vec[j] = malloc((unsigned)strlen(name)+1);
X	strcpy(vec[j],name);
X	vec[j+1] = 0;
X}
END_OF_FILE
if test 1508 -ne `wc -c <'src/line_to_vec.c'`; then
    echo shar: \"'src/line_to_vec.c'\" unpacked with wrong size!
fi
# end of 'src/line_to_vec.c'
fi
if test -f 'src/mtaccess.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mtaccess.c'\"
else
echo shar: Extracting \"'src/mtaccess.c'\" \(4564 characters\)
sed "s/^X//" >'src/mtaccess.c' <<'END_OF_FILE'
X/*
X   mtaccess: control access to the tape drive.
X*/
X
X#include "defs.h"
X#include <sys/file.h>
X#include <grp.h>
X
extern char *tapenames[];
extern int n_tapes, oper_uid, remote_managed;
extern char *strncpy();
extern char *gets();
extern int errno, pid;
X
X
void
mtaccess()
X{
X	char *gname;		/* group name of tape drives */
X	struct group *g;	/* yields actual group-id */
X	char line[MAX_STR];
X	char cmd[MAX_STR];
X	char ans[MAX_STR];
X	struct passwd *user;
X	int proc_id;                /*proc_id is pid of child process*/
X	int itime, i;
X	int	drive;
X	char	curnt_drive[50];
X	struct stat stat_buf;
X
X    if ( remote_managed ) {
X	printf("Since this host is remotely managed, please do not do this.\n");
X	return;
X    }
X
X	if ( access(tapenames[0], F_OK) < 0 ) {
X		printf( "Drive %d does not exist.\n", drive );
X		return;
X	}
X	stat( tapenames[0], &stat_buf );
X	if ( stat_buf.st_uid != oper_uid ) {		/* we don't own drive */
X		sprintf( line, "%s '%s'. %s? [y/n] ",
X			"Mag tape already allocated to",
X			( getpwuid((uid_t)stat_buf.st_uid) )->pw_name,
X			"Reallocate" );
X		getans( line, "y/n", ans );
X		if ( ans[0]== 'n')
X			return;
X		else if ( kill(pid, SIGKILL) == -1 )
X			if ( errno != ESRCH ) {
X				fprintf( stderr, "%s %d %s?\n",
X					"Wait!  Where did pid", pid, "go" );
X				perror( "tape drive child" );
X				return;
X			}
X	}
X
X	if ( (gname=getinfo("TAPE_GROUP")) == (char *) NULL || *gname == '\0' ){
X		fprintf( stderr, "oper: can't locate tape group id.\n" );
X		fprintf( stderr, "oper: getinfo(\"%s\") failed.\n",
X								"TAPE_GROUP" );
X		fprintf( stderr, "oper: returning to main menu.\n" );
X		return;
X	}
X
X	if ( (g=getgrnam(gname)) == (struct group *) NULL ) {
X		fprintf( stderr, "oper: could not find group '%s'.\n", gname );
X		fprintf( stderr, "oper: returning to main menu.\n" );
X		return;
X	}
X
X	setpwent();
X	for (;;) {
X		printf( "Enter the new tape drive user's login: " );
X		if ( strlen(gets(ans)) == 0 ) {
X			printf( "No name specified.  Bye..." );
X			return;
X		} else if ( (user=getpwnam(ans)) == (struct passwd *) NULL )
X			printf( "%s '%s' %s\n%s\n\n",
X				"Can't find", ans, "in the password file.",
X				"Please try again, or hit <return> to exit." );
X		else
X			break;
X	}
X
X	for (;;) {
X		printf( "Enter the time limit in minutes: " );
X		itime = atoi( gets(ans) );
X		if ( itime <= 0 )
X			printf( "Wait... I don't understand that.\n\n" );
X		else
X			break;
X	}
X
X	sprintf( line, "User=%s  Time=%d(min)  Ok? [y/n] ",
X							user->pw_name, itime );
X	getans( line, "y/n", ans );
X
X	if ( ans[0] == 'y' ) {		/* do the stuff! */
X
X		for ( i=0; i < n_tapes; i++ ) {
X			if (chown(tapenames[i], user->pw_uid, g->gr_gid) != 0) {
X				fprintf( stderr, "%s '%s' %s '%s'.\n",
X					"FAILED to set ownership of tape drive",
X					tapenames[i], "to user", user->pw_name);
X				perror( tapenames[i] );
X				printf( "Returning to the menu...\n" );
X				return;
X			}
X			if ( chmod(tapenames[i], 0660) != 0 ) {
X				fprintf( stderr, "%s '%s' %s '%s'.\n",
X					"FAILED to set perms on tape drive",
X					tapenames[i], "for user",
X					user->pw_name );
X				perror( tapenames[i] );
X				printf( "Returning to the menu...\n" );
X				return;
X			}
X#ifdef MTACCT
X			{
X				FILE	*af;
X				char	*ct;
X				long	t;
X
X				if((af = fopen(MTACCT, "a")) != (FILE *)NULL) {
X					time(&t);
X					ct = ctime(&t);
X					ct[4] = tolower(ct[4]);
X					if(ct[8] == ' ') ct[8] = '0';
X					fprintf(af, "%s %d %8s %2.2s%3.3s%4.4s\n",
X						user->pw_name, 1,
X						ct + 11, ct + 8, ct + 4, ct + 20);
X					fflush(af); fclose(af);
X				}
X			}
X#endif	MTACCT
X			putchar( '*' ), fflush( stdout );
X		}
X		printf("\n");
X
X#ifndef DEBUG
X		if ( (proc_id=fork()) == 0 ) {
X		    signal(SIGINT, SIG_IGN);
X		    sleep( itime * 60 );
X
X		    for ( i=0; i < n_tapes; i++ ) {
X			if ( chown(tapenames[i], oper_uid, g->gr_gid) != 0 ) {
X				fprintf( stderr, "%s '%s' %s '%s'.\n",
X					"FAILED to set ownership of tape drive",
X					tapenames[i], "to user", user->pw_name);
X				perror( tapenames[i] );
X				printf( "Returning to the menu...\n" );
X				return;
X			}
X			if ( chmod(tapenames[i], 0660) != 0 ) {
X				fprintf( stderr, "%s '%s' %s '%s'.\n",
X					"FAILED to set perms on tape drive",
X					tapenames[i], "for user",
X					user->pw_name );
X				perror( tapenames[i] );
X				printf( "Returning to the menu...\n" );
X				return;
X			}
X		    }
X		    _exit(0);
X		} else { 
X			pid = proc_id;
X			printf( "%s %d %s.\n",
X				"Operator regains control in", itime, "minutes");
X		}
X#else DEBUG
X		printf( "Debugging on:  would sleep %d minutes for '%s'.\n",
X			itime, user->pw_name );
X#endif DEBUG
X	} else 
X		printf( "Ok, if you'ld rather not, we won't...\n" );
X	return;
X}
END_OF_FILE
if test 4564 -ne `wc -c <'src/mtaccess.c'`; then
    echo shar: \"'src/mtaccess.c'\" unpacked with wrong size!
fi
# end of 'src/mtaccess.c'
fi
if test -f 'src/ps_open.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/ps_open.c'\"
else
echo shar: Extracting \"'src/ps_open.c'\" \(1758 characters\)
sed "s/^X//" >'src/ps_open.c' <<'END_OF_FILE'
X/*LINTLIBRARY*/
X/*
X   ps_open & ps_close: faster version of popen & pclose. Based upon
X	xopen which was gleaned from sysstat.c from net.sources on usenet.
X
X   Assumptions:
X
X   Arguments:
X	command: command to open.
X	mode: mode to open command with.  Just like fopen.
X	fd: file opened with ps_open to close.
X
X   Returns:
X	ps_open returns a file pointer to a pipe to the command or NULL
X	if it could not be done.
X
X   Global data used:
X	white_space: array containing characters considered white space.
X	errno: holds reason for error with failed system calls.
X
X   Global data modified:
X	none.
X   
X   Local variables:
X	ret_fp: file pointer to return.
X	arg: vector of the command to execute.
X	pipe_fd: pipe file descriptors.
X	i: loop index.
X
X   Notes:
X	ps_close should not be called with a file pointer that was not
X	opened with ps_open.
X
X   Author:
X	Kenneth Ingham
X
X   Date:
X	Thu Sep  5 14:13:52 MDT 1985
X
X*/
X
X#include <stdio.h>
X#include <errno.h>
X#include <sys/types.h>
X
X#define MAX_STR	256
X
char white_space[] = {' ', '\t', '\0'};
X
XFILE *ps_open(command, mode)
char command[], mode[];
X{
X	extern uid_t uid, gid;
X	FILE *ret_fp;
X	char *arg[MAX_STR];
X	int pipe_fd[2];
X	extern int errno;
X	extern char white_space[];
X
X	line_to_vec(command, arg, white_space);
X
X	pipe(pipe_fd);
X	switch(fork()) {
X		case -1:
X			return NULL;
X		case 0:
X			setuid(uid);
X			setgid(gid);
X			break;
X		default:
X			close(pipe_fd[1]);
X			if ((ret_fp = fdopen(pipe_fd[0], mode)) == NULL)
X				return NULL;
X			return ret_fp;
X	}
X	close(pipe_fd[0]);
X	close(1);
X	dup2(pipe_fd[1], 1);
X
X	execvp(arg[0], arg);
X
X	if (errno == ENOENT) {
X		printf("Unknown command: %s",arg[0]);
X	}
X	else 
X		perror(arg[0]);
X	_exit(0);
X	return 0; /* for lint */
X}
X
ps_close(fd)
XFILE *fd;
X{
X    fclose(fd);
X    wait((int *)0);
X}
END_OF_FILE
if test 1758 -ne `wc -c <'src/ps_open.c'`; then
    echo shar: \"'src/ps_open.c'\" unpacked with wrong size!
fi
# end of 'src/ps_open.c'
fi
if test -f 'src/reroute_printer.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/reroute_printer.c'\"
else
echo shar: Extracting \"'src/reroute_printer.c'\" \(8088 characters\)
sed "s/^X//" >'src/reroute_printer.c' <<'END_OF_FILE'
X#define	MAXPTR		256
X#define	MAXNAM		32
X#define	MAXROUT		32
X#define	TMPCAP		"/develop/collier/tempcap"
X#define	PRINTCAP	"/develop/collier/printcap"
X#define	ROUT1SED	"/^%s/s/^/%s|/"	/* sed script for rerouting */
X#define	ROUT2SED	"/^#%sS/,/^#%sE/s/^/#/"	/* sed script for rerouting */
X#define	UNDO1SED	"/^%s|/s/%s|//"	/* sed script for undoing */
X#define	UNDO2SED	"/^##%sS/,/^##%sE/s/^#//" /* sed script for undoing */
X#define	SWCH1SED	"s/^#>%s:/#<%s:/"
X#define	SWCH2SED	"s/^#<%s:/#>%s:/"
X#define	SWCH3SED	"s/^#>%s:/#%%%s:/"
X#define	SWCH4SED	"s/^#%%%s:/#>%s:/"
X
X#include	<stdio.h>
X
struct printer {
X	char	pr_name[MAXNAM],	/* name of printer */
X		pr_dest[MAXROUT][MAXNAM];	/* routing information */
X	int	pr_pcount,		/* number of routings */
X		pr_pri[MAXROUT];	/* routing priority */
X} *p, *pfree, plist[MAXPTR];
X
reroute()
X{
X
X	FILE	*f;
X	int	i,
X		r,
X		pri,
X		resp,
X		tries;
X	char	sbuf1[1024],
X		sbuf2[1024],
X		sbuf3[1024],
X		fbuf[1024],
X		ans[32];
X
loop:	clearerr(stdin);
X	if( (f=fopen(PRINTCAP, "r")) == (FILE *) NULL) {
X		fprintf(stderr, "Reroute: failed to open %s.", PRINTCAP);
X		return(0);
X	}
X
X	fprintf(stdout, "\nPrinter Rerouting.\n\n");
X	fprintf(stdout, "\t1. Re-route a printer.\n");
X	fprintf(stdout, "\t2. Undo rerouting.\n");
X	fprintf(stdout, "\t3. List of routed printers.\n");
X	fprintf(stdout, "\t4. Quit.\n");
X	fprintf(stdout, "\nWhich (1 - 4, ^D to quit)? ");
X
X	if( gets(ans) == (char *) NULL )
X		return(0);
X	if(strlen(ans) != 1) {
X		fprintf(stderr, "Bad response.\n");
X		goto loop;
X	}
X
X	resp = atoi(ans);
X
X	pfree = plist;
X/*###62 [lint] bzero arg. 1 used inconsistently llib-lc(190) :: reroute_printer.c(62)%%%*/
X	bzero(plist, sizeof(plist));
X	switch(resp) {
X		case 1:
X			while(fgets(fbuf, 1024, f) != (char *) NULL) {
X				if(strncmp("#>", fbuf, 2) == 0 && pfree <= &plist[MAXPTR])
X					install(fbuf);
X			}
X			fclose(f);
X
X			if(pfree == plist) {
X				fprintf(stderr, "Sorry, no printers may be rerouted.\n");
X				goto loop;
X			}
X
X			tries = 0;
X			do {
X				fprintf(stdout, "\nThese printers can be rerouted:\n\n");
X				for(p = plist; p < pfree; ++ p)
X					fprintf(stdout, "%s\n", p->pr_name);
X				fprintf(stdout, "\nWhich one (^D to abort)? ");
X				if( gets(fbuf) == (char *) NULL ) {
X					fprintf(stderr, "Aborting.\n");
X					goto loop;
X				}
X				if(strlen(fbuf) < 1) {
X					fprintf(stderr, "Invalid response, aborting.\n");
X					goto loop;
X				}
X				for(p = plist; p < pfree; ++ p)
X					if(strcmp(fbuf, p->pr_name) == 0)
X						break;
X				if(p >= pfree)
X					fprintf(stderr, "\nNo such printer.\n");
X			} while(p >= pfree && ++ tries < 3);
X
X			if(tries >= 3) {
X				fprintf(stderr, "Please try again.\n");
X				goto loop;
X			}
X
X			for(i = 0, r = -1, pri = -1; i < p->pr_pcount; ++ i) {
X				if(p->pr_pri[i] > pri) {
X					pri = p->pr_pri[i];
X					r = i;
X				}
X			}
X
X			if(r < 0) {
X				fprintf(stderr, "%s cannot be rerouted.  Sorry.\n",
X					p->pr_name);
X				goto loop;
X			}
X
X			fprintf(stdout, "Rerouting %s to %s, o.k. (y/n/^D to abort)? ",
X				p->pr_name, p->pr_dest[r]);
X			if( gets(ans) == (char *) NULL ) {
X				fprintf(stderr, "Aborting.\n");
X				goto loop;
X			}
X			if(strlen(ans) != 1) {
X				fprintf(stderr, "Invalid response, aborting.\n");
X				goto loop;
X			}
X			if(ans[0] == 'y' || ans[0] == 'Y') {
X				route(p->pr_name, p->pr_dest[r]);
X				goto loop;
X			}
X
X			tries = 0;
X			do {
X				fprintf(stdout, "\nYou can reroute %s to these printers:\n\n",
X					p->pr_name);
X				for(i = 0; i < p->pr_pcount; ++ i)
X					fprintf(stdout, "%s\n", p->pr_dest[i]);
X
X				fprintf(stdout, "\nWhich one (^D to abort)? ");
X				if( gets(fbuf) == (char *) NULL ) {
X					fprintf(stderr, "Aborting.\n");
X					goto loop;
X				}
X				if(strlen(fbuf) < 1) {
X					fprintf(stderr, "Invalid response, aborting.\n");
X					goto loop;
X				}
X				for(i = 0, r = -1; i < p->pr_pcount; i ++) {
X					if(strcmp(fbuf, p->pr_dest[i]) == 0) {
X						r = i;
X						break;
X					}
X				}
X				if(r < 0)
X					fprintf(stderr, "No such printer.\n");
X			} while(r < 0 && ++ tries < 3);
X
X			if(tries > 3) {
X				fprintf(stderr, "Please try again.\n");
X				goto loop;
X			}
X
X			fprintf(stdout, "Rerouting %s to %s, o.k. (y/n/^D to abort)? ",
X				p->pr_name, p->pr_dest[r]);
X			if( gets(ans) == (char *) NULL ) {
X				fprintf(stderr, "Aborting.\n");
X				goto loop;
X			}
X			if(strlen(ans) < 1) {
X				fprintf(stderr, "Invalid response, aborting.\n");
X				goto loop;
X			}
X			if(ans[0] == 'y' || ans[0] == 'Y') {
X				route(p->pr_name, p->pr_dest[r]);
X				goto loop;
X			}
X			else {
X				fprintf(stdout, "Please try again.\n");
X				goto loop;
X			}
X			break;
X		case 2:
X			while(fgets(fbuf, 1024, f) != (char *) NULL) {
X				if(strncmp("#<", fbuf, 2) == 0 && pfree <= &plist[MAXPTR])
X					install(fbuf);
X			}
X			fclose(f);
X
X			if(pfree == plist) {
X				fprintf(stderr, "Sorry, no printers to un-reroute.\n");
X				goto loop;
X			}
X
X			tries = 0;
X			do {
X				fprintf(stdout, "\nThese printers can be un-rerouted:\n\n");
X				for(p = plist; p < pfree; ++ p)
X					fprintf(stdout, "%s (-> %s)\n", p->pr_name, p->pr_dest[0]);
X				fprintf(stdout, "\nWhich one (^D to abort)? ");
X				if( gets(fbuf) == (char *) NULL ) {
X					fprintf(stderr, "Aborting.\n");
X					goto loop;
X				}
X				if(strlen(fbuf) < 1) {
X					fprintf(stderr, "Invalid response, aborting.\n");
X					goto loop;
X				}
X				for(p = plist; p < pfree; ++ p)
X					if(strcmp(fbuf, p->pr_name) == 0)
X						break;
X				if(p >= pfree)
X					fprintf(stderr, "\nNo such printer.\n");
X			} while(p >= pfree && ++ tries < 3);
X
X			if(tries > 3) {
X				fprintf(stderr, "Please try again.\n");
X				goto loop;
X			}
X
X			fprintf(stdout, "Un-rerouting %s from %s, o.k. (y/n/^D to abort)? ",
X				p->pr_name, p->pr_dest[0]);
X			if( gets(ans) == (char *) NULL ) {
X				fprintf(stderr, "Aborting.\n");
X				goto loop;
X			}
X			if(strlen(ans) < 1) {
X				fprintf(stderr, "Invalid response, aborting.\n");
X				goto loop;
X			}
X			if(ans[0] == 'y' || ans[0] == 'Y') {
X				unroute(p->pr_name, p->pr_dest[0]);
X				goto loop;
X			}
X			break;
X		case 3:
X			while(fgets(fbuf, 1024, f) != (char *) NULL) {
X				if(strncmp("#<", fbuf, 2) == 0 && pfree <= &plist[MAXPTR])
X					install(fbuf);
X			}
X			fclose(f);
X
X			if(pfree == plist) {
X				fprintf(stderr, "Sorry, no printers are routed.\n");
X				goto loop;
X			}
X
X			fprintf(stdout, "\nThese printers are routed:\n\n");
X			for(p = plist; p < pfree; ++ p)
X				fprintf(stdout, "%s (-> %s)\n",
X					p->pr_name, p->pr_dest[0]);
X			break;
X		case 4:
X			return(0);
X		default:
X			fprintf(stderr, "Bad command %d.\n", resp);
X			goto loop;
X			break;
X	}
X	fclose(f);
X	goto loop;
X}
X
install(s)
X	char	*s;
X{
X
X	char	*p1,
X		*p2,
X		*p3,
X		*index(),
X		*rindex();
X	struct printer	*p;
X
X	p1 = s + 2;
X
X	p2 = index(s, ':');
X	if(p2 != rindex(s, ':'))
X		return;
X	p2 ++;
X
X	p3 = index(s, ';');
X	if(p3 != rindex(s, ';'))
X		return;
X	p3 ++;
X
X	p2[-1] = '\0';
X	p3[-1] = '\0';
X
X	for(p = plist; p < pfree; p ++)
X		if(strcmp(p1, p->pr_name) == 0)
X			break;
X	if(p == pfree) {
X		pfree ++;
X		strcpy(p->pr_name, p1);
X	}
X/*###294 [lint] strcpy value declared inconsistently llib-lc(361) :: reroute_printer.c(294)%%%*/
X	strcpy(p->pr_dest[p->pr_pcount], p2);
X	p->pr_pri[p->pr_pcount] = atoi(p3);
X	p->pr_pcount ++;
X}
X
route(a, b)
X	char	*a,
X		*b;
X{
X	char	b1[256],
X		b2[256],
X		b3[256],
X		b4[256];
X
X	sprintf(b1, ROUT1SED, b, a);
X	sprintf(b2, ROUT2SED, a, a);
X	sprintf(b3, SWCH1SED, a, a);
X	sprintf(b4, SWCH3SED, b, b);
X
X	if(!fork()) {
X		freopen(TMPCAP, "w+", stdout);
X		execl("/bin/sed", "sed", "-e", b1, "-e", b2, "-e",
X			b3, "-e", b4, PRINTCAP, 0);
X	}
X	else {
X/*###319 [lint] wait arg. 1 used inconsistently llib-lc(163) :: reroute_printer.c(319)%%%*/
X		wait(0);
X		rename(TMPCAP, PRINTCAP);
X		chmod(PRINTCAP, 0644);
X	}
X}
X
unroute(a, b)
X	char	*a,
X		*b;
X{
X	char	b1[256],
X		b2[256],
X		b3[256],
X		b4[256];
X
X	sprintf(b1, UNDO1SED, a, a);
X	sprintf(b2, UNDO2SED, a, a);
X	sprintf(b3, SWCH2SED, a, a);
X	sprintf(b4, SWCH4SED, b, b);
X
X	if(!fork()) {
X		freopen(TMPCAP, "w+", stdout);
X		execl("/bin/sed", "sed", "-e", b1, "-e", b2,
X			"-e", b3, "-e", b4, PRINTCAP, 0);
X	}
X	else {
X/*###345 [lint] wait arg. 1 used inconsistently llib-lc(163) :: reroute_printer.c(345)%%%*/
X		wait(0);
X		rename(TMPCAP, PRINTCAP);
X		chmod(PRINTCAP, 0644);
X	}
X}
END_OF_FILE
if test 8088 -ne `wc -c <'src/reroute_printer.c'`; then
    echo shar: \"'src/reroute_printer.c'\" unpacked with wrong size!
fi
# end of 'src/reroute_printer.c'
fi
if test -f 'src/set_date.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/set_date.c'\"
else
echo shar: Extracting \"'src/set_date.c'\" \(2438 characters\)
sed "s/^X//" >'src/set_date.c' <<'END_OF_FILE'
X/*
X   setdate: set the date on the machine.
X
X   Author: Kenneth Ingham
X
X   Thu Oct 24 16:26:59 MDT 1985
X*/
X
X#include "defs.h"
X
X#define year_in_range(y)	(y > 80 && y < 100)  /* must be 2 digits */
X#define month_in_range(m)	(m >= 1 && m <= 12)
X#define date_in_range(d, m)	(d >= 1 && \
X				 ((m == 1 && d <= 31) ||\
X				  (m == 2 && d <= 29) ||\
X				  (m == 3 && d <= 31) ||\
X				  (m == 4 && d <= 30) ||\
X				  (m == 5 && d <= 31) ||\
X				  (m == 6 && d <= 30) ||\
X				  (m == 7 && d <= 31) ||\
X				  (m == 8 && d <= 31) ||\
X				  (m == 9 && d <= 30) ||\
X				  (m == 10 && d <= 31) ||\
X				  (m == 11 && d <= 30) ||\
X				  (m == 12 && d <= 31)))
X#define hour_in_range(h)	(h >= 0 && h <= 11)
X#define minute_in_range(m)	(m >=0 && m <= 59)
X
void
set_date()
X{
X	extern int remote_managed;
X	int year, month, date, hour, minute, am;
X	char line[MAX_STR];
X
X    if ( remote_managed ) {
X	printf("Since this host is remotely managed, please do not do this.\n");
X	return;
X    }
X
X	do {
X		printf("Enter the last two digits of the current year: ");
X		year = atoi(gets(line));
X		if (! year_in_range(year))
X		    printf("Try again, I want the >CURRENT< year.\n\n");
X	} while (! year_in_range(year));
X
X	do {
X		printf("Enter the month as a number (ie May would be 5): ");
X		month = atoi(gets(line));
X		if (! month_in_range(month))
X		    printf("Last I checked, the months ran from 1 to 12.\n\n");
X	} while (! month_in_range(month));
X
X	do {
X		printf("Enter today's date: ");
X		date = atoi(gets(line));
X		if (! date_in_range(date, month))
X		    printf("There are not %d days in the %dth month.\n\n",
X			    date, month);
X	} while (! date_in_range(date, month));
X
X	do {
X		printf("Enter the hours past noon or midnight: ");
X		hour = atoi(gets(line));
X		if (! hour_in_range(hour))
X		    printf("I want a number from 0 to 11.\n\n");
X	} while (! hour_in_range(hour));
X
X	do {
X		printf("Enter the number of minutes past the hour: ");
X		minute = atoi(gets(line));
X		if (! minute_in_range(minute))
X			printf("I want a number from 0 to 59.\n\n");
X	} while (! minute_in_range(minute));
X
X	do {
X		printf("is it morning still? [y/n] ");
X		gets(line);
X		if (line[0] != 'y' && line[0] != 'n')
X			printf("Use either the 'n' or the 'y' key to answer the question.\n\n");
X	} while (line[0] != 'y' && line[0] != 'n');
X	am = line[0] == 'y';
X
X	if (!am) hour += 12;
X
X	sprintf(line, "date %02d%02d%02d%02d%02d", year, month, date, hour, minute);
X	printf("%s\n", line);
X	system(line);
X}
END_OF_FILE
if test 2438 -ne `wc -c <'src/set_date.c'`; then
    echo shar: \"'src/set_date.c'\" unpacked with wrong size!
fi
# end of 'src/set_date.c'
fi
if test -f 'src/setdate.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/setdate.c'\"
else
echo shar: Extracting \"'src/setdate.c'\" \(2542 characters\)
sed "s/^X//" >'src/setdate.c' <<'END_OF_FILE'
X/*
X   setdate: set the date on the machine.
X
X   Author: Kenneth Ingham
X
X   Thu Oct 24 16:26:59 MDT 1985
X*/
X
X#include "defs.h"
X
X#define year_in_range(y)	(y > 80 && y < 90)
X#define month_in_range(m)	(m >= 1 && m <= 12)
X#define date_in_range(d, m)	(d >= 1 && \
X				 ((m == 1 && d <= 31) ||\
X				  (m == 2 && d <= 29) ||\
X				  (m == 3 && d <= 31) ||\
X				  (m == 4 && d <= 30) ||\
X				  (m == 5 && d <= 31) ||\
X				  (m == 6 && d <= 30) ||\
X				  (m == 7 && d <= 31) ||\
X				  (m == 8 && d <= 31) ||\
X				  (m == 9 && d <= 30) ||\
X				  (m == 10 && d <= 31) ||\
X				  (m == 11 && d <= 30) ||\
X				  (m == 12 && d <= 31)))
X#define hour_in_range(h)	(h >= 0 && h <= 11)
X#define minute_in_range(m)	(m >=0 && m <= 59)
X
extern int machine;		/* the number of the machine i'm currently on */
extern int machflags[];		/* list of flags for all machines */
X
setdate()
X{
X	int year, month, date, hour, minute, am;
X	char line[MAX_STR];
X
X    if ( (machflags[machine] & MF_RMANAGED) != 0 ) {
X	printf("Since this host is remotely managed, please do not do this.\n");
X	return( 0 );
X    }
X
X	do {
X		printf("Enter the last two digits of the current year: ");
X		year = atoi(gets(line));
X		if (! year_in_range(year))
X		    printf("Try again, I want the >CURRENT< year.\n\n");
X	} while (! year_in_range(year));
X
X	do {
X		printf("Enter the month as a number (ie May would be 5): ");
X		month = atoi(gets(line));
X		if (! month_in_range(month))
X		    printf("Last I checked, the months ran from 1 to 12.\n\n");
X	} while (! month_in_range(month));
X
X	do {
X		printf("Enter today's date: ");
X		date = atoi(gets(line));
X		if (! date_in_range(date, month))
X		    printf("There are not %d days in the %dth month.\n\n",
X			    date, month);
X	} while (! date_in_range(date, month));
X
X	do {
X		printf("Enter the hours past noon or midnight: ");
X		hour = atoi(gets(line));
X		if (! hour_in_range(hour))
X		    printf("I want a number from 0 to 11.\n\n");
X	} while (! hour_in_range(hour));
X
X	do {
X		printf("Enter the number of minutes past the hour: ");
X		minute = atoi(gets(line));
X		if (! minute_in_range(minute))
X			printf("I want a number from 0 to 59.\n\n");
X	} while (! minute_in_range(minute));
X
X	do {
X		printf("is it morning still? [y/n] ");
X		gets(line);
X		if (line[0] != 'y' && line[0] != 'n')
X			printf("Use either the 'n' or the 'y' key to answer the question.\n\n");
X	} while (line[0] != 'y' && line[0] != 'n');
X	am = line[0] == 'y';
X
X	if (!am) hour += 12;
X
X	sprintf(line, "date %02d%02d%02d%02d%02d", year, month, date, hour, minute);
X	printf("%s\n", line);
X	system(line);
X}
END_OF_FILE
if test 2542 -ne `wc -c <'src/setdate.c'`; then
    echo shar: \"'src/setdate.c'\" unpacked with wrong size!
fi
# end of 'src/setdate.c'
fi
echo shar: End of archive 2 \(of 2\).
cp /dev/null ark2isdone
MISSING=""
for I in 1 2 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked both 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
-- 

Steve.                    sfreed@ariel.unm.edu