*BSD News Article 85568


Return to BSD News archive

Newsgroups: comp.bugs.2bsd
Path: euryale.cc.adfa.oz.au!newshost.carno.net.au!harbinger.cc.monash.edu.au!munnari.OZ.AU!news.ecn.uoknor.edu!feed1.news.erols.com!news.dra.com!xara.net!emerald.xara.net!news.thenet.net!wlbr!moe.2bsd.com!sms
From: sms@moe.2bsd.com (Steven M. Schultz)
Subject: lpd can't exec, 'ls -f' appends extra colon (#360)
Organization: 2BSD, Simi Valley CA USA
Message-ID: <E2wKMx.HyI@moe.2bsd.com>
Date: Tue, 24 Dec 1996 05:30:33 GMT
Lines: 452
Xref: euryale.cc.adfa.oz.au comp.bugs.2bsd:724

Subject: lpd can't exec, 'ls -f' appends extra colon (#360)
Index:	usr.sbin/lpr/printjob.c,bin/ls/ls.c 2.11BSD

Description:
	lpd logs a "can't exec ..." error and no jobs go to the printer.

	"ls -f *" appends extraneous colon to files which are not directories.

Repeat-By:
	1) Try to print something after 'lpd' was recompile with the font
	   directories in /usr/share/

	2) Note that "ls -f /*" on a 4.4BSD based system looks like this:

/boot           /bsd            /bsd.generic    /bsd.old

/a:
.       ..

	While on a 2.11BSD system it looks like this:


/README:

/VERSION:

/VERSION.old:

/a:
.
..

	Note the ':' appended to things which are not directories.

Fix:
	The first problem, in lpd, was a combination of bad programming (IMHO)
	practice on the part of the author of lpd and "Steve can't count".  
	When the [tn]roff font directories moved from /usr/lib to /usr/share
	the hardcoded string lengths in the 'ifonts' array were not correctly
	updated.

	I consider it "bad form" to do something such as this:

		char ifont[4][18] = { "string1...", "string2...", ...} ;

	and have to make sure that the strings are *exactly* the right size
	(18 characters).  FAR better to let the compiler do the counting
	(correctly) by using:

		char *ifont[4] = { "string1...", "string2...", ...};

	What happened was I miscounted (forgot to include the trailing null)
	the length of the new font directory names and 'lpd' was overwriting 
	his data segment when doing a 'strcpy'.

	The second problem was caused by 'ls' not checking if the file was
	a directory when the '-f' (not sorted) option had been specified.
	Since the 4.4 'ls' command can't be imported (it uses the fts(3)
	package which can at times use more memory than may physically 
	attached to a PDP-11) the next best thing is to simply fix up the
	2.11BSD version of 'ls'.

	To install this update cut where indicated saving to a file (/tmp/360).
	Then:

		patch -p0 < /tmp/360
		cd /usr/src/usr.sbin/lpr
		make lpd
		install -m 6755 -o root -g daemon -s lpd /usr/sbin/lpd
		make clean
		cd /usr/src/bin/ls
		make
		make install
		make clean
		/usr/man/manroff /usr/src/man/man1/ls.1 > /usr/man/cat1/ls.0

	If 'lpd' is currently running you will want to kill and restart it.

	As always this and previous updates to 2.11BSD are available via
	anonymous FTP to either FTP.IIPO.GTEGSC.COM or MOE.2BSD.COM in the
	directory /pub/2.11BSD.

------------------------cut here----------------------
*** /usr/src/usr.sbin/lpr/printjob.c.old	Tue Nov  5 17:41:25 1996
--- /usr/src/usr.sbin/lpr/printjob.c	Mon Dec 23 09:44:03 1996
***************
*** 5,11 ****
   */
  
  #if	!defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)printjob.c	5.2.2 (2.11BSD GTE) 1996/10/24";
  #endif
  
  /*
--- 5,11 ----
   */
  
  #if	!defined(lint) && defined(DOSCCS)
! static char sccsid[] = "@(#)printjob.c	5.2.3 (2.11BSD GTE) 1996/12/23";
  #endif
  
  /*
***************
*** 16,21 ****
--- 16,22 ----
   */
  
  #include "lp.h"
+ #include <sys/time.h>
  
  #define DORETURN	0	/* absorb fork error */
  #define DOABORT		1	/* abort if dofork fails */
***************
*** 45,51 ****
  dev_t	fdev;			/* device of file pointed to by symlink */
  ino_t	fino;			/* inode of file pointed to by symlink */
  
! char	fromhost[32];		/* user's host machine */
  char	logname[32];		/* user's login name */
  char	jobname[100];		/* job or file name */
  char	class[32];		/* classification field */
