xref: /titanic_51/usr/src/cmd/saf/misc.c (revision 34e485807cef99a975f8962a04f4b7d1aa3529fe)
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  */
227c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
237c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*34e48580Sdp /*
25*34e48580Sdp  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
26*34e48580Sdp  * Use is subject to license terms.
27*34e48580Sdp  */
287c478bd9Sstevel@tonic-gate 
29*34e48580Sdp #pragma ident	"%Z%%M%	%I%	%E% SMI"
307c478bd9Sstevel@tonic-gate 
317c478bd9Sstevel@tonic-gate 
327c478bd9Sstevel@tonic-gate #include <stdio.h>
337c478bd9Sstevel@tonic-gate #include <unistd.h>
34*34e48580Sdp #include <stdlib.h>
357c478bd9Sstevel@tonic-gate #include <fcntl.h>
367c478bd9Sstevel@tonic-gate #include <sys/types.h>
377c478bd9Sstevel@tonic-gate #include <sys/stropts.h>
387c478bd9Sstevel@tonic-gate #include <signal.h>
397c478bd9Sstevel@tonic-gate #include <sys/stat.h>
407c478bd9Sstevel@tonic-gate #include <poll.h>
417c478bd9Sstevel@tonic-gate #include "misc.h"
427c478bd9Sstevel@tonic-gate #include "msgs.h"
437c478bd9Sstevel@tonic-gate #include "extern.h"
447c478bd9Sstevel@tonic-gate #include <sac.h>
457c478bd9Sstevel@tonic-gate #include "adm.h"
467c478bd9Sstevel@tonic-gate #include "structs.h"
477c478bd9Sstevel@tonic-gate 
487c478bd9Sstevel@tonic-gate 
497c478bd9Sstevel@tonic-gate /*
507c478bd9Sstevel@tonic-gate  * findpm - find a port monitor entry
517c478bd9Sstevel@tonic-gate  *
527c478bd9Sstevel@tonic-gate  *	args:	tag - tag of desired port monitor
537c478bd9Sstevel@tonic-gate  */
547c478bd9Sstevel@tonic-gate 
557c478bd9Sstevel@tonic-gate 
567c478bd9Sstevel@tonic-gate struct sactab *
577c478bd9Sstevel@tonic-gate findpm(tag)
587c478bd9Sstevel@tonic-gate register char *tag;
597c478bd9Sstevel@tonic-gate {
607c478bd9Sstevel@tonic-gate 	register struct sactab *sp;	/* working pointer */
617c478bd9Sstevel@tonic-gate 
627c478bd9Sstevel@tonic-gate 	for (sp = Sactab; sp; sp = sp->sc_next) {
637c478bd9Sstevel@tonic-gate 		if (!strcmp(tag, sp->sc_tag))
647c478bd9Sstevel@tonic-gate 			return(sp);
657c478bd9Sstevel@tonic-gate 	}
667c478bd9Sstevel@tonic-gate 	return(NULL);
677c478bd9Sstevel@tonic-gate }
687c478bd9Sstevel@tonic-gate 
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate /*
717c478bd9Sstevel@tonic-gate  * sigpoll - handle messages coming in on the command pipe (SIGPOLL signal
727c478bd9Sstevel@tonic-gate  *		handler)
737c478bd9Sstevel@tonic-gate  */
747c478bd9Sstevel@tonic-gate 
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate void
777c478bd9Sstevel@tonic-gate sigpoll()
787c478bd9Sstevel@tonic-gate {
797c478bd9Sstevel@tonic-gate 	struct pollfd fds;			/* array of fds to poll */
807c478bd9Sstevel@tonic-gate 	struct admcmd cmd;			/* incoming command */
817c478bd9Sstevel@tonic-gate 	register struct admcmd *ap = &cmd;	/* and a pointer to it */
827c478bd9Sstevel@tonic-gate 	struct admack ack;			/* acknowledgment */
837c478bd9Sstevel@tonic-gate 	register struct admack *ak = &ack;	/* and a pointer to it */
847c478bd9Sstevel@tonic-gate 	register struct sactab *sp;		/* working pointer */
857c478bd9Sstevel@tonic-gate 	struct sacmsg sacmsg;			/* message to port monitor */
867c478bd9Sstevel@tonic-gate 	char **data;				/* "dumped" sactab */
877c478bd9Sstevel@tonic-gate 	char *p;				/* scratch pointer */
887c478bd9Sstevel@tonic-gate 	register int i;				/* loop control variable */
897c478bd9Sstevel@tonic-gate 	int ret;				/* return value */
907c478bd9Sstevel@tonic-gate 	sigset_t cset;				/* for signal handling */
917c478bd9Sstevel@tonic-gate 	sigset_t tset;				/* for signal handling */
927c478bd9Sstevel@tonic-gate 
937c478bd9Sstevel@tonic-gate # ifdef DEBUG
947c478bd9Sstevel@tonic-gate 	debug("in sigpoll");
957c478bd9Sstevel@tonic-gate # endif
967c478bd9Sstevel@tonic-gate 	fds.fd = Cfd;
977c478bd9Sstevel@tonic-gate 	fds.events = POLLIN;
987c478bd9Sstevel@tonic-gate 	fds.revents = 0;
997c478bd9Sstevel@tonic-gate 	if (poll(&fds, 1, 0) < 0)
1007c478bd9Sstevel@tonic-gate 		error(E_POLL, EXIT);
1017c478bd9Sstevel@tonic-gate 	switch (fds.revents) {
1027c478bd9Sstevel@tonic-gate 	case POLLIN:
1037c478bd9Sstevel@tonic-gate 		if (read(Cfd, ap, sizeof(struct admcmd)) < 0) {
1047c478bd9Sstevel@tonic-gate 			error(E_READ, EXIT);
1057c478bd9Sstevel@tonic-gate 		}
1067c478bd9Sstevel@tonic-gate 		switch (ap->ac_mtype) {
1077c478bd9Sstevel@tonic-gate 
1087c478bd9Sstevel@tonic-gate /*
1097c478bd9Sstevel@tonic-gate  * request to start a port monitor
1107c478bd9Sstevel@tonic-gate  */
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate 		case AC_START:
1137c478bd9Sstevel@tonic-gate # ifdef DEBUG
1147c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got AC_START for <%s>", ap->ac_tag);
1157c478bd9Sstevel@tonic-gate 			log(Scratch);
1167c478bd9Sstevel@tonic-gate # endif
1177c478bd9Sstevel@tonic-gate 			if ((sp = findpm(ap->ac_tag)) == NULL) {
1187c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1197c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_NOPM;
1207c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1217c478bd9Sstevel@tonic-gate 				sendack(ak);
1227c478bd9Sstevel@tonic-gate 				break;
1237c478bd9Sstevel@tonic-gate 			}
1247c478bd9Sstevel@tonic-gate 			switch (sp->sc_sstate) {
1257c478bd9Sstevel@tonic-gate 			case UNKNOWN:
1267c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1277c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_RECOVER;
1287c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1297c478bd9Sstevel@tonic-gate 				sendack(ak);
1307c478bd9Sstevel@tonic-gate 				break;
1317c478bd9Sstevel@tonic-gate 			case FAILED:
1327c478bd9Sstevel@tonic-gate 			case NOTRUNNING:
1337c478bd9Sstevel@tonic-gate 				sp->sc_rscnt = 0;	/* fresh start in life */
1347c478bd9Sstevel@tonic-gate 				if (ret = startpm(sp)) {
1357c478bd9Sstevel@tonic-gate 					ak->ak_pid = ap->ac_pid;
1367c478bd9Sstevel@tonic-gate 					if (ret == -1)
1377c478bd9Sstevel@tonic-gate 						ak->ak_resp = AK_PMLOCK;
1387c478bd9Sstevel@tonic-gate 					else
1397c478bd9Sstevel@tonic-gate 						ak->ak_resp = AK_REQFAIL;
1407c478bd9Sstevel@tonic-gate 					ak->ak_size = 0;
1417c478bd9Sstevel@tonic-gate 					sendack(ak);
1427c478bd9Sstevel@tonic-gate 					break;
1437c478bd9Sstevel@tonic-gate 				}
1447c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1457c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
1467c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1477c478bd9Sstevel@tonic-gate 				sendack(ak);
1487c478bd9Sstevel@tonic-gate 				break;
1497c478bd9Sstevel@tonic-gate 			case ENABLED:
1507c478bd9Sstevel@tonic-gate 			case DISABLED:
1517c478bd9Sstevel@tonic-gate 			case STARTING:
1527c478bd9Sstevel@tonic-gate 			case STOPPING:
1537c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1547c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_PMRUN;
1557c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1567c478bd9Sstevel@tonic-gate 				sendack(ak);
1577c478bd9Sstevel@tonic-gate 				break;
1587c478bd9Sstevel@tonic-gate 			}
1597c478bd9Sstevel@tonic-gate 			break;
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * request to kill a port monitor
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate 		case AC_KILL:
1667c478bd9Sstevel@tonic-gate # ifdef DEBUG
1677c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got AC_KILL for <%s>", ap->ac_tag);
1687c478bd9Sstevel@tonic-gate 			log(Scratch);
1697c478bd9Sstevel@tonic-gate # endif
1707c478bd9Sstevel@tonic-gate 			if ((sp = findpm(ap->ac_tag)) == NULL) {
1717c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1727c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_NOPM;
1737c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1747c478bd9Sstevel@tonic-gate 				sendack(ak);
1757c478bd9Sstevel@tonic-gate 				break;
1767c478bd9Sstevel@tonic-gate 			}
1777c478bd9Sstevel@tonic-gate 			switch (sp->sc_sstate) {
1787c478bd9Sstevel@tonic-gate 			case UNKNOWN:
1797c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1807c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_RECOVER;
1817c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1827c478bd9Sstevel@tonic-gate 				sendack(ak);
1837c478bd9Sstevel@tonic-gate 				break;
1847c478bd9Sstevel@tonic-gate 			case NOTRUNNING:
1857c478bd9Sstevel@tonic-gate 			case FAILED:
1867c478bd9Sstevel@tonic-gate 			case STOPPING:
1877c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
1887c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_PMNOTRUN;
1897c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
1907c478bd9Sstevel@tonic-gate 				sendack(ak);
1917c478bd9Sstevel@tonic-gate 				break;
1927c478bd9Sstevel@tonic-gate 			case STARTING:
1937c478bd9Sstevel@tonic-gate 			case ENABLED:
1947c478bd9Sstevel@tonic-gate 			case DISABLED:
1957c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, NULL, &cset);
1967c478bd9Sstevel@tonic-gate 				tset = cset;
1977c478bd9Sstevel@tonic-gate 				(void) sigaddset(&tset, SIGALRM);
1987c478bd9Sstevel@tonic-gate 				(void) sigaddset(&tset, SIGCLD);
1997c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &tset, NULL);
2007c478bd9Sstevel@tonic-gate 				if (sendsig(sp, SIGTERM)) {
2017c478bd9Sstevel@tonic-gate 					(void) sprintf(Scratch, "could not send SIGTERM to <%s>", sp->sc_tag);
2027c478bd9Sstevel@tonic-gate 					log(Scratch);
2037c478bd9Sstevel@tonic-gate 					ak->ak_pid = ap->ac_pid;
2047c478bd9Sstevel@tonic-gate 					ak->ak_resp = AK_NOCONTACT;
2057c478bd9Sstevel@tonic-gate 					ak->ak_size = 0;
2067c478bd9Sstevel@tonic-gate 					sendack(ak);
2077c478bd9Sstevel@tonic-gate 					(void) sigprocmask(SIG_SETMASK, &cset, NULL);
2087c478bd9Sstevel@tonic-gate 					break;
2097c478bd9Sstevel@tonic-gate 				}
2107c478bd9Sstevel@tonic-gate 				/* signal sent ok */
2117c478bd9Sstevel@tonic-gate 				sp->sc_lstate = NOTRUNNING;
2127c478bd9Sstevel@tonic-gate 				sp->sc_sstate = NOTRUNNING;
2137c478bd9Sstevel@tonic-gate 				sp->sc_pstate = STOPPING;
2147c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2157c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
2167c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2177c478bd9Sstevel@tonic-gate 				sendack(ak);
2187c478bd9Sstevel@tonic-gate 				(void) sprintf(Scratch, "terminating <%s>", sp->sc_tag);
2197c478bd9Sstevel@tonic-gate 				log(Scratch);
2207c478bd9Sstevel@tonic-gate 				(void) sigprocmask(SIG_SETMASK, &cset, NULL);
2217c478bd9Sstevel@tonic-gate 				break;
2227c478bd9Sstevel@tonic-gate 			}
2237c478bd9Sstevel@tonic-gate 			break;
2247c478bd9Sstevel@tonic-gate 
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate  * request to enable a port monitor
2277c478bd9Sstevel@tonic-gate  */
2287c478bd9Sstevel@tonic-gate 
2297c478bd9Sstevel@tonic-gate 		case AC_ENABLE:
2307c478bd9Sstevel@tonic-gate # ifdef DEBUG
2317c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got AC_ENABLE for <%s>", ap->ac_tag);
2327c478bd9Sstevel@tonic-gate 			log(Scratch);
2337c478bd9Sstevel@tonic-gate # endif
2347c478bd9Sstevel@tonic-gate 			if ((sp = findpm(ap->ac_tag)) == NULL) {
2357c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2367c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_NOPM;
2377c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2387c478bd9Sstevel@tonic-gate 				sendack(ak);
2397c478bd9Sstevel@tonic-gate 				break;
2407c478bd9Sstevel@tonic-gate 			}
2417c478bd9Sstevel@tonic-gate 			switch (sp->sc_sstate) {
2427c478bd9Sstevel@tonic-gate 			case UNKNOWN:
2437c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2447c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_RECOVER;
2457c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2467c478bd9Sstevel@tonic-gate 				sendack(ak);
2477c478bd9Sstevel@tonic-gate 				break;
2487c478bd9Sstevel@tonic-gate 			case NOTRUNNING:
2497c478bd9Sstevel@tonic-gate 			case FAILED:
2507c478bd9Sstevel@tonic-gate 			case STOPPING:
2517c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2527c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_PMNOTRUN;
2537c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2547c478bd9Sstevel@tonic-gate 				sendack(ak);
2557c478bd9Sstevel@tonic-gate 				break;
2567c478bd9Sstevel@tonic-gate 			case STARTING:
2577c478bd9Sstevel@tonic-gate 			case DISABLED:
2587c478bd9Sstevel@tonic-gate 				sacmsg.sc_type = SC_ENABLE;
2597c478bd9Sstevel@tonic-gate 				sacmsg.sc_size = 0;
2607c478bd9Sstevel@tonic-gate 				sp->sc_sstate = ENABLED;
2617c478bd9Sstevel@tonic-gate 				sp->sc_lstate = ENABLED;
2627c478bd9Sstevel@tonic-gate 				sendpmmsg(sp, &sacmsg);
2637c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2647c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
2657c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2667c478bd9Sstevel@tonic-gate 				sendack(ak);
2677c478bd9Sstevel@tonic-gate 				break;
2687c478bd9Sstevel@tonic-gate 			case ENABLED:
2697c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2707c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
2717c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2727c478bd9Sstevel@tonic-gate 				sendack(ak);
2737c478bd9Sstevel@tonic-gate 				break;
2747c478bd9Sstevel@tonic-gate 			}
2757c478bd9Sstevel@tonic-gate 			break;
2767c478bd9Sstevel@tonic-gate 
2777c478bd9Sstevel@tonic-gate /*
2787c478bd9Sstevel@tonic-gate  * request to disable a port monitor
2797c478bd9Sstevel@tonic-gate  */
2807c478bd9Sstevel@tonic-gate 
2817c478bd9Sstevel@tonic-gate 		case AC_DISABLE:
2827c478bd9Sstevel@tonic-gate # ifdef DEBUG
2837c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got AC_DISABLE for <%s>", ap->ac_tag);
2847c478bd9Sstevel@tonic-gate 			log(Scratch);
2857c478bd9Sstevel@tonic-gate # endif
2867c478bd9Sstevel@tonic-gate 			if ((sp = findpm(ap->ac_tag)) == NULL) {
2877c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2887c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_NOPM;
2897c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2907c478bd9Sstevel@tonic-gate 				sendack(ak);
2917c478bd9Sstevel@tonic-gate 				break;
2927c478bd9Sstevel@tonic-gate 			}
2937c478bd9Sstevel@tonic-gate 			switch (sp->sc_sstate) {
2947c478bd9Sstevel@tonic-gate 			case UNKNOWN:
2957c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
2967c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_RECOVER;
2977c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
2987c478bd9Sstevel@tonic-gate 				sendack(ak);
2997c478bd9Sstevel@tonic-gate 				break;
3007c478bd9Sstevel@tonic-gate 			case NOTRUNNING:
3017c478bd9Sstevel@tonic-gate 			case FAILED:
3027c478bd9Sstevel@tonic-gate 			case STOPPING:
3037c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
3047c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_PMNOTRUN;
3057c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
3067c478bd9Sstevel@tonic-gate 				sendack(ak);
3077c478bd9Sstevel@tonic-gate 				break;
3087c478bd9Sstevel@tonic-gate 			case STARTING:
3097c478bd9Sstevel@tonic-gate 			case ENABLED:
3107c478bd9Sstevel@tonic-gate 				sacmsg.sc_type = SC_DISABLE;
3117c478bd9Sstevel@tonic-gate 				sacmsg.sc_size = 0;
3127c478bd9Sstevel@tonic-gate 				sp->sc_sstate = DISABLED;
3137c478bd9Sstevel@tonic-gate 				sp->sc_lstate = DISABLED;
3147c478bd9Sstevel@tonic-gate 				sendpmmsg(sp, &sacmsg);
3157c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
3167c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
3177c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
3187c478bd9Sstevel@tonic-gate 				sendack(ak);
3197c478bd9Sstevel@tonic-gate 				break;
3207c478bd9Sstevel@tonic-gate 			case DISABLED:
3217c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
3227c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
3237c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
3247c478bd9Sstevel@tonic-gate 				sendack(ak);
3257c478bd9Sstevel@tonic-gate 				break;
3267c478bd9Sstevel@tonic-gate 			}
3277c478bd9Sstevel@tonic-gate 			break;
3287c478bd9Sstevel@tonic-gate 
3297c478bd9Sstevel@tonic-gate /*
3307c478bd9Sstevel@tonic-gate  * request for port monitor status information
3317c478bd9Sstevel@tonic-gate  */
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 		case AC_STATUS:
3347c478bd9Sstevel@tonic-gate # ifdef DEBUG
3357c478bd9Sstevel@tonic-gate 			log("Got AC_STATUS");
3367c478bd9Sstevel@tonic-gate # endif
3377c478bd9Sstevel@tonic-gate 			/* get all the info in one convenient place */
3387c478bd9Sstevel@tonic-gate 			data = dump_table();
3397c478bd9Sstevel@tonic-gate 			if ((data == NULL) && (Nentries > 0)) {
3407c478bd9Sstevel@tonic-gate 				/* something bad happened in dump_table */
3417c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
3427c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_REQFAIL;
3437c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
3447c478bd9Sstevel@tonic-gate 				sendack(ak);
3457c478bd9Sstevel@tonic-gate 				break;
3467c478bd9Sstevel@tonic-gate 			}
3477c478bd9Sstevel@tonic-gate 			/* count how big it is */
3487c478bd9Sstevel@tonic-gate 			ak->ak_size = 0;
3497c478bd9Sstevel@tonic-gate 			for (i = 0; i < Nentries; ++i)
3507c478bd9Sstevel@tonic-gate 				ak->ak_size += strlen(data[i]);
3517c478bd9Sstevel@tonic-gate # ifdef DEBUG
3527c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "ak_size is %d", ak->ak_size);
3537c478bd9Sstevel@tonic-gate 			debug(Scratch);
3547c478bd9Sstevel@tonic-gate # endif
3557c478bd9Sstevel@tonic-gate 			/* get a contiguous chunk */
3567c478bd9Sstevel@tonic-gate 			if ((p = malloc((unsigned) (ak->ak_size + 1))) == NULL) {
3577c478bd9Sstevel@tonic-gate 				error(E_MALLOC, CONT);
3587c478bd9Sstevel@tonic-gate 				for (i = 0; i < Nentries; ++i)
3597c478bd9Sstevel@tonic-gate 					free(data[i]);
3607c478bd9Sstevel@tonic-gate 				free((char *) data);
3617c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
3627c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_REQFAIL;
3637c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
3647c478bd9Sstevel@tonic-gate 				sendack(ak);
3657c478bd9Sstevel@tonic-gate 				break;
3667c478bd9Sstevel@tonic-gate 			}
3677c478bd9Sstevel@tonic-gate 			/* condense the data into the contiguous chunk */
3687c478bd9Sstevel@tonic-gate 			*p = '\0';
3697c478bd9Sstevel@tonic-gate 			for (i = 0; i < Nentries; ++i) {
3707c478bd9Sstevel@tonic-gate 				(void) strcat(p, data[i]);
3717c478bd9Sstevel@tonic-gate 				free(data[i]);
3727c478bd9Sstevel@tonic-gate 			}
3737c478bd9Sstevel@tonic-gate # ifdef DEBUG
3747c478bd9Sstevel@tonic-gate 			debug(p);
3757c478bd9Sstevel@tonic-gate # endif
3767c478bd9Sstevel@tonic-gate 			if (data)
3777c478bd9Sstevel@tonic-gate 				free((char *) data);
3787c478bd9Sstevel@tonic-gate 			/* ak->ak_size was set above */
3797c478bd9Sstevel@tonic-gate 			ak->ak_pid = ap->ac_pid;
3807c478bd9Sstevel@tonic-gate 			ak->ak_resp = AK_ACK;
3817c478bd9Sstevel@tonic-gate 			sendack(ak);
3827c478bd9Sstevel@tonic-gate 			if (ak->ak_size)
3837c478bd9Sstevel@tonic-gate 				if (write(Cfd, p, (unsigned) ak->ak_size) != ak->ak_size)
3847c478bd9Sstevel@tonic-gate 					log("could not send info");
3857c478bd9Sstevel@tonic-gate 			free(p);
3867c478bd9Sstevel@tonic-gate 			break;
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate /*
3897c478bd9Sstevel@tonic-gate  * request for sac to read sactab
3907c478bd9Sstevel@tonic-gate  */
3917c478bd9Sstevel@tonic-gate 
3927c478bd9Sstevel@tonic-gate 		case AC_SACREAD:
3937c478bd9Sstevel@tonic-gate # ifdef DEBUG
3947c478bd9Sstevel@tonic-gate 			log("Got AC_SACREAD");
3957c478bd9Sstevel@tonic-gate # endif
3967c478bd9Sstevel@tonic-gate 			ak->ak_pid = ap->ac_pid;
3977c478bd9Sstevel@tonic-gate 			ak->ak_resp = AK_ACK;
3987c478bd9Sstevel@tonic-gate 			ak->ak_size = 0;
3997c478bd9Sstevel@tonic-gate 			read_table(TRUE);
4007c478bd9Sstevel@tonic-gate 			sendack(ak);
4017c478bd9Sstevel@tonic-gate 			break;
4027c478bd9Sstevel@tonic-gate 
4037c478bd9Sstevel@tonic-gate /*
4047c478bd9Sstevel@tonic-gate  * request for port monitor to read _pmtab
4057c478bd9Sstevel@tonic-gate  */
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 		case AC_PMREAD:
4087c478bd9Sstevel@tonic-gate # ifdef DEBUG
4097c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got AC_PMREAD for <%s>", ap->ac_tag);
4107c478bd9Sstevel@tonic-gate 			log(Scratch);
4117c478bd9Sstevel@tonic-gate # endif
4127c478bd9Sstevel@tonic-gate 			if ((sp = findpm(ap->ac_tag)) == NULL) {
4137c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
4147c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_NOPM;
4157c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
4167c478bd9Sstevel@tonic-gate 				sendack(ak);
4177c478bd9Sstevel@tonic-gate 				break;
4187c478bd9Sstevel@tonic-gate 			}
4197c478bd9Sstevel@tonic-gate 			switch (sp->sc_sstate) {
4207c478bd9Sstevel@tonic-gate 			case UNKNOWN:
4217c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
4227c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_RECOVER;
4237c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
4247c478bd9Sstevel@tonic-gate 				sendack(ak);
4257c478bd9Sstevel@tonic-gate 				break;
4267c478bd9Sstevel@tonic-gate 			case NOTRUNNING:
4277c478bd9Sstevel@tonic-gate 			case FAILED:
4287c478bd9Sstevel@tonic-gate 			case STOPPING:
4297c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
4307c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_PMNOTRUN;
4317c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
4327c478bd9Sstevel@tonic-gate 				sendack(ak);
4337c478bd9Sstevel@tonic-gate 				break;
4347c478bd9Sstevel@tonic-gate 			case STARTING:
4357c478bd9Sstevel@tonic-gate 			case ENABLED:
4367c478bd9Sstevel@tonic-gate 			case DISABLED:
4377c478bd9Sstevel@tonic-gate 				sacmsg.sc_type = SC_READDB;
4387c478bd9Sstevel@tonic-gate 				sacmsg.sc_size = 0;
4397c478bd9Sstevel@tonic-gate 				sendpmmsg(sp, &sacmsg);
4407c478bd9Sstevel@tonic-gate 				ak->ak_pid = ap->ac_pid;
4417c478bd9Sstevel@tonic-gate 				ak->ak_resp = AK_ACK;
4427c478bd9Sstevel@tonic-gate 				ak->ak_size = 0;
4437c478bd9Sstevel@tonic-gate 				sendack(ak);
4447c478bd9Sstevel@tonic-gate 				break;
4457c478bd9Sstevel@tonic-gate 			}
4467c478bd9Sstevel@tonic-gate 			break;
4477c478bd9Sstevel@tonic-gate /*
4487c478bd9Sstevel@tonic-gate  * garbled message
4497c478bd9Sstevel@tonic-gate  */
4507c478bd9Sstevel@tonic-gate 
4517c478bd9Sstevel@tonic-gate 		default:
4527c478bd9Sstevel@tonic-gate 			(void) sprintf(Scratch, "Got unknown message for <%s>", ap->ac_tag);
4537c478bd9Sstevel@tonic-gate 			log(Scratch);
4547c478bd9Sstevel@tonic-gate 			ak->ak_pid = ap->ac_pid;
4557c478bd9Sstevel@tonic-gate 			ak->ak_resp = AK_UNKNOWN;
4567c478bd9Sstevel@tonic-gate 			ak->ak_size = 0;
4577c478bd9Sstevel@tonic-gate 			sendack(ak);
4587c478bd9Sstevel@tonic-gate 			break;
4597c478bd9Sstevel@tonic-gate 		}
4607c478bd9Sstevel@tonic-gate 		break;
4617c478bd9Sstevel@tonic-gate 	default:
4627c478bd9Sstevel@tonic-gate 		error(E_POLL, EXIT);
4637c478bd9Sstevel@tonic-gate 	}
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 
4677c478bd9Sstevel@tonic-gate /*
4687c478bd9Sstevel@tonic-gate  * sendack - send a response to the administrative command
4697c478bd9Sstevel@tonic-gate  *
4707c478bd9Sstevel@tonic-gate  *	args:	ap - pointer to acknowlegment message
4717c478bd9Sstevel@tonic-gate  */
4727c478bd9Sstevel@tonic-gate 
4737c478bd9Sstevel@tonic-gate void
4747c478bd9Sstevel@tonic-gate sendack(ap)
4757c478bd9Sstevel@tonic-gate struct admack *ap;
4767c478bd9Sstevel@tonic-gate {
4777c478bd9Sstevel@tonic-gate # ifdef DEBUG
4787c478bd9Sstevel@tonic-gate 	debug("in sendack");
4797c478bd9Sstevel@tonic-gate # endif
4807c478bd9Sstevel@tonic-gate 	if (write(Cfd, ap, sizeof(struct admack)) != sizeof(struct admack))
4817c478bd9Sstevel@tonic-gate 		log("Could not send ack");
4827c478bd9Sstevel@tonic-gate }
4837c478bd9Sstevel@tonic-gate 
4847c478bd9Sstevel@tonic-gate 
4857c478bd9Sstevel@tonic-gate /*
4867c478bd9Sstevel@tonic-gate  * sendpmmsg - send a message to a PM.  Note: sc_size is always 0 in
4877c478bd9Sstevel@tonic-gate  *	       this version so just send the header.
4887c478bd9Sstevel@tonic-gate  *
4897c478bd9Sstevel@tonic-gate  *	args:	sp - pointer to sac's port monitor information for
4907c478bd9Sstevel@tonic-gate  *		     designated port monitor
4917c478bd9Sstevel@tonic-gate  *		sm - pointer to message to send
4927c478bd9Sstevel@tonic-gate  */
4937c478bd9Sstevel@tonic-gate 
4947c478bd9Sstevel@tonic-gate void
4957c478bd9Sstevel@tonic-gate sendpmmsg(sp, sm)
4967c478bd9Sstevel@tonic-gate register struct sactab *sp;
4977c478bd9Sstevel@tonic-gate register struct sacmsg *sm;
4987c478bd9Sstevel@tonic-gate {
4997c478bd9Sstevel@tonic-gate 	char buf[SIZE];			/* scratch buffer */
5007c478bd9Sstevel@tonic-gate 
5017c478bd9Sstevel@tonic-gate # ifdef DEBUG
5027c478bd9Sstevel@tonic-gate 	debug("in sendpmmsg");
5037c478bd9Sstevel@tonic-gate # endif
5047c478bd9Sstevel@tonic-gate 	if (write(sp->sc_fd, sm, sizeof(struct sacmsg)) != sizeof(struct sacmsg)) {
5057c478bd9Sstevel@tonic-gate 		(void) sprintf(buf, "message to <%s> failed", sp->sc_tag);
5067c478bd9Sstevel@tonic-gate 		log(buf);
5077c478bd9Sstevel@tonic-gate 	}
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate 
5107c478bd9Sstevel@tonic-gate /*
5117c478bd9Sstevel@tonic-gate  * sendsig - send a signal to the port monitor
5127c478bd9Sstevel@tonic-gate  *
5137c478bd9Sstevel@tonic-gate  *	args:	sp - pointer to sac's port monitor infomation for
5147c478bd9Sstevel@tonic-gate  *		     designated port monitor
5157c478bd9Sstevel@tonic-gate  *		signo - signal number to send
5167c478bd9Sstevel@tonic-gate  */
5177c478bd9Sstevel@tonic-gate 
518*34e48580Sdp int
519*34e48580Sdp sendsig(struct sactab *sp, int signo)
5207c478bd9Sstevel@tonic-gate {
5217c478bd9Sstevel@tonic-gate 	pid_t pid;	/* pid of designated port monitor */
5227c478bd9Sstevel@tonic-gate 	pid_t checklock();
5237c478bd9Sstevel@tonic-gate 
5247c478bd9Sstevel@tonic-gate # ifdef DEBUG
5257c478bd9Sstevel@tonic-gate 	(void) sprintf(Scratch, "in sendsig - sending signo %d to %s", signo, sp->sc_tag);
5267c478bd9Sstevel@tonic-gate 	debug(Scratch);
5277c478bd9Sstevel@tonic-gate # endif
5287c478bd9Sstevel@tonic-gate 	if (pid = checklock(sp)) {
5297c478bd9Sstevel@tonic-gate 		if (kill(pid, signo) < 0) {
5307c478bd9Sstevel@tonic-gate # ifdef DEBUG
5317c478bd9Sstevel@tonic-gate 			debug("in sendsig - kill failed");
5327c478bd9Sstevel@tonic-gate # endif
5337c478bd9Sstevel@tonic-gate 			return(-1);
5347c478bd9Sstevel@tonic-gate 		}
5357c478bd9Sstevel@tonic-gate 		else
5367c478bd9Sstevel@tonic-gate 			return(0);
5377c478bd9Sstevel@tonic-gate 	}
5387c478bd9Sstevel@tonic-gate 	else {
5397c478bd9Sstevel@tonic-gate # ifdef DEBUG
5407c478bd9Sstevel@tonic-gate 		debug("in sendsig - checklock failed");
5417c478bd9Sstevel@tonic-gate # endif
5427c478bd9Sstevel@tonic-gate 		return(-1);
5437c478bd9Sstevel@tonic-gate 	}
5447c478bd9Sstevel@tonic-gate }
5457c478bd9Sstevel@tonic-gate 
5467c478bd9Sstevel@tonic-gate 
5477c478bd9Sstevel@tonic-gate /*
5487c478bd9Sstevel@tonic-gate  * checklock - check to see if a _pid file is locked
5497c478bd9Sstevel@tonic-gate  *		if so, return pid in file, else 0
5507c478bd9Sstevel@tonic-gate  *
5517c478bd9Sstevel@tonic-gate  *	args:	sp - pointer to sac's port monitor infomation for
5527c478bd9Sstevel@tonic-gate  *		     designated port monitor
5537c478bd9Sstevel@tonic-gate  */
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate pid_t
5567c478bd9Sstevel@tonic-gate checklock(sp)
5577c478bd9Sstevel@tonic-gate register struct sactab *sp;
5587c478bd9Sstevel@tonic-gate {
5597c478bd9Sstevel@tonic-gate 	int fd;			/* scratch file descriptor */
5607c478bd9Sstevel@tonic-gate 	char buf[SIZE];		/* scratch buffer */
5617c478bd9Sstevel@tonic-gate 	int ret;		/* return value */
5627c478bd9Sstevel@tonic-gate 
5637c478bd9Sstevel@tonic-gate # ifdef DEBUG
5647c478bd9Sstevel@tonic-gate 	debug("in checklock");
5657c478bd9Sstevel@tonic-gate # endif
5667c478bd9Sstevel@tonic-gate 	(void) sprintf(Scratch, "%s/%s/_pid", HOME, sp->sc_tag);
5677c478bd9Sstevel@tonic-gate 	fd = open(Scratch, O_RDONLY);
5687c478bd9Sstevel@tonic-gate 	if (fd < 0) {
5697c478bd9Sstevel@tonic-gate 		(void) sprintf(Scratch, "can not open _pid file for <%s>", sp->sc_tag);
5707c478bd9Sstevel@tonic-gate 		log(Scratch);
5717c478bd9Sstevel@tonic-gate 		return((pid_t)0);
5727c478bd9Sstevel@tonic-gate 	}
5737c478bd9Sstevel@tonic-gate 	if (lockf(fd, F_TEST, 0) < 0) {
5747c478bd9Sstevel@tonic-gate 		if ((ret = read(fd, buf, SIZE - 1)) < 0) {
5757c478bd9Sstevel@tonic-gate 			(void) close(fd);
5767c478bd9Sstevel@tonic-gate 			return((pid_t)0);
5777c478bd9Sstevel@tonic-gate 		}
5787c478bd9Sstevel@tonic-gate 		(void) close(fd);
5797c478bd9Sstevel@tonic-gate 		/* in case pid wasn't null-terminated */
5807c478bd9Sstevel@tonic-gate 		buf[ret] = '\0';
5817c478bd9Sstevel@tonic-gate 		return((pid_t)atol(buf));
5827c478bd9Sstevel@tonic-gate 	}
5837c478bd9Sstevel@tonic-gate 	(void) close(fd);
5847c478bd9Sstevel@tonic-gate 	return((pid_t)0);
5857c478bd9Sstevel@tonic-gate }
586