xref: /original-bsd/usr.bin/uucp/uucico/gnsys.c (revision c3e32dec)
1 /*-
2  * Copyright (c) 1985, 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.proprietary.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)gnsys.c	8.1 (Berkeley) 06/06/93";
10 #endif /* not lint */
11 
12 #include "uucp.h"
13 #ifdef	NDIR
14 #include "ndir.h"
15 #else
16 #include <sys/dir.h>
17 #endif
18 
19 #define LSIZE 512	/* number of systems to store */
20 #define WSUFSIZE 6	/* work file name suffix size */
21 
22 /*LINTLIBRARY*/
23 
24 /*
25  *	this routine will return the next system name which has work to be done.
26  *	"sname" is a string of size DIRSIZ - WSUFSIZE.
27  *	"pre" is the prefix for work files.
28  *	"dir" is the directory to search.
29  *
30  *	return codes:
31  *		1  -  name returned in sname
32  *		SUCCESS  -  no more names
33  *		FAIL  -  bad directory
34  */
35 gnsys(sname, dir, pre)
36 char *sname, *dir, pre;
37 {
38 	register DIR *dirp;
39 	register struct direct *dentp;
40 	static char *list[LSIZE];
41 	static int nitem = 0, n = 0, base = 0;
42 	char systname[NAMESIZE];
43 
44 retry:
45 	if (nitem == base) {
46 		/* get list of systems with work */
47 		int i;
48 		dirp = opendir(subdir(dir,pre));
49 		if (dirp == NULL) {
50 			syslog(LOG_ERR, "opendir(%s) failed: %m",
51 				subdir(dir,pre));
52 			cleanup(FAIL);
53 		}
54 		for (i = base; i < LSIZE; i++)
55 			list[i] = NULL;
56 		while (dentp = readdir(dirp)) {
57 			register char *s, *p1, *p2;
58 			if (dentp->d_name[0] != pre || dentp->d_name[1] != '.')
59 				continue;
60 			p2 = dentp->d_name + dentp->d_namlen - WSUFSIZE;
61 			p1 = dentp->d_name + 2;
62 			for(s = systname; p1 <= p2; p1++)
63 				*s++ = *p1;
64 			*s = '\0';
65 			if (systname[0] == '\0')
66 				continue;
67 			nitem = srchst(systname, list, nitem);
68 			if (LSIZE <= nitem) {
69 				syslog(LOG_WARNING,
70 					"%s: Increase LSIZE in gnsys.c",
71 					systname);
72 				break;
73 			}
74 		}
75 		closedir(dirp);
76 	}
77 
78 	if (nitem == base) {
79 		for (n = 0; n < nitem; n++)
80 			if (list[n] != NULL)
81 				free(list[n]);
82 		return SUCCESS;
83 	}
84 	while (nitem > n) {
85 		/* We only have at most a SYSNSIZE character site name encoded
86 		 * in the file. However, we would like to use the full sitename
87 		 * if possible. If the number of chars in list[n] is < SYSNSIZE
88 		 * then the sitename could not have been truncated and
89 		 * we don't bother to check. Otherwise, we scan SYSFILE
90 		 * looking for the fullname and return it if we find it
91 		 */
92 		strcpy(sname, list[n++]);
93 		if (strlen(sname) >= SYSNSIZE) {
94 			register FILE *fp;
95 			register char *p;
96 			char line[MAXFULLNAME];
97 			fp = fopen(SYSFILE, "r");
98 			if (fp == NULL) {
99 				syslog(LOG_ERR, "fopen(%s) failed: %m",
100 					SYSFILE);
101 				cleanup(FAIL);
102 			}
103 			while (cfgets(line, sizeof(line), fp) != NULL) {
104 				p = strpbrk(line, " \t");
105 				if (p)
106 					*p = '\0';
107 				if (strncmp(sname, line, SYSNSIZE) == SAME) {
108 					strncpy(sname, line, MAXBASENAME);
109 					break;
110 				}
111 			}
112 			fclose(fp);
113 		}
114 		if (callok(sname) == 0)
115 			return 1;
116 	}
117 	base = n = nitem;
118 	goto retry;
119 }
120 
121 /*
122  *	this routine will do a linear search of list (list) to find name (name).
123  *	If the name is not found, it is added to the list.
124  *	The number of items in the list (n) is returned (incremented if a
125  *	name is added).
126  *
127  *	return codes:
128  *		n - the number of items in the list
129  */
130 srchst(name, list, n)
131 char *name;
132 register char **list;
133 int n;
134 {
135 	register int i;
136 	register char *p;
137 
138 	for (i = 0; i < n; i++)
139 		if (strcmp(name, list[i]) == 0)
140 			break;
141 	if (i >= n) {
142 		if ((p = calloc((unsigned)strlen(name) + 1, sizeof (char)))
143 			== NULL)
144 			return n;
145 		strcpy(p, name);
146 		list[n++] = p;
147 	}
148 	return n;
149 }
150