1/* rdlocs.c 2 Get the locations of systems in the Taylor UUCP configuration files. 3 4 Copyright (C) 1992, 2002 Ian Lance Taylor 5 6 This file is part of the Taylor UUCP uuconf library. 7 8 This library is free software; you can redistribute it and/or 9 modify it under the terms of the GNU Library General Public License 10 as published by the Free Software Foundation; either version 2 of 11 the License, or (at your option) any later version. 12 13 This library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 Library General Public License for more details. 17 18 You should have received a copy of the GNU Library General Public 19 License along with this library; if not, write to the Free Software 20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucnfi.h" 26 27#if USE_RCS_ID 28const char _uuconf_rdlocs_rcsid[] = "$Id: rdlocs.c,v 1.10 2002/03/05 19:10:42 ian Rel $"; 29#endif 30 31#include <errno.h> 32 33static int itsystem P((pointer pglobal, int argc, char **argv, 34 pointer pvar, pointer pinfo)); 35static int itcalled_login P((pointer pglobal, int argc, char **argv, 36 pointer pvar, pointer pinfo)); 37static int itmyname P((pointer pglobal, int argc, char **argv, 38 pointer pvar, pointer pinfo)); 39 40/* This code scans through the Taylor UUCP system files in order to 41 locate each system and to gather the login restrictions (since this 42 information is held in additional arguments to the "called-login" 43 command, it can appear anywhere in the systems files). It also 44 records whether any "myname" appears, as an optimization for 45 uuconf_taylor_localname. 46 47 This table is used to dispatch the appropriate commands. Most 48 commands are simply ignored. Note that this is a uuconf_cmdtab, 49 not a cmdtab_offset. */ 50 51static const struct uuconf_cmdtab asTcmds[] = 52{ 53 { "system", UUCONF_CMDTABTYPE_FN | 2, NULL, itsystem }, 54 { "alias", UUCONF_CMDTABTYPE_FN | 2, (pointer) asTcmds, itsystem }, 55 { "called-login", UUCONF_CMDTABTYPE_FN | 0, NULL, itcalled_login }, 56 { "myname", UUCONF_CMDTABTYPE_FN | 2, NULL, itmyname }, 57 { NULL, 0, NULL, NULL } 58}; 59 60/* This structure is used to pass information into the command table 61 functions. */ 62 63struct sinfo 64{ 65 /* The sys file name. */ 66 const char *zname; 67 /* The open sys file. */ 68 FILE *e; 69 /* The list of locations we are building. */ 70 struct stsysloc *qlocs; 71 /* The list of validation restrictions we are building. */ 72 struct svalidate *qvals; 73}; 74 75/* Look through the sys files to find the location and names of all 76 the systems. Since we're scanning the sys files, we also record 77 the validation information specified by the additional arguments to 78 the called-login command. We don't use uuconf_cmd_file to avoid 79 the overhead of breaking the line up into arguments if not 80 necessary. */ 81 82int 83_uuconf_iread_locations (qglobal) 84 struct sglobal *qglobal; 85{ 86 char *zline; 87 size_t cline; 88 struct sinfo si; 89 int iret; 90 char **pz; 91 92 if (qglobal->qprocess->fread_syslocs) 93 return UUCONF_SUCCESS; 94 95 zline = NULL; 96 cline = 0; 97 98 si.qlocs = NULL; 99 si.qvals = NULL; 100 101 iret = UUCONF_SUCCESS; 102 103 for (pz = qglobal->qprocess->pzsysfiles; *pz != NULL; pz++) 104 { 105 FILE *e; 106 int cchars; 107 108 qglobal->ilineno = 0; 109 110 e = fopen (*pz, "r"); 111 if (e == NULL) 112 { 113 if (FNO_SUCH_FILE ()) 114 continue; 115 qglobal->ierrno = errno; 116 iret = UUCONF_FOPEN_FAILED | UUCONF_ERROR_ERRNO; 117 break; 118 } 119 120#ifdef CLOSE_ON_EXEC 121 CLOSE_ON_EXEC (e); 122#endif 123 124 si.zname = *pz; 125 si.e = e; 126 127 while ((cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0) 128 { 129 char *zcmd; 130 131 ++qglobal->ilineno; 132 133 zcmd = zline + strspn (zline, " \t"); 134 if (strncasecmp (zcmd, "system", sizeof "system" - 1) == 0 135 || strncasecmp (zcmd, "alias", sizeof "alias" - 1) == 0 136 || strncasecmp (zcmd, "called-login", 137 sizeof "called-login" - 1) == 0 138 || strncasecmp (zcmd, "myname", sizeof "myname" - 1) == 0) 139 { 140 iret = uuconf_cmd_line ((pointer) qglobal, zline, asTcmds, 141 (pointer) &si, (uuconf_cmdtabfn) NULL, 142 0, qglobal->pblock); 143 if ((iret & UUCONF_CMDTABRET_KEEP) != 0) 144 { 145 iret &=~ UUCONF_CMDTABRET_KEEP; 146 zline = NULL; 147 cline = 0; 148 } 149 if (iret != UUCONF_SUCCESS) 150 { 151 iret &=~ UUCONF_CMDTABRET_EXIT; 152 break; 153 } 154 } 155 } 156 157 if (iret != UUCONF_SUCCESS) 158 break; 159 } 160 161 if (zline != NULL) 162 free ((pointer) zline); 163 164 if (iret != UUCONF_SUCCESS) 165 { 166 qglobal->zfilename = *pz; 167 iret |= UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO; 168 if (UUCONF_ERROR_VALUE (iret) != UUCONF_MALLOC_FAILED) 169 qglobal->qprocess->fread_syslocs = TRUE; 170 } 171 else 172 { 173 qglobal->qprocess->qsyslocs = si.qlocs; 174 qglobal->qprocess->qvalidate = si.qvals; 175 qglobal->qprocess->fread_syslocs = TRUE; 176 } 177 178 return iret; 179} 180 181/* Handle a "system" or "alias" command by recording the file and 182 location. If pvar is not NULL, this is an "alias" command. */ 183 184/*ARGSUSED*/ 185static int 186itsystem (pglobal, argc, argv, pvar, pinfo) 187 pointer pglobal; 188 int argc ATTRIBUTE_UNUSED; 189 char **argv; 190 pointer pvar; 191 pointer pinfo; 192{ 193 struct sglobal *qglobal = (struct sglobal *) pglobal; 194 struct sinfo *qinfo = (struct sinfo *) pinfo; 195 struct stsysloc *q; 196 size_t csize; 197 198 q = (struct stsysloc *) uuconf_malloc (qglobal->pblock, 199 sizeof (struct stsysloc)); 200 if (q == NULL) 201 { 202 qglobal->ierrno = errno; 203 return (UUCONF_MALLOC_FAILED 204 | UUCONF_ERROR_ERRNO 205 | UUCONF_CMDTABRET_EXIT); 206 } 207 208 csize = strlen (argv[1]) + 1; 209 q->zname = uuconf_malloc (qglobal->pblock, csize); 210 if (q->zname == NULL) 211 { 212 qglobal->ierrno = errno; 213 return (UUCONF_MALLOC_FAILED 214 | UUCONF_ERROR_ERRNO 215 | UUCONF_CMDTABRET_EXIT); 216 } 217 218 q->qnext = qinfo->qlocs; 219 memcpy ((pointer) q->zname, (pointer) argv[1], csize); 220 q->falias = pvar != NULL; 221 q->zfile = qinfo->zname; 222 q->e = qinfo->e; 223 q->iloc = ftell (qinfo->e); 224 q->ilineno = qglobal->ilineno; 225 226 qinfo->qlocs = q; 227 228 return UUCONF_CMDTABRET_CONTINUE; 229} 230 231/* Handle the "called-login" command. This just records any extra 232 arguments, so that uuconf_validate can check them later if 233 necessary. */ 234 235/*ARGSUSED*/ 236static int 237itcalled_login (pglobal, argc, argv, pvar, pinfo) 238 pointer pglobal; 239 int argc; 240 char **argv; 241 pointer pvar ATTRIBUTE_UNUSED; 242 pointer pinfo; 243{ 244 struct sglobal *qglobal = (struct sglobal *) pglobal; 245 struct sinfo *qinfo = (struct sinfo *) pinfo; 246 register struct svalidate *qval; 247 int i; 248 249 if (argc <= 2) 250 return UUCONF_CMDTABRET_CONTINUE; 251 252 for (qval = qinfo->qvals; qval != NULL; qval = qval->qnext) 253 if (strcmp (argv[1], qval->zlogname) == 0) 254 break; 255 256 if (qval == NULL) 257 { 258 qval = (struct svalidate *) uuconf_malloc (qglobal->pblock, 259 sizeof (struct svalidate)); 260 if (qval == NULL) 261 { 262 qglobal->ierrno = errno; 263 return (UUCONF_MALLOC_FAILED 264 | UUCONF_ERROR_ERRNO 265 | UUCONF_CMDTABRET_EXIT); 266 } 267 268 qval->qnext = qinfo->qvals; 269 qval->zlogname = argv[1]; 270 qval->pzmachines = NULL; 271 272 qinfo->qvals = qval; 273 } 274 275 for (i = 2; i < argc; i++) 276 { 277 int iret; 278 279 iret = _uuconf_iadd_string (qglobal, argv[i], FALSE, TRUE, 280 &qval->pzmachines, qglobal->pblock); 281 if (iret != UUCONF_SUCCESS) 282 return iret | UUCONF_CMDTABRET_EXIT; 283 } 284 285 return UUCONF_CMDTABRET_KEEP; 286} 287 288/* Handle the "myname" command by simply recording that it appears. 289 This information is used by uuconf_taylor_localname. */ 290 291/*ARGSUSED*/ 292static int 293itmyname (pglobal, argc, argv, pvar, pinfo) 294 pointer pglobal; 295 int argc ATTRIBUTE_UNUSED; 296 char **argv ATTRIBUTE_UNUSED; 297 pointer pvar ATTRIBUTE_UNUSED; 298 pointer pinfo ATTRIBUTE_UNUSED; 299{ 300 struct sglobal *qglobal = (struct sglobal *) pglobal; 301 302 qglobal->qprocess->fuses_myname = TRUE; 303 return UUCONF_CMDTABRET_CONTINUE; 304} 305