Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 6 Apr 2002 22:57:02 -0800 (PST)
From:      Peter Wemm <peter@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 9267 for review
Message-ID:  <200204070657.g376v2C97116@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://people.freebsd.org/~peter/p4db/chv.cgi?CH=9267

Change 9267 by peter@peter_daintree on 2002/04/06 22:56:17

	IFC @9266

Affected files ...

... //depot/projects/ia64/bin/ps/ps.c#4 integrate
... //depot/projects/ia64/lib/libkvm/kvm_proc.c#5 integrate
... //depot/projects/ia64/lib/libpam/modules/pam_krb5/Makefile#3 integrate
... //depot/projects/ia64/release/scripts/print-cdrom-packages.sh#9 integrate
... //depot/projects/ia64/sbin/fsck_ffs/setup.c#5 integrate
... //depot/projects/ia64/usr.bin/xlint/xlint/xlint.c#6 integrate
... //depot/projects/ia64/usr.sbin/lpr/lpd/printjob.c#3 integrate

Differences ...

==== //depot/projects/ia64/bin/ps/ps.c#4 (text+ko) ====

@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/bin/ps/ps.c,v 1.49 2002/02/21 18:27:16 dillon Exp $");
+__FBSDID("$FreeBSD: src/bin/ps/ps.c,v 1.50 2002/04/07 04:59:13 jedgar Exp $");
 
 #ifndef lint
 static const char copyright[] =
@@ -308,7 +308,7 @@
 	/* XXX - should be cleaner */
 	if (!all && ttydev == NODEV && pid == -1 && !nuids) {
 		if ((uids = malloc(sizeof (*uids))) == NULL)
-			errx(1, "malloc: %s", strerror(errno));
+			err(1, "malloc");
 		nuids = 1;
 		*uids = getuid();
 	}
@@ -421,7 +421,7 @@
 			moreuids = realloc(uids, alloc * sizeof (*uids));
 			if (moreuids == NULL) {
 				free(uids);
-				errx(1, "realloc: %s", strerror(errno));
+				err(1, "realloc");
 			}
 			uids = moreuids;
 		}

==== //depot/projects/ia64/lib/libkvm/kvm_proc.c#5 (text+ko) ====

@@ -34,11 +34,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libkvm/kvm_proc.c,v 1.45 2002/03/21 23:38:09 obrien Exp $
+ * $FreeBSD: src/lib/libkvm/kvm_proc.c,v 1.46 2002/04/07 04:47:58 dd Exp $
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/lib/libkvm/kvm_proc.c,v 1.45 2002/03/21 23:38:09 obrien Exp $");
+__FBSDID("$FreeBSD: src/lib/libkvm/kvm_proc.c,v 1.46 2002/04/07 04:47:58 dd Exp $");
 
 #if defined(LIBC_SCCS) && !defined(lint)
 static char sccsid[] = "@(#)kvm_proc.c	8.3 (Berkeley) 9/23/93";
@@ -409,6 +409,25 @@
 			_kvm_syserr(kd, kd->program, "kvm_getprocs");
 			return (0);
 		}
+		/*
+		 * We can't continue with a size of 0 because we pass
+		 * it to realloc() (via _kvm_realloc()), and passing 0
+		 * to realloc() results in undefined behavior.
+		 */
+		if (size == 0) {
+			/*
+			 * XXX: We should probably return an invalid,
+			 * but non-NULL, pointer here so any client
+			 * program trying to dereference it will
+			 * crash.  However, _kvm_freeprocs() calls
+			 * free() on kd->procbase if it isn't NULL,
+			 * and free()'ing a junk pointer isn't good.
+			 * Then again, _kvm_freeprocs() isn't used
+			 * anywhere . . .
+			 */
+			kd->procbase = _kvm_malloc(kd, 1);
+			goto liveout;
+		}
 		do {
 			size += size / 10;
 			kd->procbase = (struct kinfo_proc *)
@@ -422,6 +441,12 @@
 			_kvm_syserr(kd, kd->program, "kvm_getprocs");
 			return (0);
 		}
