📄 lpr.c
字号:
fonts[opt - '1'] = optarg; break; case 'q': /* just q job */ qflag++; break; case '#': /* multiple copies */ if ((num = atoi(optarg)) > 0) ncopies = num; else fatal("invalid argument %s - must be number > 0",optarg); break; case 'D': /* data type */ switch (check_arg(optarg,as_data_types,&data_type)) { case 0: /* match with predefined data_type */ break; case -1: /* ambiguous data type */ invalid_arg("D",as_data_types); case -2: /* no match so assume user data_type */ data_type = optarg; break; } break; case 'I': /* input tray */ if (check_arg(optarg,as_input_trays,&input_tray) != 0) invalid_arg("I",as_input_trays); break; case 'o': /* output tray */ if (check_arg(optarg,as_output_trays,&output_tray) != 0) invalid_arg("o",as_output_trays); break; case 'O': /* orientation */ if (check_arg(optarg,as_orientations,&orientation) != 0) invalid_arg("O",as_orientations); break; case 'F': /*page size */ if (check_arg(optarg, as_page_sizes, &page_size) != 0) invalid_arg("F", as_page_sizes); break; case 'Z': /* page limit */ if ((num = valid_range(optarg, &lower,&upper)) != 0) { if (num == 2) /* second param must be wrong */ optarg = upper; fatal("invalid argument %s - must be number in range 1-%d", optarg,MAXARG); } break; case 'X': /* sheet count */ if (valid_num(optarg,0,MAXARG) == 0) nsheets = optarg; else fatal("invalid argument %s - must be number in range 1-%d", optarg,MAXARG); break; case 'S': /* sheet size */ if (check_arg(optarg, as_page_sizes, &sheet_size) != 0) invalid_arg("S", as_page_sizes); break; case 'M': /* message log */ if (check_arg(optarg, as_messages, &message) != 0) invalid_arg("M", as_messages); break; case 'N': /* number up */ if (valid_num(optarg,0,100) == 0) numberup = optarg; else fatal("invalid argument %s - must be number in range 0-100", optarg); break; case 'L': /* layup defn file */ layup = optarg; break; case 'K': /* sides */ if (check_arg(optarg, as_sides, &sides) != 0) invalid_arg("K", as_sides); break; default: /* invalid opt or no arg */ usage(); } } if (printer == NULL){ if ((printer = getenv("PRINTER")) == NULL) printer = DEFLP; chkprinter(printer); } if (SC && ncopies > 1) fatal("multiple copies are not allowed"); if (MC > 0 && ncopies > MC) fatal("only %d copies are allowed", MC); /* * Get the identity of the person doing the lpr using the same * algorithm as lprm. */ userid = getuid(); if ((pw = getpwuid(userid)) == NULL) fatal("Who are you?"); person = pw->pw_name; /* * Check to make sure queuing is enabled if userid is not root. */ (void) sprintf(buf, "%s/%s", SD, LO); if (userid && stat(buf, &stb) == 0 && (stb.st_mode & 010)) fatal("Printer queue is disabled"); /* * Initialize the control file. */ mktemps(); tfd = nfile(tfname); (void) fchown(tfd, DU, -1); /* owned by daemon for protection */ card('H', host); card('P', person); if (hdr) { if (jobname == NULL) { if (optind == argc) jobname = "stdin"; else /* extract filename in path */ jobname = (arg = rindex(argv[optind], '/')) ? arg+1 : argv[optind]; } card('J', jobname); card('C', class); card('L', person); } if (indent) card('I', indent); if (mailflg) card('M', person); if (format == 't' || format == 'n' || format == 'd') for (i = 0; i < 4; i++) if (fonts[i] != NULL) card('1'+i, fonts[i]); if (width) card('W', width); if (length) card('Z', length); if (data_type) card('D', data_type); if (input_tray) card('<', input_tray); if (output_tray) card('>', output_tray); if (orientation) card('O', orientation); if (page_size) card('F', page_size); if (sheet_size) card('S', sheet_size); if (message) card('E', message); if (nsheets) card('X', nsheets); if (lower) card('A', lower); if (upper) card('B', upper); if (numberup) card('G', numberup); if (sides) card('K', sides); /* * Spool layup file if specified */ if (layup) { char *tmpstr = (char *)malloc(strlen(layup) + strlen(LUPDIR) + 1); strcpy(tmpstr,layup); if ((i = open(layup, O_RDONLY)) < 0 ) /* check if file exists as given */ if (layup[0] == '/') fatal("cannot access file %s", layup); else { /* rel pathname so check LUPDIR */ strcpy(tmpstr,LUPDIR); if ((i = open(strcat(tmpstr,layup), O_RDONLY)) < 0 ) fatal("cannot access file %s", layup); } copy(i, tmpstr, 'z'); /* copy found layup file to spooldir */ (void) close(i); free(tmpstr); } /* * Read the files and spool them. */ if (optind == argc) { /* if no files, use stdin */ if (format == 'p') card('T', title ? title : " "); copy(0, " ", format); } else for (; optind < argc; optind++) { /* loop through files */ if (test(arg = argv[optind]) < 0) /* file unprintable */ continue; /* try next file */ /* * check if file can be removed */ if (rflag) { remove = 1; if (access(arg, W_OK) < 0) { /* no write access to file */ remove = 0; } else { if ((cp = rindex(arg, '/')) == NULL) { /* file is in current dir */ if (access(".", W_OK) < 0) { /* check access to current dir */ remove = 0; } } else { *cp = '\0'; /* extract dir and check access */ i = access(arg, W_OK); *cp = '/'; if (i < 0) { remove = 0; } } } if (!remove) warn("%s is read only - not removed", arg); } if (format == 'p') { /* use title if given, otherwise use filename */ card('T', title ? title : arg); } /* * deal with symbolic link */ if (sflag) { if ((cp = linked(arg)) != NULL) { for (i = 0; i < ncopies; i++) card(format, &dfname[inchar-2]); card('N', arg); card('U', &dfname[inchar-2]); if (remove) card('U', cp); /* Symbolic links pointing out of the spool * directory are a security risk. * Who knows what they are pointing at? * Record details of the real file in the * spool area to be checked later by lpd. * To keep the control file compatible with * other ULTRIX versions this information goes * into a separate control file. The name of * this file is the name of the data file * with the first character in upper case. * See nextname() to see why that works. * (Bsd uses an 'S' line in the control * file but we already use that.) */ dfname[inchar-2] = _toupper(dfname[inchar-2]); i = umask(0); if ((lifd = open(dfname, O_WRONLY|O_EXCL|O_CREAT, FILMOD)) < 0) fatal("cannot create %s\n", dfname); (void) umask(i); fchown(lifd, DU, -1); /* Data left in statb by test() */ sprintf(buf, "I%d\nD%d\n", statb.st_ino, statb.st_dev); i = strlen(buf); if (write(lifd, buf, i) != i) fatal("cannot write %s\n", dfname); close(lifd); card('U', &dfname[inchar-2]); dfname[inchar-2] = _tolower(dfname[inchar-2]); nextname(dfname); nact++; continue; } else warn("%s not linked, copying instead", arg); } if ((i = open(arg, O_RDONLY)) < 0) { warn("cannot open %s", arg); continue; } copy(i, arg, format); (void) close(i); if (remove && unlink(arg) < 0) warn("%s not removed", arg); } if (nact) { /* num files to act on > 0 */ (void) close(tfd); tfname[inchar]--; /* * Touch the control file to fix position in the queue. */ if ((tfd = open(tfname, O_RDWR)) >= 0) { char c; if ((read(tfd, &c, 1) == 1) && (lseek(tfd, 0L, 0) == 0) && (write(tfd, &c, 1) != 1)) { tfname[inchar]++; fatal("cannot touch file %s", tfname); } (void) close(tfd); } if (link(tfname, cfname) < 0) { tfname[inchar]++; fatal("cannot rename file %s", cfname); } (void) unlink(tfname); if (!qflag) /* exec daemon */ if (!startdaemon(printer)) warn("jobs queued, but cannot start daemon"); exit(0); /* SUCCESSFUL COMPLETION */ } cleanup(); /* NOTREACHED */} /* end of main *//*******************************************************************//* validate numerical argument and check range *//* assumes 0<= r1 <= r2 otherwise range not checked *//* return 0 if ok or 1 otherwise *//*******************************************************************/static int valid_num(str,r1,r2)char *str;int r1,r2;{ int num; if ((((num = atoi(str)) > 0) || ((num = strcmp(str,"0")) == 0)) && (strlen(str) == strlen(itoa(num))) && (r1 < 0 || num >= r1) && (r2 < 0 || num <= r2)) { return(0); } else { return(1); }}/*******************************************************************//* parse and validate range argument [n][,[m]] *//* must do two things: find the two args if they exist then check *//* are valid numbers. *//* pointers to lower and upper limits are returned in arg_1 and *//* arg_2 resp. *//* returns 0 - if one or more args exist and is/are valid *//* 1 - if lower is invalid *//* 2 - if upper is invalid *//*******************************************************************/static int valid_range(arg_str, arg_1, arg_2)char *arg_str, **arg_1, **arg_2;{ char *ptr; /* find args in string */ *arg_1 = *arg_2 = NULL; if ((ptr = index(arg_str, ',')) == NULL) /* no comma found */ *arg_1 = arg_str; else { if (ptr != arg_str) /* first arg exits */ *arg_1 = arg_str; *ptr = NULL; /* split string */ if (*(++ptr)) /* second arg exits */ *arg_2 = ptr; } /* check if valid nums */ if (*arg_1 == NULL && *arg_2 == NULL) /* neither arg exists */ return(1); if (*arg_1 && valid_num(*arg_1,1,MAXARG) != 0) /* arg_1 exists and is invalid */ return(1); if (*arg_2 && valid_num(*arg_2,1,MAXARG) != 0) /* arg_2 exists and is invalid */ return(2); return(0);}/*****************************************************************//* Copy letter and argument into the control file
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -