1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
  24  */
  25 
  26 /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T     */
  27 /*        All Rights Reserved   */
  28 
  29 #include "uucp.h"
  30 
  31 #include <unistd.h>
  32 #include "sysfiles.h"
  33 #include <sys/stropts.h>
  34 
  35 /*
  36  * manage systems files (Systems, Devices, and Dialcodes families).
  37  *
  38  * also manage new file Devconfig, allows per-device setup.
  39  * present use is to specify what streams modules to push/pop for
  40  * AT&T TLI/streams network.
  41  *
  42  * TODO:
  43  *    call bsfix()?
  44  *    combine the 3 versions of everything (sys, dev, and dial) into one.
  45  *    allow arbitrary classes of service.
  46  *    need verifysys() for uucheck.
  47  *    nameserver interface?
  48  *    pass sysname (or 0) to getsysline().  (might want reg. exp. or NS processing 
  49  */
  50 
  51 /* private variables */
  52 static void tokenize(), nameparse(), setfile(), setioctl(),
  53         scansys(), scancfg(), setconfig();
  54 static int namematch(), nextdialers(), nextdevices(), nextsystems(), getaline();
  55 
  56 /* pointer arrays might be dynamically allocated */
  57 static char *Systems[64] = {0}; /* list of Systems files */
  58 static char *Devices[64] = {0}; /* list of Devices files */
  59 static char *Dialers[64] = {0}; /* list of Dialers files */
  60 static char *Pops[64] = {0};    /* list of STREAMS modules to be popped */
  61 static char *Pushes[64] = {0};  /* list of STREAMS modules to be pushed */
  62 
  63 static int nsystems;            /* index into list of Systems files */
  64 static int ndevices;            /* index into list of Devices files */
  65 static int ndialers;            /* index into list of Dialers files */
  66 static int npops;               /* index into list of STREAMS modules */
  67                                                         /*to be popped */
  68 static int npushes;             /* index into list of STREAMS modules */
  69                                                         /*to be pushed */
  70 
  71 GLOBAL unsigned connecttime = CONNECTTIME;
  72 GLOBAL unsigned expecttime = EXPECTTIME;
  73 GLOBAL unsigned msgtime = MSGTIME;
  74 
  75 static FILE *fsystems;
  76 static FILE *fdevices;
  77 static FILE *fdialers;
  78 
  79 static char errformat[BUFSIZ];
  80 
  81 /* this might be dynamically allocated */
  82 #define NTOKENS 16
  83 static char *tokens[NTOKENS], **tokptr;
  84 
  85 /* export these */
  86 EXTERN void sysreset(), devreset(), dialreset(), setdevcfg(), setservice();
  87 EXTERN char *strsave();
  88 
  89 /* import these */
  90 extern char *strcpy(), *strtok(), *strchr(), *strsave();
  91 EXTERN int eaccess();
  92 
  93 /*
  94  * setservice init's Systems, Devices, Dialers lists from Sysfiles
  95  */
  96 GLOBAL void
  97 setservice(service)
  98 char *service;
  99 {
 100         char    *prev = _uu_setlocale(LC_ALL, "C");
 101 
 102         setconfig();
 103         scansys(service);
 104         (void) _uu_resetlocale(LC_ALL, prev);
 105         return;
 106 }
 107 
 108 /*
 109  * setdevcfg init's Pops, Pushes lists from Devconfig
 110  */
 111 
 112 GLOBAL void
 113 setdevcfg(service, device)
 114 char *service, *device;
 115 {
 116         char    *prev = _uu_setlocale(LC_ALL, "C");
 117 
 118         scancfg(service, device);
 119         (void) _uu_resetlocale(LC_ALL, prev);
 120         return;
 121 }
 122 
 123 /*      administrative files access */
 124 GLOBAL int
 125 sysaccess(type)
 126 int type;
 127 {
 128         switch (type) {
 129 
 130         case ACCESS_SYSTEMS:
 131                 return(access(Systems[nsystems], R_OK));
 132         case ACCESS_DEVICES:
 133                 return(access(Devices[ndevices], R_OK));
 134         case ACCESS_DIALERS:
 135                 return(access(Dialers[ndialers], R_OK));
 136         case EACCESS_SYSTEMS:
 137                 return(eaccess(Systems[nsystems], R_OK));
 138         case EACCESS_DEVICES:
 139                 return(eaccess(Devices[ndevices], R_OK));
 140         case EACCESS_DIALERS:
 141                 return(eaccess(Dialers[ndialers], R_OK));
 142         default:
 143                 (void)sprintf(errformat, "bad access type %d", type);
 144                 logent(errformat, "sysaccess");
 145                 return(FAIL);
 146         }
 147 }
 148 
 149 
 150 /*
 151  * read Sysfiles, set up lists of Systems/Devices/Dialers file names.
 152  * allow multiple entries for a given service, allow a service
 153  * type to describe resources more than once, e.g., systems=foo:baz systems=bar.
 154  */
 155 static void
 156 scansys(service)
 157 char *service;
 158 {       FILE *f;
 159         char *tok, buf[BUFSIZ];
 160 
 161         Systems[0] = Devices[0] = Dialers[0] = NULL;
 162         if ((f = fopen(SYSFILES, "r")) != 0) {
 163                 while (getaline(f, buf) > 0) { 
 164                         /* got a (logical) line from Sysfiles */
 165                         /* strtok's of this buf continue in tokenize() */
 166                         tok = strtok(buf, " \t");
 167                         if (namematch("service=", tok, service)) {
 168                                 tokenize();
 169                                 nameparse();
 170                         }
 171                 }
 172                 (void) fclose(f);
 173         }
 174 
 175         /* if didn't find entries in Sysfiles, use defaults */
 176         if (Systems[0] == NULL) {
 177                 Systems[0] = strsave(SYSTEMS);
 178                 ASSERT(Systems[0] != NULL, Ct_ALLOCATE, "scansys: Systems", 0);
 179                 Systems[1] = NULL;
 180         }
 181         if (Devices[0] == NULL) {
 182                 Devices[0] = strsave(DEVICES);
 183                 ASSERT(Devices[0] != NULL, Ct_ALLOCATE, "scansys: Devices", 0);
 184                 Devices[1] = NULL;
 185         }
 186         if (Dialers[0] == NULL) {
 187                 Dialers[0] = strsave(DIALERS);
 188                 ASSERT(Dialers[0] != NULL, Ct_ALLOCATE, "scansys: Dialers", 0);
 189                 Dialers[1] = NULL;
 190         }
 191         return;
 192 }
 193 
 194 
 195 /*
 196  * read Devconfig.  allow multiple entries for a given service, allow a service
 197  * type to describe resources more than once, e.g., push=foo:baz push=bar.
 198  */
 199 static void
 200 scancfg(service, device)
 201 char *service, *device;
 202 {       FILE *f;
 203         char *tok, buf[BUFSIZ];
 204 
 205         /* (re)initialize device-specific information */
 206 
 207         npops = npushes = 0;
 208         Pops[0] = Pushes[0] = NULL;
 209         connecttime = CONNECTTIME;
 210         expecttime = EXPECTTIME;
 211         msgtime = MSGTIME;
 212 
 213         if ((f = fopen(DEVCONFIG, "r")) != 0) {
 214                 while (getaline(f, buf) > 0) {
 215                         /* got a (logical) line from Devconfig */
 216                         /* strtok's of this buf continue in tokenize() */
 217                         tok = strtok(buf, " \t");
 218                         if (namematch("service=", tok, service)) {
 219                                 tok = strtok((char *)0, " \t");
 220                                 if ( namematch("device=", tok, device)) {
 221                                         tokenize();
 222                                         nameparse();
 223                                 }
 224                         }
 225                 }
 226                 (void) fclose(f);
 227         }
 228 
 229         return;
 230 
 231 }
 232 
 233 /*
 234  *  given a file pointer and buffer, construct logical line in buffer
 235  *  (i.e., concatenate lines ending in '\').  return length of line
 236  *  ASSUMES that buffer is BUFSIZ long!
 237  */
 238 
 239 static int
 240 getaline(f, line)
 241 FILE *f;
 242 char *line;
 243 {       char *lptr, *lend;
 244 
 245         lptr = line;
 246         while (fgets(lptr, (line + BUFSIZ) - lptr, f) != NULL) {
 247                 lend = lptr + strlen(lptr);
 248                 if (lend == lptr || lend[-1] != '\n')   
 249                         /* empty buf or line too long! */
 250                         break;
 251                 *--lend = '\0'; /* lop off ending '\n' */
 252                 if ( lend == line ) /* empty line - ignore */
 253                         continue;
 254                 lptr = lend;
 255                 if (lend[-1] != '\\')
 256                         break;
 257                 /* continuation */
 258                 lend[-1] = ' ';
 259         }
 260         return(lptr - line);
 261 }
 262 
 263 /*
 264  * given a label (e.g., "service=", "device="), a name ("cu", "uucico"),
 265  *  and a line:  if line begins with the label and if the name appears
 266  * in a colon-separated list of names following the label, return true;
 267  * else return false
 268  */
 269 static int
 270 namematch(label, line, name)
 271 char *label, *line, *name;
 272 {       char *lend;
 273 
 274         if (strncmp(label, line, strlen(label)) != SAME) {
 275                 return(FALSE);  /* probably a comment line */
 276         }
 277         line += strlen(label);
 278         if (*line == '\0')
 279                 return(FALSE);
 280         /*
 281          * can't use strtok() in the following because scansys(),
 282          * scancfg() do an initializing call to strtok() before
 283          * coming here and then CONTINUE calling strtok() in tokenize(),
 284          * after returning from namematch().
 285          */
 286         while ((lend = strchr(line, ':')) != NULL) {
 287                 *lend = '\0';
 288                 if (strcmp(line, name) == SAME)
 289                         return(TRUE);
 290                 line = lend+1;
 291         }
 292         return(strcmp(line, name) == SAME);
 293 }
 294 
 295 /*
 296  * tokenize() continues pulling tokens out of a buffer -- the
 297  * initializing call to strtok must have been made before calling
 298  * tokenize() -- and starts stuffing 'em into tokptr.
 299  */
 300 static void
 301 tokenize()
 302 {       char *tok;
 303 
 304         tokptr = tokens;
 305         while ((tok = strtok((char *) NULL, " \t")) != NULL) {
 306                 *tokptr++ = tok;
 307                 if (tokptr - tokens >= NTOKENS)
 308                         break;
 309         }
 310         *tokptr = NULL;
 311         return;
 312 }
 313 
 314 /*
 315  * look at top token in array: should be line of the form
 316  *      name=item1:item2:item3...
 317  * if name is one we recognize, then call set[file|ioctl] to set up 
 318  * corresponding list.  otherwise, log bad name.
 319  */
 320 static void
 321 nameparse()
 322 {       char **line, *equals;
 323         int temp;
 324 
 325 #define setuint(a,b,c) a = ( ((temp = atoi(b)) <= 0) ? (c) : temp )
 326 
 327         for (line = tokens; (line - tokens) < NTOKENS && *line; line++) {
 328                 equals = strchr(*line, '=');
 329                 if (equals == NULL)
 330                         continue;       /* may be meaningful someday? */
 331                 *equals = '\0';
 332                 /* ignore entry with empty rhs */
 333                 if (*++equals == '\0')
 334                         continue;
 335                 if (strcmp(*line, "systems") == SAME)
 336                         setfile(Systems, equals);
 337                 else if (strcmp(*line, "devices") == SAME)
 338                         setfile(Devices, equals);
 339                 else if (strcmp(*line, "dialers") == SAME)
 340                         setfile(Dialers, equals);
 341                 else if (strcmp(*line, "pop") == SAME)
 342                         setioctl(Pops, equals);
 343                 else if (strcmp(*line, "push") == SAME)
 344                         setioctl(Pushes, equals);
 345                 else if (strcmp(*line, "connecttime") == SAME)
 346                         setuint(connecttime, equals, CONNECTTIME);
 347                 else if (strcmp(*line, "expecttime") == SAME)
 348                         setuint(expecttime, equals, EXPECTTIME);
 349                 else if (strcmp(*line, "msgtime") == SAME)
 350                         setuint(msgtime, equals, MSGTIME);
 351                 else {
 352                         (void)sprintf(errformat,"unrecognized label %s",*line);
 353                         logent(errformat, "Sysfiles|Devconfig");
 354                 }
 355         }
 356         return;
 357 }
 358 
 359 /*
 360  * given the list for a particular type (systems, devices,...)
 361  * and a line of colon-separated files, add 'em to list
 362  */
 363 
 364 static void
 365 setfile(type, line)
 366 char **type, *line;
 367 {       char **tptr, *tok;
 368         char expandpath[BUFSIZ];
 369 
 370         if (*line == 0)
 371                 return;
 372         tptr = type;
 373         while (*tptr)           /* skip over existing entries to*/
 374                 tptr++;         /* concatenate multiple entries */
 375 
 376         for (tok = strtok(line, ":"); tok != NULL;
 377         tok = strtok((char *) NULL, ":")) {
 378                 expandpath[0] = '\0';
 379                 if ( *tok != '/' )
 380                         /* by default, file names are relative to SYSDIR */
 381                         sprintf(expandpath, "%s/", SYSDIR);
 382                 strcat(expandpath, tok);
 383                 if (eaccess(expandpath, R_OK) != 0)
 384                         /* if we can't read it, no point in adding to list */
 385                         continue;
 386                 *tptr = strsave(expandpath);
 387                 ASSERT(*tptr != NULL, Ct_ALLOCATE, "setfile: tptr", 0);
 388                 tptr++;
 389         }
 390         return;
 391 }
 392 
 393 /*
 394  * given the list for a particular ioctl (push, pop)
 395  * and a line of colon-separated modules, add 'em to list
 396  */
 397 
 398 static void
 399 setioctl(type, line)
 400 char **type, *line;
 401 {       char **tptr, *tok;
 402 
 403         if (*line == 0)
 404                 return;
 405         tptr = type;
 406         while (*tptr)           /* skip over existing entries to*/
 407                 tptr++;         /* concatenate multiple entries */
 408         for (tok = strtok(line, ":"); tok != NULL;
 409         tok = strtok((char *) NULL, ":")) {
 410                 *tptr = strsave(tok);
 411                 ASSERT(*tptr != NULL, Ct_ALLOCATE, "setioctl: tptr", 0);
 412                 tptr++;
 413         }
 414         return;
 415 }
 416 
 417 /*
 418  * reset Systems files
 419  */
 420 GLOBAL void
 421 sysreset()
 422 {
 423         if (fsystems)
 424                 fclose(fsystems);
 425         fsystems = NULL;
 426         nsystems = 0;
 427         devreset();
 428         return;
 429 }
 430 
 431 /*
 432  * reset Devices files
 433  */
 434 GLOBAL void             
 435 devreset()
 436 {
 437         if (fdevices)
 438                 fclose(fdevices);
 439         fdevices = NULL;
 440         ndevices = 0;
 441         dialreset();
 442         return;
 443 }
 444 
 445 /*
 446  * reset Dialers files
 447  */
 448 GLOBAL void             
 449 dialreset()
 450 {
 451         if (fdialers)
 452                 fclose(fdialers);
 453         fdialers = NULL;
 454         ndialers = 0;
 455         return;
 456 }
 457 
 458 /*
 459  * get next line from Systems file
 460  * return TRUE if successful, FALSE if not
 461  */
 462 GLOBAL int
 463 getsysline(buf, len)
 464 char *buf;
 465 {
 466         char    *prev = _uu_setlocale(LC_ALL, "C");
 467 
 468         if (Systems[0] == NULL)
 469                 /* not initialized via setservice() - use default */
 470                 setservice("uucico");
 471 
 472         /* initialize devices and dialers whenever a new line is read */
 473         /* from systems */
 474         devreset();
 475         if (fsystems == NULL)
 476                 if (nextsystems() == FALSE) {
 477                         (void) _uu_resetlocale(LC_ALL, prev);
 478                         return(FALSE);
 479                 }
 480 
 481         ASSERT(len >= BUFSIZ, "BUFFER TOO SMALL", "getsysline", 0);
 482         for(;;) {
 483                 while (getaline(fsystems, buf) != 0)
 484                     if ((*buf != '#') && (*buf != ' ') &&
 485                         (*buf != '\t') && (*buf != '\n')) {
 486                         (void) _uu_resetlocale(LC_ALL, prev);
 487                         return(TRUE);
 488                 }
 489                 if (nextsystems() == FALSE) {
 490                         (void) _uu_resetlocale(LC_ALL, prev);
 491                         return(FALSE);
 492                 }
 493         }
 494 }
 495 
 496 /*
 497  * move to next systems file.  return TRUE if successful, FALSE if not
 498  */
 499 static int
 500 nextsystems()
 501 {
 502         devreset();
 503 
 504         if (fsystems != NULL) {
 505                 (void) fclose(fsystems);
 506                 nsystems++;
 507         } else {
 508                 nsystems = 0;
 509         }
 510         for ( ; Systems[nsystems] != NULL; nsystems++)
 511                 if ((fsystems = fopen(Systems[nsystems], "r")) != NULL)
 512                         return(TRUE);
 513         return(FALSE);
 514 }
 515                 
 516 /*
 517  * get next line from Devices file
 518  * return TRUE if successful, FALSE if not
 519  */
 520 GLOBAL int
 521 getdevline(buf, len)
 522 char *buf;
 523 {
 524         char    *prev = _uu_setlocale(LC_ALL, "C");
 525 
 526         if (Devices[0] == NULL)
 527                 /* not initialized via setservice() - use default */
 528                 setservice("uucico");
 529 
 530         if (fdevices == NULL)
 531                 if (nextdevices() == FALSE) {
 532                         (void) _uu_resetlocale(LC_ALL, prev);
 533                         return(FALSE);
 534                 }
 535         for(;;) {
 536                 if (fgets(buf, len, fdevices) != NULL) {
 537                         (void) _uu_resetlocale(LC_ALL, prev);
 538                         return(TRUE);
 539                 }
 540                 if (nextdevices() == FALSE) {
 541                         (void) _uu_resetlocale(LC_ALL, prev);
 542                         return(FALSE);
 543                 }
 544         }
 545 }
 546 
 547 /*
 548  * move to next devices file.  return TRUE if successful, FALSE if not
 549  */
 550 static int
 551 nextdevices()
 552 {
 553         if (fdevices != NULL) {
 554                 (void) fclose(fdevices);
 555                 ndevices++;
 556         } else {
 557                 ndevices = 0;
 558         }
 559         for ( ; Devices[ndevices] != NULL; ndevices++)
 560                 if ((fdevices = fopen(Devices[ndevices], "r")) != NULL)
 561                         return(TRUE);
 562         return(FALSE);
 563 }
 564 
 565                 
 566 /*
 567  * get next line from Dialers file
 568  * return TRUE if successful, FALSE if not
 569  */
 570 
 571 GLOBAL int
 572 getdialline(buf, len)
 573 char *buf;
 574 {
 575         char    *prev = _uu_setlocale(LC_ALL, "C");
 576 
 577         if (Dialers[0] == NULL)
 578                 /* not initialized via setservice() - use default */
 579                 setservice("uucico");
 580 
 581         if (fdialers == NULL)
 582                 if (nextdialers() == FALSE) {
 583                         (void) _uu_resetlocale(LC_ALL, prev);
 584                         return(FALSE);
 585                 }
 586         for(;;) {
 587                 if (fgets(buf, len, fdialers) != NULL) {
 588                         (void) _uu_resetlocale(LC_ALL, prev);
 589                         return(TRUE);
 590                 }
 591                 if (nextdialers() == FALSE) {
 592                         (void) _uu_resetlocale(LC_ALL, prev);
 593                         return(FALSE);
 594                 }
 595         }
 596 }
 597 
 598 /*
 599  * move to next dialers file.  return TRUE if successful, FALSE if not
 600  */
 601 static int
 602 nextdialers()
 603 {
 604         if (fdialers) {
 605                 (void) fclose(fdialers);
 606                 ndialers++;
 607         } else {
 608                 ndialers = 0;
 609         }
 610         
 611         for ( ; Dialers[ndialers] != NULL; ndialers++)
 612                 if ((fdialers = fopen(Dialers[ndialers], "r")) != NULL)
 613                         return(TRUE);
 614         return(FALSE);
 615 }
 616 
 617 /*
 618  * get next module to be popped
 619  * return TRUE if successful, FALSE if not
 620  */
 621 static int
 622 getpop(buf, len, optional)
 623 char *buf;
 624 int len, *optional;
 625 {
 626         int slen;
 627 
 628         if ( Pops[0] == NULL || Pops[npops] == NULL )
 629                 return(FALSE);
 630 
 631         /*      if the module name is enclosed in parentheses,  */
 632         /*      is optional. set flag & strip parens                */
 633         slen = strlen(Pops[npops]) - 1;
 634         if ( Pops[npops][0] == '('  && Pops[npops][slen] == ')' ) {
 635                 *optional = 1;
 636                 len = ( slen < len ? slen : len );
 637                 strncpy(buf, &(Pops[npops++][1]), len);
 638         } else {
 639                 *optional = 0;
 640                 strncpy(buf, Pops[npops++], len);
 641         }
 642         buf[len-1] = '\0';
 643         return(TRUE);
 644 }
 645 
 646 /*
 647  * get next module to be pushed
 648  * return TRUE if successful, FALSE if not
 649  */
 650 static int
 651 getpush(buf, len)
 652 char *buf;
 653 int len;
 654 {
 655         if ( Pushes[0] == NULL || Pushes[npushes] == NULL )
 656                 return(FALSE);
 657         strncpy(buf, Pushes[npushes++], len);
 658         return(TRUE);
 659 }
 660 
 661 /*
 662  * pop/push requested modules
 663  * return TRUE if successful, FALSE if not
 664  */
 665 GLOBAL int
 666 pop_push(fd)
 667 int fd;
 668 {
 669     char        strmod[FMNAMESZ], onstream[FMNAMESZ];
 670     int         optional;
 671     char        *prev = _uu_setlocale(LC_ALL, "C");
 672 
 673     /*  check for streams modules to pop        */
 674     while ( getpop(strmod, sizeof(strmod), &optional) ) {
 675         DEBUG(5, (optional ? "pop_push: optionally POPing %s\n"
 676                            : "pop_push: POPing %s\n" ), strmod);
 677         if ( ioctl(fd, I_LOOK, onstream) == -1 ) {
 678             DEBUG(5, "pop_push: I_LOOK on fd %d failed ", fd);
 679             DEBUG(5, "errno %d\n", errno);
 680             (void) _uu_resetlocale(LC_ALL, prev);
 681             return(FALSE);
 682         }
 683         if ( strcmp(strmod, onstream) != SAME ) {
 684             if ( optional )
 685                 continue;
 686             DEBUG(5, "pop_push: I_POP: %s not there\n", strmod);
 687             (void) _uu_resetlocale(LC_ALL, prev);
 688             return(FALSE);
 689         }
 690         if ( ioctl(fd, I_POP, 0) == -1 ) {
 691             DEBUG(5, "pop_push: I_POP on fd %d failed ", fd);
 692             DEBUG(5, "errno %d\n", errno);
 693             (void) _uu_resetlocale(LC_ALL, prev);
 694             return(FALSE);
 695         }
 696     }
 697 
 698     /*  check for streams modules to push       */
 699     while ( getpush(strmod, sizeof(strmod)) ) {
 700         DEBUG(5, "pop_push: PUSHing %s\n", strmod);
 701         if ( ioctl(fd, I_PUSH, strmod) == -1 ) {
 702             DEBUG(5, "pop_push: I_PUSH on fd %d failed ", fd);
 703             DEBUG(5, "errno %d\n", errno);
 704             (void) _uu_resetlocale(LC_ALL, prev);
 705             return(FALSE);
 706         }
 707     }
 708     (void) _uu_resetlocale(LC_ALL, prev);
 709     return(TRUE);
 710 }
 711 
 712 /*
 713  *      return name of currently open Systems file
 714  */
 715 GLOBAL char *
 716 currsys()
 717 {
 718         return(Systems[nsystems]);
 719 }
 720 
 721 /*
 722  *      return name of currently open Devices file
 723  */
 724 GLOBAL char *
 725 currdev()
 726 {
 727         return(Devices[ndevices]);
 728 }
 729 
 730 /*
 731  *      return name of currently open Dialers file
 732  */
 733 GLOBAL char *
 734 currdial()
 735 {
 736         return(Dialers[ndialers]);
 737 }
 738 
 739 /*
 740  * set configuration parameters provided in Config file
 741  */
 742 static void
 743 setconfig()
 744 {
 745     FILE *f;
 746     char buf[BUFSIZ];
 747     char *tok;
 748     extern char _ProtoCfg[];
 749 
 750     if ((f = fopen(CONFIG, "r")) != 0) {
 751         while (getaline(f, buf) > 0) { 
 752             /* got a (logical) line from Config file */
 753             tok = strtok(buf, " \t");
 754             if ( (tok != NULL) && (*tok != '#') ) {
 755                 /* got a token */
 756 
 757                 /* this probably should be table driven when
 758                  * the list of configurable parameters grows.
 759                  */
 760                 if (strncmp("Protocol=", tok, strlen("Protocol=")) == SAME) {
 761                     tok += strlen("Protocol=");
 762                     if ( *tok != '\0' ) {
 763                         if ( _ProtoCfg[0] != '\0' ) {
 764                             DEBUG(7, "Protocol string %s ", tok);
 765                             DEBUG(7, "overrides %s\n", _ProtoCfg);
 766                         }
 767                         strcpy(_ProtoCfg, tok);
 768                     }
 769                 } else {
 770                     DEBUG(7, "Unknown configuration parameter %s\n", tok);
 771                 }
 772             }
 773         }
 774     }
 775 }