xref: /titanic_51/usr/src/cmd/bnu/anlwrk.c (revision 8eea8e29cc4374d1ee24c25a07f45af132db3499)
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