1/* hinit.c 2 Initialize for reading HDB configuration files. 3 4 Copyright (C) 1992, 1994 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_hinit_rcsid[] = "$Id: hinit.c,v 1.9 2002/03/05 19:10:42 ian Rel $"; 29#endif 30 31#include <errno.h> 32#include <ctype.h> 33 34/* Avoid replicating OLDCONFIGLIB several times if not necessary. */ 35static const char abHoldconfiglib[] = OLDCONFIGLIB; 36 37/* Initialize the routines which read HDB configuration files. */ 38 39int 40uuconf_hdb_init (ppglobal, zprogram) 41 pointer *ppglobal; 42 const char *zprogram; 43{ 44 struct sglobal **pqglobal = (struct sglobal **) ppglobal; 45 int iret; 46 struct sglobal *qglobal; 47 pointer pblock; 48 char abdialcodes[sizeof OLDCONFIGLIB + sizeof HDB_DIALCODES - 1]; 49 char *zsys; 50 FILE *e; 51 52 if (*pqglobal == NULL) 53 { 54 iret = _uuconf_iinit_global (pqglobal); 55 if (iret != UUCONF_SUCCESS) 56 return iret; 57 } 58 59 qglobal = *pqglobal; 60 pblock = qglobal->pblock; 61 62 if (zprogram == NULL 63 || strcmp (zprogram, "uucp") == 0) 64 zprogram = "uucico"; 65 66 /* Add the Dialcodes file to the global list. */ 67 memcpy ((pointer) abdialcodes, (pointer) abHoldconfiglib, 68 sizeof OLDCONFIGLIB - 1); 69 memcpy ((pointer) (abdialcodes + sizeof OLDCONFIGLIB - 1), 70 (pointer) HDB_DIALCODES, sizeof HDB_DIALCODES); 71 iret = _uuconf_iadd_string (qglobal, abdialcodes, TRUE, FALSE, 72 &qglobal->qprocess->pzdialcodefiles, 73 pblock); 74 if (iret != UUCONF_SUCCESS) 75 return iret; 76 77 /* Read the Sysfiles file. We allocate the name on the heap rather 78 than the stack so that we can return it in 79 qerr->uuconf_zfilename. */ 80 81 zsys = uuconf_malloc (pblock, 82 sizeof OLDCONFIGLIB + sizeof HDB_SYSFILES - 1); 83 if (zsys == NULL) 84 { 85 qglobal->ierrno = errno; 86 return UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; 87 } 88 memcpy ((pointer) zsys, (pointer) abHoldconfiglib, sizeof OLDCONFIGLIB - 1); 89 memcpy ((pointer) (zsys + sizeof OLDCONFIGLIB - 1), (pointer) HDB_SYSFILES, 90 sizeof HDB_SYSFILES); 91 92 iret = UUCONF_SUCCESS; 93 94 e = fopen (zsys, "r"); 95 if (e == NULL) 96 uuconf_free (pblock, zsys); 97 else 98 { 99 char *zline; 100 size_t cline; 101 char **pzargs; 102 size_t cargs; 103 char **pzcolon; 104 size_t ccolon; 105 int cchars; 106 107 zline = NULL; 108 cline = 0; 109 pzargs = NULL; 110 cargs = 0; 111 pzcolon = NULL; 112 ccolon = 0; 113 114 qglobal->ilineno = 0; 115 116 while (iret == UUCONF_SUCCESS 117 && (cchars = _uuconf_getline (qglobal, &zline, &cline, e)) > 0) 118 { 119 int ctypes, cnames; 120 int i; 121 122 ++qglobal->ilineno; 123 124 --cchars; 125 if (zline[cchars] == '\n') 126 zline[cchars] = '\0'; 127 if (zline[0] == '#') 128 continue; 129 130 ctypes = _uuconf_istrsplit (zline, '\0', &pzargs, &cargs); 131 if (ctypes < 0) 132 { 133 qglobal->ierrno = errno; 134 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; 135 break; 136 } 137 138 if (ctypes == 0) 139 continue; 140 141 if (strncmp (pzargs[0], "service=", sizeof "service=" - 1) != 0) 142 { 143 iret = UUCONF_SYNTAX_ERROR; 144 break; 145 } 146 pzargs[0] += sizeof "service=" - 1; 147 148 cnames = _uuconf_istrsplit (pzargs[0], ':', &pzcolon, &ccolon); 149 if (cnames < 0) 150 { 151 qglobal->ierrno = errno; 152 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; 153 break; 154 } 155 156 for (i = 0; i < cnames; i++) 157 if (strcmp (zprogram, pzcolon[i]) == 0) 158 break; 159 160 if (i >= cnames) 161 continue; 162 163 for (i = 1; i < ctypes && iret == UUCONF_SUCCESS; i++) 164 { 165 char ***ppz; 166 int cfiles, ifile; 167 168 if (strncmp (pzargs[i], "systems=", sizeof "systems=" - 1) 169 == 0) 170 { 171 ppz = &qglobal->qprocess->pzhdb_systems; 172 pzargs[i] += sizeof "systems=" - 1; 173 } 174 else if (strncmp (pzargs[i], "devices=", sizeof "devices=" - 1) 175 == 0) 176 { 177 ppz = &qglobal->qprocess->pzhdb_devices; 178 pzargs[i] += sizeof "devices=" - 1; 179 } 180 else if (strncmp (pzargs[i], "dialers=", sizeof "dialers=" - 1) 181 == 0) 182 { 183 ppz = &qglobal->qprocess->pzhdb_dialers; 184 pzargs[i] += sizeof "dialers=" - 1; 185 } 186 else 187 { 188 iret = UUCONF_SYNTAX_ERROR; 189 break; 190 } 191 192 cfiles = _uuconf_istrsplit (pzargs[i], ':', &pzcolon, &ccolon); 193 if (cfiles < 0) 194 { 195 qglobal->ierrno = errno; 196 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; 197 break; 198 } 199 200 for (ifile = 0; 201 ifile < cfiles && iret == UUCONF_SUCCESS; 202 ifile++) 203 { 204 /* Looking for a leading '/' is Unix dependent, and 205 should probably be changed. */ 206 if (pzcolon[ifile][0] == '/') 207 iret = _uuconf_iadd_string (qglobal, pzcolon[ifile], TRUE, 208 FALSE, ppz, pblock); 209 else 210 { 211 char *zdir; 212 size_t clen; 213 214 clen = strlen (pzcolon[ifile]); 215 zdir = (char *) uuconf_malloc (pblock, 216 (sizeof OLDCONFIGLIB 217 + sizeof HDB_SEPARATOR 218 + clen 219 - 1)); 220 if (zdir == NULL) 221 { 222 qglobal->ierrno = errno; 223 iret = UUCONF_MALLOC_FAILED | UUCONF_ERROR_ERRNO; 224 break; 225 } 226 memcpy ((pointer) zdir, (pointer) abHoldconfiglib, 227 sizeof OLDCONFIGLIB - 1); 228 memcpy ((pointer) (zdir + sizeof OLDCONFIGLIB - 1), 229 HDB_SEPARATOR, sizeof HDB_SEPARATOR - 1); 230 memcpy ((pointer) (zdir 231 + sizeof OLDCONFIGLIB - 1 232 + sizeof HDB_SEPARATOR - 1), 233 (pointer) pzcolon[ifile], clen + 1); 234 iret = _uuconf_iadd_string (qglobal, zdir, FALSE, FALSE, 235 ppz, pblock); 236 } 237 } 238 } 239 } 240 241 (void) fclose (e); 242 if (zline != NULL) 243 free ((pointer) zline); 244 if (pzargs != NULL) 245 free ((pointer) pzargs); 246 if (pzcolon != NULL) 247 free ((pointer) pzcolon); 248 249 if (iret != UUCONF_SUCCESS) 250 { 251 qglobal->zfilename = zsys; 252 return iret | UUCONF_ERROR_FILENAME | UUCONF_ERROR_LINENO; 253 } 254 } 255 256 if (qglobal->qprocess->pzhdb_systems == NULL) 257 { 258 char ab[sizeof OLDCONFIGLIB + sizeof HDB_SYSTEMS - 1]; 259 260 memcpy ((pointer) ab, (pointer) abHoldconfiglib, 261 sizeof OLDCONFIGLIB - 1); 262 memcpy ((pointer) (ab + sizeof OLDCONFIGLIB - 1), 263 (pointer) HDB_SYSTEMS, sizeof HDB_SYSTEMS); 264 iret = _uuconf_iadd_string (qglobal, ab, TRUE, FALSE, 265 &qglobal->qprocess->pzhdb_systems, 266 pblock); 267 } 268 if (qglobal->qprocess->pzhdb_devices == NULL && iret == UUCONF_SUCCESS) 269 { 270 char ab[sizeof OLDCONFIGLIB + sizeof HDB_DEVICES - 1]; 271 272 memcpy ((pointer) ab, (pointer) abHoldconfiglib, 273 sizeof OLDCONFIGLIB - 1); 274 memcpy ((pointer) (ab + sizeof OLDCONFIGLIB - 1), 275 (pointer) HDB_DEVICES, sizeof HDB_DEVICES); 276 iret = _uuconf_iadd_string (qglobal, ab, TRUE, FALSE, 277 &qglobal->qprocess->pzhdb_devices, 278 pblock); 279 } 280 if (qglobal->qprocess->pzhdb_dialers == NULL && iret == UUCONF_SUCCESS) 281 { 282 char ab[sizeof OLDCONFIGLIB + sizeof HDB_DIALERS - 1]; 283 284 memcpy ((pointer) ab, (pointer) abHoldconfiglib, 285 sizeof OLDCONFIGLIB - 1); 286 memcpy ((pointer) (ab + sizeof OLDCONFIGLIB - 1), 287 (pointer) HDB_DIALERS, sizeof HDB_DIALERS); 288 iret = _uuconf_iadd_string (qglobal, ab, TRUE, FALSE, 289 &qglobal->qprocess->pzhdb_dialers, 290 pblock); 291 } 292 293 return iret; 294} 295