v16i022: Public lineprinter spooler package, Part09/16

Rich Salz rsalz at bbn.com
Thu Sep 15 22:13:28 AEST 1988


Submitted-by: papowell at julius.cs.umn.edu
Posting-number: Volume 16, Issue 22
Archive-name: plp/part09

#! /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 9 (of 16)."
# Contents:  src/Makefile src/global.c src/lockfile.c
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/Makefile'\"
else
echo shar: Extracting \"'src/Makefile'\" \(12955 characters\)
sed "s/^X//" >'src/Makefile' <<'END_OF_FILE'
X#***************************************************************************
X#* U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
X#***************************************************************************
X#* MODULE: Makefile
X#***************************************************************************
X#* Revision History:  Recreated
X#* Sun Jan  3 07:27:44 CST 1988: V1
X#***************************************************************************
X#$Log:	Makefile,v $
X# Revision 3.2  88/06/24  17:58:54  papowell
X# MODS for VAX 4.3BSD UNIX
X# 
X# Revision 3.1  88/06/18  09:33:48  papowell
X# Version 3.0- Distributed Sat Jun 18 1988
X# 
X# Revision 3.0  88/06/18  09:29:46  papowell
X# Version 3.0- Distributed Sat Jun 18 1988
X# 
X# Revision 2.3  88/05/16  12:09:58  papowell
X# Added a "test" entry to make XPERIMENT version
X# 
X# Revision 2.2  88/05/11  09:53:19  papowell
X# Modified installation targets to be compatible with Berkeley LPR
X# 
X# Revision 2.1  88/05/09  10:07:22  papowell
X# PLP: Released Version
X# 
X# Revision 1.10  88/04/29  07:44:51  papowell
X# Added USE_LOCKF for alternative form of locking
X# 
X# Revision 1.9  88/04/28  17:30:23  papowell
X# Fixed installation
X# 
X#
X# This makefile will generate and install the PLP software.
X# You should create a "bin" directory,  and copy this Makefile to the bin
X# directory.  All binaries and executables will be created in the bin directory.
X#
X# The PLP stuff runs SUID ROOT.
X#
X# There are various compilation options;  see the following for details.
X#
X# Note that this Makefile does NOT create spool directories;
X# you have to do that yourself, whenever a new entry is added to /etc/printcap
X# See the "checkpc" program for help.
X#
X.SUFFIXES:
X
X# commands made by this script
COMMANDS= lpd lpr lpq lprm lpc pac checkpc
X
X# where daemons are installed: lpd
X#LIB=/usr/lib/
X#LIB=/usr/local/new/lib
LIB=/usr/lib/
X
X# where user commands are installed: lpr, lpq, lprm, lpc
X#BIN=/usr/local/new/bin/
BIN=/usr/ucb/
X
X# where maintenance commands are installed: pac, checkpc
X#MAINTDIR=/etc/
MAINTDIR=$(BIN)
X
X# source directory, holds all source
SRC=../src
X
X# lint directory, where the output of the various lintings will go
LNT=../lint
X
X#**************** OPTIONS *******************************
X# The following flags are used to control compile time dependent options
X
X# MACHINE - IS_SUN, IS_VAX, IS_UMAX (ENCORE NS32000)
X# Oh, this is sick.  You should check the lp.h file for dependencies
X# These are explained below. Most are "ifndef" or "ifdef" in a very few files.
X# Some systems do not have certain data types available,  so that you have to
X# define some types.  See "lp.h" for the set of definitions and some options
X# that have been hardwired there for ease of installation.
X  MACHINE = -DIS_SUN=1
X# MACHINE = -DIS_VAX4BSD=1
X# MACHINE = -DIS_DATAGEN=1
X# MACHINE = -DIS_UMAX=1
X# MACHINE = -DIS_APOLLO=1
X
X
X# XPERIMENT: Generation a version that can be used to experiment
X# DEBUG: Generate a version that has -X option enabled
X#   The XPERIMENT option specifies -X option always to be used
X XPERIMENT=-DXPERIMENT=1
X#DEBUG=-DDEBUG=1
X
X# SYSLOG: syslog(8) is a 4BSD logging facility.
X# If you do not have syslog, define NOSYSLOG and error messages will
X# be printed to /dev/console.  See syslogmsg.c for details.
X# The <syslog.h> include file contains a set of definitions for values
X# to be used by the SYSLOG software.  Different systems have different
X# error values, which means that the values are compile time dependent.
X# This  is usually set in lp.h based on "IS_??"
X#NOSYSLOG=-DNOSYSLOG=1
X
X# SYMLINK: If you do not have symbolic links, you cannot use them.
X# This  is usually set in lp.h based on "IS_??"
X#NOSYMLINK=-DNOSYMLINK=1
X
X# ETCPC:  printcap file; default is /etc/printcap
X# ETCPERMS:  printer permissions file; default is /etc/printer_perms
X# Modify the following.
X#ETCPC=-DETCPC='"/usr/etc/printcap"'
X#ETCPERMS=-DETCPERMS='"/usr/etc/printer_perms"'
X
X# NO_LOCKF: some systems do not have lockf() which is used to lock files;
X# The alternative is to use flock().  If you do not have either,  modify
X# the do_lock() procedure in lockfile.c to provide locking, although this has
X# proven to be fairly unsucessful in the past.
X# NOTE: lockf is essential to use in an NFS environment
X#NO_LOCKF=-DNO_LOCKF=1
X
X# Define TERMCAP and TERMLIB if curses is to be used by lpq
TERMCAP=-DTERMCAP=1
TERMLIB=-lcurses -ltermcap
X
XFLAGS= -I. -I${SRC} ${DEBUG} ${XPERIMENT} ${MACHINE} \
X	${NOSYMLINK} ${ETCPC} ${ETCPERMS} ${TERMCAP} ${USE_LOCKF}
X#CFLAGS= -O ${FLAGS}
CFLAGS= -g ${FLAGS}
LINTFLAGS= -huv ${FLAGS}
LINTFILTER = \
X	| sed -e '/warning: struct.union iovec never defined/d' -e '/:$$/d' \
X		-e '/warning: possible pointer alignment problem/d'
X
COMPILE= ${CC} -c ${CFLAGS}
CXREF=/usr/ucb/ctags -x
PRINT=cpr -r
X
all:	${COMMANDS}
X
X#
X# Binary : Object    dependencies
X# LPD
DEPlpd =  \
X	banner.o checkperm.o control_ops.o displayq.o errormsg.o getopt.o global.o \
X	link_support.o localprinter.o lockfile.o lpd.o mexecv.o print_support.o \
X	printcap.o recvfiles.o remote_ops.o remoteprinter.o rmjob.o sendmail.o \
X	servicereq.o setstatus.o setup_filter.o setup_test.o startserver.o \
X	startprinter.o utils.o find_name.o
SRClpd =  \
X	${SRC}/banner.c ${SRC}/checkperm.c ${SRC}/control_ops.c ${SRC}/displayq.c \
X	${SRC}/errormsg.c ${SRC}/getopt.c ${SRC}/global.c ${SRC}/link_support.c \
X	${SRC}/localprinter.c ${SRC}/lockfile.c ${SRC}/lpd.c ${SRC}/mexecv.c \
X	${SRC}/print_support.c ${SRC}/printcap.c ${SRC}/recvfiles.c \
X	${SRC}/remote_ops.c ${SRC}/remoteprinter.c ${SRC}/rmjob.c \
X	${SRC}/sendmail.c ${SRC}/servicereq.c ${SRC}/setstatus.c \
X	${SRC}/setup_filter.c ${SRC}/setup_test.c ${SRC}/startserver.c \
X	${SRC}/startprinter.c ${SRC}/utils.c ${SRC}/find_name.c
lpd: $(DEPlpd)
X	${CC}  ${CFLAGS}  -o lpd $(DEPlpd)
DEPlpr =  \
X	checkperm.o errormsg.o getopt.o global.o lockfile.o lpr.o lpr_canprint.o \
X	lpr_filters.o lpr_global.o lpr_job.o lpr_parms.o lpr_temp.o mexecv.o \
X	printcap.o setup_filter.o setup_test.o startserver.o utils.o getprinter.o \
X	remote_ops.o link_support.o
SRClpr =  \
X	${SRC}/checkperm.c ${SRC}/errormsg.c ${SRC}/getopt.c ${SRC}/global.c \
X	${SRC}/lockfile.c ${SRC}/lpr.c ${SRC}/lpr_canprint.c ${SRC}/lpr_filters.c \
X	${SRC}/lpr_global.c ${SRC}/lpr_job.c ${SRC}/lpr_parms.c ${SRC}/lpr_temp.c \
X	${SRC}/mexecv.c ${SRC}/printcap.c ${SRC}/setup_filter.c \
X	${SRC}/setup_test.c ${SRC}/startserver.c ${SRC}/utils.c \
X	${SRC}/getprinter.c ${SRC}/remote_ops.c ${SRC}/link_support.c
lpr: $(DEPlpr)
X	${CC}  ${CFLAGS}  -o lpr $(DEPlpr)
DEPlpq =  \
X	lpq.o getprinter.o global.o displayq.o utils.o setup_test.o \
X	lockfile.o errormsg.o printcap.o remote_ops.o link_support.o \
X	termclear.o getopt.o
SRClpq =  \
X	${SRC}/lpq.c ${SRC}/getprinter.c ${SRC}/global.c ${SRC}/displayq.c \
X	${SRC}/utils.c ${SRC}/setup_test.c ${SRC}/lockfile.c ${SRC}/errormsg.c \
X	${SRC}/printcap.c ${SRC}/remote_ops.c ${SRC}/link_support.c \
X	${SRC}/termclear.c ${SRC}/getopt.c 
lpq: $(DEPlpq)
X	${CC}  ${CFLAGS}  -o lpq $(DEPlpq) ${TERMLIB}
DEPlpc =  \
X	checkperm.o control_ops.o errormsg.o getopt.o getprinter.o global.o \
X	lockfile.o lpc.o printcap.o setup_test.o startserver.o utils.o \
X	remote_ops.o link_support.o
SRClpc =  \
X	${SRC}/checkperm.c ${SRC}/control_ops.c ${SRC}/errormsg.c \
X	${SRC}/getopt.c ${SRC}/getprinter.c ${SRC}/global.c \
X	${SRC}/lockfile.c ${SRC}/lpc.c ${SRC}/printcap.c ${SRC}/setup_test.c \
X	${SRC}/startserver.c ${SRC}/utils.c ${SRC}/remote_ops.c \
X	${SRC}/link_support.c
lpc: $(DEPlpc)
X	${CC}  ${CFLAGS}  -o lpc $(DEPlpc)
DEPlprm =  \
X	checkperm.o errormsg.o getopt.o getprinter.o global.o link_support.o \
X	lockfile.o lprm.o printcap.o remote_ops.o rmjob.o setup_test.o \
X	startserver.o utils.o
SRClprm =  \
X	${SRC}/checkperm.c ${SRC}/errormsg.c ${SRC}/getopt.c ${SRC}/getprinter.c \
X	${SRC}/global.c ${SRC}/link_support.c ${SRC}/lockfile.c ${SRC}/lprm.c \
X	${SRC}/printcap.c ${SRC}/remote_ops.c ${SRC}/rmjob.c ${SRC}/setup_test.c \
X	${SRC}/startserver.c ${SRC}/utils.c
lprm: $(DEPlprm)
X	${CC}  ${CFLAGS}  -o lprm $(DEPlprm)
DEPcheckpc= \
X	checkpc.o global.o printcap.o errormsg.o setup_test.o utils.o \
X	lockfile.o getopt.o
SRCcheckpc= \
X	${SRC}/checkpc.c ${SRC}/global.c ${SRC}/printcap.c ${SRC}/errormsg.c \
X	${SRC}/setup_test.c ${SRC}/utils.c ${SRC}/lockfile.c ${SRC}/getopt.c
checkpc: $(DEPcheckpc)
X	${CC}  ${CFLAGS}  -o checkpc $(DEPcheckpc)
DEPpac= \
X	pac.o global.o printcap.o errormsg.o setup_test.o \
X	getopt.o getprinter.o utils.o lockfile.o
SRCpac= \
X	${SRC}/pac.c ${SRC}/global.c ${SRC}/printcap.c ${SRC}/errormsg.c  \
X	${SRC}/setup_test.c ${SRC}/getopt.c ${SRC}/getprinter.c ${SRC}/utils.c \
X	${SRC}/lockfile.c
pac: $(DEPpac)
X	${CC}  ${CFLAGS}  -o pac $(DEPpac)
X#
X# Object - Source  dependencies
X#
banner.o:	$(SRC)/banner.c
X	${COMPILE} ${SRC}/banner.c
checkpc.o:	$(SRC)/checkpc.c
X	${COMPILE} ${SRC}/checkpc.c
checkperm.o:	$(SRC)/checkperm.c
X	${COMPILE} ${SRC}/checkperm.c
control_ops.o:	$(SRC)/control_ops.c
X	${COMPILE} ${SRC}/control_ops.c
displayq.o:	$(SRC)/displayq.c
X	${COMPILE} ${SRC}/displayq.c
errormsg.o:	$(SRC)/errormsg.c
X	${COMPILE} ${SRC}/errormsg.c
find_name.o:	$(SRC)/find_name.c
X	${COMPILE} ${SRC}/find_name.c
getprinter.o:	$(SRC)/getprinter.c
X	${COMPILE} ${SRC}/getprinter.c
getopt.o:	$(SRC)/getopt.c
X	${COMPILE} ${SRC}/getopt.c
global.o:	$(SRC)/global.c
X	${COMPILE} ${SRC}/global.c
link_support.o:	$(SRC)/link_support.c
X	${COMPILE} ${SRC}/link_support.c
localprinter.o:	$(SRC)/localprinter.c
X	${COMPILE} ${SRC}/localprinter.c
lockfile.o:	$(SRC)/lockfile.c
X	${COMPILE} ${SRC}/lockfile.c
lpc.o:	$(SRC)/lpc.c
X	${COMPILE} ${SRC}/lpc.c
lpd.o:	$(SRC)/lpd.c
X	${COMPILE} ${SRC}/lpd.c
lpr.o:	$(SRC)/lpr.c
X	${COMPILE} ${SRC}/lpr.c
lprm.o:	$(SRC)/lprm.c
X	${COMPILE} ${SRC}/lprm.c
lpq.o:	$(SRC)/lpq.c
X	${COMPILE} ${SRC}/lpq.c
lpr_canprint.o:	$(SRC)/lpr_canprint.c
X	${COMPILE} ${SRC}/lpr_canprint.c
lpr_filters.o:	$(SRC)/lpr_filters.c
X	${COMPILE} ${SRC}/lpr_filters.c
lpr_global.o:	$(SRC)/lpr_global.c
X	${COMPILE} ${SRC}/lpr_global.c
lpr_job.o:	$(SRC)/lpr_job.c
X	${COMPILE} ${SRC}/lpr_job.c
lpr_parms.o:	$(SRC)/lpr_parms.c
X	${COMPILE} ${SRC}/lpr_parms.c
lpr_temp.o:	$(SRC)/lpr_temp.c
X	${COMPILE} ${SRC}/lpr_temp.c
mexecv.o:	$(SRC)/mexecv.c
X	${COMPILE} ${SRC}/mexecv.c
pac.o:	$(SRC)/pac.c
X	${COMPILE} ${SRC}/pac.c
print_support.o:	$(SRC)/print_support.c
X	${COMPILE} ${SRC}/print_support.c
printcap.o:	$(SRC)/printcap.c
X	${COMPILE} ${SRC}/printcap.c
recvfiles.o:	$(SRC)/recvfiles.c
X	${COMPILE} ${SRC}/recvfiles.c
remote_ops.o:	$(SRC)/remote_ops.c
X	${COMPILE} ${SRC}/remote_ops.c
remoteprinter.o:	$(SRC)/remoteprinter.c
X	${COMPILE} ${SRC}/remoteprinter.c
rmjob.o:	$(SRC)/rmjob.c
X	${COMPILE} ${SRC}/rmjob.c
sendmail.o:	$(SRC)/sendmail.c
X	${COMPILE} ${SRC}/sendmail.c
servicereq.o:	$(SRC)/servicereq.c
X	${COMPILE} ${SRC}/servicereq.c
setstatus.o:	$(SRC)/setstatus.c
X	${COMPILE} ${SRC}/setstatus.c
setup_filter.o:	$(SRC)/setup_filter.c
X	${COMPILE} ${SRC}/setup_filter.c
setup_test.o:	$(SRC)/setup_test.c
X	${COMPILE} ${SRC}/setup_test.c
startserver.o:	$(SRC)/startserver.c
X	${COMPILE} ${SRC}/startserver.c
startprinter.o:	$(SRC)/startprinter.c
X	${COMPILE} ${SRC}/startprinter.c
termclear.o:	$(SRC)/termclear.c
X	${COMPILE} ${SRC}/termclear.c
utils.o:	$(SRC)/utils.c
X	${COMPILE} ${SRC}/utils.c
X#
X# Installation of commands
X#
install: all
X	install -s -c -o root -m u=sxr,g=xr,o=xr lpd ${LIB}
X	install -s -c -o root -m u=sxr,g=xr,o=xr lpq ${BIN}
X	install -s -c -o root -m u=sxr,g=xr,o=xr lprm ${BIN}
X	install -s -c -o root -m u=sxr,g=xr,o=xr lpc ${MAINTDIR}
X	install -s -c -o root -m u=sxr,g=xr,o=xr lpr ${BIN}
X	install -s -c -o root pac ${MAINTDIR}
X	install -s -c -o root checkpc ${MAINTDIR}
X
remove:
X	rm -f ${LIB}/lpd
X	rm -f ${BIN}/lpq
X	rm -f ${BIN}/lprm
X	rm -f ${MAINTDIR}/lpc
X	rm -f ${BIN}/lpr
X	rm -f ${MAINTDIR}/pac
X	rm -f ${MAINTDIR}/checkpc
X#
X# Lint dependencies
X#
X
lint:	$(LNT)/lpd $(LNT)/lpr $(LNT)/lpq $(LNT)/lprm \
X		$(LNT)/lpc $(LNT)/checkpc $(LNT)/pac
X
X$(LNT)/lpd: $(SRClpd)
X	lint  ${LINTFLAGS} $(SRClpd)  ${LINTFILTER} > $(LNT)/lpd
X
X$(LNT)/lpr: $(SRClpr)
X	lint  ${LINTFLAGS} $(SRClpr)  ${LINTFILTER} > $(LNT)/lpr
X
X$(LNT)/lpq: $(SRClpq)
X	lint  ${LINTFLAGS} $(SRClpq)  ${LINTFILTER} > $(LNT)/lpq
X
X$(LNT)/lprm: $(SRClprm)
X	lint  ${LINTFLAGS} $(SRClprm)  ${LINTFILTER} > $(LNT)/lprm
X
X$(LNT)/lpc: $(SRClpc)
X	lint  ${LINTFLAGS} $(SRClpc)  ${LINTFILTER} > $(LNT)/lpc
X
X$(LNT)/checkpc: $(SRCcheckpc)
X	lint  ${LINTFLAGS} $(SRCcheckpc)  ${LINTFILTER} > $(LNT)/checkpc
X
X$(LNT)/pac: $(SRCpac)
X	lint  ${LINTFLAGS} $(SRCpac)  ${LINTFILTER} > $(LNT)/pac
X
X#
X# Miscellaneous
X#
clean:
X	-rm -f ${COMMANDS} *.o core ?
X
print:
X	@${PRINT} Makefile *.h ${SRCS} | lpr -J lpd
X
xref:
X	@${CXREF} *.c | pr -h XREF
X
Tags:
X	ctags -t *.c *.h >.ctags_warnings 2>&1
perms:
X	chown root lp? lp??
X	chmod  u=sxr,g=xr,o=xr lp? lp??
unperms:
X	for i in ${COMMANDS} ; \
X	do \
X	case $$i in \
X		lp? | lp??)	\
X			echo $$i ;	\
X			cat $$i >x; rm $$i ; mv x $$i; \
X			chmod a+x $$i	;	\
X			;;	\
X	esac				\
X	done
test:
X	-rm checkpc.o lpc.o lpd.o lpq.o lpr.o lprm.o pac.o
X	make  XPERIMENT=-DXPERIMENT=1 all
END_OF_FILE
if test 12955 -ne `wc -c <'src/Makefile'`; then
    echo shar: \"'src/Makefile'\" unpacked with wrong size!
