diff --git a/usr.sbin/lpr/common_source/ctlinfo.c b/usr.sbin/lpr/common_source/ctlinfo.c index 1249a4b9e1e4..322b1c315df2 100644 --- a/usr.sbin/lpr/common_source/ctlinfo.c +++ b/usr.sbin/lpr/common_source/ctlinfo.c @@ -383,12 +383,19 @@ ctl_readcf(const char *ptrname, const char *cfname) /* * This routine renames the temporary control file as received from some - * other (remote) host. That file will always start with 'tfA*', because - * that's the name it is created with in recvjob.c. This will rewrite - * the file to 'tfB*' (correcting any lines which need correcting), rename - * 'tfB*' to 'cfA*', and then remove the original 'tfA*' file. + * other (remote) host. That file will almost always with `tfA*', because + * recvjob.c creates the file by changing `c' to `t' in the original name + * for the control file. Now if you read the RFC, you would think that all + * control filenames start with `cfA*'. However, it seems there are some + * implementations which send control filenames which start with `cf' + * followed by *any* letter, so this routine can not assume what the third + * letter will (or will not) be. Sigh. * - * The purpose of this routine is to be a little paranoid about the contents + * So this will rewrite the temporary file to `rf*' (correcting any lines + * which need correcting), rename that `rf*' file to `cf*', and then remove + * the original `tf*' temporary file. + * + * The *main* purpose of this routine is to be paranoid about the contents * of that control file. It is partially meant to protect against people * TRYING to cause trouble (perhaps after breaking into root of some host * that this host will accept print jobs from). The fact that we're willing @@ -410,7 +417,7 @@ ctl_readcf(const char *ptrname, const char *cfname) char * ctl_renametf(const char *ptrname, const char *tfname) { - int res, newfd, nogood; + int chk3rd, newfd, nogood, res; FILE *newcf; struct cjobinfo *cjinf; char *lbuff, *slash, *cp; @@ -443,7 +450,8 @@ ctl_renametf(const char *ptrname, const char *tfname) newcf = NULL; /* in case of early jump to error_ret */ *errm = '\0'; /* in case of early jump to error_ret */ - if (strncmp(tfname, "tfA", (size_t)3) != 0) { + chk3rd = tfname[2]; + if ((tfname[0] != 't') || (tfname[1] != 'f') || (!isalpha(chk3rd))) { snprintf(errm, sizeof(errm), "ctl_renametf invalid filename: %s", tfname); goto error_ret; @@ -461,7 +469,7 @@ ctl_renametf(const char *ptrname, const char *tfname) * gives us greater control over file-creation issues. */ strlcpy(tfname2, tfname, sizeof(tfname2)); - tfname2[2] = 'B'; /* tfB */ + tfname2[0] = 'r'; /* rf */ newfd = open(tfname2, O_WRONLY|O_CREAT|O_TRUNC, 0660); if (newfd == -1) { snprintf(errm, sizeof(errm), diff --git a/usr.sbin/lpr/lpc/cmds.c b/usr.sbin/lpr/lpc/cmds.c index 6b6329332d69..1e6f4002fe44 100644 --- a/usr.sbin/lpr/lpc/cmds.c +++ b/usr.sbin/lpr/lpc/cmds.c @@ -318,7 +318,8 @@ doselect(struct dirent *d) { int c = d->d_name[0]; - if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f') + if ((c == 'c' || c == 'd' || c == 'r' || c == 't') && + d->d_name[1] == 'f') return 1; if (c == 'c') { if (!strcmp(d->d_name, "core")) @@ -335,11 +336,17 @@ doselect(struct dirent *d) * Comparison routine that clean_q() uses for scandir. * * The purpose of this sort is to have all `df' files end up immediately - * after the matching `cf' file. For files matching `cf', `df', or `tf', - * it sorts by job number and machine, then by `cf', `df', or `tf', then - * by the sequence letter A-Z, a-z. This routine may also see filenames - * which do not start with `cf', `df', or `tf' (such as `errs.*'), and - * those are simply sorted by the full filename. + * after the matching `cf' file. For files matching `cf', `df', `rf', or + * `tf', it sorts by job number and machine, then by `cf', `df', `rf', or + * `tf', and then by the sequence letter (which is A-Z, or a-z). This + * routine may also see filenames which do not start with `cf', `df', `rf', + * or `tf' (such as `errs.*'), and those are simply sorted by the full + * filename. + * + * XXX + * This assumes that all control files start with `cfA*', and it turns + * out there are a few implementations of lpr which will create `cfB*' + * filenames (they will have datafile names which start with `dfB*'). */ static int sortq(const void *a, const void *b) @@ -353,9 +360,9 @@ sortq(const void *a, const void *b) /* * First separate filenames into cagatories. Catagories are - * legitimate `cf', `df', & `tf' filenames, and "other" - in - * that order. It is critical that the mapping be exactly - * the same for 'a' vs 'b', so define a macro for the job. + * legitimate `cf', `df', `rf' & `tf' filenames, and "other" - in + * that order. It is critical that the mapping be exactly the + * same for 'a' vs 'b', so define a macro for the job. * * [aside: the standard `cf' file has the jobnumber start in * position 4, but some implementations have that as an extra @@ -372,8 +379,10 @@ sortq(const void *a, const void *b) cat_X = 1; \ else if (*fname_X == 'd') \ cat_X = 2; \ - else if (*fname_X == 't') \ + else if (*fname_X == 'r') \ cat_X = 3; \ + else if (*fname_X == 't') \ + cat_X = 4; \ if (cat_X != cat_other) { \ ch = *jnum_X; \ if (!isdigit(ch)) { \ @@ -407,7 +416,7 @@ sortq(const void *a, const void *b) } /* - * At this point, we know both files are legitimate `cf', `df', + * At this point, we know both files are legitimate `cf', `df', `rf', * or `tf' files. Compare them by job-number and machine name. */ res = strcmp(jnum_a, jnum_b); @@ -595,8 +604,8 @@ clean_q(struct printer *pp) } else { /* * Must be a df with no cf (otherwise, it would have - * been skipped above) or a tf file (which can always - * be removed if it's old enough). + * been skipped above) or an rf or tf file (which can + * always be removed if it is old enough). */ rmcp = 1; }