+		/*
+		 * We have to check the size again because sysctl()
+		 * may "round up" oldlenp if oldp is NULL; hence it
+		 * might've told us that there was data to get when
+		 * there really isn't any.
+		 */
 		if (size > 0 &&
 		    kd->procbase->ki_structsize != sizeof(struct kinfo_proc)) {
 			_kvm_err(kd, kd->program,
@@ -430,6 +455,7 @@
 			    kd->procbase->ki_structsize);
 			return (0);
 		}
+liveout:
 		nprocs = size == 0 ? 0 : size / kd->procbase->ki_structsize;
 	} else {
 		struct nlist nl[4], *p;

==== //depot/projects/ia64/lib/libpam/modules/pam_krb5/Makefile#3 (text+ko) ====

@@ -22,11 +22,12 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 #
-#	$FreeBSD: src/lib/libpam/modules/pam_krb5/Makefile,v 1.6 2002/03/05 21:56:14 des Exp $
+#	$FreeBSD: src/lib/libpam/modules/pam_krb5/Makefile,v 1.7 2002/04/07 04:44:16 des Exp $
 
 LIB=		pam_krb5
 SHLIB_NAME=	${LIB}.so.${SHLIB_MAJOR}
 SRCS=		pam_krb5.c
+NO_WERROR=	yes
 DPADD=		${LIBKRB5} ${LIBGSSAPI} ${LIBASN1} ${LIBCRYPTO} ${LIBCRYPT} \
 		${LIBCOM_ERR} ${LIBROKEN}
 LDADD=		-lkrb5 -lgssapi -lasn1 -lcrypto -lcrypt -lcom_err \

==== //depot/projects/ia64/release/scripts/print-cdrom-packages.sh#9 (text+ko) ====

@@ -2,7 +2,7 @@
 #
 # Author:	Jordan Hubbard
 # Date:		Mon Jul 10 01:18:20 2000
-# Version:	$FreeBSD: src/release/scripts/print-cdrom-packages.sh,v 1.26 2002/04/06 01:24:58 murray Exp $
+# Version:	$FreeBSD: src/release/scripts/print-cdrom-packages.sh,v 1.27 2002/04/07 06:03:33 murray Exp $
 #
 # MAINTAINER:	jkh
 #
@@ -150,6 +150,8 @@
 
 ## Start of set for CDROM #3
 CDROM_SET_3="${CDROM_SET_3} editors/xemacs21"
+CDROM_SET_3="${CDROM_SET_3} net/cvsup-without-gui"
+CDROM_SET_3="${CDROM_SET_3} print/acroread4"
 CDROM_SET_3="${CDROM_SET_3} print/teTeX"
 CDROM_SET_3="${CDROM_SET_3} textproc/docproj"
 

==== //depot/projects/ia64/sbin/fsck_ffs/setup.c#5 (text+ko) ====

@@ -36,7 +36,7 @@
 static const char sccsid[] = "@(#)setup.c	8.10 (Berkeley) 5/9/95";
 #endif
 static const char rcsid[] =
-  "$FreeBSD: src/sbin/fsck_ffs/setup.c,v 1.29 2002/03/20 22:57:09 imp Exp $";
+  "$FreeBSD: src/sbin/fsck_ffs/setup.c,v 1.30 2002/04/07 05:16:33 mckusick Exp $";
 #endif /* not lint */
 
 #define DKTYPENAMES
@@ -376,9 +376,6 @@
 		{ badsb(listerr, "NCG OUT OF RANGE"); return (0); }
 	if (sblock.fs_cpg < 1)
 		{ badsb(listerr, "CPG OUT OF RANGE"); return (0); }
-	if (sblock.fs_ncg * sblock.fs_cpg < sblock.fs_ncyl ||
-	    (sblock.fs_ncg - 1) * sblock.fs_cpg >= sblock.fs_ncyl)
-		{ badsb(listerr, "NCYL LESS THAN NCG*CPG"); return (0); }
 	if (sblock.fs_sbsize > SBSIZE)
 		{ badsb(listerr, "SIZE PREPOSTEROUSLY LARGE"); return (0); }
 	/*
@@ -394,69 +391,36 @@
 		return (1);
 	}
 	/*
-	 * Set all possible fields that could differ, then do check
-	 * of whole super block against an alternate super block.
+	 * Compare all fields that should not differ in alternate super block.
 	 * When an alternate super-block is specified this check is skipped.
 	 */
 	getblk(&asblk, cgsblock(&sblock, sblock.fs_ncg - 1), sblock.fs_sbsize);
 	if (asblk.b_errs)
 		return (0);
-	altsblock.fs_firstfield = sblock.fs_firstfield;
-	altsblock.fs_unused_1 = sblock.fs_unused_1;
-	altsblock.fs_time = sblock.fs_time;
-	altsblock.fs_cstotal = sblock.fs_cstotal;
-	altsblock.fs_cgrotor = sblock.fs_cgrotor;
-	altsblock.fs_fmod = sblock.fs_fmod;
-	altsblock.fs_clean = sblock.fs_clean;
-	altsblock.fs_ronly = sblock.fs_ronly;
-	altsblock.fs_flags = sblock.fs_flags;
-	altsblock.fs_maxcontig = sblock.fs_maxcontig;
-	altsblock.fs_minfree = sblock.fs_minfree;
-	altsblock.fs_optim = sblock.fs_optim;
-	altsblock.fs_rotdelay = sblock.fs_rotdelay;
-	altsblock.fs_maxbpg = sblock.fs_maxbpg;
-	memmove(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp);
-	altsblock.fs_csp = sblock.fs_csp;
-	altsblock.fs_maxcluster = sblock.fs_maxcluster;
-	altsblock.fs_contigdirs = sblock.fs_contigdirs;
-	altsblock.fs_active = sblock.fs_active;
-	altsblock.fs_avgfilesize = sblock.fs_avgfilesize;
-	altsblock.fs_avgfpdir = sblock.fs_avgfpdir;
-	altsblock.fs_pendingblocks = sblock.fs_pendingblocks;
-	altsblock.fs_pendinginodes = sblock.fs_pendinginodes;
-	memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
-	memmove(altsblock.fs_snapinum, sblock.fs_snapinum,
-		sizeof sblock.fs_snapinum);
-	memmove(altsblock.fs_sparecon,
-		sblock.fs_sparecon, sizeof sblock.fs_sparecon);
-	/*
-	 * The following should not have to be copied.
-	 */
-	altsblock.fs_fsbtodb = sblock.fs_fsbtodb;
-	altsblock.fs_interleave = sblock.fs_interleave;
-	altsblock.fs_npsect = sblock.fs_npsect;
-	altsblock.fs_nrpos = sblock.fs_nrpos;
-	altsblock.fs_state = sblock.fs_state;
-	altsblock.fs_qbmask = sblock.fs_qbmask;
-	altsblock.fs_qfmask = sblock.fs_qfmask;
-	altsblock.fs_state = sblock.fs_state;
-	altsblock.fs_maxfilesize = sblock.fs_maxfilesize;
-	if (memcmp(&sblock, &altsblock, (int)sblock.fs_sbsize)) {
-		if (debug) {
-			long *nlp, *olp, *endlp;
-
-			printf("superblock mismatches\n");
-			nlp = (long *)&altsblock;
-			olp = (long *)&sblock;
-			endlp = olp + (sblock.fs_sbsize / sizeof *olp);
-			for ( ; olp < endlp; olp++, nlp++) {
-				if (*olp == *nlp)
-					continue;
-				printf(
-				    "offset %d, original %ld, alternate %ld\n",
-				    olp - (long *)&sblock, *olp, *nlp);
-			}
-		}
+	if (altsblock.fs_sblkno != sblock.fs_sblkno ||
+	    altsblock.fs_cblkno != sblock.fs_cblkno ||
+	    altsblock.fs_iblkno != sblock.fs_iblkno ||
+	    altsblock.fs_dblkno != sblock.fs_dblkno ||
+	    altsblock.fs_cgoffset != sblock.fs_cgoffset ||
+	    altsblock.fs_cgmask != sblock.fs_cgmask ||
+	    altsblock.fs_ncg != sblock.fs_ncg ||
+	    altsblock.fs_bsize != sblock.fs_bsize ||
+	    altsblock.fs_fsize != sblock.fs_fsize ||
+	    altsblock.fs_frag != sblock.fs_frag ||
+	    altsblock.fs_bmask != sblock.fs_bmask ||
+	    altsblock.fs_fmask != sblock.fs_fmask ||
+	    altsblock.fs_bshift != sblock.fs_bshift ||
+	    altsblock.fs_fshift != sblock.fs_fshift ||
+	    altsblock.fs_fragshift != sblock.fs_fragshift ||
+	    altsblock.fs_fsbtodb != sblock.fs_fsbtodb ||
+	    altsblock.fs_sbsize != sblock.fs_sbsize ||
+	    altsblock.fs_nindir != sblock.fs_nindir ||
+	    altsblock.fs_inopb != sblock.fs_inopb ||
+	    altsblock.fs_cssize != sblock.fs_cssize ||
+	    altsblock.fs_cpg != sblock.fs_cpg ||
+	    altsblock.fs_ipg != sblock.fs_ipg ||
+	    altsblock.fs_fpg != sblock.fs_fpg ||
+	    altsblock.fs_magic != sblock.fs_magic) {
 		badsb(listerr,
 		"VALUES IN SUPER BLOCK DISAGREE WITH THOSE IN FIRST ALTERNATE");
 		return (0);

==== //depot/projects/ia64/usr.bin/xlint/xlint/xlint.c#6 (text+ko) ====

@@ -36,7 +36,7 @@
 #if defined(__RCSID) && !defined(lint)
 __RCSID("$NetBSD: xlint.c,v 1.26 2002/01/22 01:14:03 thorpej Exp $");
 #endif
-__FBSDID("$FreeBSD: src/usr.bin/xlint/xlint/xlint.c,v 1.17 2002/03/11 11:32:55 markm Exp $");
+__FBSDID("$FreeBSD: src/usr.bin/xlint/xlint/xlint.c,v 1.18 2002/04/07 06:28:38 peter Exp $");
 
 #include <sys/param.h>
 #include <sys/wait.h>

==== //depot/projects/ia64/usr.sbin/lpr/lpd/printjob.c#3 (text+ko) ====

@@ -43,7 +43,7 @@
 static char sccsid[] = "@(#)printjob.c	8.7 (Berkeley) 5/10/95";
 */
 static const char rcsid[] =
-  "$FreeBSD: src/usr.sbin/lpr/lpd/printjob.c,v 1.44 2001/11/27 01:32:25 gad Exp $";
+  "$FreeBSD: src/usr.sbin/lpr/lpd/printjob.c,v 1.45 2002/04/07 05:37:27 gad Exp $";
 #endif /* not lint */
 
 
@@ -130,6 +130,8 @@
 static void	 banner(struct printer *_pp, char *_name1, char *_name2);
 static int	 dofork(const struct printer *_pp, int _action);
 static int	 dropit(int _c);
+static int	 execfilter(struct printer *_pp, char *_f_cmd, char **_f_av,
+		    int _infd, int _outfd);
 static void	 init(struct printer *_pp);
 static void	 openpr(const struct printer *_pp);
 static void	 opennet(const struct printer *_pp);
@@ -971,9 +973,9 @@
 {
 	register int f, i, amt;
 	struct stat stb;
-	FILE *fp;
-	char buf[BUFSIZ];
-	int closedpr, resp, sizerr, statrc;
+	char *av[15], *filtcmd;
+	char buf[BUFSIZ], opt_c[4], opt_h[4], opt_n[4];
+	int filtstat, narg, resp, sizerr, statrc;
 
 	statrc = lstat(file, &stb);
 	if (statrc < 0) {
@@ -996,145 +998,103 @@
 	    (stb.st_dev != fdev || stb.st_ino != fino))
 		return(ACCESS);
 
-	job_dfcnt++;		/* increment datafile counter for this job */
-
-	/* everything seems OK, start it up */
+	/* Everything seems OK for reading the file, now to send it */
+	filtcmd = NULL;
 	sizerr = 0;
-	closedpr = 0;
+	tfd = -1;
 	if (type == '\3') {
+		/*
+		 * Type == 3 means this is a datafile, not a control file.
+		 * Increment the counter of data-files in this job, and
+		 * then check for input or output filters (which are only
+		 * applied to datafiles, not control files).
+		 */
+		job_dfcnt++;
+
+		/*
+		 * Note that here we are filtering datafiles, one at a time,
+		 * as they are sent to the remote machine.  Here, the *only*
+		 * difference between an input filter (`if=') and an output
+		 * filter (`of=') is the argument list that the filter is
+		 * started up with.  Here, the output filter is executed
+		 * for each individual file as it is sent.  This is not the
+		 * same as local print queues, where the output filter is
+		 * started up once, and then all jobs are passed thru that
+		 * single invocation of the output filter.
+		 *
+		 * Also note that a queue for a remote-machine can have an
+		 * input filter or an output filter, but not both.
+		 */
 		if (pp->filters[LPF_INPUT]) {
-			/*
-			 * We're sending something with an ifilter.  We have to
-			 * run the ifilter and store the output as a temporary
-			 * spool file (tfile...), because the protocol requires
-			 * us to send the file size before we start sending any
-			 * of the data.
-			 */
-			char *av[15];
-			int n;
-			int ifilter;
-			union wait status; /* XXX */
+			filtcmd = pp->filters[LPF_INPUT];
+			av[0] = filtcmd;
+			narg = 0;
+			strcpy(opt_c, "-c");
+			strcpy(opt_h, "-h");
+			strcpy(opt_n, "-n");
+			if (format == 'l')
+				av[++narg] = opt_c;
+			av[++narg] = width;
+			av[++narg] = length;
+			av[++narg] = indent;
+			av[++narg] = opt_n;
+			av[++narg] = logname;
+			av[++narg] = opt_h;
+			av[++narg] = origin_host;
+			av[++narg] = pp->acct_file;
+			av[++narg] = NULL;
+		} else if (pp->filters[LPF_OUTPUT]) {
+			filtcmd = pp->filters[LPF_OUTPUT];
+			av[0] = filtcmd;
+			narg = 0;
+			av[++narg] = width;
+			av[++narg] = length;
+			av[++narg] = NULL;
+		}
+	}
+	if (filtcmd) {
+		/*
+		 * If there is an input or output filter, we have to run
+		 * the datafile thru that filter and store the result as
+		 * a temporary spool file, because the protocol requires
+		 * that we send the remote host the file-size before we
+		 * start to send any of the data.
+		 */
+		strcpy(tfile, TFILENAME);
+		tfd = mkstemp(tfile);
+		if (tfd == -1) {
+			syslog(LOG_ERR, "%s: mkstemp(%s): %m", pp->printer,
+			    TFILENAME);
+			return (ERROR);
+		}
+		filtstat = execfilter(pp, filtcmd, av, f, tfd);
 
-			strcpy(tfile,TFILENAME);
-			if ((tfd = mkstemp(tfile)) == -1) {
-				syslog(LOG_ERR, "mkstemp: %m");
-				return(ERROR);
-			}
-			if ((av[0] = strrchr(pp->filters[LPF_INPUT], '/')) == NULL)
-				av[0] = pp->filters[LPF_INPUT];
-			else
-				av[0]++;
-			if (format == 'l')
-				av[n=1] = "-c";
-			else
-				n = 0;
-			av[++n] = width;
-			av[++n] = length;
-			av[++n] = indent;
-			av[++n] = "-n";
-			av[++n] = logname;
-			av[++n] = "-h";
-			av[++n] = origin_host;
-			av[++n] = pp->acct_file;
-			av[++n] = 0;
-			if ((ifilter = dofork(pp, DORETURN)) == 0) { /* child */
-				dup2(f, 0);
-				dup2(tfd, 1);
-				/* setup stderr for the filter (child process)
-				 * so it goes to our temporary errors file */
-				n = open(tempstderr, O_WRONLY|O_TRUNC, 0664);
-				if (n >= 0)
-					dup2(n, 2);
-				closelog();
-				closeallfds(3);
-				execv(pp->filters[LPF_INPUT], av);
-				syslog(LOG_ERR, "cannot execv %s", 
-				       pp->filters[LPF_INPUT]);
-				exit(2);
-			}
-			(void) close(f);
-			if (ifilter < 0)
-				status.w_retcode = 100;
-			else {
-				while ((pid = wait((int *)&status)) > 0 &&
-					pid != ifilter)
-					;
-				if (pid < 0) {
-					status.w_retcode = 100;
-					syslog(LOG_WARNING, "%s: after execv(%s), wait() returned: %m",
-					    pp->printer, pp->filters[LPF_INPUT]);
-				}
-			}
-			/* Copy the filter's output to "lf" logfile */
-			if ((fp = fopen(tempstderr, "r"))) {
-				while (fgets(buf, sizeof(buf), fp))
-					fputs(buf, stderr);
-				fclose(fp);
-			}
-			/* process the return-code from the filter */
-			switch (status.w_retcode) {
-			case 0:
-				break;
-			case 1:
-				unlink(tfile);
-				return(REPRINT);
-			case 2:
-				unlink(tfile);
-				return(ERROR);
-			default:
-				syslog(LOG_WARNING, "%s: filter '%c' exited"
-					" (retcode=%d)",
-					pp->printer, format, status.w_retcode);
-				unlink(tfile);
-				return(FILTERERR);
-			}
-			statrc = fstat(tfd, &stb);   /* to find size of tfile */
-			if (statrc < 0)	{
-				syslog(LOG_ERR, "%s: error processing 'if', fstat(%s): %m",
-				    pp->printer, tfile);
-				return(ERROR);
-			}
-			f = tfd;
-			lseek(f,0,SEEK_SET);
-		} else if (ofilter) {
-			/*
-			 * We're sending something with an ofilter, we have to
-			 * store the output as a temporary file (tfile)... the
-			 * protocol requires us to send the file size
-			 */
-			int i;
-			for (i = 0; i < stb.st_size; i += BUFSIZ) {
-				amt = BUFSIZ;
-				if (i + amt > stb.st_size)
-					amt = stb.st_size - i;
-				if (sizerr == 0 && read(f, buf, amt) != amt) {
-					sizerr = 1;
-					break;
-				}
-				if (write(ofd, buf, amt) != amt) {
-					(void) close(f);
-					return(REPRINT);
-				}
-			}
-			close(ofd);
-			close(f);
-			while ((i = wait(NULL)) > 0 && i != ofilter)
-				;
-			if (i < 0)
-				syslog(LOG_WARNING, "%s: after closing 'of', wait() returned: %m",
-				    pp->printer);
-			ofilter = 0;
-			statrc = fstat(tfd, &stb);   /* to find size of tfile */
-			if (statrc < 0)	{
-				syslog(LOG_ERR, "%s: error processing 'of', fstat(%s): %m",
-				    pp->printer, tfile);
-				openpr(pp);
-				return(ERROR);
-			}
-			f = tfd;
-			lseek(f,0,SEEK_SET);
-			closedpr = 1;
+		/* process the return-code from the filter */
+		switch (filtstat) {
+		case 0:
+			break;
+		case 1:
+			unlink(tfile);
+			return (REPRINT);
+		case 2:
+			unlink(tfile);
+			return (ERROR);
+		default:
+			syslog(LOG_WARNING,
+			    "%s: filter '%c' exited (retcode=%d)",
+			    pp->printer, format, filtstat);
+			unlink(tfile);
+			return (FILTERERR);
+		}
+		statrc = fstat(tfd, &stb);   /* to find size of tfile */
+		if (statrc < 0)	{
+			syslog(LOG_ERR,
+			    "%s: error processing 'if', fstat(%s): %m",
+			    pp->printer, tfile);
+			return (ERROR);
 		}
+		f = tfd;
+		lseek(f,0,SEEK_SET);
 	}
 
 	(void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file);
@@ -1146,8 +1106,6 @@
 			if (tfd != -1 && type == '\3') {
 				tfd = -1;
 				unlink(tfile);
-				if (closedpr)
-					openpr(pp);
 			}
 			return(REPRINT);
 		} else if (resp == '\0')
@@ -1175,8 +1133,6 @@
 			if (tfd != -1 && type == '\3') {
 				tfd = -1;
 				unlink(tfile);
-				if (closedpr)
-					openpr(pp);
 			}
 			return(REPRINT);
 		}
@@ -1191,17 +1147,11 @@
 		syslog(LOG_INFO, "%s: %s: changed size", pp->printer, file);
 		/* tell recvjob to ignore this file */
 		(void) write(pfd, "\1", 1);
-		if (closedpr)
-			openpr(pp);
 		return(ERROR);
 	}
 	if (write(pfd, "", 1) != 1 || response(pp)) {
-		if (closedpr)
-			openpr(pp);
 		return(REPRINT);
 	}
-	if (closedpr)
-		openpr(pp);
 	if (type == '\3')
 		trstat_write(pp, TR_SENDING, stb.st_size, logname,
 				 pp->remote_host, origin_host);
@@ -1209,6 +1159,89 @@
 }
 
 /*
+ *  This routine is called to execute one of the filters as was
+ *  specified in a printcap entry.
+ */
+static int
+execfilter(struct printer *pp, char *f_cmd, char *f_av[], int infd, int outfd)
+{
+	int errfd, fpid, wpid;
+	FILE *errfp;
+	union wait status; /* XXX */
+	char buf[BUFSIZ], *slash;
+
+	fpid = dofork(pp, DORETURN);
+	if (fpid != 0) {
+		/*
+		 * This is the parent process, which just waits for the child
+		 * to complete and then returns the result.  Note that it is
+		 * the child process which reads the input stream.
+		 */
+		(void) close(infd);
+		if (fpid < 0)
+			status.w_retcode = 100;
+		else {
+			while ((wpid = wait((int *)&status)) > 0 &&
+			    wpid != fpid)
+				;
+			if (wpid < 0) {
+				status.w_retcode = 100;
+				syslog(LOG_WARNING,
+				    "%s: after execv(%s), wait() returned: %m",
+				    pp->printer, f_cmd);
+			}
+		}
+
+		/*
+		 * Copy everything the filter wrote to stderr from our
+		 * temporary errors file to the "lf=" logfile.
+		 */
+		errfp = fopen(tempstderr, "r");
+		if (errfp) {
+			while (fgets(buf, sizeof(buf), errfp))
+				fputs(buf, stderr);
+			fclose(errfp);
+		}
+
+		return (status.w_retcode);
+	}
+
+	/*
+	 * This is the child process, which is the one that executes the
+	 * given filter.
+	 */
+	/*
+	 * If the first parameter has any slashes in it, then change it
+	 * to point to the first character after the last slash.
+	 */
+	slash = strrchr(f_av[0], '/');
+	if (slash != NULL)
+		f_av[0] = slash + 1;
+	/*
+	 * XXX - in the future, this should setup an explicit list of
+	 *       environment variables and use execve()!
+	 */
+
+	/*
+	 * Setup stdin, stdout, and stderr as we want them when the filter
+	 * is running.  Stderr is setup so it points to a temporary errors
+	 * file, and the parent process will copy that temporary file to
+	 * the real logfile after the filter completes.
+	 */
+	dup2(infd, 0);
+	dup2(outfd, 1);
+	errfd = open(tempstderr, O_WRONLY|O_TRUNC, 0664);
+	if (errfd >= 0)
+		dup2(errfd, 2);
+	closelog();
+	closeallfds(3);
+	execv(f_cmd, f_av);
+	syslog(LOG_ERR, "%s: cannot execv %s", pp->printer, f_cmd);
+	exit(2);
+	/* NOTREACHED */
+}
+
+/*
  * Check to make sure there have been no errors and that both programs
  * are in sync with eachother.
  * Return non-zero if the connection was lost.
@@ -1559,6 +1592,17 @@
 
 	if (pp->remote) {
 		openrem(pp);
+		/*
+		 * Lpd does support the setting of 'of=' filters for
+		 * jobs going to remote machines, but that does not
+		 * have the same meaning as 'of=' does when handling
+		 * local print queues.  For remote machines, all 'of='
+		 * filter processing is handled in sendfile(), and that
+		 * does not use these global "output filter" variables.
+		 */ 
+		ofd = -1;
+		ofilter = 0;
+		return;
 	} else if (*pp->lp) {
 		if ((cp = strchr(pp->lp, '@')) != NULL)
 			opennet(pp);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe p4-projects" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200204070657.g376v2C97116>