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
56cd9e705SBill Taylor  * Common Development and Distribution License (the "License").
66cd9e705SBill Taylor  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
226cd9e705SBill Taylor  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #include "cfga_ib.h"
277c478bd9Sstevel@tonic-gate #include "cfga_conf.h"
287c478bd9Sstevel@tonic-gate #include <sys/stat.h>
297c478bd9Sstevel@tonic-gate 
307c478bd9Sstevel@tonic-gate /*
317c478bd9Sstevel@tonic-gate  * cfga_conf.c
327c478bd9Sstevel@tonic-gate  *
337c478bd9Sstevel@tonic-gate  *	This file supports adding/deleting/listing services from IBCONF_FILE.
347c478bd9Sstevel@tonic-gate  */
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate /*
377c478bd9Sstevel@tonic-gate  * function prototypes:
387c478bd9Sstevel@tonic-gate  */
397c478bd9Sstevel@tonic-gate static ib_service_type_t	ib_get_var_type(char *);
407c478bd9Sstevel@tonic-gate static ib_token_t		ib_lex(char *, char **);
417c478bd9Sstevel@tonic-gate static void			ib_find_eol();
427c478bd9Sstevel@tonic-gate static int			ib_get_string(char **, char *);
437c478bd9Sstevel@tonic-gate static int			ib_service_record_add(char *,
447c478bd9Sstevel@tonic-gate 				    ib_service_type_t);
457c478bd9Sstevel@tonic-gate static ib_token_t		ib_get_services(char **);
467c478bd9Sstevel@tonic-gate static boolean_t		ib_cmp_service();
477c478bd9Sstevel@tonic-gate static void			ib_free_service_recs(void);
487c478bd9Sstevel@tonic-gate static int			ib_cleanup_file(int);
497c478bd9Sstevel@tonic-gate static int			ib_init_file(char **);
507c478bd9Sstevel@tonic-gate int				ib_add_service(char **);
517c478bd9Sstevel@tonic-gate int				ib_delete_service(char **);
527c478bd9Sstevel@tonic-gate int				ib_list_services(struct cfga_msg *, char **);
537c478bd9Sstevel@tonic-gate static cfga_ib_ret_t		ib_conf_control_ioctl(char *, uint_t);
547c478bd9Sstevel@tonic-gate static int			ib_service_record_valid(char *);
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate extern void			cfga_msg(struct cfga_msg *, const char *);
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate 
597c478bd9Sstevel@tonic-gate /* Global variables */
607c478bd9Sstevel@tonic-gate 
617c478bd9Sstevel@tonic-gate /*
627c478bd9Sstevel@tonic-gate  * supported "name=value" pairs from IBCONF_FILE
637c478bd9Sstevel@tonic-gate  */
647c478bd9Sstevel@tonic-gate static ibcfg_var_t ibcfg_varlist[] = {
657c478bd9Sstevel@tonic-gate 	{ "name",		IB_NAME },
667c478bd9Sstevel@tonic-gate 	{ "class",		IB_CLASS },
677c478bd9Sstevel@tonic-gate 	{ "port-svc-list",	IB_PORT_SERVICE },
687c478bd9Sstevel@tonic-gate 	{ "vppa-svc-list",	IB_VPPA_SERVICE },
697c478bd9Sstevel@tonic-gate 	{ "hca-svc-list",	IB_HCASVC_SERVICE },
707c478bd9Sstevel@tonic-gate 	{ NULL,			IB_NONE }
717c478bd9Sstevel@tonic-gate };
727c478bd9Sstevel@tonic-gate 
737c478bd9Sstevel@tonic-gate static char		ibconf_file[] = IBCONF_FILE;	/* file being read */
747c478bd9Sstevel@tonic-gate static int		ibcfg_linenum = 1;		/* track line#s */
757c478bd9Sstevel@tonic-gate static int		ibcfg_cntr = 0;			/* current char read */
767c478bd9Sstevel@tonic-gate static int		ibcfg_brec = 0;			/* beginning of rec */
777c478bd9Sstevel@tonic-gate static int		bvpparec = 0;			/* begin of vppa rec */
787c478bd9Sstevel@tonic-gate static int		bportrec = 0;			/* begin of port rec */
797c478bd9Sstevel@tonic-gate static int		bhcarec = 0;			/* begin of HCA rec */
807c478bd9Sstevel@tonic-gate static int		ibcfg_btoken = 0;		/* begin of new token */
817c478bd9Sstevel@tonic-gate static mutex_t		ibcfg_lock = DEFAULTMUTEX;	/* lock for the file */
827c478bd9Sstevel@tonic-gate static int		ibcfg_fd = -1;			/* file descriptor */
837c478bd9Sstevel@tonic-gate static int		ibcfg_tmpfd = 0;		/* tmp file "fd" */
847c478bd9Sstevel@tonic-gate static char		*file_buf = (char *)NULL;	/* read file into buf */
857c478bd9Sstevel@tonic-gate static char		*tmpnamef = (char *)NULL;	/* tmp file name */
867c478bd9Sstevel@tonic-gate static boolean_t	wrote_tmp = B_FALSE;		/* tmp file write in */
877c478bd9Sstevel@tonic-gate 							/* progress indicator */
887c478bd9Sstevel@tonic-gate static struct stat	ibcfg_st;			/* file stat struct */
897c478bd9Sstevel@tonic-gate 
907c478bd9Sstevel@tonic-gate static int		ibcfg_nport_services;		/* # of PORT services */
917c478bd9Sstevel@tonic-gate static int		ibcfg_nvppa_services;		/* # of VPPA services */
927c478bd9Sstevel@tonic-gate static int		ibcfg_nhca_services;		/* # of HCA services */
937c478bd9Sstevel@tonic-gate static ib_svc_rec_t	*ibcfg_vppa_head;		/* VPPA service recs */
947c478bd9Sstevel@tonic-gate static ib_svc_rec_t	*ibcfg_port_head;		/* PORT service recs */
957c478bd9Sstevel@tonic-gate static ib_svc_rec_t	*ibcfg_hca_head;		/* HCA service recs */
967c478bd9Sstevel@tonic-gate 
977c478bd9Sstevel@tonic-gate extern char		*service_name;			/* service name */
987c478bd9Sstevel@tonic-gate extern ib_service_type_t service_type;			/* service type */
997c478bd9Sstevel@tonic-gate 
1007c478bd9Sstevel@tonic-gate 
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate  * Function:
1037c478bd9Sstevel@tonic-gate  *	ib_get_var_type
1047c478bd9Sstevel@tonic-gate  * Input:
1057c478bd9Sstevel@tonic-gate  *	str	-	A parsed string from IBCONF_FILE
1067c478bd9Sstevel@tonic-gate  * Output:
1077c478bd9Sstevel@tonic-gate  *	NONE
1087c478bd9Sstevel@tonic-gate  * Returns:
1097c478bd9Sstevel@tonic-gate  *	Service type
1107c478bd9Sstevel@tonic-gate  * Description:
1117c478bd9Sstevel@tonic-gate  *	Returns the field from the token
1127c478bd9Sstevel@tonic-gate  */
1137c478bd9Sstevel@tonic-gate static ib_service_type_t
ib_get_var_type(char * str)1147c478bd9Sstevel@tonic-gate ib_get_var_type(char *str)
1157c478bd9Sstevel@tonic-gate {
1167c478bd9Sstevel@tonic-gate 	register ibcfg_var_t    *cfgvar;
1177c478bd9Sstevel@tonic-gate 
1187c478bd9Sstevel@tonic-gate 	cfgvar = &ibcfg_varlist[0];
1197c478bd9Sstevel@tonic-gate 	while (cfgvar->type != IB_NONE) {
120*21f023dfSToomas Soome 		if (strcasecmp(cfgvar->name, str) == 0)
1217c478bd9Sstevel@tonic-gate 			break;
1227c478bd9Sstevel@tonic-gate 		else
1237c478bd9Sstevel@tonic-gate 			cfgvar++;
1247c478bd9Sstevel@tonic-gate 	}
1257c478bd9Sstevel@tonic-gate 	return (cfgvar->type);
1267c478bd9Sstevel@tonic-gate }
1277c478bd9Sstevel@tonic-gate 
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate /*
1307c478bd9Sstevel@tonic-gate  * Function:
1317c478bd9Sstevel@tonic-gate  *	ib_lex
1327c478bd9Sstevel@tonic-gate  * Input:
1337c478bd9Sstevel@tonic-gate  *	NONE
1347c478bd9Sstevel@tonic-gate  * Output:
1357c478bd9Sstevel@tonic-gate  *	val	-	value just read
1367c478bd9Sstevel@tonic-gate  *	errmsg	-	pointer to error message string, if there are any errors
1377c478bd9Sstevel@tonic-gate  * Returns:
1387c478bd9Sstevel@tonic-gate  *	valid IB token
1397c478bd9Sstevel@tonic-gate  * Description:
1407c478bd9Sstevel@tonic-gate  *	Read tokens from the IBCONF_FILE and parse them
1417c478bd9Sstevel@tonic-gate  */
1427c478bd9Sstevel@tonic-gate /* ARGSUSED */
1437c478bd9Sstevel@tonic-gate static ib_token_t
ib_lex(char * val,char ** errmsg)1447c478bd9Sstevel@tonic-gate ib_lex(char *val, char **errmsg)
1457c478bd9Sstevel@tonic-gate {
1467c478bd9Sstevel@tonic-gate 	int		ch, oval, badquote;
1477c478bd9Sstevel@tonic-gate 	char		*cp = val;
1487c478bd9Sstevel@tonic-gate 	ib_token_t	token;
1497c478bd9Sstevel@tonic-gate 
1506cd9e705SBill Taylor 	while ((ch = GETC(file_buf, ibcfg_cntr)) == ' ' || ch == '\t')
1516cd9e705SBill Taylor 		;
1527c478bd9Sstevel@tonic-gate 
1537c478bd9Sstevel@tonic-gate 	/* make a note of the beginning of token */
1547c478bd9Sstevel@tonic-gate 	ibcfg_btoken = ibcfg_cntr - 1;
1557c478bd9Sstevel@tonic-gate 
1567c478bd9Sstevel@tonic-gate 	*cp++ = (char)ch;
1577c478bd9Sstevel@tonic-gate 	switch (ch) {
1587c478bd9Sstevel@tonic-gate 	case '=':
1597c478bd9Sstevel@tonic-gate 		token = EQUALS;
1607c478bd9Sstevel@tonic-gate 		break;
1617c478bd9Sstevel@tonic-gate 	case '&':
1627c478bd9Sstevel@tonic-gate 		token = AMPERSAND;
1637c478bd9Sstevel@tonic-gate 		break;
1647c478bd9Sstevel@tonic-gate 	case '|':
1657c478bd9Sstevel@tonic-gate 		token = BIT_OR;
1667c478bd9Sstevel@tonic-gate 		break;
1677c478bd9Sstevel@tonic-gate 	case '*':
1687c478bd9Sstevel@tonic-gate 		token = STAR;
1697c478bd9Sstevel@tonic-gate 		break;
1707c478bd9Sstevel@tonic-gate 	case '#':
1717c478bd9Sstevel@tonic-gate 		token = POUND;
1727c478bd9Sstevel@tonic-gate 		break;
1737c478bd9Sstevel@tonic-gate 	case ':':
1747c478bd9Sstevel@tonic-gate 		token = COLON;
1757c478bd9Sstevel@tonic-gate 		break;
1767c478bd9Sstevel@tonic-gate 	case ';':
1777c478bd9Sstevel@tonic-gate 		token = SEMICOLON;
1787c478bd9Sstevel@tonic-gate 		break;
1797c478bd9Sstevel@tonic-gate 	case ',':
1807c478bd9Sstevel@tonic-gate 		token = COMMA;
1817c478bd9Sstevel@tonic-gate 		break;
1827c478bd9Sstevel@tonic-gate 	case '/':
1837c478bd9Sstevel@tonic-gate 		token = SLASH;
1847c478bd9Sstevel@tonic-gate 		break;
1857c478bd9Sstevel@tonic-gate 	case ' ':
1867c478bd9Sstevel@tonic-gate 	case '\t':
1877c478bd9Sstevel@tonic-gate 	case '\f':
1887c478bd9Sstevel@tonic-gate 		while ((ch  = GETC(file_buf, ibcfg_cntr)) == ' ' ||
1897c478bd9Sstevel@tonic-gate 		    ch == '\t' || ch == '\f')
1907c478bd9Sstevel@tonic-gate 			*cp++ = (char)ch;
1917c478bd9Sstevel@tonic-gate 		(void) UNGETC(ibcfg_cntr);
1927c478bd9Sstevel@tonic-gate 		token = WHITE_SPACE;
1937c478bd9Sstevel@tonic-gate 		break;
1947c478bd9Sstevel@tonic-gate 	case '\n':
1957c478bd9Sstevel@tonic-gate 	case '\r':
1967c478bd9Sstevel@tonic-gate 		token = NEWLINE;
1977c478bd9Sstevel@tonic-gate 		break;
1987c478bd9Sstevel@tonic-gate 	case '"':
1997c478bd9Sstevel@tonic-gate 		cp--;
2007c478bd9Sstevel@tonic-gate 		badquote = 0;
2017c478bd9Sstevel@tonic-gate 		while (!badquote && (ch  = GETC(file_buf, ibcfg_cntr)) != '"') {
2027c478bd9Sstevel@tonic-gate 			switch (ch) {
2037c478bd9Sstevel@tonic-gate 			case '\n':
2047c478bd9Sstevel@tonic-gate 			case -1:
2057c478bd9Sstevel@tonic-gate 				(void) snprintf(*errmsg, MAXPATHLEN,
2067c478bd9Sstevel@tonic-gate 				    "Missing \"");
2077c478bd9Sstevel@tonic-gate 				cp = val;
2087c478bd9Sstevel@tonic-gate 				*cp++ = '\n';
2097c478bd9Sstevel@tonic-gate 				badquote = 1;
2107c478bd9Sstevel@tonic-gate 				/* since we consumed the newline/EOF */
2117c478bd9Sstevel@tonic-gate 				(void) UNGETC(ibcfg_cntr);
2127c478bd9Sstevel@tonic-gate 				break;
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate 			case '\\':
2157c478bd9Sstevel@tonic-gate 				ch = (char)GETC(file_buf, ibcfg_cntr);
2167c478bd9Sstevel@tonic-gate 				if (!isdigit(ch)) {
2177c478bd9Sstevel@tonic-gate 					/* escape the character */
2187c478bd9Sstevel@tonic-gate 					*cp++ = (char)ch;
2197c478bd9Sstevel@tonic-gate 					break;
2207c478bd9Sstevel@tonic-gate 				}
2217c478bd9Sstevel@tonic-gate 				oval = 0;
2227c478bd9Sstevel@tonic-gate 				while (ch >= '0' && ch <= '7') {
2237c478bd9Sstevel@tonic-gate 					ch -= '0';
2247c478bd9Sstevel@tonic-gate 					oval = (oval << 3) + ch;
2257c478bd9Sstevel@tonic-gate 					ch = (char)GETC(file_buf, ibcfg_cntr);
2267c478bd9Sstevel@tonic-gate 				}
2277c478bd9Sstevel@tonic-gate 				(void) UNGETC(ibcfg_cntr);
2287c478bd9Sstevel@tonic-gate 				/* check for character overflow? */
2297c478bd9Sstevel@tonic-gate 				if (oval > 127) {
2307c478bd9Sstevel@tonic-gate 					(void) snprintf(*errmsg, MAXPATHLEN,
2317c478bd9Sstevel@tonic-gate 					    "Character overflow detected.\n");
2327c478bd9Sstevel@tonic-gate 				}
2337c478bd9Sstevel@tonic-gate 				*cp++ = (char)oval;
2347c478bd9Sstevel@tonic-gate 				break;
2357c478bd9Sstevel@tonic-gate 			default:
2367c478bd9Sstevel@tonic-gate 				*cp++ = (char)ch;
2377c478bd9Sstevel@tonic-gate 				break;
2387c478bd9Sstevel@tonic-gate 			}
2397c478bd9Sstevel@tonic-gate 		}
2407c478bd9Sstevel@tonic-gate 		token = STRING;
2417c478bd9Sstevel@tonic-gate 		break;
2427c478bd9Sstevel@tonic-gate 	default:
2437c478bd9Sstevel@tonic-gate 		if (ch == -1) {
2447c478bd9Sstevel@tonic-gate 			token = EOF;
2457c478bd9Sstevel@tonic-gate 			break;
2467c478bd9Sstevel@tonic-gate 		}
2477c478bd9Sstevel@tonic-gate 		/*
2487c478bd9Sstevel@tonic-gate 		 * detect a lone '-' (including at the end of a line), and
2497c478bd9Sstevel@tonic-gate 		 * identify it as a 'name'
2507c478bd9Sstevel@tonic-gate 		 */
2517c478bd9Sstevel@tonic-gate 		if (ch == '-') {
2527c478bd9Sstevel@tonic-gate 			*cp++ = (char)(ch = GETC(file_buf, ibcfg_cntr));
2537c478bd9Sstevel@tonic-gate 			if (iswhite(ch) || (ch == '\n')) {
2547c478bd9Sstevel@tonic-gate 				(void) UNGETC(ibcfg_cntr);
2557c478bd9Sstevel@tonic-gate 				cp--;
2567c478bd9Sstevel@tonic-gate 				token = NAME;
2577c478bd9Sstevel@tonic-gate 				break;
2587c478bd9Sstevel@tonic-gate 			}
2597c478bd9Sstevel@tonic-gate 		} else if (isunary(ch)) {
2607c478bd9Sstevel@tonic-gate 			*cp++ = (char)(ch = GETC(file_buf, ibcfg_cntr));
2617c478bd9Sstevel@tonic-gate 		}
2627c478bd9Sstevel@tonic-gate 
2637c478bd9Sstevel@tonic-gate 		if (isdigit(ch)) {
2647c478bd9Sstevel@tonic-gate 			if (ch == '0') {
2657c478bd9Sstevel@tonic-gate 				if ((ch = GETC(file_buf, ibcfg_cntr)) == 'x') {
2667c478bd9Sstevel@tonic-gate 					*cp++ = (char)ch;
2677c478bd9Sstevel@tonic-gate 					ch = GETC(file_buf, ibcfg_cntr);
2687c478bd9Sstevel@tonic-gate 					while (isxdigit(ch)) {
2697c478bd9Sstevel@tonic-gate 						*cp++ = (char)ch;
2707c478bd9Sstevel@tonic-gate 						ch = GETC(file_buf, ibcfg_cntr);
2717c478bd9Sstevel@tonic-gate 					}
2727c478bd9Sstevel@tonic-gate 					(void) UNGETC(ibcfg_cntr);
2737c478bd9Sstevel@tonic-gate 					token = HEXVAL;
2747c478bd9Sstevel@tonic-gate 				} else {
2757c478bd9Sstevel@tonic-gate 					goto digit;
2767c478bd9Sstevel@tonic-gate 				}
2777c478bd9Sstevel@tonic-gate 			} else {
2787c478bd9Sstevel@tonic-gate 				ch = GETC(file_buf, ibcfg_cntr);
2797c478bd9Sstevel@tonic-gate digit:
2807c478bd9Sstevel@tonic-gate 				while (isdigit(ch)) {
2817c478bd9Sstevel@tonic-gate 					*cp++ = (char)ch;
2827c478bd9Sstevel@tonic-gate 					ch = GETC(file_buf, ibcfg_cntr);
2837c478bd9Sstevel@tonic-gate 				}
2847c478bd9Sstevel@tonic-gate 				(void) UNGETC(ibcfg_cntr);
2857c478bd9Sstevel@tonic-gate 				token = DECVAL;
2867c478bd9Sstevel@tonic-gate 			}
2877c478bd9Sstevel@tonic-gate 		} else if (isalpha(ch) || ch == '\\') {
2887c478bd9Sstevel@tonic-gate 			if (ch != '\\') {
2897c478bd9Sstevel@tonic-gate 				ch = GETC(file_buf, ibcfg_cntr);
2907c478bd9Sstevel@tonic-gate 			} else {
2917c478bd9Sstevel@tonic-gate 				/*
2927c478bd9Sstevel@tonic-gate 				 * if the character was a backslash,
2937c478bd9Sstevel@tonic-gate 				 * back up so we can overwrite it with
2947c478bd9Sstevel@tonic-gate 				 * the next (i.e. escaped) character.
2957c478bd9Sstevel@tonic-gate 				 */
2967c478bd9Sstevel@tonic-gate 				cp--;
2977c478bd9Sstevel@tonic-gate 			}
2987c478bd9Sstevel@tonic-gate 
2997c478bd9Sstevel@tonic-gate 			while (isnamechar(ch) || ch == '\\') {
3007c478bd9Sstevel@tonic-gate 				if (ch == '\\')
3017c478bd9Sstevel@tonic-gate 					ch = GETC(file_buf, ibcfg_cntr);
3027c478bd9Sstevel@tonic-gate 				*cp++ = (char)ch;
3037c478bd9Sstevel@tonic-gate 				ch = GETC(file_buf, ibcfg_cntr);
3047c478bd9Sstevel@tonic-gate 			}
3057c478bd9Sstevel@tonic-gate 			(void) UNGETC(ibcfg_cntr);
3067c478bd9Sstevel@tonic-gate 			token = NAME;
3077c478bd9Sstevel@tonic-gate 		} else
3087c478bd9Sstevel@tonic-gate 			return (-1);
3097c478bd9Sstevel@tonic-gate 		break;
3107c478bd9Sstevel@tonic-gate 	}
3117c478bd9Sstevel@tonic-gate 	*cp = '\0';
3127c478bd9Sstevel@tonic-gate 	return (token);
3137c478bd9Sstevel@tonic-gate }
3147c478bd9Sstevel@tonic-gate 
3157c478bd9Sstevel@tonic-gate 
3167c478bd9Sstevel@tonic-gate /*
3177c478bd9Sstevel@tonic-gate  * Function:
3187c478bd9Sstevel@tonic-gate  *	ib_find_eol
3197c478bd9Sstevel@tonic-gate  * Input:
3207c478bd9Sstevel@tonic-gate  *	NONE
3217c478bd9Sstevel@tonic-gate  * Output:
3227c478bd9Sstevel@tonic-gate  *	NONE
3237c478bd9Sstevel@tonic-gate  * Returns:
3247c478bd9Sstevel@tonic-gate  *	NONE
3257c478bd9Sstevel@tonic-gate  * Description:
3267c478bd9Sstevel@tonic-gate  *	Leave NEWLINE as the next character.
3277c478bd9Sstevel@tonic-gate  */
3287c478bd9Sstevel@tonic-gate static void
ib_find_eol()3297c478bd9Sstevel@tonic-gate ib_find_eol()
3307c478bd9Sstevel@tonic-gate {
3317c478bd9Sstevel@tonic-gate 	int ch;
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 	while ((ch = GETC(file_buf, ibcfg_cntr)) != -1) {
3347c478bd9Sstevel@tonic-gate 		if (isnewline(ch))  {
3357c478bd9Sstevel@tonic-gate 			(void) UNGETC(ibcfg_cntr);
3367c478bd9Sstevel@tonic-gate 			break;
3377c478bd9Sstevel@tonic-gate 		}
3387c478bd9Sstevel@tonic-gate 	}
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate 
3427c478bd9Sstevel@tonic-gate /*
3437c478bd9Sstevel@tonic-gate  * Function:
3447c478bd9Sstevel@tonic-gate  *	ib_get_string
3457c478bd9Sstevel@tonic-gate  * Input:
3467c478bd9Sstevel@tonic-gate  *	tchar		- name of the string
3477c478bd9Sstevel@tonic-gate  * Output:
3487c478bd9Sstevel@tonic-gate  *	llptr		- Valid string
3497c478bd9Sstevel@tonic-gate  * Returns:
3507c478bd9Sstevel@tonic-gate  *	1 for success, NULL for errors.
3517c478bd9Sstevel@tonic-gate  * Description:
3527c478bd9Sstevel@tonic-gate  *	The next item on the line is a string value. Allocate memory for
3537c478bd9Sstevel@tonic-gate  *	it and copy the string. Return 1, and set arg ptr to newly allocated
3547c478bd9Sstevel@tonic-gate  *	and initialized buffer, or NULL if an error occurs.
3557c478bd9Sstevel@tonic-gate  */
3567c478bd9Sstevel@tonic-gate static int
ib_get_string(char ** llptr,char * tchar)3577c478bd9Sstevel@tonic-gate ib_get_string(char **llptr, char *tchar)
3587c478bd9Sstevel@tonic-gate {
3597c478bd9Sstevel@tonic-gate 	int	tlen = strlen(tchar);
3607c478bd9Sstevel@tonic-gate 	char	*cp;
3617c478bd9Sstevel@tonic-gate 	char	*start = (char *)0;
3627c478bd9Sstevel@tonic-gate 
3637c478bd9Sstevel@tonic-gate 	start = tchar;
3647c478bd9Sstevel@tonic-gate 	/* copy string */
3657c478bd9Sstevel@tonic-gate 	if ((cp = (char *)calloc(tlen + 1, sizeof (char))) == (char *)NULL) {
3667c478bd9Sstevel@tonic-gate 		*llptr = NULL;
3677c478bd9Sstevel@tonic-gate 		return (0);
3687c478bd9Sstevel@tonic-gate 	}
3697c478bd9Sstevel@tonic-gate 	bzero(cp, tlen + 1);
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	*llptr = cp;
3727c478bd9Sstevel@tonic-gate 	for (; tlen > 0; tlen--) {
3737c478bd9Sstevel@tonic-gate 		/* convert some common escape sequences */
3747c478bd9Sstevel@tonic-gate 		if (*start == '\\') {
3757c478bd9Sstevel@tonic-gate 			switch (*(start + 1)) {
3767c478bd9Sstevel@tonic-gate 			case 't':
3777c478bd9Sstevel@tonic-gate 				/* tab */
3787c478bd9Sstevel@tonic-gate 				*cp++ = '\t';
3797c478bd9Sstevel@tonic-gate 				tlen--;
3807c478bd9Sstevel@tonic-gate 				start += 2;
3817c478bd9Sstevel@tonic-gate 				break;
3827c478bd9Sstevel@tonic-gate 			case 'n':
3837c478bd9Sstevel@tonic-gate 				/* new line */
3847c478bd9Sstevel@tonic-gate 				*cp++ = '\n';
3857c478bd9Sstevel@tonic-gate 				tlen--;
3867c478bd9Sstevel@tonic-gate 				start += 2;
3877c478bd9Sstevel@tonic-gate 				break;
3887c478bd9Sstevel@tonic-gate 			case 'b':
3897c478bd9Sstevel@tonic-gate 				/* back space */
3907c478bd9Sstevel@tonic-gate 				*cp++ = '\b';
3917c478bd9Sstevel@tonic-gate 				tlen--;
3927c478bd9Sstevel@tonic-gate 				start += 2;
3937c478bd9Sstevel@tonic-gate 				break;
3947c478bd9Sstevel@tonic-gate 			default:
3957c478bd9Sstevel@tonic-gate 				/* simply copy it */
3967c478bd9Sstevel@tonic-gate 				*cp++ = *start++;
3977c478bd9Sstevel@tonic-gate 				break;
3987c478bd9Sstevel@tonic-gate 			}
3997c478bd9Sstevel@tonic-gate 		} else {
4007c478bd9Sstevel@tonic-gate 			*cp++ = *start++;
4017c478bd9Sstevel@tonic-gate 		}
4027c478bd9Sstevel@tonic-gate 	}
4037c478bd9Sstevel@tonic-gate 	*cp = '\0';
4047c478bd9Sstevel@tonic-gate 	return (1);
4057c478bd9Sstevel@tonic-gate }
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 
4087c478bd9Sstevel@tonic-gate /*
4097c478bd9Sstevel@tonic-gate  * Function:
4107c478bd9Sstevel@tonic-gate  *	ib_service_record_add
4117c478bd9Sstevel@tonic-gate  * Input:
4127c478bd9Sstevel@tonic-gate  *	service		- name of the service
4137c478bd9Sstevel@tonic-gate  *	type		- type of the service
4147c478bd9Sstevel@tonic-gate  * Output:
4157c478bd9Sstevel@tonic-gate  *	rec		- one valid service record
4167c478bd9Sstevel@tonic-gate  * Returns:
4177c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
4187c478bd9Sstevel@tonic-gate  * Description:
4197c478bd9Sstevel@tonic-gate  *	Add one record to internal data structures
4207c478bd9Sstevel@tonic-gate  */
4217c478bd9Sstevel@tonic-gate static int
ib_service_record_add(char * service,ib_service_type_t type)4227c478bd9Sstevel@tonic-gate ib_service_record_add(char *service, ib_service_type_t type)
4237c478bd9Sstevel@tonic-gate {
4247c478bd9Sstevel@tonic-gate 	ib_svc_rec_t	*tmp, *recp;
4257c478bd9Sstevel@tonic-gate 
4267c478bd9Sstevel@tonic-gate 	DPRINTF("ib_service_record_add: (%x, %s) "
4277c478bd9Sstevel@tonic-gate 	    "(#port = %d #vppa = %d #hca = %d)\n", type, service,
4287c478bd9Sstevel@tonic-gate 	    ibcfg_nport_services, ibcfg_nvppa_services,
4297c478bd9Sstevel@tonic-gate 	    ibcfg_nhca_services);
4307c478bd9Sstevel@tonic-gate 	recp = (ib_svc_rec_t *)calloc(1, sizeof (ib_svc_rec_t));
4317c478bd9Sstevel@tonic-gate 	if (recp == NULL)
4327c478bd9Sstevel@tonic-gate 		return (CFGA_IB_ALLOC_FAIL);
4337c478bd9Sstevel@tonic-gate 
4347c478bd9Sstevel@tonic-gate 	recp->type = type;
4357c478bd9Sstevel@tonic-gate 	recp->name = strdup((char *)service);
4367c478bd9Sstevel@tonic-gate 	if (type == IB_PORT_SERVICE) {
4377c478bd9Sstevel@tonic-gate 		if (ibcfg_port_head) {
4387c478bd9Sstevel@tonic-gate 			for (tmp = ibcfg_port_head; tmp->next != NULL; )
4397c478bd9Sstevel@tonic-gate 				tmp = tmp->next;
4407c478bd9Sstevel@tonic-gate 			tmp->next = recp;
4417c478bd9Sstevel@tonic-gate 		} else
4427c478bd9Sstevel@tonic-gate 			ibcfg_port_head = recp;
4437c478bd9Sstevel@tonic-gate 		ibcfg_nport_services++;
4447c478bd9Sstevel@tonic-gate 	} else if (type == IB_VPPA_SERVICE) {
4457c478bd9Sstevel@tonic-gate 		if (ibcfg_vppa_head) {
4467c478bd9Sstevel@tonic-gate 			for (tmp = ibcfg_vppa_head; tmp->next != NULL; )
4477c478bd9Sstevel@tonic-gate 				tmp = tmp->next;
4487c478bd9Sstevel@tonic-gate 			tmp->next = recp;
4497c478bd9Sstevel@tonic-gate 		} else
4507c478bd9Sstevel@tonic-gate 			ibcfg_vppa_head = recp;
4517c478bd9Sstevel@tonic-gate 		ibcfg_nvppa_services++;
4527c478bd9Sstevel@tonic-gate 	} else if (type == IB_HCASVC_SERVICE) {
4537c478bd9Sstevel@tonic-gate 		if (ibcfg_hca_head) {
4547c478bd9Sstevel@tonic-gate 			for (tmp = ibcfg_hca_head; tmp->next != NULL; )
4557c478bd9Sstevel@tonic-gate 				tmp = tmp->next;
4567c478bd9Sstevel@tonic-gate 			tmp->next = recp;
4577c478bd9Sstevel@tonic-gate 		} else
4587c478bd9Sstevel@tonic-gate 			ibcfg_hca_head = recp;
4597c478bd9Sstevel@tonic-gate 		ibcfg_nhca_services++;
4607c478bd9Sstevel@tonic-gate 	}
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	return (CFGA_IB_OK);
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate 
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate /*
4677c478bd9Sstevel@tonic-gate  * Function:
4687c478bd9Sstevel@tonic-gate  *	ib_get_services
4697c478bd9Sstevel@tonic-gate  * Input:
4707c478bd9Sstevel@tonic-gate  *	errmsg		- Error message filled in case of a failure
4717c478bd9Sstevel@tonic-gate  * Output:
4727c478bd9Sstevel@tonic-gate  *	rec		- one valid service record
4737c478bd9Sstevel@tonic-gate  * Returns:
4747c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
4757c478bd9Sstevel@tonic-gate  * Description:
4767c478bd9Sstevel@tonic-gate  *	Fetch one record from the IBCONF_FILE
4777c478bd9Sstevel@tonic-gate  */
4787c478bd9Sstevel@tonic-gate static ib_token_t
ib_get_services(char ** errmsg)4797c478bd9Sstevel@tonic-gate ib_get_services(char **errmsg)
4807c478bd9Sstevel@tonic-gate {
4817c478bd9Sstevel@tonic-gate 	char			tokval[MAXLINESIZE];
4827c478bd9Sstevel@tonic-gate 	char			*llptr;
4837c478bd9Sstevel@tonic-gate 	boolean_t		sor = B_TRUE;
4847c478bd9Sstevel@tonic-gate 	ib_token_t		token;
4857c478bd9Sstevel@tonic-gate 	ib_service_type_t	cfgvar;
4867c478bd9Sstevel@tonic-gate 	ib_parse_state_t	parse_state = IB_NEWVAR;
4877c478bd9Sstevel@tonic-gate 
4887c478bd9Sstevel@tonic-gate 	token = ib_lex(tokval, errmsg);
4897c478bd9Sstevel@tonic-gate 	while ((token != EOF) && (token != SEMICOLON)) {
4907c478bd9Sstevel@tonic-gate 		if (token == STAR || token == POUND) {
4917c478bd9Sstevel@tonic-gate 			/* skip comments */
4927c478bd9Sstevel@tonic-gate 			ib_find_eol();
4937c478bd9Sstevel@tonic-gate 		} else if (token == NEWLINE) {
4947c478bd9Sstevel@tonic-gate 			ibcfg_linenum++;
4957c478bd9Sstevel@tonic-gate 		} else if (token == NAME || token == STRING) {
4967c478bd9Sstevel@tonic-gate 			if (parse_state == IB_NEWVAR) {
4977c478bd9Sstevel@tonic-gate 				cfgvar = ib_get_var_type(tokval);
4987c478bd9Sstevel@tonic-gate 				if (cfgvar == IB_NONE) {
4997c478bd9Sstevel@tonic-gate 					parse_state = IB_ERROR;
5007c478bd9Sstevel@tonic-gate 					(void) snprintf(*errmsg, MAXPATHLEN,
5017c478bd9Sstevel@tonic-gate 					    "Syntax Error: Invalid type %s",
5027c478bd9Sstevel@tonic-gate 					    tokval);
5037c478bd9Sstevel@tonic-gate 				} else {
5047c478bd9Sstevel@tonic-gate 					/* Note the beginning of the entry */
5057c478bd9Sstevel@tonic-gate 					if (sor) {
5067c478bd9Sstevel@tonic-gate 						ibcfg_brec = ibcfg_btoken;
5077c478bd9Sstevel@tonic-gate 						sor = B_FALSE;
5087c478bd9Sstevel@tonic-gate 					}
5097c478bd9Sstevel@tonic-gate 					parse_state = IB_CONFIG_VAR;
5107c478bd9Sstevel@tonic-gate 					if (cfgvar == IB_PORT_SERVICE)
5117c478bd9Sstevel@tonic-gate 						bportrec = ibcfg_cntr + 1;
5127c478bd9Sstevel@tonic-gate 					else if (cfgvar == IB_VPPA_SERVICE)
5137c478bd9Sstevel@tonic-gate 						bvpparec = ibcfg_cntr + 1;
5147c478bd9Sstevel@tonic-gate 					else if (cfgvar == IB_HCASVC_SERVICE)
5157c478bd9Sstevel@tonic-gate 						bhcarec = ibcfg_cntr + 1;
5167c478bd9Sstevel@tonic-gate 				}
5177c478bd9Sstevel@tonic-gate 
5187c478bd9Sstevel@tonic-gate 			} else if (parse_state == IB_VAR_VALUE) {
5197c478bd9Sstevel@tonic-gate 				llptr = NULL;
5207c478bd9Sstevel@tonic-gate 				if (ib_get_string(&llptr, tokval)) {
5217c478bd9Sstevel@tonic-gate 					if ((cfgvar == IB_PORT_SERVICE) ||
5227c478bd9Sstevel@tonic-gate 					    (cfgvar == IB_VPPA_SERVICE) ||
5237c478bd9Sstevel@tonic-gate 					    (cfgvar == IB_HCASVC_SERVICE)) {
5247c478bd9Sstevel@tonic-gate 						if (ib_service_record_valid(
5256cd9e705SBill Taylor 						    llptr) &&
5266cd9e705SBill Taylor 						    ib_service_record_add(
5276cd9e705SBill Taylor 						    (char *)llptr, cfgvar) !=
5286cd9e705SBill Taylor 						    CFGA_IB_OK) {
5296cd9e705SBill Taylor 							return (E_O_F);
5307c478bd9Sstevel@tonic-gate 						} else {
5317c478bd9Sstevel@tonic-gate 							parse_state =
5326cd9e705SBill Taylor 							    IB_CONFIG_VAR;
5337c478bd9Sstevel@tonic-gate 						}
5347c478bd9Sstevel@tonic-gate 					} else if ((cfgvar == IB_NAME) ||
5357c478bd9Sstevel@tonic-gate 					    (cfgvar == IB_CLASS)) {
5367c478bd9Sstevel@tonic-gate 						free((char *)llptr);
5377c478bd9Sstevel@tonic-gate 						parse_state = IB_NEWVAR;
5387c478bd9Sstevel@tonic-gate 					} else {
5397c478bd9Sstevel@tonic-gate 						free((char *)llptr);
5407c478bd9Sstevel@tonic-gate 						parse_state = IB_ERROR;
5417c478bd9Sstevel@tonic-gate 					}
5427c478bd9Sstevel@tonic-gate 				} else {
5437c478bd9Sstevel@tonic-gate 					parse_state = IB_ERROR;
5447c478bd9Sstevel@tonic-gate 					(void) snprintf(*errmsg, MAXPATHLEN,
5457c478bd9Sstevel@tonic-gate 					    "Syntax Error: Invalid value %s "
5467c478bd9Sstevel@tonic-gate 					    "for type: %s\n", tokval,
5477c478bd9Sstevel@tonic-gate 					    ibcfg_varlist[cfgvar].name);
5487c478bd9Sstevel@tonic-gate 				}
5497c478bd9Sstevel@tonic-gate 			} else if (parse_state == IB_ERROR) {
5507c478bd9Sstevel@tonic-gate 				/* just skip */
5517c478bd9Sstevel@tonic-gate 				DPRINTF("ib_get_services: ERROR\n");
5527c478bd9Sstevel@tonic-gate 			} else {
5537c478bd9Sstevel@tonic-gate 				parse_state = IB_ERROR;
5547c478bd9Sstevel@tonic-gate 				(void) snprintf(*errmsg, MAXPATHLEN,
5557c478bd9Sstevel@tonic-gate 				    "Syntax Error: at %s", tokval);
5567c478bd9Sstevel@tonic-gate 			}
5577c478bd9Sstevel@tonic-gate 		} else if (token == COMMA || token == EQUALS) {
5587c478bd9Sstevel@tonic-gate 			if (parse_state == IB_CONFIG_VAR) {
5597c478bd9Sstevel@tonic-gate 				if (cfgvar == IB_NONE) {
5607c478bd9Sstevel@tonic-gate 					parse_state = IB_ERROR;
5617c478bd9Sstevel@tonic-gate 					(void) snprintf(*errmsg, MAXPATHLEN,
5627c478bd9Sstevel@tonic-gate 					    "Syntax Error: unexpected '='");
5637c478bd9Sstevel@tonic-gate 				} else {
5647c478bd9Sstevel@tonic-gate 					parse_state = IB_VAR_VALUE;
5657c478bd9Sstevel@tonic-gate 				}
5667c478bd9Sstevel@tonic-gate 			} else if (parse_state != IB_ERROR) {
5677c478bd9Sstevel@tonic-gate 				(void) snprintf(*errmsg, MAXPATHLEN,
5687c478bd9Sstevel@tonic-gate 				    "Syntax Error: unexpected '='");
5697c478bd9Sstevel@tonic-gate 				parse_state = IB_ERROR;
5707c478bd9Sstevel@tonic-gate 			}
5717c478bd9Sstevel@tonic-gate 		} else {
5727c478bd9Sstevel@tonic-gate 			(void) snprintf(*errmsg, MAXPATHLEN,
5737c478bd9Sstevel@tonic-gate 			    "Syntax Error: at: %s", tokval);
5747c478bd9Sstevel@tonic-gate 			parse_state = IB_ERROR;
5757c478bd9Sstevel@tonic-gate 		}
5767c478bd9Sstevel@tonic-gate 		token = ib_lex(tokval, errmsg);
5777c478bd9Sstevel@tonic-gate 		if (ib_get_var_type(tokval) != IB_NONE)
5787c478bd9Sstevel@tonic-gate 			parse_state = IB_NEWVAR;
5797c478bd9Sstevel@tonic-gate 	}
5807c478bd9Sstevel@tonic-gate 	return (token);
5817c478bd9Sstevel@tonic-gate }
5827c478bd9Sstevel@tonic-gate 
5837c478bd9Sstevel@tonic-gate /*
5847c478bd9Sstevel@tonic-gate  * Function:
5857c478bd9Sstevel@tonic-gate  *	ib_cmp_service
5867c478bd9Sstevel@tonic-gate  * Input:
5877c478bd9Sstevel@tonic-gate  *	NONE
5887c478bd9Sstevel@tonic-gate  * Output:
5897c478bd9Sstevel@tonic-gate  *	NONE
5907c478bd9Sstevel@tonic-gate  * Returns:
5917c478bd9Sstevel@tonic-gate  *	B_TRUE if this service is already seen. B_FALSE if not.
5927c478bd9Sstevel@tonic-gate  * Description:
5937c478bd9Sstevel@tonic-gate  *	Compare the service just read from the services already seen.
5947c478bd9Sstevel@tonic-gate  *	Check if this service was already seen or not.
5957c478bd9Sstevel@tonic-gate  */
5967c478bd9Sstevel@tonic-gate static boolean_t
ib_cmp_service()5977c478bd9Sstevel@tonic-gate ib_cmp_service()
5987c478bd9Sstevel@tonic-gate {
5997c478bd9Sstevel@tonic-gate 	ib_svc_rec_t	*recp;
6007c478bd9Sstevel@tonic-gate 
6017c478bd9Sstevel@tonic-gate 	DPRINTF("ib_cmp_service: (%x, %s) "
6027c478bd9Sstevel@tonic-gate 	    "(#port = %d #vppa = %d #hca = %d)\n", service_type,
6037c478bd9Sstevel@tonic-gate 	    service_name, ibcfg_nport_services, ibcfg_nvppa_services,
6047c478bd9Sstevel@tonic-gate 	    ibcfg_nhca_services);
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_port_head; recp != NULL; recp = recp->next) {
6077c478bd9Sstevel@tonic-gate 		DPRINTF("ib_cmp_service:P usvc = %s, usvc_name = %s\n",
6087c478bd9Sstevel@tonic-gate 		    service_name, recp->name ? recp->name : "NONE");
6097c478bd9Sstevel@tonic-gate 		if (recp->name && strcmp(recp->name, service_name) == 0)
6107c478bd9Sstevel@tonic-gate 			return (B_TRUE);
6117c478bd9Sstevel@tonic-gate 	}
6127c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_vppa_head; recp != NULL; recp = recp->next) {
6137c478bd9Sstevel@tonic-gate 		DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
6147c478bd9Sstevel@tonic-gate 		    recp->type, recp->name ? recp->name : "NONE");
6157c478bd9Sstevel@tonic-gate 		if (recp->name && strcmp(recp->name, service_name) == 0)
6167c478bd9Sstevel@tonic-gate 			return (B_TRUE);
6177c478bd9Sstevel@tonic-gate 	}
6187c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_hca_head; recp != NULL; recp = recp->next) {
6197c478bd9Sstevel@tonic-gate 		DPRINTF("ib_cmp_service:V utype = %x, usvc_name = %s\n",
6207c478bd9Sstevel@tonic-gate 		    recp->type, recp->name ? recp->name : "NONE");
6217c478bd9Sstevel@tonic-gate 		if (recp->name && strcmp(recp->name, service_name) == 0)
6227c478bd9Sstevel@tonic-gate 			return (B_TRUE);
6237c478bd9Sstevel@tonic-gate 	}
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate 	return (B_FALSE);
6267c478bd9Sstevel@tonic-gate }
6277c478bd9Sstevel@tonic-gate 
6287c478bd9Sstevel@tonic-gate 
6297c478bd9Sstevel@tonic-gate /*
6307c478bd9Sstevel@tonic-gate  * Function:
6317c478bd9Sstevel@tonic-gate  *	ib_free_service_recs
6327c478bd9Sstevel@tonic-gate  * Input:
6337c478bd9Sstevel@tonic-gate  *	NONE
6347c478bd9Sstevel@tonic-gate  * Output:
6357c478bd9Sstevel@tonic-gate  *	NONE
6367c478bd9Sstevel@tonic-gate  * Returns:
6377c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
6387c478bd9Sstevel@tonic-gate  * Description:
6397c478bd9Sstevel@tonic-gate  *	Free the service records allocated in ib_get_services
6407c478bd9Sstevel@tonic-gate  */
6417c478bd9Sstevel@tonic-gate static void
ib_free_service_recs(void)6427c478bd9Sstevel@tonic-gate ib_free_service_recs(void)
6437c478bd9Sstevel@tonic-gate {
6447c478bd9Sstevel@tonic-gate 	ib_svc_rec_t	*tmp, *recp;
6457c478bd9Sstevel@tonic-gate 
6467c478bd9Sstevel@tonic-gate 	DPRINTF("ib_free_service_recs: "
6477c478bd9Sstevel@tonic-gate 	    "#port_services = %d, #vppa_services = %d, #hca_services = %d\n",
6487c478bd9Sstevel@tonic-gate 	    ibcfg_nport_services, ibcfg_nvppa_services, ibcfg_nhca_services);
6497c478bd9Sstevel@tonic-gate 
6507c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_port_head; recp != NULL; ) {
6517c478bd9Sstevel@tonic-gate 		if (recp && strlen(recp->name))
6527c478bd9Sstevel@tonic-gate 			S_FREE(recp->name);
6537c478bd9Sstevel@tonic-gate 		tmp = recp;
6547c478bd9Sstevel@tonic-gate 		recp = recp->next;
6557c478bd9Sstevel@tonic-gate 		S_FREE(tmp);
6567c478bd9Sstevel@tonic-gate 	}
6577c478bd9Sstevel@tonic-gate 
6587c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_vppa_head; recp != NULL; ) {
6597c478bd9Sstevel@tonic-gate 		if (recp && strlen(recp->name))
6607c478bd9Sstevel@tonic-gate 			S_FREE(recp->name);
6617c478bd9Sstevel@tonic-gate 		tmp = recp;
6627c478bd9Sstevel@tonic-gate 		recp = recp->next;
6637c478bd9Sstevel@tonic-gate 		S_FREE(tmp);
6647c478bd9Sstevel@tonic-gate 	}
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate 	for (recp = ibcfg_hca_head; recp != NULL; ) {
6677c478bd9Sstevel@tonic-gate 		if (recp && strlen(recp->name))
6687c478bd9Sstevel@tonic-gate 			S_FREE(recp->name);
6697c478bd9Sstevel@tonic-gate 		tmp = recp;
6707c478bd9Sstevel@tonic-gate 		recp = recp->next;
6717c478bd9Sstevel@tonic-gate 		S_FREE(tmp);
6727c478bd9Sstevel@tonic-gate 	}
6737c478bd9Sstevel@tonic-gate }
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate /*
6777c478bd9Sstevel@tonic-gate  * Function:
6787c478bd9Sstevel@tonic-gate  *	ib_cleanup_file
6797c478bd9Sstevel@tonic-gate  * Input:
6807c478bd9Sstevel@tonic-gate  *	rval		- error return value
6817c478bd9Sstevel@tonic-gate  * Output:
6827c478bd9Sstevel@tonic-gate  *	NONE
6837c478bd9Sstevel@tonic-gate  * Returns:
6847c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
6857c478bd9Sstevel@tonic-gate  * Description:
6867c478bd9Sstevel@tonic-gate  *	Cleanup  IBCONF_FILE etc.
6877c478bd9Sstevel@tonic-gate  */
6887c478bd9Sstevel@tonic-gate static int
ib_cleanup_file(int rval)6897c478bd9Sstevel@tonic-gate ib_cleanup_file(int rval)
6907c478bd9Sstevel@tonic-gate {
6917c478bd9Sstevel@tonic-gate 	int	rv = rval;
6927c478bd9Sstevel@tonic-gate 
6937c478bd9Sstevel@tonic-gate 	ib_free_service_recs();
6947c478bd9Sstevel@tonic-gate 	if (lockf(ibcfg_fd, F_ULOCK, 0) == -1) {
6957c478bd9Sstevel@tonic-gate 		DPRINTF("ib_cleanup_file: unlock file %s failed\n",
6967c478bd9Sstevel@tonic-gate 		    ibconf_file);
6977c478bd9Sstevel@tonic-gate 		rv = CFGA_IB_UNLOCK_FILE_ERR;
6987c478bd9Sstevel@tonic-gate 	}
6997c478bd9Sstevel@tonic-gate 	S_FREE(file_buf);
7007c478bd9Sstevel@tonic-gate 	close(ibcfg_fd);
7017c478bd9Sstevel@tonic-gate 	ibcfg_fd = -1;
7027c478bd9Sstevel@tonic-gate 	if (ibcfg_tmpfd && wrote_tmp == B_TRUE) {
7037c478bd9Sstevel@tonic-gate 		DPRINTF("ib_cleanup_file: tmpfile %s being renamed to %s\n",
7047c478bd9Sstevel@tonic-gate 		    tmpnamef, IBCONF_FILE);
7057c478bd9Sstevel@tonic-gate 		close(ibcfg_tmpfd);
7067c478bd9Sstevel@tonic-gate 		rename((const char *)tmpnamef, (const char *)IBCONF_FILE);
7077c478bd9Sstevel@tonic-gate 		unlink(tmpnamef);
7087c478bd9Sstevel@tonic-gate 	}
7097c478bd9Sstevel@tonic-gate 	(void) mutex_unlock(&ibcfg_lock);
7107c478bd9Sstevel@tonic-gate 	return (rv);
7117c478bd9Sstevel@tonic-gate }
7127c478bd9Sstevel@tonic-gate 
7137c478bd9Sstevel@tonic-gate 
7147c478bd9Sstevel@tonic-gate /*
7157c478bd9Sstevel@tonic-gate  * Function:
7167c478bd9Sstevel@tonic-gate  *	ib_init_file
7177c478bd9Sstevel@tonic-gate  * Input:
7187c478bd9Sstevel@tonic-gate  *	NONE
7197c478bd9Sstevel@tonic-gate  * Output:
7207c478bd9Sstevel@tonic-gate  *	errmsg		- Error message filled in case of a failure
7217c478bd9Sstevel@tonic-gate  * Returns:
7227c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
7237c478bd9Sstevel@tonic-gate  * Description:
7247c478bd9Sstevel@tonic-gate  *	Initialize IBCONF_FILE for reading
7257c478bd9Sstevel@tonic-gate  */
7267c478bd9Sstevel@tonic-gate static int
ib_init_file(char ** errmsg)7277c478bd9Sstevel@tonic-gate ib_init_file(char **errmsg)
7287c478bd9Sstevel@tonic-gate {
7297c478bd9Sstevel@tonic-gate 	(void) mutex_lock(&ibcfg_lock);
7307c478bd9Sstevel@tonic-gate 
7317c478bd9Sstevel@tonic-gate 	if (*errmsg == (char *)NULL) {
7327c478bd9Sstevel@tonic-gate 		if ((*errmsg = calloc(MAXPATHLEN, 1)) == (char *)NULL) {
7337c478bd9Sstevel@tonic-gate 			(void) mutex_unlock(&ibcfg_lock);
7347c478bd9Sstevel@tonic-gate 			DPRINTF("ib_init_file: calloc errmsg failed\n");
7357c478bd9Sstevel@tonic-gate 			return (CFGA_IB_CONFIG_FILE_ERR);
7367c478bd9Sstevel@tonic-gate 		}
7377c478bd9Sstevel@tonic-gate 	}
7387c478bd9Sstevel@tonic-gate 
7397c478bd9Sstevel@tonic-gate 	/* Open the .conf file */
7407c478bd9Sstevel@tonic-gate 	if ((ibcfg_fd = open(ibconf_file, O_RDWR, 0666)) == -1) {
7417c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN,
7427c478bd9Sstevel@tonic-gate 		    "failed to open %s file\n", ibconf_file);
7437c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&ibcfg_lock);
7447c478bd9Sstevel@tonic-gate 		return (CFGA_IB_CONFIG_FILE_ERR);
7457c478bd9Sstevel@tonic-gate 	}
7467c478bd9Sstevel@tonic-gate 
7477c478bd9Sstevel@tonic-gate 	/* Lock the file so that another cfgadm instance doesn't modify it */
7487c478bd9Sstevel@tonic-gate 	if (lockf(ibcfg_fd, F_TLOCK, 0) == -1) {
7497c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN,
7507c478bd9Sstevel@tonic-gate 		    "failed to lock %s file\n", ibconf_file);
7517c478bd9Sstevel@tonic-gate 		close(ibcfg_fd);
7527c478bd9Sstevel@tonic-gate 		ibcfg_fd = -1;
7537c478bd9Sstevel@tonic-gate 		(void) mutex_unlock(&ibcfg_lock);
7547c478bd9Sstevel@tonic-gate 		return (CFGA_IB_LOCK_FILE_ERR);
7557c478bd9Sstevel@tonic-gate 	}
7567c478bd9Sstevel@tonic-gate 
7577c478bd9Sstevel@tonic-gate 	if (fstat(ibcfg_fd, &ibcfg_st) != 0) {
7587c478bd9Sstevel@tonic-gate 		DPRINTF("ib_init_file: failed to fstat %s file\n", ibconf_file);
7597c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
7607c478bd9Sstevel@tonic-gate 	}
7617c478bd9Sstevel@tonic-gate 
7627c478bd9Sstevel@tonic-gate 	/* Allocate a buffer for the file */
7637c478bd9Sstevel@tonic-gate 	if ((file_buf = (char *)malloc(ibcfg_st.st_size)) == NULL) {
7647c478bd9Sstevel@tonic-gate 		DPRINTF("ib_init_file: failed to fstat %s file\n",
7657c478bd9Sstevel@tonic-gate 		    ibconf_file);
7667c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
7677c478bd9Sstevel@tonic-gate 	}
7687c478bd9Sstevel@tonic-gate 
7697c478bd9Sstevel@tonic-gate 	/* Check if size matches */
7707c478bd9Sstevel@tonic-gate 	if (ibcfg_st.st_size != read(ibcfg_fd, file_buf, ibcfg_st.st_size)) {
7717c478bd9Sstevel@tonic-gate 		DPRINTF("ib_init_file: failed to read %s file\n", ibconf_file);
7727c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
7737c478bd9Sstevel@tonic-gate 	}
7747c478bd9Sstevel@tonic-gate 
7757c478bd9Sstevel@tonic-gate 	/*
7767c478bd9Sstevel@tonic-gate 	 * These variables need to be reinitialized here as they may
7777c478bd9Sstevel@tonic-gate 	 * have been modified by a previous thread that called this
7787c478bd9Sstevel@tonic-gate 	 * function
7797c478bd9Sstevel@tonic-gate 	 */
7807c478bd9Sstevel@tonic-gate 	ibcfg_linenum = 1;
7817c478bd9Sstevel@tonic-gate 	ibcfg_cntr = 0;
7827c478bd9Sstevel@tonic-gate 	ibcfg_brec = 0;
7837c478bd9Sstevel@tonic-gate 	ibcfg_btoken = 0;
7847c478bd9Sstevel@tonic-gate 
7857c478bd9Sstevel@tonic-gate 	ibcfg_nport_services = 0;
7867c478bd9Sstevel@tonic-gate 	ibcfg_nvppa_services = 0;
7877c478bd9Sstevel@tonic-gate 	ibcfg_nhca_services = 0;
7887c478bd9Sstevel@tonic-gate 	ibcfg_port_head = (ib_svc_rec_t *)NULL;
7897c478bd9Sstevel@tonic-gate 	ibcfg_vppa_head = (ib_svc_rec_t *)NULL;
7907c478bd9Sstevel@tonic-gate 	ibcfg_hca_head = (ib_svc_rec_t *)NULL;
7917c478bd9Sstevel@tonic-gate 	return (CFGA_IB_OK);
7927c478bd9Sstevel@tonic-gate }
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 
7957c478bd9Sstevel@tonic-gate /*
7967c478bd9Sstevel@tonic-gate  * Function:
7977c478bd9Sstevel@tonic-gate  *	ib_add_service
7987c478bd9Sstevel@tonic-gate  * Input:
7997c478bd9Sstevel@tonic-gate  *	NONE
8007c478bd9Sstevel@tonic-gate  * Output:
8017c478bd9Sstevel@tonic-gate  *	errmsg		- Error message filled in case of a failure
8027c478bd9Sstevel@tonic-gate  * Returns:
8037c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
8047c478bd9Sstevel@tonic-gate  * Description:
8057c478bd9Sstevel@tonic-gate  *	open IBCONF_FILE and add "service_name".
8067c478bd9Sstevel@tonic-gate  */
8077c478bd9Sstevel@tonic-gate int
ib_add_service(char ** errmsg)8087c478bd9Sstevel@tonic-gate ib_add_service(char **errmsg)
8097c478bd9Sstevel@tonic-gate {
8107c478bd9Sstevel@tonic-gate 	int		rval;
8117c478bd9Sstevel@tonic-gate 	char		*sbuf;
8127c478bd9Sstevel@tonic-gate 	boolean_t	found = B_FALSE;
8137c478bd9Sstevel@tonic-gate 	ib_token_t	token = NEWLINE;
8147c478bd9Sstevel@tonic-gate 
8157c478bd9Sstevel@tonic-gate 	DPRINTF("ib_add_service: type = %x, service_name=%s\n", service_type,
8167c478bd9Sstevel@tonic-gate 	    service_name);
8177c478bd9Sstevel@tonic-gate 	if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
8187c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: initializing file failed\n");
8197c478bd9Sstevel@tonic-gate 		return (rval);
8207c478bd9Sstevel@tonic-gate 	}
8217c478bd9Sstevel@tonic-gate 
8227c478bd9Sstevel@tonic-gate 	/* Start reading the file */
8237c478bd9Sstevel@tonic-gate 	while (token != EOF) {
8247c478bd9Sstevel@tonic-gate 		token = ib_get_services(errmsg);
8257c478bd9Sstevel@tonic-gate 		found = ib_cmp_service();
8267c478bd9Sstevel@tonic-gate 		if (found == B_TRUE) {
8277c478bd9Sstevel@tonic-gate 			DPRINTF("ib_add_service: token=%x, found=%x\n",
8287c478bd9Sstevel@tonic-gate 			    token, found);
8297c478bd9Sstevel@tonic-gate 			break;
8307c478bd9Sstevel@tonic-gate 		}
8317c478bd9Sstevel@tonic-gate 	}
8327c478bd9Sstevel@tonic-gate 
8337c478bd9Sstevel@tonic-gate 	/* Service shouldn't already exist while adding */
8347c478bd9Sstevel@tonic-gate 	if (found) {
8357c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN, "service entry %s exists ",
8367c478bd9Sstevel@tonic-gate 		    service_name);
8377c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: invalid add operation\n");
8387c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
8397c478bd9Sstevel@tonic-gate 	}
8407c478bd9Sstevel@tonic-gate 
8417c478bd9Sstevel@tonic-gate 	DPRINTF("!FOUND and adding\n");
8427c478bd9Sstevel@tonic-gate 	switch (service_type) {
8437c478bd9Sstevel@tonic-gate 		case IB_PORT_SERVICE :
8447c478bd9Sstevel@tonic-gate 			ibcfg_brec = bportrec;
8457c478bd9Sstevel@tonic-gate 			break;
8467c478bd9Sstevel@tonic-gate 		case IB_VPPA_SERVICE :
8477c478bd9Sstevel@tonic-gate 			ibcfg_brec = bvpparec;
8487c478bd9Sstevel@tonic-gate 			break;
8497c478bd9Sstevel@tonic-gate 		case IB_HCASVC_SERVICE :
8507c478bd9Sstevel@tonic-gate 			ibcfg_brec = bhcarec;
8517c478bd9Sstevel@tonic-gate 			break;
8527c478bd9Sstevel@tonic-gate 		default :
8537c478bd9Sstevel@tonic-gate 			DPRINTF("ib_add_service: invalid add operation\n");
8547c478bd9Sstevel@tonic-gate 			return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR));
8557c478bd9Sstevel@tonic-gate 	}
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 
8587c478bd9Sstevel@tonic-gate 	if ((sbuf = (char *)calloc(12, sizeof (char))) == NULL) {
8597c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: failed to calloc sbuf %s file\n",
8607c478bd9Sstevel@tonic-gate 		    ibconf_file);
8617c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
8627c478bd9Sstevel@tonic-gate 	}
8637c478bd9Sstevel@tonic-gate 	if (file_buf[ibcfg_brec] == '"' && file_buf[ibcfg_brec + 1] == '"') {
8647c478bd9Sstevel@tonic-gate 		(void) snprintf(sbuf, 9, "%s", service_name);
8657c478bd9Sstevel@tonic-gate 		ibcfg_brec += 1;
8667c478bd9Sstevel@tonic-gate 	} else
8677c478bd9Sstevel@tonic-gate 		(void) snprintf(sbuf, 9, "\"%s\", ", service_name);
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 
8707c478bd9Sstevel@tonic-gate 	/* Seek to the beginning of the file */
8717c478bd9Sstevel@tonic-gate 	if (lseek(ibcfg_fd, ibcfg_brec, SEEK_SET) == -1) {
8727c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: lseek %s file failed\n", ibconf_file);
8737c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8747c478bd9Sstevel@tonic-gate 	}
8757c478bd9Sstevel@tonic-gate 
8767c478bd9Sstevel@tonic-gate 	/* Add service to w/ IBNEX  */
8777c478bd9Sstevel@tonic-gate 	if (ib_conf_control_ioctl(service_name, IBNEX_CONF_ENTRY_ADD)) {
8787c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: ioctl add failed %d\n", errno);
8797c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN, "failed to add "
8807c478bd9Sstevel@tonic-gate 		    "%s service incore ", service_name);
8817c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
8827c478bd9Sstevel@tonic-gate 	}
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate 	/* Write the modified file */
8857c478bd9Sstevel@tonic-gate 	if (write(ibcfg_fd, sbuf, strlen(sbuf)) == -1) {
8867c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: write %s file failed\n", ibconf_file);
8877c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8887c478bd9Sstevel@tonic-gate 	}
8897c478bd9Sstevel@tonic-gate 
8907c478bd9Sstevel@tonic-gate 	/* Write the rest of the file as it was */
8917c478bd9Sstevel@tonic-gate 	if (write(ibcfg_fd, file_buf + ibcfg_brec,
8927c478bd9Sstevel@tonic-gate 	    ibcfg_st.st_size - ibcfg_brec) == -1) {
8937c478bd9Sstevel@tonic-gate 		DPRINTF("ib_add_service: write %s file failed 2\n",
8947c478bd9Sstevel@tonic-gate 		    ibconf_file);
8957c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
8967c478bd9Sstevel@tonic-gate 	}
8977c478bd9Sstevel@tonic-gate 
8987c478bd9Sstevel@tonic-gate 	return (ib_cleanup_file(rval));
8997c478bd9Sstevel@tonic-gate }
9007c478bd9Sstevel@tonic-gate 
9017c478bd9Sstevel@tonic-gate 
9027c478bd9Sstevel@tonic-gate /*
9037c478bd9Sstevel@tonic-gate  * Function:
9047c478bd9Sstevel@tonic-gate  *	ib_delete_service
9057c478bd9Sstevel@tonic-gate  * Input:
9067c478bd9Sstevel@tonic-gate  *	NONE
9077c478bd9Sstevel@tonic-gate  * Output:
9087c478bd9Sstevel@tonic-gate  *	errmsg		- Error message filled in case of a failure
9097c478bd9Sstevel@tonic-gate  * Returns:
9107c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
9117c478bd9Sstevel@tonic-gate  * Description:
9127c478bd9Sstevel@tonic-gate  *	open ib.conf file and delete "service_name"
9137c478bd9Sstevel@tonic-gate  */
9147c478bd9Sstevel@tonic-gate int
ib_delete_service(char ** errmsg)9157c478bd9Sstevel@tonic-gate ib_delete_service(char **errmsg)
9167c478bd9Sstevel@tonic-gate {
9177c478bd9Sstevel@tonic-gate 	int		rval;
9187c478bd9Sstevel@tonic-gate 	int		num_svcs;
9197c478bd9Sstevel@tonic-gate 	int		skip_len;
9207c478bd9Sstevel@tonic-gate 	int		sbuf_len;
9217c478bd9Sstevel@tonic-gate 	int		tot_len;
9227c478bd9Sstevel@tonic-gate 	char		tmp[12];
9237c478bd9Sstevel@tonic-gate 	char		*sbuf = (char *)NULL;
9247c478bd9Sstevel@tonic-gate 	boolean_t	found = B_FALSE;
9257c478bd9Sstevel@tonic-gate 	ib_token_t	token = NEWLINE;
9267c478bd9Sstevel@tonic-gate 	ib_svc_rec_t	*recp;
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 	DPRINTF("ib_delete_service: type = %x, service_name=%s\n",
9297c478bd9Sstevel@tonic-gate 	    service_type, service_name);
9307c478bd9Sstevel@tonic-gate 	if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
9317c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: initializing file failed\n");
9327c478bd9Sstevel@tonic-gate 		return (rval);
9337c478bd9Sstevel@tonic-gate 	}
9347c478bd9Sstevel@tonic-gate 
9357c478bd9Sstevel@tonic-gate 	/* Start reading the file */
9367c478bd9Sstevel@tonic-gate 	while (token != EOF) {
9377c478bd9Sstevel@tonic-gate 		token = ib_get_services(errmsg);
9387c478bd9Sstevel@tonic-gate 		found = ib_cmp_service();		/* search for a match */
9397c478bd9Sstevel@tonic-gate 		if (found == B_TRUE) {
9407c478bd9Sstevel@tonic-gate 			DPRINTF("ib_delete_service: token=%x, found=%x\n",
9417c478bd9Sstevel@tonic-gate 			    token, found);
9427c478bd9Sstevel@tonic-gate 			break;
9437c478bd9Sstevel@tonic-gate 		}
9447c478bd9Sstevel@tonic-gate 	}
9457c478bd9Sstevel@tonic-gate 
9467c478bd9Sstevel@tonic-gate 	/* No service found, return */
9477c478bd9Sstevel@tonic-gate 	if (!found) {
9487c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: invalid delete operation\n");
9497c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN, "service entry %s "
9507c478bd9Sstevel@tonic-gate 		    "does not exist ", service_name);
9517c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_SVC_NO_EXIST_ERR));
9527c478bd9Sstevel@tonic-gate 	}
9537c478bd9Sstevel@tonic-gate 
9547c478bd9Sstevel@tonic-gate 	DPRINTF("FOUND and deleting \n");
9557c478bd9Sstevel@tonic-gate 
9567c478bd9Sstevel@tonic-gate 	switch (service_type) {
9577c478bd9Sstevel@tonic-gate 		case IB_PORT_SERVICE :
9587c478bd9Sstevel@tonic-gate 			ibcfg_brec = bportrec;
9597c478bd9Sstevel@tonic-gate 			num_svcs = ibcfg_nport_services;
9607c478bd9Sstevel@tonic-gate 			break;
9617c478bd9Sstevel@tonic-gate 		case IB_VPPA_SERVICE :
9627c478bd9Sstevel@tonic-gate 			ibcfg_brec = bvpparec;
9637c478bd9Sstevel@tonic-gate 			num_svcs = ibcfg_nvppa_services;
9647c478bd9Sstevel@tonic-gate 			break;
9657c478bd9Sstevel@tonic-gate 		case IB_HCASVC_SERVICE :
9667c478bd9Sstevel@tonic-gate 			ibcfg_brec = bhcarec;
9677c478bd9Sstevel@tonic-gate 			num_svcs = ibcfg_nhca_services;
9687c478bd9Sstevel@tonic-gate 			break;
9697c478bd9Sstevel@tonic-gate 		default :
9707c478bd9Sstevel@tonic-gate 			DPRINTF("ib_delete_service: invalid delete "
9717c478bd9Sstevel@tonic-gate 			    "operation\n");
9727c478bd9Sstevel@tonic-gate 			return (ib_cleanup_file(CFGA_IB_SVC_INVAL_ERR));
9737c478bd9Sstevel@tonic-gate 	}
9747c478bd9Sstevel@tonic-gate 
9757c478bd9Sstevel@tonic-gate 	if ((sbuf = (char *)calloc(num_svcs * 8, sizeof (char))) == NULL) {
9767c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: sbuf alloc failed %s\n",
9777c478bd9Sstevel@tonic-gate 		    ibconf_file);
9787c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
9797c478bd9Sstevel@tonic-gate 	}
9807c478bd9Sstevel@tonic-gate 
9817c478bd9Sstevel@tonic-gate 	if (num_svcs == 1) {
9826cd9e705SBill Taylor 		(void) snprintf(sbuf, 9, "\"\"");
9836cd9e705SBill Taylor 		sbuf_len = 2;
9846cd9e705SBill Taylor 		skip_len = 0;
9857c478bd9Sstevel@tonic-gate 	} else {
9867c478bd9Sstevel@tonic-gate 		if (service_type == IB_PORT_SERVICE) {
9877c478bd9Sstevel@tonic-gate 			for (recp = ibcfg_port_head; recp; recp = recp->next) {
9887c478bd9Sstevel@tonic-gate 				if (strcmp(recp->name, service_name) == 0)
9897c478bd9Sstevel@tonic-gate 					continue;
9907c478bd9Sstevel@tonic-gate 				(void) snprintf(tmp, 9, "\"%s\", ", recp->name);
9917c478bd9Sstevel@tonic-gate 				(void) strcat(sbuf, tmp);
9927c478bd9Sstevel@tonic-gate 			}
9937c478bd9Sstevel@tonic-gate 
9947c478bd9Sstevel@tonic-gate 		} else if (service_type == IB_VPPA_SERVICE) {
9957c478bd9Sstevel@tonic-gate 			for (recp = ibcfg_vppa_head; recp; recp = recp->next) {
9967c478bd9Sstevel@tonic-gate 				if (strcmp(recp->name, service_name) == 0)
9977c478bd9Sstevel@tonic-gate 					continue;
9987c478bd9Sstevel@tonic-gate 				(void) snprintf(tmp, 9, "\"%s\", ", recp->name);
9997c478bd9Sstevel@tonic-gate 				(void) strcat(sbuf, tmp);
10007c478bd9Sstevel@tonic-gate 			}
10017c478bd9Sstevel@tonic-gate 		} else {
10027c478bd9Sstevel@tonic-gate 			for (recp = ibcfg_hca_head; recp; recp = recp->next) {
10037c478bd9Sstevel@tonic-gate 				if (strcmp(recp->name, service_name) == 0)
10047c478bd9Sstevel@tonic-gate 					continue;
10057c478bd9Sstevel@tonic-gate 				(void) snprintf(tmp, 9, "\"%s\", ", recp->name);
10067c478bd9Sstevel@tonic-gate 				(void) strcat(sbuf, tmp);
10077c478bd9Sstevel@tonic-gate 			}
10087c478bd9Sstevel@tonic-gate 		}
10097c478bd9Sstevel@tonic-gate 		skip_len = 4;
10106cd9e705SBill Taylor 		sbuf_len = strlen(sbuf);
10116cd9e705SBill Taylor 		sbuf[sbuf_len - 2] = '\0';
10126cd9e705SBill Taylor 		sbuf_len -= 2;
10137c478bd9Sstevel@tonic-gate 	}
10147c478bd9Sstevel@tonic-gate 
10157c478bd9Sstevel@tonic-gate 	tot_len = strlen(service_name) + skip_len;
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	tmpnamef = tmpnam(ibconf_file);
10187c478bd9Sstevel@tonic-gate 	DPRINTF("ib_delete_service: tmpnamef = %s\n", tmpnamef);
10197c478bd9Sstevel@tonic-gate 	if ((ibcfg_tmpfd = creat(tmpnamef, 0666)) == -1) {
10207c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN,
10217c478bd9Sstevel@tonic-gate 		    "failed to creat %s file\n", ibconf_file);
10227c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: failed to creat tmpnamef\n");
10237c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_ALLOC_FAIL));
10247c478bd9Sstevel@tonic-gate 	}
10257c478bd9Sstevel@tonic-gate 
10267c478bd9Sstevel@tonic-gate 	/* Delete service from IBNEX  */
10277c478bd9Sstevel@tonic-gate 	if (ib_conf_control_ioctl(service_name, IBNEX_CONF_ENTRY_DEL)) {
10287c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: ioctl delete failed %d\n", errno);
10297c478bd9Sstevel@tonic-gate 		(void) snprintf(*errmsg, MAXPATHLEN, "failed to delete "
10307c478bd9Sstevel@tonic-gate 		    "in core %s entry ", service_name);
10317c478bd9Sstevel@tonic-gate 		close(ibcfg_tmpfd);
10327c478bd9Sstevel@tonic-gate 		unlink(tmpnamef);
10337c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_SVC_EXISTS_ERR));
10347c478bd9Sstevel@tonic-gate 	}
10357c478bd9Sstevel@tonic-gate 
10367c478bd9Sstevel@tonic-gate 	/* write till ibcfg_brec */
10377c478bd9Sstevel@tonic-gate 	if (write(ibcfg_tmpfd, file_buf, ibcfg_brec) == -1) {
10387c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: write %s file failed 1\n",
10397c478bd9Sstevel@tonic-gate 		    ibconf_file);
10407c478bd9Sstevel@tonic-gate 		close(ibcfg_tmpfd);
10417c478bd9Sstevel@tonic-gate 		unlink(tmpnamef);
10427c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10437c478bd9Sstevel@tonic-gate 	}
10447c478bd9Sstevel@tonic-gate 
10457c478bd9Sstevel@tonic-gate 	/* write modified buffer */
10467c478bd9Sstevel@tonic-gate 	if (write(ibcfg_tmpfd, sbuf, sbuf_len) == -1) {
10477c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: write %s file failed 2\n",
10487c478bd9Sstevel@tonic-gate 		    ibconf_file);
10497c478bd9Sstevel@tonic-gate 		close(ibcfg_tmpfd);
10507c478bd9Sstevel@tonic-gate 		unlink(tmpnamef);
10517c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10527c478bd9Sstevel@tonic-gate 	}
10537c478bd9Sstevel@tonic-gate 
10547c478bd9Sstevel@tonic-gate 	/* Write the rest of the file as it was */
10557c478bd9Sstevel@tonic-gate 	if (write(ibcfg_tmpfd, file_buf + ibcfg_brec + sbuf_len + tot_len,
10566cd9e705SBill Taylor 	    ibcfg_st.st_size - ibcfg_brec - sbuf_len - tot_len) == -1) {
10577c478bd9Sstevel@tonic-gate 		DPRINTF("ib_delete_service: write %s file failed 3\n",
10587c478bd9Sstevel@tonic-gate 		    ibconf_file);
10597c478bd9Sstevel@tonic-gate 		close(ibcfg_tmpfd);
10607c478bd9Sstevel@tonic-gate 		unlink(tmpnamef);
10617c478bd9Sstevel@tonic-gate 		return (ib_cleanup_file(CFGA_IB_CONFIG_FILE_ERR));
10627c478bd9Sstevel@tonic-gate 	}
10637c478bd9Sstevel@tonic-gate 	wrote_tmp = B_TRUE;
10647c478bd9Sstevel@tonic-gate 
10657c478bd9Sstevel@tonic-gate 	/* No error encountered */
10667c478bd9Sstevel@tonic-gate 	return (ib_cleanup_file(rval));
10677c478bd9Sstevel@tonic-gate }
10687c478bd9Sstevel@tonic-gate 
10697c478bd9Sstevel@tonic-gate 
10707c478bd9Sstevel@tonic-gate /*
10717c478bd9Sstevel@tonic-gate  * Function:
10727c478bd9Sstevel@tonic-gate  *	ib_list_services
10737c478bd9Sstevel@tonic-gate  * Input:
10747c478bd9Sstevel@tonic-gate  *	msgp		- CFGADM message pointer
10757c478bd9Sstevel@tonic-gate  * Output:
10767c478bd9Sstevel@tonic-gate  *	errmsg		- Error message filled in case of a failure
10777c478bd9Sstevel@tonic-gate  * Returns:
10787c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK on success or an appropriate error
10797c478bd9Sstevel@tonic-gate  * Description:
10807c478bd9Sstevel@tonic-gate  *	open IBCONF_FILE and list services.
10817c478bd9Sstevel@tonic-gate  */
10827c478bd9Sstevel@tonic-gate int
ib_list_services(struct cfga_msg * msgp,char ** errmsg)10837c478bd9Sstevel@tonic-gate ib_list_services(struct cfga_msg *msgp, char **errmsg)
10847c478bd9Sstevel@tonic-gate {
10857c478bd9Sstevel@tonic-gate 	int		rval = CFGA_IB_OK;
10867c478bd9Sstevel@tonic-gate 	char		pbuf[IBCONF_SERVICE_HDR_LEN];
10877c478bd9Sstevel@tonic-gate 	ib_token_t	token = NEWLINE;
10887c478bd9Sstevel@tonic-gate 	ib_svc_rec_t	*recp;
10897c478bd9Sstevel@tonic-gate 
10907c478bd9Sstevel@tonic-gate 	DPRINTF("ib_list_services:\n");
10917c478bd9Sstevel@tonic-gate 	if ((rval = ib_init_file(errmsg)) != CFGA_IB_OK) {
10927c478bd9Sstevel@tonic-gate 		DPRINTF("ib_list_services: initializing file failed\n");
10937c478bd9Sstevel@tonic-gate 		return (rval);
10947c478bd9Sstevel@tonic-gate 	}
10957c478bd9Sstevel@tonic-gate 
10967c478bd9Sstevel@tonic-gate 	/* start reading the file */
10977c478bd9Sstevel@tonic-gate 	while (token != EOF)
10987c478bd9Sstevel@tonic-gate 		token = ib_get_services(errmsg);
10997c478bd9Sstevel@tonic-gate 
11007c478bd9Sstevel@tonic-gate 	DPRINTF("ib_list_services: #port_services = %d, #vppa_services = %d,"
11017c478bd9Sstevel@tonic-gate 	    " #hca_services = %d\n", ibcfg_nport_services,
11027c478bd9Sstevel@tonic-gate 	    ibcfg_nvppa_services, ibcfg_nhca_services);
11037c478bd9Sstevel@tonic-gate 
11047c478bd9Sstevel@tonic-gate 	bzero(pbuf, IBCONF_SERVICE_HDR_LEN);
11057c478bd9Sstevel@tonic-gate 	if (ibcfg_nport_services) {
11067c478bd9Sstevel@tonic-gate 		(void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11077c478bd9Sstevel@tonic-gate 		    IBCONF_PORT_SERVICE_HDR);
11087c478bd9Sstevel@tonic-gate 		cfga_msg(msgp, pbuf);
11097c478bd9Sstevel@tonic-gate 		for (recp = ibcfg_port_head; recp; recp = recp->next) {
11107c478bd9Sstevel@tonic-gate 			DPRINTF("ib_list_services: svc_name = %s\n",
11117c478bd9Sstevel@tonic-gate 			    recp->name ? recp->name : "NONE");
11127c478bd9Sstevel@tonic-gate 			(void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11137c478bd9Sstevel@tonic-gate 			cfga_msg(msgp, pbuf);
11147c478bd9Sstevel@tonic-gate 		}
11157c478bd9Sstevel@tonic-gate 		(void) snprintf(pbuf, 2, "\n");
11167c478bd9Sstevel@tonic-gate 		cfga_msg(msgp, pbuf);
11177c478bd9Sstevel@tonic-gate 	}
11187c478bd9Sstevel@tonic-gate 
11197c478bd9Sstevel@tonic-gate 	if (ibcfg_nvppa_services) {
11207c478bd9Sstevel@tonic-gate 		(void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11217c478bd9Sstevel@tonic-gate 		    IBCONF_VPPA_SERVICE_HDR);
11227c478bd9Sstevel@tonic-gate 		cfga_msg(msgp, pbuf);
11237c478bd9Sstevel@tonic-gate 		for (recp = ibcfg_vppa_head; recp; recp = recp->next) {
11247c478bd9Sstevel@tonic-gate 			DPRINTF("ib_list_services: svc_name = %s\n",
11257c478bd9Sstevel@tonic-gate 			    strlen(recp->name) > 0 ? recp->name : "NONE");
11267c478bd9Sstevel@tonic-gate 			(void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11277c478bd9Sstevel@tonic-gate 			cfga_msg(msgp, pbuf);
11287c478bd9Sstevel@tonic-gate 		}
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	if (ibcfg_nhca_services) {
11327c478bd9Sstevel@tonic-gate 		(void) snprintf(pbuf, IBCONF_SERVICE_HDR_LEN,
11337c478bd9Sstevel@tonic-gate 		    IBCONF_HCA_SERVICE_HDR);
11347c478bd9Sstevel@tonic-gate 		cfga_msg(msgp, pbuf);
11357c478bd9Sstevel@tonic-gate 		for (recp = ibcfg_hca_head; recp; recp = recp->next) {
11367c478bd9Sstevel@tonic-gate 			DPRINTF("ib_list_services: svc_name = %s\n",
11377c478bd9Sstevel@tonic-gate 			    strlen(recp->name) > 0 ? recp->name : "NONE");
11387c478bd9Sstevel@tonic-gate 			(void) snprintf(pbuf, 14, "\t\t%s\n", recp->name);
11397c478bd9Sstevel@tonic-gate 			cfga_msg(msgp, pbuf);
11407c478bd9Sstevel@tonic-gate 		}
11417c478bd9Sstevel@tonic-gate 	}
11427c478bd9Sstevel@tonic-gate 	return (ib_cleanup_file(CFGA_IB_OK));
11437c478bd9Sstevel@tonic-gate }
11447c478bd9Sstevel@tonic-gate 
11457c478bd9Sstevel@tonic-gate 
11467c478bd9Sstevel@tonic-gate /*
11477c478bd9Sstevel@tonic-gate  * Function:
11487c478bd9Sstevel@tonic-gate  *	ib_conf_control_ioctl
11497c478bd9Sstevel@tonic-gate  * Input:
11507c478bd9Sstevel@tonic-gate  *	svc		- Service being added/deleted
11517c478bd9Sstevel@tonic-gate  *	cmd		- Command to DEVCTL_AP_CONTROL devctl
11527c478bd9Sstevel@tonic-gate  * Output:
11537c478bd9Sstevel@tonic-gate  *	NONE
11547c478bd9Sstevel@tonic-gate  * Returns:
11557c478bd9Sstevel@tonic-gate  *	CFGA_IB_OK if it succeeds or an appropriate error.
11567c478bd9Sstevel@tonic-gate  * Description:
11577c478bd9Sstevel@tonic-gate  *	Issues DEVCTL_AP_CONTROL devctl with cmd
11587c478bd9Sstevel@tonic-gate  */
11597c478bd9Sstevel@tonic-gate static cfga_ib_ret_t
ib_conf_control_ioctl(char * svc,uint_t cmd)11607c478bd9Sstevel@tonic-gate ib_conf_control_ioctl(char *svc, uint_t cmd)
11617c478bd9Sstevel@tonic-gate {
11627c478bd9Sstevel@tonic-gate 	int			apid_fd = -1;
11637c478bd9Sstevel@tonic-gate 	cfga_ib_ret_t		rv = CFGA_IB_OK;
11647c478bd9Sstevel@tonic-gate 	struct ibnex_ioctl_data	ioctl_data;
11657c478bd9Sstevel@tonic-gate 
11667c478bd9Sstevel@tonic-gate 	DPRINTF("Service = %s len = %x, type = %x\n", svc,
11677c478bd9Sstevel@tonic-gate 	    strlen(svc), service_type);
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 	/* try to open the static IB ap_id */
11707c478bd9Sstevel@tonic-gate 	if ((apid_fd = open(IB_STATIC_APID, O_RDONLY)) == -1) {
11717c478bd9Sstevel@tonic-gate 		DPRINTF("ib_conf_control_ioctl: open failed: errno = %d\n",
11727c478bd9Sstevel@tonic-gate 		    errno);
11737c478bd9Sstevel@tonic-gate 		/* Provides a more useful error msg */
11747c478bd9Sstevel@tonic-gate 		rv = (errno == EBUSY) ? CFGA_IB_BUSY_ERR : CFGA_IB_OPEN_ERR;
11757c478bd9Sstevel@tonic-gate 		return (rv);
11767c478bd9Sstevel@tonic-gate 	}
11777c478bd9Sstevel@tonic-gate 
11787c478bd9Sstevel@tonic-gate 	ioctl_data.cmd = cmd;
11797c478bd9Sstevel@tonic-gate 	ioctl_data.misc_arg = (uint_t)service_type;
11807c478bd9Sstevel@tonic-gate 	ioctl_data.buf = (caddr_t)svc;
11817c478bd9Sstevel@tonic-gate 	ioctl_data.bufsiz = strlen(svc);
11827c478bd9Sstevel@tonic-gate 	ioctl_data.ap_id = (caddr_t)IB_STATIC_APID;
11837c478bd9Sstevel@tonic-gate 	ioctl_data.ap_id_len = strlen(IB_STATIC_APID);
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate 	if (ioctl(apid_fd, DEVCTL_AP_CONTROL, &ioctl_data) != 0) {
11867c478bd9Sstevel@tonic-gate 		DPRINTF("ib_conf_control_ioctl: size ioctl ERR, errno: %d\n",
11877c478bd9Sstevel@tonic-gate 		    errno);
11887c478bd9Sstevel@tonic-gate 		rv = (errno == EBUSY) ? CFGA_IB_BUSY_ERR : CFGA_IB_IOCTL_ERR;
11897c478bd9Sstevel@tonic-gate 	}
11907c478bd9Sstevel@tonic-gate 	(void) close(apid_fd);
11917c478bd9Sstevel@tonic-gate 	return (rv);
11927c478bd9Sstevel@tonic-gate }
11937c478bd9Sstevel@tonic-gate 
11947c478bd9Sstevel@tonic-gate /*
11957c478bd9Sstevel@tonic-gate  * This functions checks if the service name is valid. Valid
11967c478bd9Sstevel@tonic-gate  * service names have  :
11977c478bd9Sstevel@tonic-gate  *		0 < strlen(name) <= 4
11987c478bd9Sstevel@tonic-gate  *		Service name is unique
11997c478bd9Sstevel@tonic-gate  * Returns: 	0 - Name is not valid, 1 - Name is valid
12007c478bd9Sstevel@tonic-gate  */
12017c478bd9Sstevel@tonic-gate static int
ib_service_record_valid(char * sname)12027c478bd9Sstevel@tonic-gate ib_service_record_valid(char *sname)
12037c478bd9Sstevel@tonic-gate {
12047c478bd9Sstevel@tonic-gate 	int rc = 1, len;
12057c478bd9Sstevel@tonic-gate 	char *tmp_service_name;
12067c478bd9Sstevel@tonic-gate 
12077c478bd9Sstevel@tonic-gate 	tmp_service_name = service_name;
12087c478bd9Sstevel@tonic-gate 	service_name = strdup(sname);
12097c478bd9Sstevel@tonic-gate 	len = strlen(sname);
12107c478bd9Sstevel@tonic-gate 	if (len == 0 || len > 4) {
12117c478bd9Sstevel@tonic-gate 		S_FREE(service_name);
12127c478bd9Sstevel@tonic-gate 		service_name = tmp_service_name;
12137c478bd9Sstevel@tonic-gate 		return (0);
12147c478bd9Sstevel@tonic-gate 	}
12157c478bd9Sstevel@tonic-gate 	if (ib_cmp_service() == B_TRUE)
12167c478bd9Sstevel@tonic-gate 		rc = 0;
12177c478bd9Sstevel@tonic-gate 	S_FREE(service_name);
12187c478bd9Sstevel@tonic-gate 	service_name = tmp_service_name;
12197c478bd9Sstevel@tonic-gate 	return (rc);
12207c478bd9Sstevel@tonic-gate }
1221