1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23 /* All Rights Reserved */ 24 25 26 #ident "%Z%%M% %I% %E% SMI" /* from SVR4 bnu:anlwrk.c 2.6 */ 27 /* 28 This module contains routines that find C. files 29 in a system spool directory, return the next C. file 30 to process, and break up the C. line into arguments 31 for processing. 32 */ 33 34 #include "uucp.h" 35 36 #define BOOKMARK_PRE 'A' 37 #define CLEAN_RETURN(fp) {\ 38 if (fp != NULL) \ 39 (void) fclose(fp); \ 40 fp = NULL; \ 41 return(0); \ 42 /* NOTREACHED */ \ 43 } 44 45 /* C.princetN0026 - ('C' + '.') - "princet" */ 46 #define SUFSIZE (MAXBASENAME - 2 - SYSNSIZE) 47 #define LLEN 50 48 #define MAXRQST 250 49 50 static void insert(); 51 static int anlwrk(), bldflst(); 52 extern int iswrk(), gtwvec(), gnamef(); 53 54 static char Filent[LLEN][NAMESIZE]; /* array of C. file names (text) */ 55 static char *Fptr[LLEN]; /* pointers to names in Filent */ 56 static short Nnext; /* index of next C. file in Fptr list */ 57 static short Nfiles = 0; /* Number of files in Filent */ 58 59 /* 60 * read a line from the workfile (C.file) 61 * file -> work file (Input/Output) made '\0' after work completion 62 * wvec -> address of array to return arguments (Output) 63 * wcount -> maximum # of arguments to return in wvec 64 * NOTE: wvec should be large enough to accept wcount + 1 pointers 65 * since NULL is inserted after last item. 66 * returns: 67 * 0 -> no more work in this file 68 * positive # -> number of arguments 69 */ 70 static int 71 anlwrk(file, wvec, wcount) 72 char *file, **wvec; 73 { 74 register i; 75 register FILE *p_bookmark; /* pointer to afile */ 76 static FILE *fp = NULL; /* currently opened C. file pointer */ 77 static char afile[NAMESIZE]; /* file with line count for book marks */ 78 static char str[MAXRQST]; /* the string which wvec points to */ 79 static short acount; 80 struct stat stbuf; 81 int nargs; /* return value == # args in the line */ 82 83 if (file[0] == '\0') { 84 if (fp != NULL) 85 errent("anlwrk", 86 "attempt made to use old workfile was thwarted", 0, 87 __FILE__, __LINE__); 88 CLEAN_RETURN(fp); 89 /* NOTREACHED */ 90 } 91 if (fp == NULL) { 92 fp = fopen(file, "r"); 93 94 if (fp == NULL){ /* can't open C. file! */ 95 errent(Ct_OPEN,file,errno, __FILE__, __LINE__); 96 /* this may not work, but we'll try it */ 97 /* It will fail if the C. name is more than */ 98 /* the standard 14 characters - if this is the */ 99 /* tocorrupt will exit with ASSERT */ 100 toCorrupt(file); 101 return(0); 102 } 103 (void) fstat(fileno(fp), &stbuf); 104 Nstat.t_qtime = stbuf.st_mtime; 105 106 (void) strncpy(afile, BASENAME(file, '/'), NAMESIZE); 107 afile[NAMESIZE-1] = NULLCHAR; 108 *afile = BOOKMARK_PRE; /* make up name by replacing C with A */ 109 acount = 0; 110 p_bookmark = fopen(afile, "r"); 111 if (p_bookmark != NULL) { 112 /* get count of already completed work */ 113 i = fscanf(p_bookmark, "%hd", &acount); 114 (void) fclose(p_bookmark); 115 if (i <= 0) 116 acount = 0; 117 118 /* skip lines which have already been processed */ 119 for (i = 0; i < acount; i++) { 120 if (fgets(str, MAXRQST, fp) == NULL) 121 break; 122 } 123 } 124 125 } 126 127 if (fgets(str, MAXRQST, fp) == NULL) { 128 ASSERT(unlink(file) == 0, Ct_UNLINK, file, errno); 129 (void) unlink(afile); 130 DEBUG(4,"Finished Processing file: %s\n",file); 131 *file = '\0'; 132 CLEAN_RETURN(fp); 133 /*NOTREACHED*/ 134 } 135 136 nargs = getargs(str, wvec, wcount); 137 138 /* sanity checks for C. file */ 139 if ((str[0] != 'R' && str[0] != 'S') /* legal wrktypes are R and S */ 140 || (str[0] == 'R' && nargs < 6) /* R lines need >= 6 entries */ 141 || (str[0] == 'S' && nargs < 7)) { /* S lines need >= 7 entries */ 142 /* bad C. file - stash it */ 143 toCorrupt(file); 144 (void) unlink(afile); 145 *file = '\0'; 146 CLEAN_RETURN(fp); 147 /*NOTREACHED*/ 148 } 149 150 p_bookmark = fopen(afile, "w"); /* update bookmark file */ 151 if (p_bookmark == NULL) 152 errent(Ct_OPEN, afile, errno, __FILE__, __LINE__); 153 else { 154 chmod(afile, CFILEMODE); 155 (void) fprintf(p_bookmark, "%d", acount); 156 (void) fclose(p_bookmark); 157 } 158 acount++; 159 return(nargs); 160 } 161 162 /* 163 * Check the list of work files (C.sys). 164 * If it is empty or the present work is exhausted, it 165 * will call bldflst to generate a new list. 166 * 167 * If there are no more jobs in the current job grade, 168 * it will call findgrade to get the new job grade to process. 169 * 170 * file -> address of array to return full pathname in 171 * returns: 172 * 0 -> no more work (or some error) 173 * 1 -> there is work 174 */ 175 extern int 176 iswrk(file) 177 char *file; 178 { 179 char newspool[MAXFULLNAME]; 180 char lockname[MAXFULLNAME]; 181 char gradedir[2*MAXBASENAME]; 182 183 if (Nfiles == 0) { 184 /* If Role is MASTER and JobGrade is null, then 185 * there is no work for the remote. 186 * 187 * In the case of uucico slave, the job grade 188 * to process should be determined before building 189 * the work list. 190 */ 191 if (Role == MASTER) { 192 if (*JobGrade == NULLCHAR) 193 return(0); 194 195 if (bldflst() != 0) { 196 (void) sprintf(file, "%s/%s", RemSpool, Fptr[Nnext]); 197 Nfiles--; 198 Nnext++; 199 return(1); 200 } 201 (void) sprintf(lockname, "%.*s.%s", SYSNSIZE, Rmtname, JobGrade); 202 delock(LOCKPRE, lockname); 203 } else { 204 (void) sprintf(lockname, "%ld", (long) getpid()); 205 delock(LOCKPRE, lockname); 206 } 207 208 (void) sprintf(newspool, "%s/%s", SPOOL, Rmtname); 209 ASSERT(chdir(newspool) == 0, Ct_CHDIR, newspool, errno); 210 211 findgrade(newspool, JobGrade); 212 DEBUG(4, "Job grade to process - %s\n", JobGrade); 213 if (*JobGrade == NULLCHAR) 214 return(0); 215 216 (void) sprintf(lockname, "%.*s.%s", SYSNSIZE, Rmtname, JobGrade); 217 (void) umlock(LOCKPRE, lockname); 218 219 /* Make the new job grade directory the working directory 220 * and set RemSpool. 221 */ 222 (void) sprintf(gradedir, "%s/%s", Rmtname, JobGrade); 223 chremdir(gradedir); 224 bldflst(); 225 } 226 227 (void) sprintf(file, "%s/%s", RemSpool, Fptr[Nnext]); 228 Nfiles--; 229 Nnext++; 230 return(1); 231 } 232 233 234 /* 235 * build list of work files for given system using an insertion sort 236 * Nfiles, Nnext, RemSpool and Rmtname are global 237 * 238 * return: 239 * number of C. files in list - (Nfiles) 240 */ 241 static int 242 bldflst() 243 { 244 register DIR *pdir; 245 char filename[NAMESIZE]; 246 char prefix[SYSNSIZE+3]; 247 248 Nnext = Nfiles = 0; 249 if ((pdir = opendir(RemSpool)) == NULL) 250 return(0); 251 252 (void) sprintf(prefix, "C.%.*s", SYSNSIZE, Rmtname); 253 while (gnamef(pdir, filename) ) { 254 if (!PREFIX(prefix, filename)) 255 continue; 256 if ((strlen(filename)-strlen(prefix)) != SUFSIZE) { 257 errent("bldflst: Funny filename", filename, 0, 258 __FILE__, __LINE__); 259 continue; 260 } 261 insert(filename); 262 } 263 closedir(pdir); 264 return(Nfiles); 265 } 266 267 /* 268 * get work return 269 * file -> place to deposit file name 270 * wrkvec -> array to return arguments 271 * wcount -> max number of args for wrkvec 272 * returns: 273 * nargs -> number of arguments 274 * 0 -> no arguments - fail 275 */ 276 extern int 277 gtwvec(file, wrkvec, wcount) 278 char *file, **wrkvec; 279 { 280 register int nargs; 281 282 DEBUG(7, "gtwvec: dir %s\n", RemSpool); 283 while ((nargs = anlwrk(file, wrkvec, wcount)) == 0) { 284 if (!iswrk(file)) 285 return(0); 286 } 287 DEBUG(7, " return - %d\n", nargs); 288 return(nargs); 289 } 290 291 292 /* 293 * insert - insert file name in sorted list 294 * return - none 295 */ 296 static void 297 insert(file) 298 char *file; 299 { 300 register i, j; 301 register char *p; 302 303 DEBUG(7, "insert(%s) ", file); 304 for (i = Nfiles; i>0; i--) { 305 if (strcmp(file, Fptr[i-1]) > 0) 306 break; 307 } 308 if (i == LLEN) /* if this is off the end get out */ 309 return; 310 311 /* get p (pointer) to where the text of name will go */ 312 if (Nfiles == LLEN) /* last possible entry */ 313 /* put in text of last and decrement Nfiles for make hole */ 314 p = strcpy(Fptr[--Nfiles], file); 315 else 316 p = strcpy(Filent[Nfiles], file); /* copy to next free */ 317 318 /* make a hole for new entry */ 319 for (j = Nfiles; j >i; j--) 320 Fptr[j] = Fptr[j-1]; 321 322 DEBUG(7, "insert %s ", p); 323 DEBUG(7, "at %d\n", i); 324 Fptr[i] = p; 325 Nfiles++; 326 return; 327 } 328