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
This commit is contained in:
parent
8a57f7e245
commit
98f6cc5401
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=95293
@ -72,6 +72,7 @@ struct printer {
|
||||
long page_width; /* PW: page width */
|
||||
long page_pwidth; /* PX: page width in pixels */
|
||||
long page_plength; /* PY: page length in pixels */
|
||||
long resend_copies; /* RC: resend copies to remote host */
|
||||
char *restrict_grp; /* RG: restricted group */
|
||||
char *remote_host; /* RM: remote machine name */
|
||||
char *remote_queue; /* RP: remote printer name */
|
||||
|
@ -257,6 +257,7 @@ getprintcap_int(char *bp, struct printer *pp)
|
||||
&pp->status_file));
|
||||
CHK(capdb_getaltstr(bp, "tr", "job.trailer", 0, &pp->trailer));
|
||||
|
||||
pp->resend_copies = capdb_getaltlog(bp, "rc", "remote.resend_copies");
|
||||
pp->restricted = capdb_getaltlog(bp, "rs", "daemon.restricted");
|
||||
pp->short_banner = capdb_getaltlog(bp, "sb", "banner.short");
|
||||
pp->no_copies = capdb_getaltlog(bp, "sc", "job.no_copies");
|
||||
|
@ -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 @@ print(struct printer *pp, int format, char *file)
|
||||
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:
|
||||
|
@ -109,6 +109,7 @@ blocks), zero = unlimited
|
||||
.It "pw num 132 page width (in characters)"
|
||||
.It "px num 0 page width in pixels (horizontal)"
|
||||
.It "py num 0 page length in pixels (vertical)"
|
||||
.It "rc bool false when sending to a remote host, resend copies (see below)"
|
||||
.It "rf str" Ta Dv NULL Ta No "filter for printing"
|
||||
.Tn FORTRAN
|
||||
style text files
|
||||
@ -157,6 +158,7 @@ Each two-letter capability has a human-readable alternate name.
|
||||
.It "pw page.width"
|
||||
.It "px page.pwidth"
|
||||
.It "py page.plength"
|
||||
.It "rc remote.resend_copies"
|
||||
.It "rf filt.fortran"
|
||||
.It "rg daemon.restrictgrp"
|
||||
.It "rm remote.host"
|
||||
@ -325,6 +327,24 @@ will therefore happen before
|
||||
.Xr pr 1
|
||||
is executed rather than afterwards.
|
||||
.Pp
|
||||
There are some models of network printers which accept jobs from
|
||||
.Xr lpd 8 , but they ignore the control file for a job and simply print
|
||||
each data file as it arrives at the printer.
|
||||
One side-effect of this behavior is that the printer will ignore any request
|
||||
for multiple copies as given with the
|
||||
.Fl #
|
||||
flag on the
|
||||
.Xr lpr 1 command.
|
||||
The
|
||||
.Cm rc
|
||||
entry will cause
|
||||
.Xr lpd 8 to resend each data file for each copy that the user
|
||||
originally requested.
|
||||
Note that the
|
||||
.Cm rc
|
||||
entry should only be specified on hosts which send jobs directly to
|
||||
the printer.
|
||||
.Pp
|
||||
If
|
||||
.Cm lp
|
||||
is specified as
|
||||
|
Loading…
Reference in New Issue
Block a user