fi
# end of 'src/Makefile'
fi
if test -f 'src/global.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/global.c'\"
else
echo shar: Extracting \"'src/global.c'\" \(14489 characters\)
sed "s/^X//" >'src/global.c' <<'END_OF_FILE'
X/***************************************************************************
X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
X ***************************************************************************
X * MODULE: globals.c
X * Definitions of global variables.
X * NOTE: system dependent,  default values defined in lp.h
X ***************************************************************************
X * Revision History: Created Sun Jan  3 08:25:42 CST 1988
X * $Log:	global.c,v $
X * Revision 3.1  88/06/18  09:34:18  papowell
X * Version 3.0- Distributed Sat Jun 18 1988
X * 
X * Revision 2.3  88/05/21  10:27:41  papowell
X * Minor editing
X * 
X * Revision 2.2  88/05/14  10:18:12  papowell
X * Use long format for job file names;
X * Added 'fd', no forward flag;
X * Control file has to have hostname and origination agree.
X * 
X * Revision 2.1  88/05/09  10:08:15  papowell
X * PLP: Released Version
X * 
X * Revision 1.7  88/05/09  10:03:32  papowell
X * Revised effects of -h option
X * 
X * Revision 1.6  88/04/27  20:25:40  papowell
X * Modified to remove unused variables
X * 
X * Revision 1.5  88/04/07  12:31:25  papowell
X * 
X * Revision 1.4  88/03/25  14:59:34  papowell
X * Debugged Version:
X * 1. Added the PLP control file first transfer
X * 2. Checks for MX during file transfers
X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
X * 	apparently they open files and then assume that they will stay
X * 	open.
X * 4. Made sure that stdin, stdout, stderr was available at all times.
X * 
X * Revision 1.3  88/03/11  19:29:31  papowell
X * Minor Changes, Updates
X * 
X * Revision 1.2  88/03/05  15:02:05  papowell
X * Minor Corrections,  Lint Problems
X * 
X * Revision 1.1  88/03/01  11:08:27  papowell
X * Initial revision
X * 
X ***************************************************************************/
X#ifndef lint
static char id_str1[] =
X	"$Header: global.c,v 3.1 88/06/18 09:34:18 papowell Exp $ PLP Copyright 1988 Patrick Powell";
X#endif lint
X
X#include "lp.h"
X
X/*************************************************************************
X * global variables
X *************************************************************************/
X
char  *Name;					/* program Name (argv[0]) */
char  *Printer;					/* Printer Name, set for a queue handler */
char   Host[64];				/* Host machine name */
char  *From;					/* client's machine Name */
char  *Person;					/* Name of Person making request */
XFILE  *Lfd;						/* lock file file descriptor */
char  *First_name;				/* first name in printcap entry */
int    Debug;					/* Debugging level */
int    Echo_on_stdout;			/* error messages on stdout and stderr */
int    Errorcode = 2;			/* exit() value for fatal termination */
struct parm Parms[MAXPARMS];    /* character parameters */
int    Parmcount;				/* number of requests */
char   Last_errormsg[BUFSIZ];	/* last errormessage */
struct queue *Jobentry;			/* current job entry in queue */
int    Request;					/* current lpd request code */
int    Print_fd;				/* output printer file descriptor */
char   CFparm[26][MAXPARMLEN+1];	/* parameters read from control file */
struct queue *Queue;			/* Getq generates a vector of jobs */
int    Jobcount;				/* and returns the number of jobs  */
int    Short_format;			/* short status format */
int    Rec_cnt;					/* number of files in a job */
int    Is_root;                 /* is this the root user? */
int    Is_local;				/* doing this locally or remotely? */
struct stat LO_statb;			/* used to stat lockfile */
int    Daemon_uid;				/* daemon UID */
int    Daemon_gid;				/* daemon GID */
X
X/******************************************************************
X * Definitions for the printcap variables.
X ******************************************************************/
X
int    AB;		/* Always have a banner flag, ignore lpr -h option */
char  *AF;		/* accounting file */
int    BK;		/* Berkeley compatible remote and local */
char  *BP;		/* banner printer filter */
int    BR;		/* baud rate if lp is a tty */
int    CO;		/* cost of printing in dollars per thousand pages */
char  *EP;		/* end printer filter */
int    FC;		/* flags to clear if lp is a tty */
int    FD;		/* No forwarding, accept only from original site */
char  *FF;		/* form feed string */
int    FJ;		/* send control file  first to remote site */
int    FO;		/* print a form feed when device is opened */
int    FQ;		/* form feed on quitting */
int    FS;		/* flags to set if lp is a tty */
char  *FX;		/* allowable formats */
char  *LD;		/* leader string on opening */
char  *LF;		/* log file for error messages */
int    LH;		/* use long host name */
char  *LN;		/* group allowed to use links */
char  *LO;		/* lock file Name */
char  *LP;		/* line Printer device Name */
int    MC;		/* maximum number of copies allowed */
int    MX;		/* maximum number of blocks to copy */
int    NW;		/* Networked file system, do not make copies */
int    PL;		/* page length */
char  *PR;		/* pr program Name Name */
char  *PS;		/* Printer status file Name */
int    PW;		/* page width */
int    PX;		/* page width in pixels */
int    PY;		/* page length in pixels */
char  *QH;		/* queue handler */
char  *RG;		/* restrict use to group */
char  *RM;		/* remote machine Name */
char  *RP;		/* remote Printer Name */
int    RT;		/* max retries */
int    RW;		/* open LP for reading and writing */
int    SB;		/* short banner instead of normal header */
int    SC;		/* suppress multiple copies */
char  *SD;		/* spool directory */
int    SF;		/* suppress FF on each print job */
int    SH;		/* suppress header page */
char  *SS;		/* name of queue that the server serves  */
char  *ST;		/* status file Name */
char  *SV;		/* names of servers */
char  *TR;		/* trailer string to be output when Q empties */
char  *TY;		/* terminal characteristics, stty options */
int    XC;		/* flags to clear for local mode */
int    XS;		/* flags to set for local mode */
char  *XU;		/* restrict use to users with perms in file */
char  *XT;		/* check format in string for printable text only */
X/*
X * filter arguments are indexed by first letter of the filter Name.
X * For example:
X * "if=/usr/lib/iffilter" -> Filter_name['i'-'a']
X */
char *Filter_name[26];
X/*
X * Prefilter arguments are indexed by first letter of the filter Name,
X * as for the filters
X */
char *Prefilter_name[26];
X
X/*************************************************************************
X * Printcap Entries,  Defaults, and Variables
X * The All_pc_vars[] and Status_pc_vars[] arrays contain the Names
X * of the printcap entries, the type of entry,  the default value,
X * and the variable which is set by the entry.
X * The array is sorted by the printcap entry.
X *************************************************************************/
X
PC_ENTRY All_pc_vars[] = {
X{ "ab", PC_FLAG, 0, 0, (char **)&AB },
X{ "ae", PC_STRING, 0, 0, &Prefilter_name['a'-'a'] },
X{ "af", PC_STRING, 0, DEFACCT, &AF },
X{ "be", PC_STRING, 0, 0, &Prefilter_name['b'-'a'] },
X{ "bf", PC_STRING, 0, 0, &Filter_name['b'-'a'] },
X{ "bk", PC_NUM, 0, 0, (char **)&BK },
X{ "bp", PC_STRING, 0, 0, &BP },
X{ "br", PC_NUM, 0, 0, (char **)&BR },
X{ "ce", PC_STRING, 0, 0, &Prefilter_name['c'-'a'] },
X{ "cf", PC_STRING, 0, 0, &Filter_name['c'-'a'] },
X{ "co", PC_NUM, 0, 0, (char **)&CO },
X{ "de", PC_STRING, 0, 0, &Prefilter_name['d'-'a'] },
X{ "df", PC_STRING, 0, 0, &Filter_name['d'-'a'] },
X{ "ee", PC_STRING, 0, 0, &Prefilter_name['e'-'a'] },
X{ "ef", PC_STRING, 0, 0, &Filter_name['e'-'a'] },
X{ "ep", PC_STRING, 0, 0, &EP },
X{ "fc", PC_NUM, 0, 0, (char **)&FC },
X{ "fd", PC_FLAG, 0, 0, (char **)&FD },
X{ "ff", PC_STRING, 0, DEFFF, &FF },
X{ "fj", PC_FLAG, 0, 0, (char **)&FJ },
X{ "fo", PC_FLAG, 0, 0, (char **)&FO },
X{ "fq", PC_FLAG, 0, 0, (char **)&FQ },
X{ "fs", PC_NUM, 0, 0, (char **)&FS },
X{ "fx", PC_STRING, 0, 0, &FX },
X{ "ge", PC_STRING, 0, 0, &Prefilter_name['g'-'a'] },
X{ "gf", PC_STRING, 0, 0, &Filter_name['g'-'a'] },
X{ "he", PC_STRING, 0, 0, &Prefilter_name['h'-'a'] },
X{ "hf", PC_STRING, 0, 0, &Filter_name['h'-'a'] },
X{ "ie", PC_STRING, 0, 0, &Prefilter_name['i'-'a'] },
X{ "if", PC_STRING, 0, 0, &Filter_name['i'-'a'] },
X{ "je", PC_STRING, 0, 0, &Prefilter_name['j'-'a'] },
X{ "jf", PC_STRING, 0, 0, &Filter_name['j'-'a'] },
X{ "ke", PC_STRING, 0, 0, &Prefilter_name['k'-'a'] },
X{ "kf", PC_STRING, 0, 0, &Filter_name['k'-'a'] },
X{ "le", PC_STRING, 0, 0, &Prefilter_name['l'-'a'] },
X{ "lf", PC_STRING, 0, DEFLOGF, &LF },
X{ "lh", PC_NUM, 0, 0, (char **)&LH },
X{ "ln", PC_STRING, 0, 0, &LN },
X{ "lo", PC_STRING, 0, DEFLOCK, &LO },
X{ "lp", PC_STRING, 0, 0, &LP },
X{ "mc", PC_NUM, DEFMAXCOPIES, 0, (char **)&MC },
X{ "me", PC_STRING, 0, 0, &Prefilter_name['m'-'a'] },
X{ "mf", PC_STRING, 0, 0, &Filter_name['m'-'a'] },
X{ "mx", PC_NUM, DEFMX, 0, (char **)&MX },
X{ "ne", PC_STRING, 0, 0, &Prefilter_name['n'-'a'] },
X{ "nf", PC_STRING, 0, 0, &Filter_name['n'-'a'] },
X{ "nw", PC_FLAG, 0, 0, (char **)&NW },
X{ "oe", PC_STRING, 0, 0, &Prefilter_name['o'-'a'] },
X{ "of", PC_STRING, 0, 0, &Filter_name['o'-'a'] },
X{ "pe", PC_STRING, 0, 0, &Prefilter_name['p'-'a'] },
X{ "pf", PC_STRING, 0, 0, &Filter_name['p'-'a'] },
X{ "pl", PC_NUM, DEFLENGTH, 0, (char **)&PL },
X{ "pr", PC_STRING, 0, DEFPR, &PR },
X{ "ps", PC_STRING, 0, 0, &PS },
X{ "pw", PC_NUM, DEFWIDTH, 0, (char **)&PW },
X{ "px", PC_NUM, 0, 0, (char **)&PX },
X{ "py", PC_NUM, 0, 0, (char **)&PY },
X{ "qe", PC_STRING, 0, 0, &Prefilter_name['q'-'a'] },
X{ "qf", PC_STRING, 0, 0, &Filter_name['q'-'a'] },
X{ "qh", PC_STRING, 0, 0, &QH },
X{ "re", PC_STRING, 0, 0, &Prefilter_name['r'-'a'] },
X{ "rf", PC_STRING, 0, 0, &Filter_name['r'-'a'] },
X{ "rg", PC_STRING, 0, 0, &RG },
X{ "rm", PC_STRING, 0, 0, &RM },
X{ "rp", PC_STRING, 0, 0, &RP },
X{ "rt", PC_NUM, DEFRETRY, 0, (char **)&RT },
X{ "rw", PC_FLAG, 0, 0, (char **)&RW },
X{ "sb", PC_FLAG, 0, 0, (char **)&SB },
X{ "sc", PC_FLAG, 0, 0, (char **)&SC },
X{ "sd", PC_STRING, 0, 0, &SD },
X{ "se", PC_STRING, 0, 0, &Prefilter_name['s'-'a'] },
X{ "sf", PC_FLAG, 0, 0, (char **)&SF },
X{ "sh", PC_FLAG, 0, 0, (char **)&SH },
X{ "ss", PC_STRING, 0, 0, &SS },
X{ "st", PC_STRING, 0, DEFSTAT, &ST },
X{ "sv", PC_STRING, 0, 0, &SV },
X{ "te", PC_STRING, 0, 0, &Prefilter_name['t'-'a'] },
X{ "tf", PC_STRING, 0, 0, &Filter_name['t'-'a'] },
X{ "tr", PC_STRING, 0, 0, &TR },
X{ "ty", PC_STRING, 0, 0, &TY },
X{ "ue", PC_STRING, 0, 0, &Prefilter_name['u'-'a'] },
X{ "uf", PC_STRING, 0, 0, &Filter_name['u'-'a'] },
X{ "ve", PC_STRING, 0, 0, &Prefilter_name['v'-'a'] },
X{ "vf", PC_STRING, 0, 0, &Filter_name['v'-'a'] },
X{ "we", PC_STRING, 0, 0, &Prefilter_name['w'-'a'] },
X{ "wf", PC_STRING, 0, 0, &Filter_name['w'-'a'] },
X{ "xc", PC_NUM, 0, 0, (char **)&XC },
X{ "xe", PC_STRING, 0, 0, &Prefilter_name['x'-'a'] },
X{ "xf", PC_STRING, 0, 0, &Filter_name['x'-'a'] },
X{ "xs", PC_NUM, 0, 0, (char **)&XS },
X{ "xt", PC_STRING, 0, 0, &XT },
X{ "xu", PC_STRING, 0, 0, &XU },
X{ "ye", PC_STRING, 0, 0, &Prefilter_name['y'-'a'] },
X{ "yf", PC_STRING, 0, 0, &Filter_name['y'-'a'] },
X{ "ze", PC_STRING, 0, 0, &Prefilter_name['z'-'a'] },
X{ "zf", PC_STRING, 0, 0, &Filter_name['z'-'a'] }
X};
X
int	All_pc_len = sizeof(All_pc_vars)/sizeof(PC_ENTRY);
X
X/**************************************************************************
X * Status_pc_vars[] 
X * status checking uses only a subset of all the printcap entries
X **************************************************************************/
PC_ENTRY Status_pc_vars[] = {
X{ "af", PC_STRING, 0, 0, &AF },
X{ "co", PC_NUM, 0, 0, (char **)&CO },
X{ "fd", PC_FLAG, 0, 0, (char **)&FD },
X{ "lf", PC_STRING, 0, DEFLOGF, &LF },
X{ "lh", PC_NUM, 0, 0, (char **)&LH },
X{ "lo", PC_STRING, 0, DEFLOCK, &LO },
X{ "lp", PC_STRING, 0, 0, &LP },
X{ "mx", PC_NUM, DEFMX, 0, (char **)&MX },
X{ "nw", PC_FLAG, 0, 0, (char **)&NW },
X{ "ps", PC_STRING, 0, 0, &PS },
X{ "rg", PC_STRING, 0, 0, &RG },
X{ "rm", PC_STRING, 0, 0, &RM },
X{ "rp", PC_STRING, 0, 0, &RP },
X{ "sd", PC_STRING, 0, 0, &SD },
X{ "ss", PC_STRING, 0, 0, &SS },
X{ "st", PC_STRING, 0, DEFSTAT, &ST },
X{ "sv", PC_STRING, 0, 0, &SV },
X{ "xu", PC_STRING, 0, 0, &XU }
X};
int	Status_pc_len = sizeof(Status_pc_vars)/sizeof(PC_ENTRY);
X
X/**************************************************************************
X * Server_pc_vars[] 
X * just used to get a select set of server information
X **************************************************************************/
PC_ENTRY Server_pc_vars[] = {
X{ "ps", PC_STRING, 0, 0, &PS },
X{ "ss", PC_STRING, 0, 0, &SS },
X{ "st", PC_STRING, 0, DEFSTAT, &ST },
X{ "sv", PC_STRING, 0, 0, &SV }
X};
X
int	Server_pc_len = sizeof(Server_pc_vars)/sizeof(PC_ENTRY);
X/*
X * Location of LPD and LPR dependent files
X * Note that this will get updated to site dependent versions.
X */
char Lpdlogf[MAXPATHLEN]  = RDEFLPDLOGF;
char Masterlock[MAXPATHLEN]  = RMASTERLOCK;
int	Lpr_port_num;		/* port number to connect to */
int Maxportno = RMAXPORTNO;
int Minportno = RMINPORTNO;
char Permfile[MAXPATHLEN]  = RPERMFILE;
char Printcap[MAXPATHLEN]  = RPRINTCAP;
X
X
X/*
X *  SYSLOG.H -- declarations for system logging program
X *
X *	These are used as the first parameter to logmsg().
X *	Their meanings are approximately as follows:
X *
X *	LOG_ERR -- these represent error conditions, such as soft
X *		disk failures, etc.
X *	LOG_CRIT -- such messages contain critical information,
X *		but which can not be classed as errors, for example,
X *		'su' attempts.
X *	LOG_WARNING -- issued when an abnormal condition has been
X *		detected, but recovery can take place.
X *	LOG_NOTICE -- something that falls in the class of
X *		"important information"; this class is informational
X *		but important enough that you don't want to throw
X *		it away casually.
X *	LOG_INFO -- information level messages.  These messages
X *		could be thrown away without problems, but should
X *		be included if you want to keep a close watch on
X *		your system.
X *	LOG_DEBUG -- it may be useful to log certain Debugging
X *		information.  Normally this will be thrown away.
X */
X
X#ifdef NOSYSLOG
X
X/* defines for priorities */
X#define	LOG_ERR		4	/* synonym of LOG_ERROR */
X#define	LOG_CRIT	5	/* critical information */
X#define	LOG_WARNING	6	/* warning */
X#define	LOG_NOTICE	7	/* important information */
X#define	LOG_INFO	8	/* informational message */
X#define	LOG_DEBUG	9	/* Debug level info */
X
X#else
X#include <syslog.h>
X#endif
X
int XLOG_ERR	= LOG_ERR;			/* synonym of LOG_ERROR */
int XLOG_CRIT	= LOG_CRIT;			/* critical information */
int XLOG_WARNING	= LOG_WARNING;	/* warning */
int XLOG_NOTICE	= LOG_NOTICE;		/* important information */
int XLOG_INFO	= LOG_INFO;			/* informational message */
int XLOG_DEBUG	= LOG_DEBUG;		/* Debug level info */
END_OF_FILE
if test 14489 -ne `wc -c <'src/global.c'`; then
    echo shar: \"'src/global.c'\" unpacked with wrong size!
