Deleted Added
full compact
lpr.c (68275) lpr.c (78146)
1/*
2 * Copyright (c) 1983, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 34 unchanged lines hidden (view full) ---

43 The Regents of the University of California. All rights reserved.\n";
44#endif /* not lint */
45
46#ifndef lint
47#if 0
48static char sccsid[] = "@(#)from: lpr.c 8.4 (Berkeley) 4/28/95";
49#endif
50static const char rcsid[] =
1/*
2 * Copyright (c) 1983, 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 * (c) UNIX System Laboratories, Inc.
5 * All or some portions of this file are derived from material licensed
6 * to the University of California by American Telephone and Telegraph
7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
8 * the permission of UNIX System Laboratories, Inc.

--- 34 unchanged lines hidden (view full) ---

43 The Regents of the University of California. All rights reserved.\n";
44#endif /* not lint */
45
46#ifndef lint
47#if 0
48static char sccsid[] = "@(#)from: lpr.c 8.4 (Berkeley) 4/28/95";
49#endif
50static const char rcsid[] =
51 "$FreeBSD: head/usr.sbin/lpr/lpr/lpr.c 68275 2000-11-03 03:29:01Z gad $";
51 "$FreeBSD: head/usr.sbin/lpr/lpr/lpr.c 78146 2001-06-12 16:38:20Z gad $";
52#endif /* not lint */
53
54/*
55 * lpr -- off line print
56 *
57 * Allows multiple printers and printers on remote machines by
58 * using information from a printer data base.
59 */

--- 23 unchanged lines hidden (view full) ---

83static char *class = host; /* class title on header page */
84static char *dfname; /* data files */
85static char *fonts[4]; /* troff font names */
86static char format = 'f'; /* format char for printing files */
87static int hdr = 1; /* print header or not (default is yes) */
88static int iflag; /* indentation wanted */
89static int inchar; /* location to increment char in file names */
90static int indent; /* amount to indent */
52#endif /* not lint */
53
54/*
55 * lpr -- off line print
56 *
57 * Allows multiple printers and printers on remote machines by
58 * using information from a printer data base.
59 */

--- 23 unchanged lines hidden (view full) ---

