17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
22113f4232Sakaplan
23113f4232Sakaplan /*
24113f4232Sakaplan * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25113f4232Sakaplan * Use is subject to license terms.
26113f4232Sakaplan */
27113f4232Sakaplan
287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
297c478bd9Sstevel@tonic-gate /* All Rights Reserved */
307c478bd9Sstevel@tonic-gate
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate /*
337c478bd9Sstevel@tonic-gate * data base routines for the network listener process
347c478bd9Sstevel@tonic-gate */
357c478bd9Sstevel@tonic-gate
367c478bd9Sstevel@tonic-gate /* system include files */
377c478bd9Sstevel@tonic-gate
387c478bd9Sstevel@tonic-gate #include <fcntl.h>
397c478bd9Sstevel@tonic-gate #include <stdio.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <ctype.h>
427c478bd9Sstevel@tonic-gate #include <sys/param.h>
437c478bd9Sstevel@tonic-gate #include <sys/types.h>
447c478bd9Sstevel@tonic-gate #include <sys/tiuser.h>
457c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
467c478bd9Sstevel@tonic-gate
477c478bd9Sstevel@tonic-gate /* listener include files */
487c478bd9Sstevel@tonic-gate
497c478bd9Sstevel@tonic-gate #include "lsparam.h" /* listener parameters */
507c478bd9Sstevel@tonic-gate #include "listen.h" /* listener includes */
517c478bd9Sstevel@tonic-gate #include "lsfiles.h" /* listener files info */
527c478bd9Sstevel@tonic-gate #include "lserror.h" /* listener error codes */
537c478bd9Sstevel@tonic-gate #include "lsdbf.h" /* data base file stuff */
547c478bd9Sstevel@tonic-gate /* #include "nsaddr.h" nls includes */
557c478bd9Sstevel@tonic-gate
567c478bd9Sstevel@tonic-gate #define SUPPRESS 1 /* suppress messages during scan*/
577c478bd9Sstevel@tonic-gate #define NOSUPPRESS 0 /* don't suppress messages */
587c478bd9Sstevel@tonic-gate
597c478bd9Sstevel@tonic-gate /* static data */
607c478bd9Sstevel@tonic-gate
617c478bd9Sstevel@tonic-gate static char *dbfopenmsg = "Trouble opening data base file";
627c478bd9Sstevel@tonic-gate static char *dbfrderror = "Error reading data base file: line %d";
637c478bd9Sstevel@tonic-gate static char *dbfbadlmsg = "Data base file: Error on line %d";
647c478bd9Sstevel@tonic-gate static char *dbfdupcmsg = "Data base file: Duplicate service code: <%s>";
657c478bd9Sstevel@tonic-gate static char *dbfunknown = "Unknown error reading data base file: line %d";
667c478bd9Sstevel@tonic-gate static char *dbfsvccmsg = "Data base file: Illegal service code: <%s>";
677c478bd9Sstevel@tonic-gate static char *dbfcorrupt = "Data base file has been corrupted";
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate static int Dbflineno; /* current line number in dbf */
707c478bd9Sstevel@tonic-gate static unsigned Dbfentries; /* number of non-comment lines */
717c478bd9Sstevel@tonic-gate extern char *Server_cmd_lines; /* contains svc_code, cmd_line, mod_list */
727c478bd9Sstevel@tonic-gate extern char *New_cmd_lines; /* svc_code, cmd_line, mod_list (on reread)*/
737c478bd9Sstevel@tonic-gate
747c478bd9Sstevel@tonic-gate /* public variables */
757c478bd9Sstevel@tonic-gate
767c478bd9Sstevel@tonic-gate
777c478bd9Sstevel@tonic-gate /*
787c478bd9Sstevel@tonic-gate * read_dbf:
797c478bd9Sstevel@tonic-gate *
807c478bd9Sstevel@tonic-gate * read the data base file into internal structures
817c478bd9Sstevel@tonic-gate *
827c478bd9Sstevel@tonic-gate * all data base routines under read_dbf log there own errors and return -1
837c478bd9Sstevel@tonic-gate * in case of an error.
847c478bd9Sstevel@tonic-gate *
85*55fea89dSDan Cross * if 're_read' is non-zero, this stuff is being called to read a new
867c478bd9Sstevel@tonic-gate * data base file after the listener's initialization.
877c478bd9Sstevel@tonic-gate */
887c478bd9Sstevel@tonic-gate
89113f4232Sakaplan int
read_dbf(re_read)907c478bd9Sstevel@tonic-gate read_dbf(re_read)
917c478bd9Sstevel@tonic-gate int re_read; /* zero means first time */
927c478bd9Sstevel@tonic-gate {
937c478bd9Sstevel@tonic-gate register unsigned size;
947c478bd9Sstevel@tonic-gate int exit_flag = EXIT | NOCORE;
957c478bd9Sstevel@tonic-gate register dbf_t *dbf_p;
967c478bd9Sstevel@tonic-gate register char *cmd_p;
977c478bd9Sstevel@tonic-gate unsigned scan_dbf();
987c478bd9Sstevel@tonic-gate extern dbf_t *Dbfhead; /* Dbfentries (when allocated) */
997c478bd9Sstevel@tonic-gate extern dbf_t *Newdbf; /* Dbfentries (on re-read) */
1007c478bd9Sstevel@tonic-gate extern char *calloc();
1017c478bd9Sstevel@tonic-gate
1027c478bd9Sstevel@tonic-gate DEBUG((9,"in read_dbf"));
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate if (check_version())
1057c478bd9Sstevel@tonic-gate error(E_BADVER, EXIT | NOCORE);
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate if (re_read) { /* not first time */
1087c478bd9Sstevel@tonic-gate exit_flag = CONTINUE;
1097c478bd9Sstevel@tonic-gate }
1107c478bd9Sstevel@tonic-gate
1117c478bd9Sstevel@tonic-gate /*
1127c478bd9Sstevel@tonic-gate * note: data base routines log their own error messages
1137c478bd9Sstevel@tonic-gate */
1147c478bd9Sstevel@tonic-gate
1157c478bd9Sstevel@tonic-gate Dbfentries = 0;
1167c478bd9Sstevel@tonic-gate DEBUG((9,"read_dbf: open file here: %s", DBFNAME));
1177c478bd9Sstevel@tonic-gate if ( (size = scan_dbf(DBFNAME)) == (unsigned)(-1) )
1187c478bd9Sstevel@tonic-gate error( E_SCAN_DBF, exit_flag | NO_MSG );
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate DEBUG((5,"read_dbf: scan complete: non-commented lines: %u, size: %u",
1217c478bd9Sstevel@tonic-gate Dbfentries, size));
1227c478bd9Sstevel@tonic-gate
1237c478bd9Sstevel@tonic-gate if (!size) {
1247c478bd9Sstevel@tonic-gate logmessage("No database? 0 entries?");
1257c478bd9Sstevel@tonic-gate return(0);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate /*
1297c478bd9Sstevel@tonic-gate * allocate enough space for Dbfentries of 'size' bytes (total)
1307c478bd9Sstevel@tonic-gate * The +1 is to insure a NULL last entry!
1317c478bd9Sstevel@tonic-gate */
1327c478bd9Sstevel@tonic-gate
1337c478bd9Sstevel@tonic-gate if (!(dbf_p = (dbf_t *)calloc(Dbfentries+1,sizeof(dbf_t)))
1347c478bd9Sstevel@tonic-gate || !(cmd_p = calloc(size, 1))) {
1357c478bd9Sstevel@tonic-gate DEBUG((1,"cannot calloc %u + %u bytes", size,
1367c478bd9Sstevel@tonic-gate (Dbfentries+1)*(unsigned)sizeof(dbf_t)));
137*55fea89dSDan Cross error( E_DBF_ALLOC, exit_flag); /* if init, exit */
1387c478bd9Sstevel@tonic-gate
139*55fea89dSDan Cross /* if still here, this is a re-read */
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate if (dbf_p)
1427c478bd9Sstevel@tonic-gate free(dbf_p);
1437c478bd9Sstevel@tonic-gate if (cmd_p)
1447c478bd9Sstevel@tonic-gate free(cmd_p);
1457c478bd9Sstevel@tonic-gate return(-1);
1467c478bd9Sstevel@tonic-gate }
1477c478bd9Sstevel@tonic-gate
1487c478bd9Sstevel@tonic-gate if (get_dbf(dbf_p, cmd_p)) {
1497c478bd9Sstevel@tonic-gate DEBUG((9, "get_dbf FAILED"));
1507c478bd9Sstevel@tonic-gate error(E_DBF_IO, exit_flag | NO_MSG);
1517c478bd9Sstevel@tonic-gate
1527c478bd9Sstevel@tonic-gate /* if still here, this is a re_read */
153*55fea89dSDan Cross free(dbf_p);
154*55fea89dSDan Cross free(cmd_p);
1557c478bd9Sstevel@tonic-gate return(-1);
1567c478bd9Sstevel@tonic-gate }
1577c478bd9Sstevel@tonic-gate
1587c478bd9Sstevel@tonic-gate if (re_read) {
1597c478bd9Sstevel@tonic-gate Newdbf = dbf_p;
1607c478bd9Sstevel@tonic-gate New_cmd_lines = cmd_p;
1617c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
1627c478bd9Sstevel@tonic-gate DEBUG((7,"read_dbf: NEW data base dump..."));
1637c478bd9Sstevel@tonic-gate if (Newdbf)
1647c478bd9Sstevel@tonic-gate for (dbf_p = Newdbf; dbf_p->dbf_svc_code; ++dbf_p)
1657c478bd9Sstevel@tonic-gate DEBUG((7, "svc code <%s>; id: %s; private address: %s; modules: %s; cmd line: %s; sflags: %x, prognum: %d version: %d",
1667c478bd9Sstevel@tonic-gate dbf_p->dbf_svc_code, dbf_p->dbf_id, dbf_p->dbf_prv_adr, dbf_p->dbf_modules, dbf_p->dbf_cmd_line, dbf_p->dbf_sflags, dbf_p->dbf_prognum, dbf_p->dbf_version));
1677c478bd9Sstevel@tonic-gate #endif /* DEBUGMODE */
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate else {
1707c478bd9Sstevel@tonic-gate Dbfhead = dbf_p;
1717c478bd9Sstevel@tonic-gate Server_cmd_lines = cmd_p;
1727c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
1737c478bd9Sstevel@tonic-gate DEBUG((7,"read_dbf: data base dump..."));
1747c478bd9Sstevel@tonic-gate if (Dbfhead)
1757c478bd9Sstevel@tonic-gate for (dbf_p = Dbfhead; dbf_p->dbf_svc_code; ++dbf_p)
1767c478bd9Sstevel@tonic-gate DEBUG((7, "svc code <%s>; id: %s; r1: %s; r2: %s; r3: %s; private address: %s; modules: %s; cmd line: %s; sflags: %x, prognum: %d version: %d",
1777c478bd9Sstevel@tonic-gate dbf_p->dbf_svc_code, dbf_p->dbf_id, dbf_p->dbf_res1, dbf_p->dbf_res2, dbf_p->dbf_res3, dbf_p->dbf_prv_adr, dbf_p->dbf_modules, dbf_p->dbf_cmd_line, dbf_p->dbf_sflags, dbf_p->dbf_prognum, dbf_p->dbf_version));
1787c478bd9Sstevel@tonic-gate #endif /* DEBUGMODE */
1797c478bd9Sstevel@tonic-gate }
1807c478bd9Sstevel@tonic-gate
1817c478bd9Sstevel@tonic-gate return(0);
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate
1847c478bd9Sstevel@tonic-gate
1857c478bd9Sstevel@tonic-gate /*
1867c478bd9Sstevel@tonic-gate * get_dbf: read the file and fill the structures
1877c478bd9Sstevel@tonic-gate * checking for duplicate entries as we go
1887c478bd9Sstevel@tonic-gate */
1897c478bd9Sstevel@tonic-gate
190113f4232Sakaplan int
get_dbf(dbf_p,cmd_p)1917c478bd9Sstevel@tonic-gate get_dbf(dbf_p, cmd_p)
1927c478bd9Sstevel@tonic-gate register dbf_t *dbf_p;
1937c478bd9Sstevel@tonic-gate register char *cmd_p;
1947c478bd9Sstevel@tonic-gate {
1957c478bd9Sstevel@tonic-gate dbf_t *dbfhead = dbf_p;
1967c478bd9Sstevel@tonic-gate register int n, i;
1977c478bd9Sstevel@tonic-gate char buf[DBFLINESZ];
1987c478bd9Sstevel@tonic-gate register char *p = buf;
1997c478bd9Sstevel@tonic-gate char scratch[128];
2007c478bd9Sstevel@tonic-gate FILE *dbfilep;
2017c478bd9Sstevel@tonic-gate char *cmd_line_p;
2027c478bd9Sstevel@tonic-gate int flags;
2037c478bd9Sstevel@tonic-gate char *svc_code_p;
2047c478bd9Sstevel@tonic-gate char *id_p;
2057c478bd9Sstevel@tonic-gate char *res1_p;
2067c478bd9Sstevel@tonic-gate char *res2_p;
2077c478bd9Sstevel@tonic-gate char *res3_p;
2087c478bd9Sstevel@tonic-gate char *private_p;
2097c478bd9Sstevel@tonic-gate int sflags;
2107c478bd9Sstevel@tonic-gate int prognum;
2117c478bd9Sstevel@tonic-gate int vernum;
2127c478bd9Sstevel@tonic-gate char *module_p;
2137c478bd9Sstevel@tonic-gate register dbf_t *tdbf_p;
2147c478bd9Sstevel@tonic-gate extern int atoi();
2157c478bd9Sstevel@tonic-gate extern int Dbf_entries;
2167c478bd9Sstevel@tonic-gate extern int NLPS_proc;
2177c478bd9Sstevel@tonic-gate extern int errno;
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate Dbflineno = 0;
2207c478bd9Sstevel@tonic-gate Dbf_entries = 0; /* number of private addresses in dbf file */
2217c478bd9Sstevel@tonic-gate
2227c478bd9Sstevel@tonic-gate DEBUG((9,"in get_dbf: "));
2237c478bd9Sstevel@tonic-gate if (!(dbfilep = fopen(DBFNAME,"r"))) {
2247c478bd9Sstevel@tonic-gate logmessage(dbfopenmsg);
2257c478bd9Sstevel@tonic-gate error(E_DBF_IO, EXIT | NOCORE | NO_MSG);
2267c478bd9Sstevel@tonic-gate }
2277c478bd9Sstevel@tonic-gate
2287c478bd9Sstevel@tonic-gate while (n = rd_dbf_line(dbfilep,p,&svc_code_p,&flags,&id_p,&res1_p,&res2_p,&res3_p,&private_p,&prognum,&vernum,&module_p,&sflags,&cmd_line_p,NOSUPPRESS)) {
2297c478bd9Sstevel@tonic-gate
2307c478bd9Sstevel@tonic-gate if (n == -1) { /* read error */
2317c478bd9Sstevel@tonic-gate fclose(dbfilep);
2327c478bd9Sstevel@tonic-gate return(-1);
2337c478bd9Sstevel@tonic-gate }
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate /* make sure service code is legal */
2367c478bd9Sstevel@tonic-gate
2377c478bd9Sstevel@tonic-gate i = strlen(svc_code_p);
2387c478bd9Sstevel@tonic-gate if ( (i == 0) || (i >= SVC_CODE_SZ) )
2397c478bd9Sstevel@tonic-gate goto reject;
2407c478bd9Sstevel@tonic-gate
2417c478bd9Sstevel@tonic-gate /* check for duplicate service code */
2427c478bd9Sstevel@tonic-gate tdbf_p = dbfhead;
2437c478bd9Sstevel@tonic-gate while (tdbf_p->dbf_svc_code) { /* duplicate svc code? */
2447c478bd9Sstevel@tonic-gate if (!strcmp(svc_code_p, tdbf_p->dbf_svc_code)) {
2457c478bd9Sstevel@tonic-gate sprintf(scratch, dbfdupcmsg, svc_code_p);
2467c478bd9Sstevel@tonic-gate logmessage(scratch);
2477c478bd9Sstevel@tonic-gate return(-1);
2487c478bd9Sstevel@tonic-gate }
2497c478bd9Sstevel@tonic-gate ++tdbf_p;
2507c478bd9Sstevel@tonic-gate }
2517c478bd9Sstevel@tonic-gate
2527c478bd9Sstevel@tonic-gate /* NLPS_proc is set by the nlps_server, which also uses these
2537c478bd9Sstevel@tonic-gate * routines. The actual listener child shouldn't ever need
2547c478bd9Sstevel@tonic-gate * to read a database, so it will never be here
2557c478bd9Sstevel@tonic-gate */
2567c478bd9Sstevel@tonic-gate if (!NLPS_proc && (strlen(private_p) == 0) && !(sflags & DFLAG))
2577c478bd9Sstevel@tonic-gate continue; /* ignore entries with no address */
2587c478bd9Sstevel@tonic-gate
2597c478bd9Sstevel@tonic-gate /*
2607c478bd9Sstevel@tonic-gate * child doesn't care about private addresses
2617c478bd9Sstevel@tonic-gate */
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate if (!NLPS_proc) {
2647c478bd9Sstevel@tonic-gate i = strlen(private_p);
2657c478bd9Sstevel@tonic-gate if (i >= PRV_ADR_SZ) {
2667c478bd9Sstevel@tonic-gate goto p_reject;
267*55fea89dSDan Cross }
2687c478bd9Sstevel@tonic-gate Dbf_entries++;
269*55fea89dSDan Cross }
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate /*
2727c478bd9Sstevel@tonic-gate * legal, non-duplicate entry: copy it into internal data base
2737c478bd9Sstevel@tonic-gate */
2747c478bd9Sstevel@tonic-gate
2757c478bd9Sstevel@tonic-gate dbf_p->dbf_fd = -1; /* set to actual fd in add_prvaddr */
2767c478bd9Sstevel@tonic-gate dbf_p->dbf_flags = flags;
2777c478bd9Sstevel@tonic-gate dbf_p->dbf_sflags = sflags;
2787c478bd9Sstevel@tonic-gate dbf_p->dbf_prognum = prognum;
2797c478bd9Sstevel@tonic-gate dbf_p->dbf_version = vernum;
2807c478bd9Sstevel@tonic-gate strcpy(cmd_p, svc_code_p);
2817c478bd9Sstevel@tonic-gate dbf_p->dbf_svc_code = cmd_p;
2827c478bd9Sstevel@tonic-gate cmd_p += strlen(svc_code_p) + 1; /* +1 for null */
2837c478bd9Sstevel@tonic-gate strcpy(cmd_p, cmd_line_p);
2847c478bd9Sstevel@tonic-gate dbf_p->dbf_cmd_line = cmd_p;
2857c478bd9Sstevel@tonic-gate cmd_p += strlen(cmd_line_p) + 1;
2867c478bd9Sstevel@tonic-gate strcpy(cmd_p, id_p);
2877c478bd9Sstevel@tonic-gate dbf_p->dbf_id = cmd_p;
2887c478bd9Sstevel@tonic-gate cmd_p += strlen(id_p) + 1;
2897c478bd9Sstevel@tonic-gate strcpy(cmd_p, res1_p);
2907c478bd9Sstevel@tonic-gate dbf_p->dbf_res1 = cmd_p;
2917c478bd9Sstevel@tonic-gate cmd_p += strlen(res1_p) + 1;
2927c478bd9Sstevel@tonic-gate strcpy(cmd_p, res2_p);
2937c478bd9Sstevel@tonic-gate dbf_p->dbf_res2 = cmd_p;
2947c478bd9Sstevel@tonic-gate cmd_p += strlen(res2_p) + 1;
2957c478bd9Sstevel@tonic-gate strcpy(cmd_p, res3_p);
2967c478bd9Sstevel@tonic-gate dbf_p->dbf_res3 = cmd_p;
2977c478bd9Sstevel@tonic-gate cmd_p += strlen(res3_p) + 1;
2987c478bd9Sstevel@tonic-gate if (strlen(private_p) != 0) {
2997c478bd9Sstevel@tonic-gate strcpy(cmd_p, private_p);
3007c478bd9Sstevel@tonic-gate dbf_p->dbf_prv_adr = cmd_p;
301*55fea89dSDan Cross cmd_p += strlen(private_p) + 1;
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate else
3047c478bd9Sstevel@tonic-gate dbf_p->dbf_prv_adr = NULL;
3057c478bd9Sstevel@tonic-gate strcpy(cmd_p, module_p);
3067c478bd9Sstevel@tonic-gate dbf_p->dbf_modules = cmd_p;
3077c478bd9Sstevel@tonic-gate cmd_p += strlen(module_p) + 1; /* cmd line + null char */
3087c478bd9Sstevel@tonic-gate ++dbf_p;
3097c478bd9Sstevel@tonic-gate }
3107c478bd9Sstevel@tonic-gate
3117c478bd9Sstevel@tonic-gate fclose(dbfilep);
3127c478bd9Sstevel@tonic-gate return(0);
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate reject:
3157c478bd9Sstevel@tonic-gate DEBUG((9, "svc_code <%s> failed validation test", svc_code_p));
3167c478bd9Sstevel@tonic-gate sprintf(scratch, dbfsvccmsg, svc_code_p);
3177c478bd9Sstevel@tonic-gate logmessage(scratch);
3187c478bd9Sstevel@tonic-gate return(-1);
3197c478bd9Sstevel@tonic-gate p_reject:
3207c478bd9Sstevel@tonic-gate DEBUG((9,"private address <%s> failed validation test", private_p));
3217c478bd9Sstevel@tonic-gate sprintf(scratch, "Invalid private address ignored: \\x%x", private_p);
3227c478bd9Sstevel@tonic-gate logmessage(scratch);
3237c478bd9Sstevel@tonic-gate return(-1);
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate
3277c478bd9Sstevel@tonic-gate /*
3287c478bd9Sstevel@tonic-gate * scan_dbf: Take a quick pass through the data base file to figure out
329*55fea89dSDan Cross * approx. how many items in the file we'll need to
3307c478bd9Sstevel@tonic-gate * allocate storage for. Essentially, returns the number
3317c478bd9Sstevel@tonic-gate * of non-null, non-comment lines in the data base file.
3327c478bd9Sstevel@tonic-gate *
3337c478bd9Sstevel@tonic-gate * return: -1 == error.
3347c478bd9Sstevel@tonic-gate * other == number of non-comment characters.
3357c478bd9Sstevel@tonic-gate * Dbfentries set.
3367c478bd9Sstevel@tonic-gate */
3377c478bd9Sstevel@tonic-gate
3387c478bd9Sstevel@tonic-gate unsigned
scan_dbf(path)3397c478bd9Sstevel@tonic-gate scan_dbf(path)
3407c478bd9Sstevel@tonic-gate register char *path;
3417c478bd9Sstevel@tonic-gate {
3427c478bd9Sstevel@tonic-gate register unsigned int size = 0;
3437c478bd9Sstevel@tonic-gate register int n;
3447c478bd9Sstevel@tonic-gate register FILE *dbfilep;
3457c478bd9Sstevel@tonic-gate char buf[DBFLINESZ];
3467c478bd9Sstevel@tonic-gate register char *p = buf;
3477c478bd9Sstevel@tonic-gate char *svc_code_p;
3487c478bd9Sstevel@tonic-gate int flags;
3497c478bd9Sstevel@tonic-gate char *cmd_line_p;
3507c478bd9Sstevel@tonic-gate char *module_p;
3517c478bd9Sstevel@tonic-gate char *id_p;
3527c478bd9Sstevel@tonic-gate char *res1_p;
3537c478bd9Sstevel@tonic-gate char *res2_p;
3547c478bd9Sstevel@tonic-gate char *res3_p;
3557c478bd9Sstevel@tonic-gate int sflags;
3567c478bd9Sstevel@tonic-gate int prognum;
3577c478bd9Sstevel@tonic-gate int vernum;
3587c478bd9Sstevel@tonic-gate char *private_p;
3597c478bd9Sstevel@tonic-gate extern int errno;
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate DEBUG((9, "In scan_dbf. Scanning data base file %s.", path));
3627c478bd9Sstevel@tonic-gate
3637c478bd9Sstevel@tonic-gate if (!(dbfilep = fopen(path,"r"))) {
3647c478bd9Sstevel@tonic-gate DEBUG((9,"errorno = %d", errno));
3657c478bd9Sstevel@tonic-gate logmessage(dbfopenmsg);
3667c478bd9Sstevel@tonic-gate return(-1);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate do {
3707c478bd9Sstevel@tonic-gate n = rd_dbf_line(dbfilep,p,&svc_code_p,&flags,&id_p,&res1_p,&res2_p,&res3_p,&private_p,&prognum,&vernum,&module_p,&sflags,&cmd_line_p,SUPPRESS);
3717c478bd9Sstevel@tonic-gate if (n == -1) {
3727c478bd9Sstevel@tonic-gate fclose(dbfilep);
3737c478bd9Sstevel@tonic-gate return(-1);
3747c478bd9Sstevel@tonic-gate }
3757c478bd9Sstevel@tonic-gate size += (unsigned)n;
3767c478bd9Sstevel@tonic-gate if (n)
3777c478bd9Sstevel@tonic-gate ++Dbfentries;
3787c478bd9Sstevel@tonic-gate } while (n);
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate fclose(dbfilep);
3817c478bd9Sstevel@tonic-gate return(size);
3827c478bd9Sstevel@tonic-gate }
3837c478bd9Sstevel@tonic-gate
3847c478bd9Sstevel@tonic-gate
3857c478bd9Sstevel@tonic-gate /*
3867c478bd9Sstevel@tonic-gate * rd_dbf_line: Returns the next non-comment line into the
3877c478bd9Sstevel@tonic-gate * given buffer (up to DBFLINESZ bytes).
3887c478bd9Sstevel@tonic-gate * Skips 'ignore' lines.
3897c478bd9Sstevel@tonic-gate *
390*55fea89dSDan Cross * Returns: 0 = done, -1 = error,
3917c478bd9Sstevel@tonic-gate * other = cmd line size incl. terminating null.
3927c478bd9Sstevel@tonic-gate * *svc_code_p = service code;
3937c478bd9Sstevel@tonic-gate * *id_p = user id string;
3947c478bd9Sstevel@tonic-gate * *res1_p = reserved string;
3957c478bd9Sstevel@tonic-gate * *res2_p = reserved string;
3967c478bd9Sstevel@tonic-gate * *res3_p = reserved string;
3977c478bd9Sstevel@tonic-gate * *private_p = contains private address;
3987c478bd9Sstevel@tonic-gate * *flags_p = decoded flags;
3997c478bd9Sstevel@tonic-gate * prognum = RPC program #;
4007c478bd9Sstevel@tonic-gate * vernum = RPC version $;
4017c478bd9Sstevel@tonic-gate * cnd_line_p points to null terminated cmd line;
4027c478bd9Sstevel@tonic-gate *
4037c478bd9Sstevel@tonic-gate * When logging errors, the extern Dbflineno is used.
4047c478bd9Sstevel@tonic-gate */
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate int
rd_dbf_line(fp,bp,svc_code_p,flags_p,id_p,res1_p,res2_p,res3_p,private_p,prognum,vernum,module_p,sflags,cmd_line_p,mflag)4077c478bd9Sstevel@tonic-gate rd_dbf_line(fp, bp, svc_code_p, flags_p, id_p, res1_p, res2_p, res3_p, private_p, prognum, vernum, module_p, sflags, cmd_line_p, mflag)
4087c478bd9Sstevel@tonic-gate register FILE *fp;
4097c478bd9Sstevel@tonic-gate register char *bp;
4107c478bd9Sstevel@tonic-gate char **svc_code_p;
4117c478bd9Sstevel@tonic-gate int *flags_p;
4127c478bd9Sstevel@tonic-gate char **id_p;
4137c478bd9Sstevel@tonic-gate char **res1_p;
4147c478bd9Sstevel@tonic-gate char **res2_p;
4157c478bd9Sstevel@tonic-gate char **res3_p;
4167c478bd9Sstevel@tonic-gate char **private_p;
4177c478bd9Sstevel@tonic-gate int *prognum;
4187c478bd9Sstevel@tonic-gate int *vernum;
4197c478bd9Sstevel@tonic-gate char **module_p;
4207c478bd9Sstevel@tonic-gate int *sflags;
4217c478bd9Sstevel@tonic-gate char **cmd_line_p;
4227c478bd9Sstevel@tonic-gate int mflag;
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate register int length;
4257c478bd9Sstevel@tonic-gate register char *p;
4267c478bd9Sstevel@tonic-gate
4277c478bd9Sstevel@tonic-gate do {
4287c478bd9Sstevel@tonic-gate ++Dbflineno;
4297c478bd9Sstevel@tonic-gate length = 0;
4307c478bd9Sstevel@tonic-gate
4317c478bd9Sstevel@tonic-gate if (!fgets(bp, DBFLINESZ, fp)) {
4327c478bd9Sstevel@tonic-gate if (feof(fp)) {
4337c478bd9Sstevel@tonic-gate return(0); /* EOF */
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate if (ferror(fp)) {
4367c478bd9Sstevel@tonic-gate sprintf(bp,dbfrderror,Dbflineno);
4377c478bd9Sstevel@tonic-gate logmessage(bp);
4387c478bd9Sstevel@tonic-gate return(-1);
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate sprintf(bp,dbfunknown,Dbflineno);
4417c478bd9Sstevel@tonic-gate logmessage(bp);
4427c478bd9Sstevel@tonic-gate return(-1); /* Unknown error (?) */
4437c478bd9Sstevel@tonic-gate }
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate if (*(bp+strlen(bp)-1) != '\n') { /* terminating newline? */
4467c478bd9Sstevel@tonic-gate sprintf(bp, dbfbadlmsg, Dbflineno);
4477c478bd9Sstevel@tonic-gate logmessage(bp);
4487c478bd9Sstevel@tonic-gate return(-1);
4497c478bd9Sstevel@tonic-gate }
4507c478bd9Sstevel@tonic-gate
4517c478bd9Sstevel@tonic-gate *(bp + strlen(bp) -1) = (char)0; /* delete newline */
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate if (strlen(bp) && (p = strchr(bp, DBFCOMMENT)))
4547c478bd9Sstevel@tonic-gate *p = (char)0; /* delete comments */
4557c478bd9Sstevel@tonic-gate if (!strlen(bp))
4567c478bd9Sstevel@tonic-gate continue;
4577c478bd9Sstevel@tonic-gate
4587c478bd9Sstevel@tonic-gate p = bp + strlen(bp) - 1; /* bp->start; p->end */
4597c478bd9Sstevel@tonic-gate while ((p != bp) && (isspace(*p))) {
4607c478bd9Sstevel@tonic-gate *p = (char)0; /* delete terminating spaces */
4617c478bd9Sstevel@tonic-gate --p;
4627c478bd9Sstevel@tonic-gate }
4637c478bd9Sstevel@tonic-gate
4647c478bd9Sstevel@tonic-gate while (*bp) /* del beginning white space*/
4657c478bd9Sstevel@tonic-gate if (isspace(*bp))
4667c478bd9Sstevel@tonic-gate ++bp;
4677c478bd9Sstevel@tonic-gate else
4687c478bd9Sstevel@tonic-gate break;
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate if (strlen(bp)) { /* anything left? */
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gate if (!(length=scan_line(bp,svc_code_p,flags_p,id_p,res1_p,res2_p,res3_p,private_p,prognum,vernum,module_p,sflags,cmd_line_p,mflag))) {
4737c478bd9Sstevel@tonic-gate
4747c478bd9Sstevel@tonic-gate DEBUG((1, "rd_dbf_line line %d, error while scanning entry",
4757c478bd9Sstevel@tonic-gate Dbflineno));
4767c478bd9Sstevel@tonic-gate sprintf(bp, dbfbadlmsg, Dbflineno);
4777c478bd9Sstevel@tonic-gate logmessage(bp);
4787c478bd9Sstevel@tonic-gate return(-1);
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate } while (!length); /* until we have something */
4837c478bd9Sstevel@tonic-gate
4847c478bd9Sstevel@tonic-gate DEBUG((5,"rd_dbf_line: line: %d,cmd line len: %d",Dbflineno, length+1));
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate return(length+1); /* +1 for the trailing NULL */
4877c478bd9Sstevel@tonic-gate
4887c478bd9Sstevel@tonic-gate }
4897c478bd9Sstevel@tonic-gate
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate /*
4927c478bd9Sstevel@tonic-gate * scan a non-white space line
4937c478bd9Sstevel@tonic-gate * 0 = error;
4947c478bd9Sstevel@tonic-gate * other = length of cmd line;
4957c478bd9Sstevel@tonic-gate *
4967c478bd9Sstevel@tonic-gate * non-null lines have the following format:
4977c478bd9Sstevel@tonic-gate *
4987c478bd9Sstevel@tonic-gate * service_code: flags: id: res1: res2: res3: private address: rpcdata: sflags: modules: cmd_line # comments
4997c478bd9Sstevel@tonic-gate *
5007c478bd9Sstevel@tonic-gate * mflag is set to suppress messages (scan_line is called both for parsing
5017c478bd9Sstevel@tonic-gate * and counting, messages should only be output once)
5027c478bd9Sstevel@tonic-gate */
5037c478bd9Sstevel@tonic-gate
5047c478bd9Sstevel@tonic-gate int
scan_line(bp,svc_code_p,flags_p,id_p,res1_p,res2_p,res3_p,private_p,prognum,vernum,module_p,sflags,cmd_line_p,mflag)5057c478bd9Sstevel@tonic-gate scan_line(bp, svc_code_p, flags_p, id_p, res1_p, res2_p, res3_p, private_p, prognum, vernum, module_p, sflags, cmd_line_p, mflag)
5067c478bd9Sstevel@tonic-gate register char *bp;
5077c478bd9Sstevel@tonic-gate char **svc_code_p;
5087c478bd9Sstevel@tonic-gate register int *flags_p;
5097c478bd9Sstevel@tonic-gate char **id_p;
5107c478bd9Sstevel@tonic-gate char **res1_p;
5117c478bd9Sstevel@tonic-gate char **res2_p;
5127c478bd9Sstevel@tonic-gate char **res3_p;
5137c478bd9Sstevel@tonic-gate char **private_p;
5147c478bd9Sstevel@tonic-gate int *prognum;
5157c478bd9Sstevel@tonic-gate int *vernum;
5167c478bd9Sstevel@tonic-gate char **module_p;
5177c478bd9Sstevel@tonic-gate int *sflags;
5187c478bd9Sstevel@tonic-gate register char **cmd_line_p;
5197c478bd9Sstevel@tonic-gate int mflag;
5207c478bd9Sstevel@tonic-gate {
5217c478bd9Sstevel@tonic-gate register char *p;
5227c478bd9Sstevel@tonic-gate register char *nexttok;
5237c478bd9Sstevel@tonic-gate register char *ptr;
5247c478bd9Sstevel@tonic-gate int sawsep = 0;
5257c478bd9Sstevel@tonic-gate char scratch[BUFSIZ];
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate *flags_p = 0;
5287c478bd9Sstevel@tonic-gate
5297c478bd9Sstevel@tonic-gate if (!(p = strchr(bp, DBFTOKSEP ))) { /* look for service code string */
5307c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed svc_code strchr"));
5317c478bd9Sstevel@tonic-gate return(0);
5327c478bd9Sstevel@tonic-gate }
5331a3a3bd4SToomas Soome *p = '\0';
5347c478bd9Sstevel@tonic-gate *svc_code_p = bp;
5357c478bd9Sstevel@tonic-gate nexttok = ++p;
5367c478bd9Sstevel@tonic-gate
5377c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5387c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed flags strchr"));
5397c478bd9Sstevel@tonic-gate return(0);
5407c478bd9Sstevel@tonic-gate }
5411a3a3bd4SToomas Soome *p = '\0';
5427c478bd9Sstevel@tonic-gate
5437c478bd9Sstevel@tonic-gate while (*nexttok) {
5447c478bd9Sstevel@tonic-gate switch (*nexttok) {
5457c478bd9Sstevel@tonic-gate case 'x': /* service is turned off */
5467c478bd9Sstevel@tonic-gate case 'X':
5477c478bd9Sstevel@tonic-gate *flags_p |= DBF_OFF;
5487c478bd9Sstevel@tonic-gate break;
5497c478bd9Sstevel@tonic-gate case 'u': /* create utmp entry */
5507c478bd9Sstevel@tonic-gate *flags_p |= DBF_UTMP;
5517c478bd9Sstevel@tonic-gate break;
5527c478bd9Sstevel@tonic-gate default:
5537c478bd9Sstevel@tonic-gate DEBUG((1,"scan_line: unknown flag char: 0x%x",*nexttok));
5547c478bd9Sstevel@tonic-gate *flags_p = DBF_UNKNOWN;
5557c478bd9Sstevel@tonic-gate break;
5567c478bd9Sstevel@tonic-gate }
5577c478bd9Sstevel@tonic-gate ++nexttok;
5587c478bd9Sstevel@tonic-gate }
5597c478bd9Sstevel@tonic-gate nexttok = ++p;
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5627c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed id strchr"));
5637c478bd9Sstevel@tonic-gate return(0);
5647c478bd9Sstevel@tonic-gate }
5651a3a3bd4SToomas Soome *p = '\0';
5667c478bd9Sstevel@tonic-gate *id_p = nexttok;
5677c478bd9Sstevel@tonic-gate nexttok = ++p;
5687c478bd9Sstevel@tonic-gate
5697c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5707c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed res1 strchr"));
5717c478bd9Sstevel@tonic-gate return(0);
5727c478bd9Sstevel@tonic-gate }
5731a3a3bd4SToomas Soome *p = '\0';
5747c478bd9Sstevel@tonic-gate *res1_p = nexttok;
5757c478bd9Sstevel@tonic-gate nexttok = ++p;
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5787c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed res2 strchr"));
5797c478bd9Sstevel@tonic-gate return(0);
5807c478bd9Sstevel@tonic-gate }
5811a3a3bd4SToomas Soome *p = '\0';
5827c478bd9Sstevel@tonic-gate *res2_p = nexttok;
5837c478bd9Sstevel@tonic-gate nexttok = ++p;
5847c478bd9Sstevel@tonic-gate
5857c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5867c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed res3 strchr"));
5877c478bd9Sstevel@tonic-gate return(0);
5887c478bd9Sstevel@tonic-gate }
5891a3a3bd4SToomas Soome *p = '\0';
5907c478bd9Sstevel@tonic-gate *res3_p = nexttok;
5917c478bd9Sstevel@tonic-gate nexttok = ++p;
5927c478bd9Sstevel@tonic-gate
5937c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
5947c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed private strchr"));
5957c478bd9Sstevel@tonic-gate return(0);
5967c478bd9Sstevel@tonic-gate }
5971a3a3bd4SToomas Soome *p = '\0';
5987c478bd9Sstevel@tonic-gate *private_p = nexttok;
5997c478bd9Sstevel@tonic-gate nexttok = ++p;
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
6027c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed rpc strchr"));
6037c478bd9Sstevel@tonic-gate return(0);
6047c478bd9Sstevel@tonic-gate }
6051a3a3bd4SToomas Soome *p = '\0';
6067c478bd9Sstevel@tonic-gate
6077c478bd9Sstevel@tonic-gate *prognum = -1;
6087c478bd9Sstevel@tonic-gate *vernum = -1;
6097c478bd9Sstevel@tonic-gate if (*nexttok) {
6107c478bd9Sstevel@tonic-gate /* there is rpc info */
6117c478bd9Sstevel@tonic-gate for (ptr = nexttok; *ptr; ++ptr) {
6127c478bd9Sstevel@tonic-gate if ((*ptr == ',') && !sawsep) {
6137c478bd9Sstevel@tonic-gate /*
6147c478bd9Sstevel@tonic-gate * skip separator - note that if
6157c478bd9Sstevel@tonic-gate * separator has been seen, it's not
6167c478bd9Sstevel@tonic-gate * a digit so it will fail below
6177c478bd9Sstevel@tonic-gate */
6187c478bd9Sstevel@tonic-gate sawsep++;
6197c478bd9Sstevel@tonic-gate continue;
6207c478bd9Sstevel@tonic-gate }
6217c478bd9Sstevel@tonic-gate if (!isdigit(*ptr)) {
6227c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> specifies non-integer rpc info", *svc_code_p);
6237c478bd9Sstevel@tonic-gate logmessage(scratch);
6247c478bd9Sstevel@tonic-gate return(0);
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate ptr = strchr(nexttok, ',');
6287c478bd9Sstevel@tonic-gate if (ptr) {
6297c478bd9Sstevel@tonic-gate if ((*prognum = atoi(nexttok)) < 0) {
6307c478bd9Sstevel@tonic-gate if (!mflag) {
6317c478bd9Sstevel@tonic-gate /* messages aren't suppressed */
6327c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> specifies negative program number", *svc_code_p);
6337c478bd9Sstevel@tonic-gate logmessage(scratch);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate return(0);
6367c478bd9Sstevel@tonic-gate }
6377c478bd9Sstevel@tonic-gate if ((*vernum = atoi(ptr + 1)) < 0) {
6387c478bd9Sstevel@tonic-gate if (!mflag) {
6397c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> specifies negative version number", *svc_code_p);
6407c478bd9Sstevel@tonic-gate logmessage(scratch);
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate return(0);
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate }
6457c478bd9Sstevel@tonic-gate else {
6467c478bd9Sstevel@tonic-gate if (!mflag) {
6477c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> - invalid rpcinfo", *svc_code_p);
6487c478bd9Sstevel@tonic-gate logmessage(scratch);
6497c478bd9Sstevel@tonic-gate }
6507c478bd9Sstevel@tonic-gate return(0);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate }
6537c478bd9Sstevel@tonic-gate nexttok = ++p;
6547c478bd9Sstevel@tonic-gate
6557c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
6567c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed sflags strchr"));
6577c478bd9Sstevel@tonic-gate return(0);
6587c478bd9Sstevel@tonic-gate }
6591a3a3bd4SToomas Soome *p = '\0';
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate *sflags = 0;
6627c478bd9Sstevel@tonic-gate while (*nexttok) {
6637c478bd9Sstevel@tonic-gate switch (*nexttok) {
6647c478bd9Sstevel@tonic-gate case 'c': /* dbf_cmd_line is a command */
6657c478bd9Sstevel@tonic-gate *sflags |= CFLAG;
6667c478bd9Sstevel@tonic-gate break;
6677c478bd9Sstevel@tonic-gate case 'd': /* dynamic address */
6687c478bd9Sstevel@tonic-gate if ((int) strlen(*private_p) > 0) {
6697c478bd9Sstevel@tonic-gate if (!mflag) {
6707c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> specifies static and dynamic address", *svc_code_p);
6717c478bd9Sstevel@tonic-gate logmessage(scratch);
6727c478bd9Sstevel@tonic-gate logmessage(" address info ignored");
6737c478bd9Sstevel@tonic-gate }
6747c478bd9Sstevel@tonic-gate /* don't set DFLAG and wipe out private addr */
6757c478bd9Sstevel@tonic-gate **private_p = '\0';
6767c478bd9Sstevel@tonic-gate }
6777c478bd9Sstevel@tonic-gate else {
6787c478bd9Sstevel@tonic-gate *sflags |= DFLAG;
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate break;
6817c478bd9Sstevel@tonic-gate case 'p': /* dbf_cmd_line is a pipe */
6827c478bd9Sstevel@tonic-gate *sflags |= PFLAG;
6837c478bd9Sstevel@tonic-gate break;
6847c478bd9Sstevel@tonic-gate default:
6857c478bd9Sstevel@tonic-gate if (!mflag) {
6867c478bd9Sstevel@tonic-gate sprintf(scratch, "service code <%s> unknown flag <%c> ignored", *svc_code_p, *nexttok);
6877c478bd9Sstevel@tonic-gate logmessage(scratch);
6887c478bd9Sstevel@tonic-gate }
6897c478bd9Sstevel@tonic-gate break;
6907c478bd9Sstevel@tonic-gate }
6917c478bd9Sstevel@tonic-gate ++nexttok;
6927c478bd9Sstevel@tonic-gate }
6937c478bd9Sstevel@tonic-gate nexttok = ++p;
6947c478bd9Sstevel@tonic-gate
6957c478bd9Sstevel@tonic-gate if (!(p = strchr(nexttok, DBFTOKSEP ))) {
6967c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line failed module strchr"));
6977c478bd9Sstevel@tonic-gate return(0);
6987c478bd9Sstevel@tonic-gate }
6991a3a3bd4SToomas Soome *p = '\0';
7007c478bd9Sstevel@tonic-gate *module_p = nexttok;
7017c478bd9Sstevel@tonic-gate nexttok = ++p;
7027c478bd9Sstevel@tonic-gate
7037c478bd9Sstevel@tonic-gate *cmd_line_p = nexttok;
7047c478bd9Sstevel@tonic-gate
7057c478bd9Sstevel@tonic-gate DEBUG((9,"scan_line: modules: %s; line: %s; len: %d", *module_p, *cmd_line_p, strlen(*svc_code_p)+strlen(*id_p)+strlen(*res1_p)+strlen(*res2_p)+strlen(*res3_p)+strlen(*private_p)+strlen(*module_p)+strlen(*cmd_line_p)+9));
7067c478bd9Sstevel@tonic-gate /*
7077c478bd9Sstevel@tonic-gate * return the length of the buffer. Add 9 for the NULLs after each
7087c478bd9Sstevel@tonic-gate * string
7097c478bd9Sstevel@tonic-gate */
7107c478bd9Sstevel@tonic-gate return(strlen(*svc_code_p)+strlen(*id_p)+strlen(*res1_p)+strlen(*res2_p)+strlen(*res3_p)+strlen(*private_p)+strlen(*module_p)+strlen(*cmd_line_p)+9);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate
7157c478bd9Sstevel@tonic-gate #define VERSIONSTR "# VERSION="
7167c478bd9Sstevel@tonic-gate
717113f4232Sakaplan int
check_version(void)718113f4232Sakaplan check_version(void)
7197c478bd9Sstevel@tonic-gate {
7207c478bd9Sstevel@tonic-gate FILE *fp;
7217c478bd9Sstevel@tonic-gate char *line, *p, *tmp;
7227c478bd9Sstevel@tonic-gate int version;
7237c478bd9Sstevel@tonic-gate
7247c478bd9Sstevel@tonic-gate if ((fp = fopen(DBFNAME, "r")) == NULL) {
7257c478bd9Sstevel@tonic-gate logmessage(dbfopenmsg);
7267c478bd9Sstevel@tonic-gate error(E_DBF_IO, EXIT | NOCORE | NO_MSG);
7277c478bd9Sstevel@tonic-gate }
7287c478bd9Sstevel@tonic-gate if ((line = (char *) malloc(DBFLINESZ)) == NULL)
7297c478bd9Sstevel@tonic-gate error(E_DBF_ALLOC, EXIT | NOCORE);
7307c478bd9Sstevel@tonic-gate p = line;
7317c478bd9Sstevel@tonic-gate while (fgets(p, DBFLINESZ, fp)) {
7327c478bd9Sstevel@tonic-gate if (!strncmp(p, VERSIONSTR, strlen(VERSIONSTR))) {
7337c478bd9Sstevel@tonic-gate /* pitch the newline */
7347c478bd9Sstevel@tonic-gate tmp = strchr(p, '\n');
7357c478bd9Sstevel@tonic-gate if (tmp)
7367c478bd9Sstevel@tonic-gate *tmp = '\0';
7377c478bd9Sstevel@tonic-gate else {
7387c478bd9Sstevel@tonic-gate logmessage(dbfcorrupt);
7397c478bd9Sstevel@tonic-gate error(E_DBF_CORRUPT, EXIT | NOCORE);
7407c478bd9Sstevel@tonic-gate }
7417c478bd9Sstevel@tonic-gate p += strlen(VERSIONSTR);
7427c478bd9Sstevel@tonic-gate if (*p)
7437c478bd9Sstevel@tonic-gate version = atoi(p);
7447c478bd9Sstevel@tonic-gate else {
7457c478bd9Sstevel@tonic-gate logmessage(dbfcorrupt);
7467c478bd9Sstevel@tonic-gate error(E_DBF_CORRUPT, EXIT | NOCORE);
7477c478bd9Sstevel@tonic-gate }
7487c478bd9Sstevel@tonic-gate free(line);
7497c478bd9Sstevel@tonic-gate fclose(fp);
7507c478bd9Sstevel@tonic-gate if (version != VERSION)
7517c478bd9Sstevel@tonic-gate return(1); /* wrong version */
7527c478bd9Sstevel@tonic-gate else
7537c478bd9Sstevel@tonic-gate return(0); /* version ok */
7547c478bd9Sstevel@tonic-gate }
7557c478bd9Sstevel@tonic-gate p = line;
7567c478bd9Sstevel@tonic-gate }
7577c478bd9Sstevel@tonic-gate logmessage(dbfcorrupt);
7587c478bd9Sstevel@tonic-gate error(E_DBF_CORRUPT, EXIT | NOCORE);
7597c478bd9Sstevel@tonic-gate return(1);
7607c478bd9Sstevel@tonic-gate }
7617c478bd9Sstevel@tonic-gate
7627c478bd9Sstevel@tonic-gate
7637c478bd9Sstevel@tonic-gate /*
7647c478bd9Sstevel@tonic-gate * mkdbfargv: Given a pointer to a dbf_t, construct argv
7657c478bd9Sstevel@tonic-gate * for an exec system call.
7667c478bd9Sstevel@tonic-gate * Warning: returns a pointer to static data which are
7677c478bd9Sstevel@tonic-gate * overritten by each call.
7687c478bd9Sstevel@tonic-gate *
7697c478bd9Sstevel@tonic-gate * There is a practical limit of 50 arguments (including argv[0])
7707c478bd9Sstevel@tonic-gate *
7717c478bd9Sstevel@tonic-gate * Warning: calling mkdbfargv destroys the data (by writing null
7727c478bd9Sstevel@tonic-gate * characters via strtok) pointed to by dbp->dbf_cmd_line.
7737c478bd9Sstevel@tonic-gate */
7747c478bd9Sstevel@tonic-gate
7757c478bd9Sstevel@tonic-gate static char *dbfargv[50];
7767c478bd9Sstevel@tonic-gate static char *delim = " \t'\""; /* delimiters */
7777c478bd9Sstevel@tonic-gate
7787c478bd9Sstevel@tonic-gate char **
mkdbfargv(dbp)7797c478bd9Sstevel@tonic-gate mkdbfargv(dbp)
7807c478bd9Sstevel@tonic-gate register dbf_t *dbp;
7817c478bd9Sstevel@tonic-gate {
7827c478bd9Sstevel@tonic-gate register char **argvp = dbfargv;
7837c478bd9Sstevel@tonic-gate register char *p = dbp->dbf_cmd_line;
7847c478bd9Sstevel@tonic-gate char delch;
7857c478bd9Sstevel@tonic-gate register char *savep;
7867c478bd9Sstevel@tonic-gate register char *tp;
7877c478bd9Sstevel@tonic-gate char scratch[BUFSIZ];
7887c478bd9Sstevel@tonic-gate char *strpbrk();
7897c478bd9Sstevel@tonic-gate #ifdef DEBUGMODE
7907c478bd9Sstevel@tonic-gate register int i = 0;
7917c478bd9Sstevel@tonic-gate #endif
7927c478bd9Sstevel@tonic-gate
7937c478bd9Sstevel@tonic-gate *argvp = 0;
7947c478bd9Sstevel@tonic-gate savep = p;
7957c478bd9Sstevel@tonic-gate while (p && *p) {
7967c478bd9Sstevel@tonic-gate if (p = strpbrk(p, delim)) {
7977c478bd9Sstevel@tonic-gate switch (*p) {
7987c478bd9Sstevel@tonic-gate case ' ':
7997c478bd9Sstevel@tonic-gate case '\t':
8007c478bd9Sstevel@tonic-gate /* "normal" cases */
8017c478bd9Sstevel@tonic-gate *p++ = '\0';
8027c478bd9Sstevel@tonic-gate *argvp++ = savep;
8037c478bd9Sstevel@tonic-gate DEBUG((9, "argv[%d] = %s", i++, savep));
8047c478bd9Sstevel@tonic-gate /* zap trailing white space */
8057c478bd9Sstevel@tonic-gate while (isspace(*p))
8067c478bd9Sstevel@tonic-gate p++;
8077c478bd9Sstevel@tonic-gate savep = p;
8087c478bd9Sstevel@tonic-gate break;
8097c478bd9Sstevel@tonic-gate case '"':
8107c478bd9Sstevel@tonic-gate case '\'':
8117c478bd9Sstevel@tonic-gate /* found a string */
8127c478bd9Sstevel@tonic-gate delch = *p; /* remember the delimiter */
8137c478bd9Sstevel@tonic-gate savep = ++p;
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate /*
8167c478bd9Sstevel@tonic-gate * We work the string in place, embedded instances of the string delimiter,
8177c478bd9Sstevel@tonic-gate * i.e. \" must have the '\' removed. Since we'd have to do a compare to
8187c478bd9Sstevel@tonic-gate * decide if a copy were needed, it's less work to just do the copy, even
8197c478bd9Sstevel@tonic-gate * though it is most likely unnecessary.
8207c478bd9Sstevel@tonic-gate */
8217c478bd9Sstevel@tonic-gate
8227c478bd9Sstevel@tonic-gate tp = p;
8237c478bd9Sstevel@tonic-gate for (;;) {
8247c478bd9Sstevel@tonic-gate if (*p == '\0') {
8257c478bd9Sstevel@tonic-gate sprintf(scratch, "invalid command line, non-terminated string for service code %s", dbp->dbf_svc_code);
8267c478bd9Sstevel@tonic-gate logmessage(scratch);
8277c478bd9Sstevel@tonic-gate exit(2); /* server, don't log */
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate if (*p == delch) {
8307c478bd9Sstevel@tonic-gate if (*(tp - 1) == '\\') { /* \delim */
8317c478bd9Sstevel@tonic-gate *(tp - 1) = *p;
8327c478bd9Sstevel@tonic-gate p++;
8337c478bd9Sstevel@tonic-gate }
8347c478bd9Sstevel@tonic-gate else { /* end of string */
8357c478bd9Sstevel@tonic-gate *tp = 0;
8367c478bd9Sstevel@tonic-gate *argvp++ = savep;
8377c478bd9Sstevel@tonic-gate DEBUG((9, "argv[%d] = %s", i++, savep));
8387c478bd9Sstevel@tonic-gate p++;
8397c478bd9Sstevel@tonic-gate /* zap trailing white space */
8407c478bd9Sstevel@tonic-gate while (isspace(*p))
8417c478bd9Sstevel@tonic-gate p++;
8427c478bd9Sstevel@tonic-gate savep = p;
8437c478bd9Sstevel@tonic-gate break;
8447c478bd9Sstevel@tonic-gate }
8457c478bd9Sstevel@tonic-gate }
8467c478bd9Sstevel@tonic-gate else {
8477c478bd9Sstevel@tonic-gate *tp++ = *p++;
8487c478bd9Sstevel@tonic-gate }
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate break;
8517c478bd9Sstevel@tonic-gate default:
8527c478bd9Sstevel@tonic-gate logmessage("Internal error in parse routine");
8537c478bd9Sstevel@tonic-gate exit(2); /* server, don't log */
8547c478bd9Sstevel@tonic-gate }
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate else {
8577c478bd9Sstevel@tonic-gate *argvp++ = savep;
8587c478bd9Sstevel@tonic-gate DEBUG((9, "argv[%d] = %s", i++, savep));
8597c478bd9Sstevel@tonic-gate }
8607c478bd9Sstevel@tonic-gate }
8617c478bd9Sstevel@tonic-gate *argvp = 0;
8627c478bd9Sstevel@tonic-gate return(dbfargv);
8637c478bd9Sstevel@tonic-gate }
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate
8667c478bd9Sstevel@tonic-gate
8677c478bd9Sstevel@tonic-gate /*
8687c478bd9Sstevel@tonic-gate *
8697c478bd9Sstevel@tonic-gate * getentry: Given a fd, this routine will return a
870*55fea89dSDan Cross * dbf entry. If the entry doesn't exist it will
8717c478bd9Sstevel@tonic-gate * return NULL.
8727c478bd9Sstevel@tonic-gate */
8737c478bd9Sstevel@tonic-gate
8747c478bd9Sstevel@tonic-gate dbf_t *
getentry(fd)8757c478bd9Sstevel@tonic-gate getentry(fd)
8767c478bd9Sstevel@tonic-gate int fd;
8777c478bd9Sstevel@tonic-gate {
8787c478bd9Sstevel@tonic-gate extern dbf_t *Dbfhead; /* Dbfentries (when allocated) */
8797c478bd9Sstevel@tonic-gate register dbf_t *dbp = Dbfhead;
8807c478bd9Sstevel@tonic-gate
8817c478bd9Sstevel@tonic-gate if (!Dbfhead) { /* no private address in database file */
8827c478bd9Sstevel@tonic-gate DEBUG((9, "getdbfentry - nothing in Dbfhead = %s ",Dbfhead));
8837c478bd9Sstevel@tonic-gate return((dbf_t *)0);
8847c478bd9Sstevel@tonic-gate }
8857c478bd9Sstevel@tonic-gate else
8867c478bd9Sstevel@tonic-gate for (dbp = Dbfhead; dbp->dbf_prv_adr; ++dbp)
8877c478bd9Sstevel@tonic-gate if (fd == dbp->dbf_fd) {
8887c478bd9Sstevel@tonic-gate return(dbp);
8897c478bd9Sstevel@tonic-gate }
8907c478bd9Sstevel@tonic-gate
8917c478bd9Sstevel@tonic-gate return((dbf_t *)0); /* requested private address not in list */
8927c478bd9Sstevel@tonic-gate
8937c478bd9Sstevel@tonic-gate }
8947c478bd9Sstevel@tonic-gate
8957c478bd9Sstevel@tonic-gate
8967c478bd9Sstevel@tonic-gate /*
8977c478bd9Sstevel@tonic-gate * pushmod: push modules if defined in the data base entry.
8987c478bd9Sstevel@tonic-gate *
8997c478bd9Sstevel@tonic-gate * WARNING: This routine writes into the in-memory copy
9007c478bd9Sstevel@tonic-gate * of the database file. Therefore, after it is called,
9017c478bd9Sstevel@tonic-gate * the incore copy of the database file will no longer be valid.
9027c478bd9Sstevel@tonic-gate */
9037c478bd9Sstevel@tonic-gate
9047c478bd9Sstevel@tonic-gate int
pushmod(fd,mp)9057c478bd9Sstevel@tonic-gate pushmod(fd, mp)
9067c478bd9Sstevel@tonic-gate int fd;
9077c478bd9Sstevel@tonic-gate register char *mp;
9087c478bd9Sstevel@tonic-gate {
9097c478bd9Sstevel@tonic-gate register char *cp;
9107c478bd9Sstevel@tonic-gate register char *bufp = mp;
9117c478bd9Sstevel@tonic-gate char name[32];
9127c478bd9Sstevel@tonic-gate extern int errno;
9137c478bd9Sstevel@tonic-gate
9147c478bd9Sstevel@tonic-gate DEBUG((9,"in pushmod:"));
9151a3a3bd4SToomas Soome if (!mp || *mp == '\0') {
9167c478bd9Sstevel@tonic-gate DEBUG((9,"NULL list: exiting pushmod"));
9177c478bd9Sstevel@tonic-gate return(0);
9187c478bd9Sstevel@tonic-gate }
9197c478bd9Sstevel@tonic-gate /* pop timod if it is on the stack */
9207c478bd9Sstevel@tonic-gate if (ioctl(fd, I_LOOK, name) >= 0) {
9217c478bd9Sstevel@tonic-gate if (strcmp(name, "timod") == 0) {
9227c478bd9Sstevel@tonic-gate if (ioctl(fd, I_POP, 0) < 0)
9237c478bd9Sstevel@tonic-gate DEBUG((9,"pushmod: I_POP failed"));
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate }
9267c478bd9Sstevel@tonic-gate while ((cp = strtok(bufp, ",")) != NULL) {
9277c478bd9Sstevel@tonic-gate bufp = NULL;
9287c478bd9Sstevel@tonic-gate DEBUG((9,"pushmod: about to push %s", cp));
9297c478bd9Sstevel@tonic-gate if (ioctl(fd, I_PUSH, cp) < 0) {
9307c478bd9Sstevel@tonic-gate DEBUG((9,"pushmod: ioctl failed, errno = %d",errno));
9317c478bd9Sstevel@tonic-gate return(1);
9327c478bd9Sstevel@tonic-gate }
9337c478bd9Sstevel@tonic-gate }
9347c478bd9Sstevel@tonic-gate DEBUG((9,"exiting pushmod:"));
9357c478bd9Sstevel@tonic-gate return(0);
9367c478bd9Sstevel@tonic-gate }
937