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} |