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