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 #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 ============