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