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 */
gnsys(sname,dir,pre)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 */
srchst(name,list,n)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