[net.sources] The Printer Spooler I Promised

perry@sbcs.UUCP (Perry Kivolowitz) (10/04/83)

From perry Tue Oct  4 15:51:38 1983 remote from steinmetz
Date: 4 Oct 1983 15:48-EST
From: Perry S. Kivolowitz   <perry@steinmetz-SBCS-VLSI-vax>
Subject: None
To: sbcs!perry

#
#	makefile for the Perry's Printer Deamon
#
#	perry s kivolowitz
#
#	Possible entries in DEFINES:
#	
#	SPOOLDIR - MUST BE PRESENT - full name of spool directory
#	DEBUG	 - OPTIONAL	   - set to get debugging lines.
#	CONSOLE  - OPTIONAL	   - set to get ghost story on sys console.
#	SLEEPY_TIME - OPTIONAL	   - set to a number to redefine sleep time.
#
#

DEFINES	=	-DSPOOLDIR=\"/usr/spool/ppdir\"
CFLAGS = -O

ppdemon	: 	printer.o
	  	cc -o ppdeamon printer.o

printer.o:	printer.c
		cc $(DEFINES) $(CFLAGS) -c printer.c

ppq	:	ppq.csh
		cp ppq.csh ppq
		chmod 711 ppq

ppr	:	ppr.csh
		cp ppr.csh ppr
		chmod 711 ppr

------------------------------------------------------------------
ppr is a shell script which registers files for printing
------------------------------------------------------------------
#
#	P  P  R  -  P e r r y ' s   P r i n t e r 
#
#	Permission is hereby granted for unlimited distribution for
#	non-commercial use only.
#
#	Perry S. Kivolowitz
#	allegra!sbcs!perry
#	philabs!sbcs!perry
#	(516) 467 - 3176
#
#	MUST PLACE SPOOL DIRECTORY ON YOUR MACHINE IN THE CP AND CHMOD
#	STATEMENTS!!!
#
if ($1 == "") then
	echo Usage: ppr filelist
	exit(1)
endif
foreach file ($*)
	if (! -e $file ) then
		echo ${file}: does not exist
		continue
	endif
	if ((${file:e} == out) || ($file == core)) then
		echo "${file}: shouldn't print object files"
		continue
	endif
	cp $file /usr/spool/ppdir/$$.$file
	chmod 600 /usr/spool/ppdir/$$.$file
end

-----------------------------------------------------------------
ppq is a shell script which prints the queue - Change the heading
-----------------------------------------------------------------
#
#	P  P  Q  -  P e r r y ' s   P r i n t e r   Q u e u e (printer)
#
#
#	Permission is hereby granted for unlimited distribution for
#	non-commercial use only.
#
#	Perry S. Kivolowitz
#	allegra!sbcs!perry
#	philabs!sbcs!perry
#	(516) 467 - 3176
#
#	MUST SET sd TO SPOOL DIRECTORY ON YOUR MACHINE!
#
set sd = /usr/spool/ppdir 
echo "Undergraduate Laboratory Printer Queue"
set n = `ls -1 $sd | wc -l`
if ($n == "0") then
	echo "         Printer Queue Empty"
	exit
endif
echo -n "Owner      Size   Created    File"
ls -ltr $sd | colrm 1 13
-----------------------------------------------------------------
ppdeamon is the c program which does all the printing etc.
-----------------------------------------------------------------
/*
**	Perry's Printer Deamon
**	(or is it ppdaemon?)
**
**	Perry S. Kivolowitz
** 	allegra!sbcs!perry
**	philabs!sbcs!perry
**	(516) 467 - 3176
**
**	Permission is hereby granted for unlimited distribution for
**	NON-COMERCIAL purposes. 
**
**	the routine ``pprint'' is  what  needs to be modifed to suit
**	the specific needs of the site.
**
**	A really nice thing about this arrangement is that the queue
**	dump program - eg tpq or ipq - is replaced  by ls -lr of the
**	spool directory since the files  are  always  printed oldest
**	first.
**
**	Also, this  deamon  occupies  little  space  and little cpu
**	resources.
**
**	DEFINES:
**
**	SPOOLDIR - directory in which files to be printed will  be
**		   placed. 
**	SLEEPY_TIME
**		 - if set, will redefing the number of seconds the
**		   daemon will  sleep after clearing out the spool
**		   directory.
**	CONSOLE  - if set, will tell the system console why we
**		   gave up the ghost.
**	DEBUG	 - yeah.
**
*/

