diff options
author | gad <gad@FreeBSD.org> | 2002-04-23 00:06:10 +0000 |
---|---|---|
committer | gad <gad@FreeBSD.org> | 2002-04-23 00:06:10 +0000 |
commit | 45f3bdde744be43fd191ee929a8c5a7cec0b0856 (patch) | |
tree | 82ccb92a46cd5cb4524779c4ff8a1c2dd3cfaa9f /usr.sbin/lpr/lpd | |
parent | c141c42f1c29ac0cccbf419c008c2829aaed2bdf (diff) | |
download | FreeBSD-src-45f3bdde744be43fd191ee929a8c5a7cec0b0856.zip FreeBSD-src-45f3bdde744be43fd191ee929a8c5a7cec0b0856.tar.gz |
Implement new printcap option of "rc" aka "remote.resend_copies".
This is a boolean option, and if it is specified in a print queue
for a remote host, it causes lpd to resend the data file for each
copy the user requested on 'lpr -#n'. This is useful for network
printers which accept lpd-style jobs, but which ignore the control
file (and thus they ignore any request for multiple copies).
PR: 25635
Reviewed by: short review on freebsd-audit
MFC after: 6 days
Diffstat (limited to 'usr.sbin/lpr/lpd')
-rw-r--r-- | usr.sbin/lpr/lpd/printjob.c | 59 |
1 files changed, 48 insertions, 11 deletions
diff --git a/usr.sbin/lpr/lpd/printjob.c b/usr.sbin/lpr/lpd/printjob.c index 3ac859e..59ccccb 100644 --- a/usr.sbin/lpr/lpd/printjob.c +++ b/usr.sbin/lpr/lpd/printjob.c @@ -146,7 +146,7 @@ static void scan_out(struct printer *_pp, int _scfd, char *_scsp, int _dlm); static char *scnline(int _key, char *_p, int _c); static int sendfile(struct printer *_pp, int _type, char *_file, - char _format); + char _format, int _copyreq); static int sendit(struct printer *_pp, char *_file); static void sendmail(struct printer *_pp, char *_userid, int _bombed); static void setty(const struct printer *_pp); @@ -868,7 +868,7 @@ start: static int sendit(struct printer *pp, char *file) { - register int i, err = OK; + int dfcopies, err, i; char *cp, last[BUFSIZ]; /* @@ -895,6 +895,7 @@ sendit(struct printer *pp, char *file) /* * pass 1 */ + err = OK; while (getline(cfp)) { again: if (line[0] == 'S') { @@ -925,11 +926,14 @@ sendit(struct printer *pp, char *file) } else if (line[0] == 'I') { strlcpy(indent+2, line + 1, sizeof(indent) - 2); } else if (line[0] >= 'a' && line[0] <= 'z') { + dfcopies = 1; strcpy(last, line); - while ((i = getline(cfp)) != 0) - if (strcmp(last, line)) + while ((i = getline(cfp)) != 0) { + if (strcmp(last, line) != 0) break; - switch (sendfile(pp, '\3', last+1, *last)) { + dfcopies++; + } + switch (sendfile(pp, '\3', last+1, *last, dfcopies)) { case OK: if (i) goto again; @@ -945,7 +949,7 @@ sendit(struct printer *pp, char *file) break; } } - if (err == OK && sendfile(pp, '\2', file, '\0') > 0) { + if (err == OK && sendfile(pp, '\2', file, '\0', 1) > 0) { (void) fclose(cfp); return(REPRINT); } @@ -969,13 +973,13 @@ sendit(struct printer *pp, char *file) * Return positive if we should try resending. */ static int -sendfile(struct printer *pp, int type, char *file, char format) +sendfile(struct printer *pp, int type, char *file, char format, int copyreq) { int i, amt; struct stat stb; char *av[15], *filtcmd; char buf[BUFSIZ], opt_c[4], opt_h[4], opt_n[4]; - int filtstat, narg, resp, sfd, sfres, sizerr, statrc; + int copycnt, filtstat, narg, resp, sfd, sfres, sizerr, statrc; statrc = lstat(file, &stb); if (statrc < 0) { @@ -1102,7 +1106,15 @@ sendfile(struct printer *pp, int type, char *file, char format) lseek(sfd, 0, SEEK_SET); } - (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file); + copycnt = 0; +sendagain: + copycnt++; + + if (copycnt < 2) + (void) sprintf(buf, "%c%qd %s\n", type, stb.st_size, file); + else + (void) sprintf(buf, "%c%qd %s_c%d\n", type, stb.st_size, + file, copycnt); amt = strlen(buf); for (i = 0; ; i++) { if (write(pfd, buf, amt) != amt || @@ -1121,6 +1133,10 @@ sendfile(struct printer *pp, int type, char *file, char format) } if (i) pstatus(pp, "sending to %s", pp->remote_host); + /* + * XXX - we should change trstat_init()/trstat_write() to include + * the copycnt in the statistics record it may write. + */ if (type == '\3') trstat_init(pp, file, job_dfcnt); for (i = 0; i < stb.st_size; i += BUFSIZ) { @@ -1146,9 +1162,30 @@ sendfile(struct printer *pp, int type, char *file, char format) sfres = REPRINT; goto return_sfres; } - if (type == '\3') + if (type == '\3') { trstat_write(pp, TR_SENDING, stb.st_size, logname, - pp->remote_host, origin_host); + pp->remote_host, origin_host); + /* + * Usually we only need to send one copy of a datafile, + * because the control-file will simply print the same + * file multiple times. However, some printers ignore + * the control file, and simply print each data file as + * it arrives. For such "remote hosts", we need to + * transfer the same data file multiple times. Such a + * a host is indicated by adding 'rc' to the printcap + * entry. + * XXX - Right now this ONLY works for remote hosts which + * do ignore the name of the data file, because + * this sends the file multiple times with slight + * changes to the filename. To do this right would + * require that we also rewrite the control file + * to match those filenames. + */ + if (pp->resend_copies && (copycnt < copyreq)) { + lseek(sfd, 0, SEEK_SET); + goto sendagain; + } + } sfres = OK; return_sfres: |