--- 46,52 ----
  dev_t	fdev;			/* device of file pointed to by symlink */
  ino_t	fino;			/* inode of file pointed to by symlink */
  
! char	fromhost[64];		/* user's host machine */
  char	logname[32];		/* user's login name */
  char	jobname[100];		/* job or file name */
  char	class[32];		/* classification field */
***************
*** 207,213 ****
  
  char	fonts[4][50];	/* fonts for troff */
  
! char ifonts[4][18] = {
  	"/usr/share/vfont/R",
  	"/usr/share/vfont/I",
  	"/usr/share/vfont/B",
--- 208,214 ----
  
  char	fonts[4][50];	/* fonts for troff */
  
! char *ifonts[4] = {
  	"/usr/share/vfont/R",
  	"/usr/share/vfont/I",
  	"/usr/share/vfont/B",
***************
*** 786,792 ****
  	char *name1, *name2;
  {
  	time_t tvec;
- 	extern char *ctime();
  
  	time(&tvec);
  	if (!SF && !tof)
--- 787,792 ----
*** /usr/src/bin/ls/ls.c.old	Tue Dec 20 08:48:11 1994
--- /usr/src/bin/ls/ls.c	Mon Dec 23 11:29:03 1996
***************
*** 9,15 ****
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)ls.c	5.9.1 (2.11BSD GTE) 12/3/94";
  #endif
  
  /*
--- 9,15 ----
  "@(#) Copyright (c) 1980 Regents of the University of California.\n\
   All rights reserved.\n";
  
! static char sccsid[] = "@(#)ls.c	5.9.2 (2.11BSD GTE) 1996/12/23";
  #endif
  
  /*
***************
*** 91,102 ****
  		usetabs = 1;
  	while ((ch = getopt(argc, argv, "1ACLFRacdfgiloqrstu")) != EOF)
  		switch((char)ch) {
  		case '1':
  			Cflg = 0; break;
- 		case 'A':
- 			Aflg++; break;
  		case 'C':
  			Cflg = 1; break;
  		case 'L':
  			Lflg++; break;
  		case 'F':
--- 91,111 ----
  		usetabs = 1;
  	while ((ch = getopt(argc, argv, "1ACLFRacdfgiloqrstu")) != EOF)
  		switch((char)ch) {
+ /*
+  * The -1, -C, and -l options override each other so shell aliasing 
+  * works right.
+ */
  		case '1':
+ 			lflg = 0;
  			Cflg = 0; break;
  		case 'C':
+ 			lflg = 0;
  			Cflg = 1; break;
+ 		case 'l':
+ 			Cflg = 0;
+ 			lflg++; break;
+ 		case 'A':
+ 			Aflg++; break;
  		case 'L':
  			Lflg++; break;
  		case 'F':
***************
*** 106,113 ****
--- 115,124 ----
  		case 'a':
  			aflg++; break;
  		case 'c':
+ 			uflg = 0;	/* -c overrides -u */
  			cflg++; break;
  		case 'd':
+ 			Rflg = 0;	/* -d overrides -R */
  			dflg++; break;
  		case 'f':
  			fflg++; break;
***************
*** 115,122 ****
  			gflg++; break;
  		case 'i':
  			iflg++; break;
- 		case 'l':
- 			lflg++; break;
  		case 'o':
  			oflg++; break;
  		case 'q':
--- 126,131 ----
***************
*** 128,133 ****
--- 137,143 ----
  		case 't':
  			tflg++; break;
  		case 'u':
+ 			cflg = 0;	/* -u overrides -c */
  			uflg++; break;
  		case '?':
  		default:
***************
*** 136,142 ****
  	}
  	if (!lflg)
  		oflg = 0;
! 	if (fflg) { 
  		aflg++; lflg = 0; sflg = 0; tflg = 0;
  	}
  	if (lflg)
--- 146,153 ----
  	}
  	if (!lflg)
  		oflg = 0;
! 	if (fflg) {
! 		Aflg++;
  		aflg++; lflg = 0; sflg = 0; tflg = 0;
  	}
  	if (lflg)
***************
*** 162,172 ****
  		argv++;
  	}
  	fplast = fp;
! 	qsort(fp0, fplast - fp0, sizeof (struct afile), fcmp);
  	if (dflg) {
  		formatf(fp0, fplast);
  		exit(0);
  	}
  	if (fflg)
  		fp = fp0;
  	else {
--- 173,185 ----
  		argv++;
  	}
  	fplast = fp;
! 	if (fflg == 0)
! 		qsort(fp0, fplast - fp0, sizeof (struct afile), fcmp);
  	if (dflg) {
  		formatf(fp0, fplast);
  		exit(0);
  	}
+ 
  	if (fflg)
  		fp = fp0;
  	else {
***************
*** 174,179 ****
--- 187,193 ----
  			continue;
  		formatf(fp0, fp);
  	}
+ 
  	if (fp < fplast) {
  		if (fp > fp0)
  			putchar('\n');
***************
*** 196,217 ****
  	exit(0);
  }
  
! formatd(name, title)
  	char *name;
! 	int title;
  {
  	register struct afile *fp;
  	register struct subdirs *dp;
  	struct afile *dfp0, *dfplast;
  	long nkb, getdir();
  
! 	nkb = getdir(name, &dfp0, &dfplast);
  	if (dfp0 == 0)
  		return;
  	if (fflg == 0)
  		qsort(dfp0, dfplast - dfp0, sizeof (struct afile), fcmp);
! 	if (title)
! 		printf("%s:\n", name);
  	if (lflg || sflg)
  		printf("total %ld\n", nkb);
  	formatf(dfp0, dfplast);
--- 210,232 ----
  	exit(0);
  }
  
! formatd(name, dotitle)
  	char *name;
! 	int dotitle;
  {
  	register struct afile *fp;
  	register struct subdirs *dp;
  	struct afile *dfp0, *dfplast;
+ 	int isadir;
  	long nkb, getdir();
  
! 	nkb = getdir(name, &dfp0, &dfplast, &isadir);
  	if (dfp0 == 0)
  		return;
  	if (fflg == 0)
  		qsort(dfp0, dfplast - dfp0, sizeof (struct afile), fcmp);
! 	if (dotitle)
! 		printf("%s%s\n", name, isadir ? ":" : "");
  	if (lflg || sflg)
  		printf("total %ld\n", nkb);
  	formatf(dfp0, dfplast);
***************
*** 235,247 ****
  }
  
  long
! getdir(dir, pfp0, pfplast)
  	char *dir;
  	struct afile **pfp0, **pfplast;
  {
  	register struct afile *fp;
  	DIR *dirp;
  	register struct direct *dp;
  	long nb;
  	int nent = 20;
  
--- 250,264 ----
  }
  
  long
! getdir(dir, pfp0, pfplast, isadir)
  	char *dir;
  	struct afile **pfp0, **pfplast;
+ 	int *isadir;
  {
  	register struct afile *fp;
  	DIR *dirp;
  	register struct direct *dp;
+ 	struct	stat st;
  	long nb;
  	int nent = 20;
  
***************
*** 251,256 ****
--- 268,278 ----
  		printf("%s unreadable\n", dir);		/* not stderr! */
  		return (0);
  	}
+ 	fstat(dirfd(dirp), &st);
+ 	if (S_ISDIR(st.st_mode))
+ 		*isadir = 1;
+ 	else
+ 		*isadir = 0;
  	fp = *pfp0 = (struct afile *)calloc(nent, sizeof (struct afile));
  	*pfplast = *pfp0 + nent;
  	nb = 0;
*** /usr/src/man/man1/ls.1.old	Tue Dec 20 08:49:26 1994
--- /usr/src/man/man1/ls.1	Mon Dec 23 20:51:48 1996
***************
*** 2,8 ****
  .\" All rights reserved.  The Berkeley software License Agreement
  .\" specifies the terms and conditions for redistribution.
  .\"
! .\"	@(#)ls.1	6.4.1 (2.11BSD GTE) 12/12/94
  .\"
  .TH LS 1 "December 20, 1994"
  .UC
--- 2,8 ----
  .\" All rights reserved.  The Berkeley software License Agreement
  .\" specifies the terms and conditions for redistribution.
  .\"
! .\"	@(#)ls.1	6.4.2 (2.11BSD GTE) 1996/12/23
  .\"
  .TH LS 1 "December 20, 1994"
  .UC
***************
*** 86,102 ****
  For each file, print the i-number in the first column of the report.
  .TP
  .B \-f
! Force each argument to be interpreted as a directory
! and list the name found in each slot.
! This option turns off
! .B "\-l, \-t, \-s,"
! and
! .B \-r,
! and
! turns on
! .B \-a;
! the order is the order in which entries
! appear in the directory.
  .TP
  .B \-F
  cause directories to be marked with a trailing `/',
--- 86,92 ----
  For each file, print the i-number in the first column of the report.
  .TP
  .B \-f
! Output is not sorted.
  .TP
  .B \-F
  cause directories to be marked with a trailing `/',
*** /VERSION.old	Mon Dec 23 15:59:54 1996
--- /VERSION	Mon Dec 23 16:55:33 1996
***************
*** 1,4 ****
! Current Patch Level: 359
  
  2.11 BSD
  ============
--- 1,4 ----
! Current Patch Level: 360
  
  2.11 BSD
  ============