fi
# end of 'src/global.c'
fi
if test -f 'src/lockfile.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/lockfile.c'\"
else
echo shar: Extracting \"'src/lockfile.c'\" \(12577 characters\)
sed "s/^X//" >'src/lockfile.c' <<'END_OF_FILE'
X/***************************************************************************
X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
X ***************************************************************************
X * MODULE: lockfile.c
X * lock file manipulation procedures.
X ***************************************************************************
X * Revision History: Created Sat Jan  2 06:59:04 CST 1988
X * $Log:	lockfile.c,v $
X * Revision 3.1  88/06/18  09:34:27  papowell
X * Version 3.0- Distributed Sat Jun 18 1988
X * 
X * Revision 2.2  88/05/19  10:34:01  papowell
X * Fixed open() calls to have a 0 parameter, ie: open(f, perms, 0), where needed
X * 
X * Revision 2.1  88/05/09  10:08:33  papowell
X * PLP: Released Version
X * 
X * Revision 1.6  88/05/03  11:45:45  papowell
X * Added LOCKF and FLOCK support
X * 
X * Revision 1.5  88/04/28  10:04:42  papowell
X * minor definitions to keep lint happy
X * 
X * Revision 1.4  88/04/27  20:23:42  papowell
X * Added flock() and lockf() functionality
X * 
X * Revision 1.3  88/04/06  12:13:32  papowell
X * Minor updates, changes in error message formats.
X * Elimination of the AF_UNIX connections, use AF_INET only.
X * Better error messages.
X * 
X * Revision 1.2  88/03/25  14:59:49  papowell
X * Debugged Version:
X * 1. Added the PLP control file first transfer
X * 2. Checks for MX during file transfers
X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
X * 	apparently they open files and then assume that they will stay
X * 	open.
X * 4. Made sure that stdin, stdout, stderr was available at all times.
X * 
X * Revision 1.1  88/03/01  11:08:33  papowell
X * Initial revision
X * 
X ***************************************************************************/
X#ifndef lint
static char id_str1[] =
X	"$Header: lockfile.c,v 3.1 88/06/18 09:34:27 papowell Exp $ PLP Copyright 1988 Patrick Powell";
X#endif lint
X/***************************************************************************
X * File Locking Routines:
X * FILE * Lockcf( char *filename )
X *     locks the indicated file if it exists
X *     Returns: a FILE * for RW if successful, NULL otherwise;
X * FILE * Readlockfile(char *filename,int *pid,char *str,int len,struct stat *s)
X *     reads the information in the lock file.
X * int Checklockfile(char *filename,int *pid,char *str,int len,struct stat *s)
X *     Checks for the presence of a server by using kill(0,pid).
X *     Returns 1 if server present, 0 if not.
X *     Side Effect: if the server is present, returns PID and string from file
X *       in pid and str, stats the file as well
X * FILE * Getlockfile(char *filename,int *pid,char *str,int len,struct stat *s)
X *     locks the indicated file;
X *     Returns a FILE * if successful, NULL otherwise;
X *     Side Effect: if the file is locked, returns PID and string from file
X *       in pid and str, stats the file as well
X * Setlockfile( FILE *fp; int pid; char *str);
X *     write PID and str into the file
X * Closelockfile( FILE *fp );
X *     truncates the lock file and closes it.
X * int Exlockcf( char *filename )
X *    creates and locks the file.
X *    Returns: FILE * for writing, NULL if file exists and is locked
X ***************************************************************************
X * Lock File Manipulation:
X * Each active server has a lock file, which it uses to record its
X * activity.  The lock file is created and then locked;
X * the deamon will place its PID and an activity in the lock file.
X * Programs wanting to know the server status will read the file.
X * Note:  only active server, not status programs, will lock the file.
X * This prevents a status program from locking out a server.
X * Note that the information in the status file may be stale,  as the
X * may update the file without the knowledge of the checker.  This
X * appears to be a small price to pay;  the only place where it may
X * have an effect is when a job is being removed.
X ***************************************************************************/
X#include "lp.h"
extern long lseek();
static int do_lock();
X
XFILE *
Lockcf( filename )
X	char *filename;		/* Name of file */
X{
X	int fd;				/* fd for file descriptor */
X	FILE *fp;			/* fp for FILE * */
X	int lock;			/* lock status */
X
X	/*
X	 * Open the lock file for RW
X	 */
X	fp = NULL;
X	if( (fd = open_daemon(filename, O_RDWR, 0)) < 0 ){
X		logerr(XLOG_DEBUG,"Lockcf: cannot open file %s", filename);
X	} else if( fd < 3 ){
X		fatal( XLOG_CRIT, "Lockcf: open '%s' fd is %d", filename, fd);
X	} else if( (lock = do_lock(fd, filename)) < 0) {
X		logerr_die( XLOG_CRIT, "Lockcf: lock '%s' failed", filename);
X	} else if( lock == 0 ){
X		if(Debug>3)logerr( XLOG_DEBUG, "Lockcf: lock failed '%s' active",
X			filename);
X		(void)close( fd );
X		fd = -1;
X	} else if( (fp = fdopen( fd, "r+")) == NULL ){
X		logerr_die( XLOG_CRIT, "Lockcf: fdopen '%s' failed", filename);
X	}
X	if(Debug>5)log(XLOG_DEBUG,"Lockcf: file '%s', fd %d", filename, fd );
X	return( fp );
X}
X/***************************************************************************
X * File *Readlockfile( .... )
X * Utility function used by Getlockfile and Checklockfile
X * Implements the lock manipulation and reading of the lock file.
X ***************************************************************************/
XFILE *
Readlockfile( filename, pid, str, len, sb )
X	char *filename;		/* Name of file */
X	int *pid;			/* pid */
X	char *str;			/* string */
X	int len;			/* max string length */
X	struct stat *sb;	/* stat buffer */
X{
X	int fd;				/* file descriptor */
X	FILE *fp = NULL;	/* stream */
X	int p;				/* ACME Integer and Buggy Works, Inc. */
X	char buffer[BUFSIZ]; /* holds the pid read from file */
X	char *cp;			/* ACME Pointer, Inc. */
X	struct stat s;		/* try stating first */
X
X	/*
X	 * Open the lock file, creating if necessary
X	 */
X	if(Debug>4)log(XLOG_DEBUG,"Readlockfile: lockfile '%s'", filename );
X	if( (fd = open_daemon(filename, O_RDWR|O_CREAT, 0644) ) < 0 ){
X		logerr_die(XLOG_DEBUG,
X			"Readlockfile: cannot create lock file '%s'", filename);
X	}
X	/*
X	 * check to see that you are not clobbering stdin, stdout, stderr
X	 */
X	if( fd < 3 ){
X		fatal( XLOG_CRIT, "Readlockfile: open '%s' fd is %d", filename, fd);
X	}
X	/*
X	 * need a FILE * for stdio
X	 */
X	if( (fp = fdopen( fd, "r+" )) == NULL ){
X		logerr_die(XLOG_CRIT,"Readlockfile: fdopen '%s' failed",filename);
X	}
X	/*
X	 * stat the file for use by others
X	 */
X	if( fstat( fd, &s ) < 0 ){
X		logerr_die( XLOG_INFO,"Readlockfile: fstat '%s' failed", filename);
X	}
X	if( sb ){
X		*sb = s;
X	}
X	if(Debug>4)log(XLOG_DEBUG,"Readlockfile: %s, perms 0%o",
X		filename,s.st_mode);
X	/* read the process number */
X	if( fseek( fp, 0L, 0 ) < 0 ){
X		logerr_die( XLOG_INFO,"Readlockfile: fseek '%s' failed", filename);
X	}
X	p = 0;
X	if( fgets( buffer, sizeof(buffer), fp ) ){
X		p = atoi( buffer );
X	}
X	if(Debug>2)log(XLOG_DEBUG, "Readlockfile: '%s' pid %d len %d",
X		filename,p, s.st_size);
X	if( fgets( buffer, sizeof(buffer), fp ) ){
X		if( cp = index(buffer, '\n') ){
X			*cp = 0;
X		}
X		if(Debug>2)log(XLOG_DEBUG, "Readlockfile: info '%s'", buffer );
X		if( str ){
X			(void)strncpy(str,buffer,len);
X		}
X	}
X	if( pid ){
X		*pid = p;
X	}
X	if( fseek( fp, 0L, 0 ) < 0 ){
X		logerr_die( XLOG_INFO,"Readlockfile: fseek '%s' failed", filename);
X	}
X	return( fp );
X}
X
X
X/***************************************************************************
X * int Checklockfile( ... )
X * Calls Readlockfile() to read the interesting information, passes
X * things onwards.
X ***************************************************************************/
X
Checklockfile( filename, pid, str, len, sb )
X	char *filename;		/* Name of file */
X	int *pid;			/* pid */
X	char *str;			/* string */
X	int len;			/* max string length */
X	struct stat *sb;	/* stat buffer */
X{
X	FILE *fp;			/* stream */
X	int p;				/* ACME Integer and Buggy Works, Inc. */
X	/*
X	 * Read the information
X	 */
X	fp = Readlockfile( filename, &p, str, len, sb );
X	/* check to see if deamon present by using KILL */
X	if( p != 0 && kill( p, 0 ) < 0 ){
X		if(Debug>4)log(XLOG_DEBUG, "Checklockfile: server %d not present", p );
X		/* sigh... not present */
X		p = 0;
X	}
X	if( pid ){
X		*pid = p;
X	}
X	if( fp ){
X		(void)fclose( fp );
X	}
X	if(Debug>2)log(XLOG_DEBUG, "Checklockfile: %s server %d", filename,p );
X	return( p );
X}
X 
X
X/***************************************************************************
X * FILE * Getlockfile( ... )
X * Calls Readlockfile() to read the interesting information, passes
X * things onwards.  Will try to lock the file; if it fails, assume status
X * correct.  Slight race condition here.
X ***************************************************************************/
X
XFILE *
Getlockfile( filename, pid, str, len, statb )
X	char *filename;		/* Name of file */
X	int *pid;			/* pid */
X	char *str;			/* string */
X	int len;			/* max string length */
X	struct stat *statb;	/* status buffer */
X{
X	FILE *fp;		/* lockfile */
X	int p;
X	int lock;
X
X	fp = Readlockfile( filename, &p, str, len, statb );
X	if( pid ){
X		*pid = p;
X	}
X	if( fp != NULL ){
X		if( (lock = do_lock(fileno(fp), filename) ) < 0) {
X			logerr_die( XLOG_CRIT, "Getlockfile: lock '%s' failed", filename);
X		} else if( lock == 0 ){
X			if(Debug>3)log(XLOG_DEBUG,"Getlockfile: locked by %d",p);
X			(void)fclose( fp );
X			fp = NULL;
X		}
X	}
X	if(Debug>2)log(XLOG_DEBUG,"Getlockfile: %s %s",
X		filename,fp!=NULL?"success":"fail");
X	return( fp );
X}
X
X/***************************************************************************
X * Setlockfile( FILE *lockfile; int pid; char *str )
X * will write things into the lock file
X * This has the format:
X * line 1: pid\n
X * line 2: string\n
X ***************************************************************************/
X
Setlockfile(name, fp, pid, str)
X	char *name;
X	FILE *fp;
X	int pid;
X	char *str;
X{
X	/* clear the lock file */
X	if( fseek(fp, 0L, 0) < 0 ){
X		logerr_die( XLOG_CRIT, "Setlockfile: fseek failed %s",name);
X	}
X	if( ftruncate(fileno(fp), (off_t)0) < 0 ){
X		logerr_die( XLOG_CRIT, "Setlockfile: ftruncate failed %s", name);
X	}
X	if( fprintf( fp, "%d\n%s\n", pid, str?str:"" ) == EOF ){
X		logerr_die( XLOG_CRIT, "Setlockfile: fprintf failed %s", name);
X	}
X	if( fflush( fp ) == EOF ){
X		logerr_die( XLOG_CRIT, "Setlockfile: fflush failed %s", name);
X	}
X	if(Debug>4)log(XLOG_DEBUG,"Setlockfile: %s (%d), %s",name,pid,
X		str?str:"(nil)");
X}
X
X/***************************************************************************
X * Closelockfile( FILE *lockfile)
X * Truncate the file.
X ***************************************************************************/
Closelockfile(name, fp )
X	char *name;
X	FILE *fp;
X{
X	if(Debug>4)log(XLOG_DEBUG,"Closelockfile: closing %s", name );
X	if( fp == NULL ){
X		return;
X	}
X	/* clear the lock file */
X	(void)fflush(fp);
X	if( ftruncate(fileno(fp), (off_t)0) < 0 ){
X		logerr( XLOG_CRIT, "Closelockfile: cannot truncate %s", name);
X		return;
X	}
X	if( fclose( fp ) == EOF ){
X		logerr( XLOG_CRIT, "Closelockfile: fclose failed %s", name);
X		return;
X	}
X}
X
X/***************************************************************************
X * int Exlockcf( char *userfile )
X * Create a user file in the directory and lock it. Prevents things
X * from getting confused.
X ***************************************************************************/
X
XExlockcf( filename )
X	char *filename;		/* Name of file */
X{
X	int fd;				/* fd for file descriptor */
X	int lock;
X
X	/*
X	 * Open the lock file, creating if necessary
X	 */
X	fd = open_daemon(filename, O_RDWR|O_CREAT, FILMOD);
X	if (fd < 0) {
X		logerr_die(XLOG_DEBUG,"EXlockcf: cannot create file %s", filename);
X	}
X	if( (lock = do_lock(fd, filename)) < 0) {
X		logerr_die( XLOG_CRIT, "Exlockcf: lock '%s' failed", filename);
X	} else if( lock == 0 ){
X		if(Debug>4)log( XLOG_DEBUG, "Exlockcf: '%s' locked", filename);
X		(void)close( fd );
X		fd = -1;
X	} else if( ftruncate( fd, (off_t)0) < 0 ){
X		logerr_die( XLOG_CRIT, "Exlockcf: cannot truncate %s", filename);
X	}
X	return( fd );
X}
X
X/***************************************************************************
X * do_lock( fd , char *filename)
X * does a lock on a file;
X * Returns: 1 if successful; 0 if locked; -1 otherwise
X ***************************************************************************/
static int
do_lock( fd, filename )
X	int fd;
X	char *filename;
X{
X	int code;
X
X	code = -1;
X	if(Debug>5)log(XLOG_DEBUG,"do_lock: file %s, fd %d", filename, fd );
X#ifndef NO_LOCKF
X	/*
X	 * want to try F_TLOCK
X	 */
X	if( lockf(fd, F_TLOCK, 0L) < 0) {
X		code = 0;
X	} else {
X		code = 1;
X	}
X#else
X	if( flock(fd, LOCK_EX|LOCK_NB) < 0) {
X		if (errno == EWOULDBLOCK){
X			code = 0;
X		}
X	} else {
X		code = 1;
X	}
X#endif NO_LOCKF
X	if(Debug>5)log(XLOG_DEBUG,"do_lock: status %d", code );
X	return( code );
X}
END_OF_FILE
if test 12577 -ne `wc -c <'src/lockfile.c'`; then
    echo shar: \"'src/lockfile.c'\" unpacked with wrong size!
fi
# end of 'src/lockfile.c'
fi
echo shar: End of archive 9 \(of 16\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0

-- 
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.



More information about the Comp.sources.unix mailing list