#include <stdio.h>
#include <sys/types.h>
#include <dir.h>
#include <sys/stat.h>
#include <whoami.h>
#include <sgtty.h>
#include <pwd.h>
#define	VAX

struct passwd *getpwuid();
struct dir temp;	/* place to read directory entries */
struct stat statbuf;	/* place to perform stat on files */
int sdir;		/* fd for spool directory */
int interval = 30;	/* sleeping time between passes */

#define	BSIZE	512

struct {
	char 	name[DIRSIZ];
	time_t	mtime;
} oldest;

#ifdef	VAX
#define	PRINTER_LINE	"/dev/tty15"	/* name of printer */
int	pfd;				/* printer file descriptor */
FILE	*pfp , *fdopen();		/* printer file stream */
struct  sgttyb ttybuf;
#endif
 
main()
{
	int i;

#ifdef	SLEEPY_TIME
	interval = SLEEPY_TIME;
#endif
#ifdef	VAX
	if ((pfd = open(PRINTER_LINE , 1)) < 0) fatal("Can't open printer");
	gtty(pfd , &ttybuf);
	ttybuf.sg_ispeed = ttybuf.sg_ospeed = B9600;
	ttybuf.sg_erase = ttybuf.sg_kill = 0;
	ttybuf.sg_flags = CRMOD | XTABS | ANYP;
	stty(pfd , &ttybuf);
	pfp = fdopen(pfd , "w");
#endif
	if (access(SPOOLDIR , 4)) 
		fatal("Can't access spool directory");
	if (chdir(SPOOLDIR))
		fatal("Can't cd to spool directory");
top:
	oldest.mtime = ~(1 << 31);
	if ((sdir = open("." , 0)) < 0) 
		fatal("Can't open spool directory");
	while (read(sdir , &temp , sizeof(struct dir)) > 0) {
		if (temp.d_ino == 0) continue;
		if (temp.d_name[0] == '.') continue;
		if (stat(temp.d_name , &statbuf))
		   fatal("Couldn't take status of a spooled file");
		if (statbuf.st_mtime < oldest.mtime) {
			oldest.mtime = statbuf.st_mtime;
			for (i = 0; i < DIRSIZ; i++)
			    oldest.name[i] = temp.d_name[i];
		}
	}
	close(sdir);
	if (oldest.mtime != ~(1 << 31)) {
		stat(oldest.name , &statbuf);	/* re-stat file to be printed */
		pprint(oldest.name);
		goto top;
	}
#ifdef	DEBUG
	printf("Sleeping - done everything in directory\n");
#endif
	sleep(interval);
	goto top;
}

fatal(s)
char *s;
{
	FILE *fp;

	fprintf(stderr,"Make sure your T.A. sees the following message\n");
	fflush(stderr);
	perror(s);
#ifdef	CONSOLE
	if ((fp = fopen("/dev/console" , "w")) != NULL) {
#else
	fp = stdout;
#endif
		fprintf(fp,"Ppdemon failed: %s\n" , s);
#ifdef	CONSOLE
	}
	fclose(fp);
#endif
	exit(1);
}

pprint(name)
char *name;
{
#ifdef	VAX
	int fd;
	char c[BSIZE];
	int i;

	banner();
	fd = open(name , 0);
	while ((i = read(fd,c,BSIZE)) == BSIZE) write(pfd,c,BSIZE);
	write(pfd , c , i);
	close(fd);
#endif
	unlink(name);
}

#ifdef	VAX

char	form_feed = '\f';
char	new_line  = '\n';
char	carr_rtn  = '\r';

#define	ff()	write(pfd , &form_feed , 1)

struct passwd	*ps;

/*
**	banner - print a banner page
**
**	USES INFO LEFT IN STATBUF - hence the second call to stat on
**	the file which will actually be printed.
**
*/

banner()
{
	int	i , j;
	long	t;

	ff();
	ps = getpwuid(statbuf.st_uid);
	fflush(pfp);
	fprintf(pfp , "machine name: %s\n" , sysname);
	fprintf(pfp , "user name: %s\n" , ps->pw_name);
	fprintf(pfp , "file creation time: %s" , ctime(&statbuf.st_ctime));
	time(&t);
	fprintf(pfp , "current time: %s" , ctime(&t));
	fflush(pfp);
	ff();

}

#endif



-----------------------------------------------------------------
END OF TRANSMISSION
-----------------------------------------------------------------