xref: /illumos-gate/usr/src/cmd/listen/lsdbf.c (revision 55fea89d)
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