83static char *class = host; /* class title on header page */
84static char *dfname; /* data files */
85static char *fonts[4]; /* troff font names */
86static char format = 'f'; /* format char for printing files */
87static int hdr = 1; /* print header or not (default is yes) */
88static int iflag; /* indentation wanted */
89static int inchar; /* location to increment char in file names */
90static int indent; /* amount to indent */
91static char *jobname; /* job name on header page */
91static const char *jobname; /* job name on header page */
92static int mailflg; /* send mail */
93static int nact; /* number of jobs to act on */
94static int ncopies = 1; /* # of copies to make */
95static char *person; /* user name */
96static int qflag; /* q job, but don't exec daemon */
97static int rflag; /* remove files upon completion */
98static int sflag; /* symbolic link flag */
99static int tfd; /* control file descriptor */
100static char *tfname; /* tmp copy of cf before linking */
101static char *title; /* pr'ing title */
102static char *locale; /* pr'ing locale */
103static int userid; /* user id */
104static char *Uflag; /* user name specified with -U flag */
105static char *width; /* width for versatec printing */
106static char *Zflag; /* extra filter options for LPRng servers */
107
108static struct stat statb;
109
92static int mailflg; /* send mail */
93static int nact; /* number of jobs to act on */
94static int ncopies = 1; /* # of copies to make */
95static char *person; /* user name */
96static int qflag; /* q job, but don't exec daemon */
97static int rflag; /* remove files upon completion */
98static int sflag; /* symbolic link flag */
99static int tfd; /* control file descriptor */
100static char *tfname; /* tmp copy of cf before linking */
101static char *title; /* pr'ing title */
102static char *locale; /* pr'ing locale */
103static int userid; /* user id */
104static char *Uflag; /* user name specified with -U flag */
105static char *width; /* width for versatec printing */
106static char *Zflag; /* extra filter options for LPRng servers */
107
108static struct stat statb;
109
110static void card __P((int, char *));
111static int checkwriteperm __P((char*, char *));
112static void chkprinter __P((char *printer, struct printer *pp));
113static void cleanup __P((int));
114static void copy __P((const struct printer *, int, char []));
115static char *itoa __P((int));
116static char *linked __P((char *));
117int main __P((int, char **));
118static char *lmktemp __P((const struct printer *pp, char *, int, int));
119static void mktemps __P((const struct printer *pp));
120static int nfile __P((char *));
121static int test __P((char *));
122static void usage __P((void));
110static void card(int _c, const char *_p2);
111static int checkwriteperm(const char *_file, const char *_directory);
112static void chkprinter(const char *_ptrname, struct printer *_pp);
113static void cleanup(int _signo);
114static void copy(const struct printer *_pp, int _f, const char _n[]);
115static char *itoa(int _i);
116static const char *linked(const char *_file);
117int main(int _argc, char *_argv[]);
118static char *lmktemp(const struct printer *_pp, const char *_id,
119 int _num, int len);
120static void mktemps(const struct printer *_pp);
121static int nfile(char *_n);
122static int test(const char *_file);
123static void usage(void);
123
124uid_t uid, euid;
125
126int
124
125uid_t uid, euid;
126
127int
127main(argc, argv)
128 int argc;
129 char *argv[];
128main(int argc, char *argv[])
130{
131 struct passwd *pw;
132 struct group *gptr;
129{
130 struct passwd *pw;
131 struct group *gptr;
133 char *arg, *cp, *printer, *p;
132 const char *arg, *cp, *printer;
133 char *p;
134 char buf[BUFSIZ];
135 int c, i, f, errs;
136 int ret, didlink;
137 struct stat stb;
138 struct stat statb1, statb2;
139 struct printer myprinter, *pp = &myprinter;
140
141 printer = NULL;

--- 381 unchanged lines hidden (view full) ---

523 return (1);
524 /* NOTREACHED */
525}
526
527/*
528 * Create the file n and copy from file descriptor f.
529 */
530static void
134 char buf[BUFSIZ];
135 int c, i, f, errs;
136 int ret, didlink;
137 struct stat stb;
138 struct stat statb1, statb2;
139 struct printer myprinter, *pp = &myprinter;
140
141 printer = NULL;

--- 381 unchanged lines hidden (view full) ---

523 return (1);
524 /* NOTREACHED */
525}
526
527/*
528 * Create the file n and copy from file descriptor f.
529 */
530static void
531copy(pp, f, n)
532 const struct printer *pp;
533 int f;
534 char n[];
531copy(const struct printer *pp, int f, const char n[])
535{
536 register int fd, i, nr, nc;
537 char buf[BUFSIZ];
538
539 if (format == 'p')
540 card('T', title ? title : n);
541 for (i = 0; i < ncopies; i++)
542 card(format, &dfname[inchar-2]);

--- 23 unchanged lines hidden (view full) ---

566 else
567 nact++;
568}
569
570/*
571 * Try and link the file to dfname. Return a pointer to the full
572 * path name if successful.
573 */
532{
533 register int fd, i, nr, nc;
534 char buf[BUFSIZ];
535
536 if (format == 'p')
537 card('T', title ? title : n);
538 for (i = 0; i < ncopies; i++)
539 card(format, &dfname[inchar-2]);

--- 23 unchanged lines hidden (view full) ---

563 else
564 nact++;
565}
566
567/*
568 * Try and link the file to dfname. Return a pointer to the full
569 * path name if successful.
570 */
574static char *
575linked(file)
576 register char *file;
571static const char *
572linked(const char *file)
577{
578 register char *cp;
579 static char buf[MAXPATHLEN];
580 register int ret;
581
582 if (*file != '/') {
583 if (getcwd(buf, sizeof(buf)) == NULL)
584 return(NULL);

--- 21 unchanged lines hidden (view full) ---

606 seteuid(uid);
607 return(ret ? NULL : file);
608}
609
610/*
611 * Put a line into the control file.
612 */
613static void
573{
574 register char *cp;
575 static char buf[MAXPATHLEN];
576 register int ret;
577
578 if (*file != '/') {
579 if (getcwd(buf, sizeof(buf)) == NULL)
580 return(NULL);

--- 21 unchanged lines hidden (view full) ---

602 seteuid(uid);
603 return(ret ? NULL : file);
604}
605
606/*
607 * Put a line into the control file.
608 */
609static void
614card(c, p2)
615 register int c;
616 register char *p2;
610card(int c, const char *p2)
617{
618 char buf[BUFSIZ];
619 register char *p1 = buf;
620 register int len = 2;
621
622 *p1++ = c;
623 while ((c = *p2++) != '\0' && len < sizeof(buf)) {
624 *p1++ = (c == '\n') ? ' ' : c;
625 len++;
626 }
627 *p1++ = '\n';
628 write(tfd, buf, len);
629}
630
631/*
632 * Create a new file in the spool directory.
633 */
634static int
611{
612 char buf[BUFSIZ];
613 register char *p1 = buf;
614 register int len = 2;
615
616 *p1++ = c;
617 while ((c = *p2++) != '\0' && len < sizeof(buf)) {
618 *p1++ = (c == '\n') ? ' ' : c;
619 len++;
620 }
621 *p1++ = '\n';
622 write(tfd, buf, len);
623}
624
625/*
626 * Create a new file in the spool directory.
627 */
628static int
635nfile(n)
636 char *n;
629nfile(char *n)
637{
638 register int f;
639 int oldumask = umask(0); /* should block signals */
640
641 seteuid(euid);
642 f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
643 (void) umask(oldumask);
644 if (f < 0) {

--- 15 unchanged lines hidden (view full) ---

660 n[inchar] = 'a';
661 return(f);
662}
663
664/*
665 * Cleanup after interrupts and errors.
666 */
667static void
630{
631 register int f;
632 int oldumask = umask(0); /* should block signals */
633
634 seteuid(euid);
635 f = open(n, O_WRONLY | O_EXCL | O_CREAT, FILMOD);
636 (void) umask(oldumask);
637 if (f < 0) {

--- 15 unchanged lines hidden (view full) ---

653 n[inchar] = 'a';
654 return(f);
655}
656
657/*
658 * Cleanup after interrupts and errors.
659 */
660static void
668cleanup(signo)
669 int signo;
661cleanup(int signo __unused)
670{
671 register int i;
672
673 signal(SIGHUP, SIG_IGN);
674 signal(SIGINT, SIG_IGN);
675 signal(SIGQUIT, SIG_IGN);
676 signal(SIGTERM, SIG_IGN);
677 i = inchar;

--- 17 unchanged lines hidden (view full) ---

695}
696
697/*
698 * Test to see if this is a printable file.
699 * Return -1 if it is not, 0 if its printable, and 1 if
700 * we should remove it after printing.
701 */
702static int
662{
663 register int i;
664
665 signal(SIGHUP, SIG_IGN);
666 signal(SIGINT, SIG_IGN);
667 signal(SIGQUIT, SIG_IGN);
668 signal(SIGTERM, SIG_IGN);
669 i = inchar;

--- 17 unchanged lines hidden (view full) ---

687}
688
689/*
690 * Test to see if this is a printable file.
691 * Return -1 if it is not, 0 if its printable, and 1 if
692 * we should remove it after printing.
693 */
694static int
703test(file)
704 char *file;
695test(const char *file)
705{
706 struct exec execb;
707 char *path;
708 register int fd;
709 register char *cp;
710
711 if (access(file, 4) < 0) {
712 printf("%s: cannot access %s\n", name, file);

--- 47 unchanged lines hidden (view full) ---

760
761error1:
762 printf(" and is unprintable\n");
763 (void) close(fd);
764 return(-1);
765}
766
767static int
696{
697 struct exec execb;
698 char *path;
699 register int fd;
700 register char *cp;
701
702 if (access(file, 4) < 0) {
703 printf("%s: cannot access %s\n", name, file);

--- 47 unchanged lines hidden (view full) ---

751
752error1:
753 printf(" and is unprintable\n");
754 (void) close(fd);
755 return(-1);
756}
757
758static int
768checkwriteperm(file, directory)
769 char *file, *directory;
759checkwriteperm(const char *file, const char *directory)
770{
771 struct stat stats;
772 if (access(directory, W_OK) == 0) {
773 stat(directory, &stats);
774 if (stats.st_mode & S_ISVTX) {
775 stat(file, &stats);
776 if(stats.st_uid == userid) {
777 return(0);
778 }
779 } else return(0);
780 }
781 return(-1);
782}
783
784/*
785 * itoa - integer to string conversion
786 */
787static char *
760{
761 struct stat stats;
762 if (access(directory, W_OK) == 0) {
763 stat(directory, &stats);
764 if (stats.st_mode & S_ISVTX) {
765 stat(file, &stats);
766 if(stats.st_uid == userid) {
767 return(0);
768 }
769 } else return(0);
770 }
771 return(-1);
772}
773
774/*
775 * itoa - integer to string conversion
776 */
777static char *
788itoa(i)
789 register int i;
778itoa(int i)
790{
791 static char b[10] = "########";
792 register char *p;
793
794 p = &b[8];
795 do
796 *p-- = i%10 + '0';
797 while (i /= 10);
798 return(++p);
799}
800
801/*
802 * Perform lookup for printer name or abbreviation --
803 */
804static void
779{
780 static char b[10] = "########";
781 register char *p;
782
783 p = &b[8];
784 do
785 *p-- = i%10 + '0';
786 while (i /= 10);
787 return(++p);
788}
789
790/*
791 * Perform lookup for printer name or abbreviation --
792 */
793static void
805chkprinter(s, pp)
806 char *s;
807 struct printer *pp;
794chkprinter(const char *ptrname, struct printer *pp)
808{
809 int status;
810
811 init_printer(pp);
795{
796 int status;
797
798 init_printer(pp);
812 status = getprintcap(s, pp);
799 status = getprintcap(ptrname, pp);
813 switch(status) {
814 case PCAPERR_OSERR:
815 case PCAPERR_TCLOOP:
800 switch(status) {
801 case PCAPERR_OSERR:
802 case PCAPERR_TCLOOP:
816 errx(1, "%s: %s", s, pcaperr(status));
803 errx(1, "%s: %s", ptrname, pcaperr(status));
817 case PCAPERR_NOTFOUND:
804 case PCAPERR_NOTFOUND:
818 errx(1, "%s: unknown printer", s);
805 errx(1, "%s: unknown printer", ptrname);
819 case PCAPERR_TCOPEN:
806 case PCAPERR_TCOPEN:
820 warnx("%s: unresolved tc= reference(s)", s);
807 warnx("%s: unresolved tc= reference(s)", ptrname);
821 }
822}
823
824/*
825 * Tell the user what we wanna get.
826 */
827static void
808 }
809}
810
811/*
812 * Tell the user what we wanna get.
813 */
814static void
828usage()
815usage(void)
829{
830 fprintf(stderr, "%s\n",
831"usage: lpr [-Pprinter] [-#num] [-C class] [-J job] [-T title] [-U user]\n"
832 "\t[-Z daemon-options] [-i[numcols]] [-i[numcols]] [-1234 font]\n"
833 "\t[-L locale] [-wnum] [-cdfghlnmprstv] [name ...]");
834 exit(1);
835}
836
837
838/*
839 * Make the temp files.
840 */
841static void
816{
817 fprintf(stderr, "%s\n",
818"usage: lpr [-Pprinter] [-#num] [-C class] [-J job] [-T title] [-U user]\n"
819 "\t[-Z daemon-options] [-i[numcols]] [-i[numcols]] [-1234 font]\n"
820 "\t[-L locale] [-wnum] [-cdfghlnmprstv] [name ...]");
821 exit(1);
822}
823
824
825/*
826 * Make the temp files.
827 */
828static void
842mktemps(pp)
843 const struct printer *pp;
829mktemps(const struct printer *pp)
844{
845 register int len, fd, n;
846 register char *cp;
847 char buf[BUFSIZ];
848
849 (void) snprintf(buf, sizeof(buf), "%s/.seq", pp->spool_dir);
850 seteuid(euid);
851 if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) {

--- 24 unchanged lines hidden (view full) ---

876 (void) write(fd, buf, strlen(buf));
877 (void) close(fd); /* unlocks as well */
878}
879
880/*
881 * Make a temp file name.
882 */
883static char *
830{
831 register int len, fd, n;
832 register char *cp;
833 char buf[BUFSIZ];
834
835 (void) snprintf(buf, sizeof(buf), "%s/.seq", pp->spool_dir);
836 seteuid(euid);
837 if ((fd = open(buf, O_RDWR|O_CREAT, 0661)) < 0) {

--- 24 unchanged lines hidden (view full) ---

862 (void) write(fd, buf, strlen(buf));
863 (void) close(fd); /* unlocks as well */
864}
865
866/*
867 * Make a temp file name.
868 */
869static char *
884lmktemp(pp, id, num, len)
885 const struct printer *pp;
886 char *id;
887 int num, len;
870lmktemp(const struct printer *pp, const char *id, int num, int len)
888{
889 register char *s;
890
891 if ((s = malloc(len)) == NULL)
892 errx(1, "out of memory");
893 (void) snprintf(s, len, "%s/%sA%03d%s", pp->spool_dir, id, num, host);
894 return(s);
895}
871{
872 register char *s;
873
874 if ((s = malloc(len)) == NULL)
875 errx(1, "out of memory");
876 (void) snprintf(s, len, "%s/%sA%03d%s", pp->spool_dir, id, num, host);
877 return(s);
878}