static char sccsid
[] = "@(#)anlwrk.c 5.7 (Berkeley) %G%";
#define NITEMS(X) (sizeof (X) / sizeof ((X)[0]))
char Filent
[LLEN
][NAMESIZE
];
extern int TransferSucceeded
;
* create a vector of command arguments
* 0 - no more work in this file
* positive number - number of arguments
register char *file
, **wvec
;
static char str
[MAXRQST
], nstr
[MAXRQST
], lastfile
[MAXFULLNAME
] = "";
static long nextread
, nextwrite
;
* If called with a null string, force a shutdown
* of the current work file.
if (strncmp(file
, lastfile
, MAXFULLNAME
) == 0) {
DEBUG(5,"Workfilename repeated: %s\n", file
);
strncpy(lastfile
, file
, MAXFULLNAME
);
fp
= fopen(subfile(file
), "r+w");
char *bnp
, rqstr
[MAXFULLNAME
];
sprintf(rqstr
, "%s/%s", CORRUPT
, bnp
? bnp
+ 1 : file
);
syslog(LOG_WARNING
, "fopen(%s) failed: %m",
nextread
= nextwrite
= 0L;
if (nstr
[0] != '\0' && TransferSucceeded
) {
if (fgets(str
, MAXRQST
, fp
) == NULL
) {
} while (!isupper(str
[0]));
strncpy(nstr
, str
, MAXRQST
);
nstr
[0] = tolower(nstr
[0]);
return getargs(str
, wvec
, 20);
* build list of work files for given system
* return value - 1 if work was found, else 0
bldflst (reqst
, dir
, pre
)
register char *dir
, *pre
;
register struct direct
*dentp
;
if ((dirp
= opendir(subdir(dir
,pre
[0]))) == NULL
) {
DEBUG(1,"opendir(%s) FAILS\n",subdir(dir
,pre
[0]));
while ((dentp
= readdir(dirp
)) != NULL
&& Nfiles
< LLEN
) {
/* Check for two systems with the same prefix.
* Magic number "5" is 1 for "grade" character plus
* 4 for sequence number. The point here is to not
* send work for a system which has as a prefix the
* name of the system called for.
* Special case: prefix "X." does not do this check
* so uuxqt can use bldflst.
if (!prefix(pre
, dentp
->d_name
) ||
(plen
!= 2 && (dentp
->d_namlen
-plen
) != 5)) {
DEBUG(99,"bldflst rejects %s\n",dentp
->d_name
);
if (dentp
->d_name
[dentp
->d_namlen
-5] > MaxGrade
) {
DEBUG(8, "bldflst rejects %s, grade too low\n",
/* locate position for the new file and make room for it */
for (i
= Nfiles
; i
> 0; i
--) {
if (pcompar(dentp
->d_name
, Filent
[i
-1]) <= 0)
strcpy(Filent
[i
], Filent
[i
-1]);
/* add new file (if there is room), and increase Nfiles if need be */
DEBUG(99,"bldflst accepts %s",dentp
->d_name
);
DEBUG(99," as Filent[%d]\n", i
);
strcpy(Filent
[i
], dentp
->d_name
);
DEBUG(99,"Filent full, %s rejected by bldflst\n", dentp
->d_name
);
fprintf(stderr
,"Filent[%d]=%s\n",i
,Filent
[i
]);
Compare priority of filenames p1 and p2. Return:
* < 0 if p1 "has lower priority than" p2.
* = 0 if p1 "has priority equal to" p2.
* > 0 if p1 "has greater priority than" p2.
* lower sequence number wins (unless wrap-around is suspected).
/* strlen(p1) and strlen(p2) are >= 5 */
/* check for sequence wrap-around */
/* check remaining digits */
* positive number - number of arguments
* 0 - no arguments - fail
gtwvec(file
, dir
, wkpre
, wrkvec
)
char *dir
, *wkpre
, **wrkvec
;
while ((nargs
= anlwrk(file
, wrkvec
)) == 0) {
if (++n
> 3 || !iswrk(file
, "get", dir
, wkpre
))
* iswrk - this routine will check the work list (list).
* If it is empty or the present work is exhausted, it
* will call bldflst to generate a new list.
* The "reqst" field will be the string "chk" or "get" to
* check for work, or get the next work file respectively.
* 0 - no more work (or some error)
iswrk(file
, reqst
, dir
, pre
)
register char *file
, *reqst
, *dir
, *pre
;
static char *lastpre
= 0;
/* Starting new system; re-init */
if (lastpre
== 0 || strcmp(lastpre
, pre
) != SAME
) {
/* Force close of work file */
/* Save last worked-on prefix */
lastpre
= malloc((unsigned)(strlen(pre
)+1));
/* Set the external indexes properly */
* If the list is empty or new files have entered
* the spool area, call "bldflst" to read
* some file names into it.
if (Nfiles
<= 0 || newspool((time_t)TLIMIT
)) {
ret
= bldflst(reqst
, dir
, pre
);
DEBUG(99, "bldflst returns %d\n", ret
);
/* If they only wanted to check, return
* boolean list not empty. NB: the list
* will be forcibly emptied as soon as
* a new system name is mentioned.
/* Didn't find any files in the spool area */
/* Found some files, return the first one */
sprintf(file
, "%s/%s", dir
, Filent
[0]);
for (i
= 0; i
< Nfiles
; i
++)
strcpy(Filent
[i
], Filent
[i
+1]);
/* Return non-zero if there is new work in the spool
* area since last check. Assumes that if the sequence
* file has been modified, there is new work. This is
* not absolutely correct, but should be close enough.
* Only checks every <limit> seconds at most. Called
* from "iswrk()" when a new work file is requested.
static time_t lastcheck
= 0, lastmod
= 0;
/* (void) */ time (&check
);
if (check
- lastcheck
> limit
|| lastcheck
- check
> limit
) {
/* (void) */ stat (SEQFILE
, &mod
);
if (mod
.st_mtime
!= lastmod
)