17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
22*462be471Sceastha /*
23*462be471Sceastha * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24*462be471Sceastha * Use is subject to license terms.
25*462be471Sceastha */
26*462be471Sceastha
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate
31*462be471Sceastha #pragma ident "%Z%%M% %I% %E% SMI"
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate This module contains routines that find C. files
347c478bd9Sstevel@tonic-gate in a system spool directory, return the next C. file
357c478bd9Sstevel@tonic-gate to process, and break up the C. line into arguments
367c478bd9Sstevel@tonic-gate for processing.
377c478bd9Sstevel@tonic-gate */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate #include "uucp.h"
407c478bd9Sstevel@tonic-gate
417c478bd9Sstevel@tonic-gate #define BOOKMARK_PRE 'A'
427c478bd9Sstevel@tonic-gate #define CLEAN_RETURN(fp) {\
437c478bd9Sstevel@tonic-gate if (fp != NULL) \
447c478bd9Sstevel@tonic-gate (void) fclose(fp); \
457c478bd9Sstevel@tonic-gate fp = NULL; \
467c478bd9Sstevel@tonic-gate return(0); \
477c478bd9Sstevel@tonic-gate /* NOTREACHED */ \
487c478bd9Sstevel@tonic-gate }
497c478bd9Sstevel@tonic-gate
507c478bd9Sstevel@tonic-gate /* C.princetN0026 - ('C' + '.') - "princet" */
517c478bd9Sstevel@tonic-gate #define SUFSIZE (MAXBASENAME - 2 - SYSNSIZE)
527c478bd9Sstevel@tonic-gate #define LLEN 50
537c478bd9Sstevel@tonic-gate #define MAXRQST 250
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate static void insert();
567c478bd9Sstevel@tonic-gate static int anlwrk(), bldflst();
577c478bd9Sstevel@tonic-gate extern int iswrk(), gtwvec(), gnamef();
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate static char Filent[LLEN][NAMESIZE]; /* array of C. file names (text) */
607c478bd9Sstevel@tonic-gate static char *Fptr[LLEN]; /* pointers to names in Filent */
617c478bd9Sstevel@tonic-gate static short Nnext; /* index of next C. file in Fptr list */
627c478bd9Sstevel@tonic-gate static short Nfiles = 0; /* Number of files in Filent */
637c478bd9Sstevel@tonic-gate
647c478bd9Sstevel@tonic-gate /*
657c478bd9Sstevel@tonic-gate * read a line from the workfile (C.file)
667c478bd9Sstevel@tonic-gate * file -> work file (Input/Output) made '\0' after work completion
677c478bd9Sstevel@tonic-gate * wvec -> address of array to return arguments (Output)
687c478bd9Sstevel@tonic-gate * wcount -> maximum # of arguments to return in wvec
697c478bd9Sstevel@tonic-gate * NOTE: wvec should be large enough to accept wcount + 1 pointers
707c478bd9Sstevel@tonic-gate * since NULL is inserted after last item.
717c478bd9Sstevel@tonic-gate * returns:
727c478bd9Sstevel@tonic-gate * 0 -> no more work in this file
737c478bd9Sstevel@tonic-gate * positive # -> number of arguments
747c478bd9Sstevel@tonic-gate */
757c478bd9Sstevel@tonic-gate static int
anlwrk(file,wvec,wcount)767c478bd9Sstevel@tonic-gate anlwrk(file, wvec, wcount)
777c478bd9Sstevel@tonic-gate char *file, **wvec;
787c478bd9Sstevel@tonic-gate {
79*462be471Sceastha int i;
80*462be471Sceastha FILE *p_bookmark; /* pointer to afile */
817c478bd9Sstevel@tonic-gate static FILE *fp = NULL; /* currently opened C. file pointer */
827c478bd9Sstevel@tonic-gate static char afile[NAMESIZE]; /* file with line count for book marks */
837c478bd9Sstevel@tonic-gate static char str[MAXRQST]; /* the string which wvec points to */
847c478bd9Sstevel@tonic-gate static short acount;
857c478bd9Sstevel@tonic-gate struct stat stbuf;
867c478bd9Sstevel@tonic-gate int nargs; /* return value == # args in the line */
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate if (file[0] == '\0') {
897c478bd9Sstevel@tonic-gate if (fp != NULL)
907c478bd9Sstevel@tonic-gate errent("anlwrk",
917c478bd9Sstevel@tonic-gate "attempt made to use old workfile was thwarted", 0,
927c478bd9Sstevel@tonic-gate __FILE__, __LINE__);
937c478bd9Sstevel@tonic-gate CLEAN_RETURN(fp);
947c478bd9Sstevel@tonic-gate /* NOTREACHED */
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate if (fp == NULL) {
977c478bd9Sstevel@tonic-gate fp = fopen(file, "r");
987c478bd9Sstevel@tonic-gate
997c478bd9Sstevel@tonic-gate if (fp == NULL){ /* can't open C. file! */
1007c478bd9Sstevel@tonic-gate errent(Ct_OPEN,file,errno, __FILE__, __LINE__);
1017c478bd9Sstevel@tonic-gate /* this may not work, but we'll try it */
1027c478bd9Sstevel@tonic-gate /* It will fail if the C. name is more than */
1037c478bd9Sstevel@tonic-gate /* the standard 14 characters - if this is the */
1047c478bd9Sstevel@tonic-gate /* tocorrupt will exit with ASSERT */
1057c478bd9Sstevel@tonic-gate toCorrupt(file);
1067c478bd9Sstevel@tonic-gate return(0);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate (void) fstat(fileno(fp), &stbuf);
1097c478bd9Sstevel@tonic-gate Nstat.t_qtime = stbuf.st_mtime;
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate (void) strncpy(afile, BASENAME(file, '/'), NAMESIZE);
1127c478bd9Sstevel@tonic-gate afile[NAMESIZE-1] = NULLCHAR;
1137c478bd9Sstevel@tonic-gate *afile = BOOKMARK_PRE; /* make up name by replacing C with A */
1147c478bd9Sstevel@tonic-gate acount = 0;
1157c478bd9Sstevel@tonic-gate p_bookmark = fopen(afile, "r");
1167c478bd9Sstevel@tonic-gate if (p_bookmark != NULL) {
1177c478bd9Sstevel@tonic-gate /* get count of already completed work */
1187c478bd9Sstevel@tonic-gate i = fscanf(p_bookmark, "%hd", &acount);
1197c478bd9Sstevel@tonic-gate (void) fclose(p_bookmark);
1207c478bd9Sstevel@tonic-gate if (i <= 0)
1217c478bd9Sstevel@tonic-gate acount = 0;
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate /* skip lines which have already been processed */
1247c478bd9Sstevel@tonic-gate for (i = 0; i < acount; i++) {
1257c478bd9Sstevel@tonic-gate if (fgets(str, MAXRQST, fp) == NULL)
1267c478bd9Sstevel@tonic-gate break;
1277c478bd9Sstevel@tonic-gate }
1287c478bd9Sstevel@tonic-gate }
1297c478bd9Sstevel@tonic-gate
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate if (fgets(str, MAXRQST, fp) == NULL) {
1337c478bd9Sstevel@tonic-gate ASSERT(unlink(file) == 0, Ct_UNLINK, file, errno);
1347c478bd9Sstevel@tonic-gate (void) unlink(afile);
1357c478bd9Sstevel@tonic-gate DEBUG(4,"Finished Processing file: %s\n",file);
1367c478bd9Sstevel@tonic-gate *file = '\0';
1377c478bd9Sstevel@tonic-gate CLEAN_RETURN(fp);
1387c478bd9Sstevel@tonic-gate /*NOTREACHED*/
1397c478bd9Sstevel@tonic-gate }
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate nargs = getargs(str, wvec, wcount);
1427c478bd9Sstevel@tonic-gate
1437c478bd9Sstevel@tonic-gate /* sanity checks for C. file */
1447c478bd9Sstevel@tonic-gate if ((str[0] != 'R' && str[0] != 'S') /* legal wrktypes are R and S */
1457c478bd9Sstevel@tonic-gate || (str[0] == 'R' && nargs < 6) /* R lines need >= 6 entries */
1467c478bd9Sstevel@tonic-gate || (str[0] == 'S' && nargs < 7)) { /* S lines need >= 7 entries */
1477c478bd9Sstevel@tonic-gate /* bad C. file - stash it */
1487c478bd9Sstevel@tonic-gate toCorrupt(file);
1497c478bd9Sstevel@tonic-gate (void) unlink(afile);
1507c478bd9Sstevel@tonic-gate *file = '\0';
1517c478bd9Sstevel@tonic-gate CLEAN_RETURN(fp);
1527c478bd9Sstevel@tonic-gate /*NOTREACHED*/
1537c478bd9Sstevel@tonic-gate }
1547c478bd9Sstevel@tonic-gate
1557c478bd9Sstevel@tonic-gate p_bookmark = fopen(afile, "w"); /* update bookmark file */
1567c478bd9Sstevel@tonic-gate if (p_bookmark == NULL)
1577c478bd9Sstevel@tonic-gate errent(Ct_OPEN, afile, errno, __FILE__, __LINE__);
1587c478bd9Sstevel@tonic-gate else {
1597c478bd9Sstevel@tonic-gate chmod(afile, CFILEMODE);
1607c478bd9Sstevel@tonic-gate (void) fprintf(p_bookmark, "%d", acount);
1617c478bd9Sstevel@tonic-gate (void) fclose(p_bookmark);
1627c478bd9Sstevel@tonic-gate }
1637c478bd9Sstevel@tonic-gate acount++;
1647c478bd9Sstevel@tonic-gate return(nargs);
1657c478bd9Sstevel@tonic-gate }
1667c478bd9Sstevel@tonic-gate
1677c478bd9Sstevel@tonic-gate /*
1687c478bd9Sstevel@tonic-gate * Check the list of work files (C.sys).
1697c478bd9Sstevel@tonic-gate * If it is empty or the present work is exhausted, it
1707c478bd9Sstevel@tonic-gate * will call bldflst to generate a new list.
1717c478bd9Sstevel@tonic-gate *
1727c478bd9Sstevel@tonic-gate * If there are no more jobs in the current job grade,
1737c478bd9Sstevel@tonic-gate * it will call findgrade to get the new job grade to process.
1747c478bd9Sstevel@tonic-gate *
1757c478bd9Sstevel@tonic-gate * file -> address of array to return full pathname in
1767c478bd9Sstevel@tonic-gate * returns:
1777c478bd9Sstevel@tonic-gate * 0 -> no more work (or some error)
1787c478bd9Sstevel@tonic-gate * 1 -> there is work
1797c478bd9Sstevel@tonic-gate */
1807c478bd9Sstevel@tonic-gate extern int
1817c478bd9Sstevel@tonic-gate iswrk(file)
1827c478bd9Sstevel@tonic-gate char *file;
1837c478bd9Sstevel@tonic-gate {
1847c478bd9Sstevel@tonic-gate char newspool[MAXFULLNAME];
1857c478bd9Sstevel@tonic-gate char lockname[MAXFULLNAME];
1867c478bd9Sstevel@tonic-gate char gradedir[2*MAXBASENAME];
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate if (Nfiles == 0) {
1897c478bd9Sstevel@tonic-gate /* If Role is MASTER and JobGrade is null, then
1907c478bd9Sstevel@tonic-gate * there is no work for the remote.
1917c478bd9Sstevel@tonic-gate *
1927c478bd9Sstevel@tonic-gate * In the case of uucico slave, the job grade
1937c478bd9Sstevel@tonic-gate * to process should be determined before building
1947c478bd9Sstevel@tonic-gate * the work list.
1957c478bd9Sstevel@tonic-gate */
1967c478bd9Sstevel@tonic-gate if (Role == MASTER) {
1977c478bd9Sstevel@tonic-gate if (*JobGrade == NULLCHAR)
1987c478bd9Sstevel@tonic-gate return(0);
1997c478bd9Sstevel@tonic-gate
2007c478bd9Sstevel@tonic-gate if (bldflst() != 0) {
2017c478bd9Sstevel@tonic-gate (void) sprintf(file, "%s/%s", RemSpool, Fptr[Nnext]);
2027c478bd9Sstevel@tonic-gate Nfiles--;
2037c478bd9Sstevel@tonic-gate Nnext++;
2047c478bd9Sstevel@tonic-gate return(1);
2057c478bd9Sstevel@tonic-gate }
2067c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%.*s.%s", SYSNSIZE, Rmtname, JobGrade);
2077c478bd9Sstevel@tonic-gate delock(LOCKPRE, lockname);
2087c478bd9Sstevel@tonic-gate } else {
2097c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%ld", (long) getpid());
2107c478bd9Sstevel@tonic-gate delock(LOCKPRE, lockname);
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate (void) sprintf(newspool, "%s/%s", SPOOL, Rmtname);
2147c478bd9Sstevel@tonic-gate ASSERT(chdir(newspool) == 0, Ct_CHDIR, newspool, errno);
2157c478bd9Sstevel@tonic-gate
2167c478bd9Sstevel@tonic-gate findgrade(newspool, JobGrade);
2177c478bd9Sstevel@tonic-gate DEBUG(4, "Job grade to process - %s\n", JobGrade);
2187c478bd9Sstevel@tonic-gate if (*JobGrade == NULLCHAR)
2197c478bd9Sstevel@tonic-gate return(0);
2207c478bd9Sstevel@tonic-gate
2217c478bd9Sstevel@tonic-gate (void) sprintf(lockname, "%.*s.%s", SYSNSIZE, Rmtname, JobGrade);
2227c478bd9Sstevel@tonic-gate (void) umlock(LOCKPRE, lockname);
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate /* Make the new job grade directory the working directory
2257c478bd9Sstevel@tonic-gate * and set RemSpool.
2267c478bd9Sstevel@tonic-gate */
2277c478bd9Sstevel@tonic-gate (void) sprintf(gradedir, "%s/%s", Rmtname, JobGrade);
2287c478bd9Sstevel@tonic-gate chremdir(gradedir);
2297c478bd9Sstevel@tonic-gate bldflst();
2307c478bd9Sstevel@tonic-gate }
2317c478bd9Sstevel@tonic-gate
2327c478bd9Sstevel@tonic-gate (void) sprintf(file, "%s/%s", RemSpool, Fptr[Nnext]);
2337c478bd9Sstevel@tonic-gate Nfiles--;
2347c478bd9Sstevel@tonic-gate Nnext++;
2357c478bd9Sstevel@tonic-gate return(1);
2367c478bd9Sstevel@tonic-gate }
2377c478bd9Sstevel@tonic-gate
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate /*
2407c478bd9Sstevel@tonic-gate * build list of work files for given system using an insertion sort
2417c478bd9Sstevel@tonic-gate * Nfiles, Nnext, RemSpool and Rmtname are global
2427c478bd9Sstevel@tonic-gate *
2437c478bd9Sstevel@tonic-gate * return:
2447c478bd9Sstevel@tonic-gate * number of C. files in list - (Nfiles)
2457c478bd9Sstevel@tonic-gate */
2467c478bd9Sstevel@tonic-gate static int
bldflst()2477c478bd9Sstevel@tonic-gate bldflst()
2487c478bd9Sstevel@tonic-gate {
249*462be471Sceastha DIR *pdir;
2507c478bd9Sstevel@tonic-gate char filename[NAMESIZE];
2517c478bd9Sstevel@tonic-gate char prefix[SYSNSIZE+3];
2527c478bd9Sstevel@tonic-gate
2537c478bd9Sstevel@tonic-gate Nnext = Nfiles = 0;
2547c478bd9Sstevel@tonic-gate if ((pdir = opendir(RemSpool)) == NULL)
2557c478bd9Sstevel@tonic-gate return(0);
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate (void) sprintf(prefix, "C.%.*s", SYSNSIZE, Rmtname);
2587c478bd9Sstevel@tonic-gate while (gnamef(pdir, filename) ) {
2597c478bd9Sstevel@tonic-gate if (!PREFIX(prefix, filename))
2607c478bd9Sstevel@tonic-gate continue;
2617c478bd9Sstevel@tonic-gate if ((strlen(filename)-strlen(prefix)) != SUFSIZE) {
2627c478bd9Sstevel@tonic-gate errent("bldflst: Funny filename", filename, 0,
2637c478bd9Sstevel@tonic-gate __FILE__, __LINE__);
2647c478bd9Sstevel@tonic-gate continue;
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate insert(filename);
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate closedir(pdir);
2697c478bd9Sstevel@tonic-gate return(Nfiles);
2707c478bd9Sstevel@tonic-gate }
2717c478bd9Sstevel@tonic-gate
2727c478bd9Sstevel@tonic-gate /*
2737c478bd9Sstevel@tonic-gate * get work return
2747c478bd9Sstevel@tonic-gate * file -> place to deposit file name
2757c478bd9Sstevel@tonic-gate * wrkvec -> array to return arguments
2767c478bd9Sstevel@tonic-gate * wcount -> max number of args for wrkvec
2777c478bd9Sstevel@tonic-gate * returns:
2787c478bd9Sstevel@tonic-gate * nargs -> number of arguments
2797c478bd9Sstevel@tonic-gate * 0 -> no arguments - fail
2807c478bd9Sstevel@tonic-gate */
2817c478bd9Sstevel@tonic-gate extern int
2827c478bd9Sstevel@tonic-gate gtwvec(file, wrkvec, wcount)
2837c478bd9Sstevel@tonic-gate char *file, **wrkvec;
2847c478bd9Sstevel@tonic-gate {
285*462be471Sceastha int nargs;
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate DEBUG(7, "gtwvec: dir %s\n", RemSpool);
2887c478bd9Sstevel@tonic-gate while ((nargs = anlwrk(file, wrkvec, wcount)) == 0) {
2897c478bd9Sstevel@tonic-gate if (!iswrk(file))
2907c478bd9Sstevel@tonic-gate return(0);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate DEBUG(7, " return - %d\n", nargs);
2937c478bd9Sstevel@tonic-gate return(nargs);
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate
2967c478bd9Sstevel@tonic-gate
2977c478bd9Sstevel@tonic-gate /*
2987c478bd9Sstevel@tonic-gate * insert - insert file name in sorted list
2997c478bd9Sstevel@tonic-gate * return - none
3007c478bd9Sstevel@tonic-gate */
3017c478bd9Sstevel@tonic-gate static void
insert(file)3027c478bd9Sstevel@tonic-gate insert(file)
3037c478bd9Sstevel@tonic-gate char *file;
3047c478bd9Sstevel@tonic-gate {
305*462be471Sceastha int i, j;
306*462be471Sceastha char *p;
3077c478bd9Sstevel@tonic-gate
3087c478bd9Sstevel@tonic-gate DEBUG(7, "insert(%s) ", file);
3097c478bd9Sstevel@tonic-gate for (i = Nfiles; i>0; i--) {
3107c478bd9Sstevel@tonic-gate if (strcmp(file, Fptr[i-1]) > 0)
3117c478bd9Sstevel@tonic-gate break;
3127c478bd9Sstevel@tonic-gate }
3137c478bd9Sstevel@tonic-gate if (i == LLEN) /* if this is off the end get out */
3147c478bd9Sstevel@tonic-gate return;
3157c478bd9Sstevel@tonic-gate
3167c478bd9Sstevel@tonic-gate /* get p (pointer) to where the text of name will go */
3177c478bd9Sstevel@tonic-gate if (Nfiles == LLEN) /* last possible entry */
3187c478bd9Sstevel@tonic-gate /* put in text of last and decrement Nfiles for make hole */
3197c478bd9Sstevel@tonic-gate p = strcpy(Fptr[--Nfiles], file);
3207c478bd9Sstevel@tonic-gate else
3217c478bd9Sstevel@tonic-gate p = strcpy(Filent[Nfiles], file); /* copy to next free */
3227c478bd9Sstevel@tonic-gate
3237c478bd9Sstevel@tonic-gate /* make a hole for new entry */
3247c478bd9Sstevel@tonic-gate for (j = Nfiles; j >i; j--)
3257c478bd9Sstevel@tonic-gate Fptr[j] = Fptr[j-1];
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate DEBUG(7, "insert %s ", p);
3287c478bd9Sstevel@tonic-gate DEBUG(7, "at %d\n", i);
3297c478bd9Sstevel@tonic-gate Fptr[i] = p;
3307c478bd9Sstevel@tonic-gate Nfiles++;
3317c478bd9Sstevel@tonic-gate return;
3327c478bd9Sstevel@tonic-gate }
333