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