My recent changes to add the ctl_renametf routine assumed that print job
control-files will always start with 'cfA*'. It turns out that some implementations of lpd (such as solaris) may send a control file which starts with 'cfB*', or really 'cf<anyLetter>*'. Although such filenames are very odd, we did used to accept them. This changes ctl_renametf to work correctly with them, and fixes up 'lpc clean' to match. PR: bin/32183 MFC after: 10 days
This commit is contained in:
parent
89709a06f9
commit
1fd731fa25
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=87034
@ -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<job><hostname> */
|
||||
tfname2[0] = 'r'; /* rf<letter><job><hostname> */
|
||||
newfd = open(tfname2, O_WRONLY|O_CREAT|O_TRUNC, 0660);
|
||||
if (newfd == -1) {
|
||||
snprintf(errm, sizeof(errm),
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user