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