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