10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
230Sstevel@tonic-gate /* All Rights Reserved */
24*334Sdp /*
25*334Sdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
26*334Sdp * Use is subject to license terms.
27*334Sdp */
280Sstevel@tonic-gate
29*334Sdp #pragma ident "%Z%%M% %I% %E% SMI"
300Sstevel@tonic-gate
310Sstevel@tonic-gate
32*334Sdp #include <stdio.h>
33*334Sdp #include <unistd.h>
34*334Sdp #include <stdlib.h>
35*334Sdp #include <fcntl.h>
36*334Sdp #include <sys/types.h>
37*334Sdp #include <sys/stropts.h>
38*334Sdp #include <signal.h>
39*334Sdp #include <sys/stat.h>
40*334Sdp #include <poll.h>
41*334Sdp #include "misc.h"
42*334Sdp #include "msgs.h"
43*334Sdp #include "extern.h"
44*334Sdp #include <sac.h>
45*334Sdp #include "adm.h"
46*334Sdp #include "structs.h"
470Sstevel@tonic-gate
480Sstevel@tonic-gate
490Sstevel@tonic-gate /*
500Sstevel@tonic-gate * findpm - find a port monitor entry
510Sstevel@tonic-gate *
520Sstevel@tonic-gate * args: tag - tag of desired port monitor
530Sstevel@tonic-gate */
540Sstevel@tonic-gate
550Sstevel@tonic-gate
560Sstevel@tonic-gate struct sactab *
findpm(tag)570Sstevel@tonic-gate findpm(tag)
580Sstevel@tonic-gate register char *tag;
590Sstevel@tonic-gate {
600Sstevel@tonic-gate register struct sactab *sp; /* working pointer */
610Sstevel@tonic-gate
620Sstevel@tonic-gate for (sp = Sactab; sp; sp = sp->sc_next) {
630Sstevel@tonic-gate if (!strcmp(tag, sp->sc_tag))
640Sstevel@tonic-gate return(sp);
650Sstevel@tonic-gate }
660Sstevel@tonic-gate return(NULL);
670Sstevel@tonic-gate }
680Sstevel@tonic-gate
690Sstevel@tonic-gate
700Sstevel@tonic-gate /*
710Sstevel@tonic-gate * sigpoll - handle messages coming in on the command pipe (SIGPOLL signal
720Sstevel@tonic-gate * handler)
730Sstevel@tonic-gate */
740Sstevel@tonic-gate
750Sstevel@tonic-gate
760Sstevel@tonic-gate void
sigpoll()770Sstevel@tonic-gate sigpoll()
780Sstevel@tonic-gate {
790Sstevel@tonic-gate struct pollfd fds; /* array of fds to poll */
800Sstevel@tonic-gate struct admcmd cmd; /* incoming command */
810Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */
820Sstevel@tonic-gate struct admack ack; /* acknowledgment */
830Sstevel@tonic-gate register struct admack *ak = &ack; /* and a pointer to it */
840Sstevel@tonic-gate register struct sactab *sp; /* working pointer */
850Sstevel@tonic-gate struct sacmsg sacmsg; /* message to port monitor */
860Sstevel@tonic-gate char **data; /* "dumped" sactab */
870Sstevel@tonic-gate char *p; /* scratch pointer */
880Sstevel@tonic-gate register int i; /* loop control variable */
890Sstevel@tonic-gate int ret; /* return value */
900Sstevel@tonic-gate sigset_t cset; /* for signal handling */
910Sstevel@tonic-gate sigset_t tset; /* for signal handling */
920Sstevel@tonic-gate
930Sstevel@tonic-gate # ifdef DEBUG
940Sstevel@tonic-gate debug("in sigpoll");
950Sstevel@tonic-gate # endif
960Sstevel@tonic-gate fds.fd = Cfd;
970Sstevel@tonic-gate fds.events = POLLIN;
980Sstevel@tonic-gate fds.revents = 0;
990Sstevel@tonic-gate if (poll(&fds, 1, 0) < 0)
1000Sstevel@tonic-gate error(E_POLL, EXIT);
1010Sstevel@tonic-gate switch (fds.revents) {
1020Sstevel@tonic-gate case POLLIN:
1030Sstevel@tonic-gate if (read(Cfd, ap, sizeof(struct admcmd)) < 0) {
1040Sstevel@tonic-gate error(E_READ, EXIT);
1050Sstevel@tonic-gate }
1060Sstevel@tonic-gate switch (ap->ac_mtype) {
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate /*
1090Sstevel@tonic-gate * request to start a port monitor
1100Sstevel@tonic-gate */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate case AC_START:
1130Sstevel@tonic-gate # ifdef DEBUG
1140Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_START for <%s>", ap->ac_tag);
1150Sstevel@tonic-gate log(Scratch);
1160Sstevel@tonic-gate # endif
1170Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) {
1180Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1190Sstevel@tonic-gate ak->ak_resp = AK_NOPM;
1200Sstevel@tonic-gate ak->ak_size = 0;
1210Sstevel@tonic-gate sendack(ak);
1220Sstevel@tonic-gate break;
1230Sstevel@tonic-gate }
1240Sstevel@tonic-gate switch (sp->sc_sstate) {
1250Sstevel@tonic-gate case UNKNOWN:
1260Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1270Sstevel@tonic-gate ak->ak_resp = AK_RECOVER;
1280Sstevel@tonic-gate ak->ak_size = 0;
1290Sstevel@tonic-gate sendack(ak);
1300Sstevel@tonic-gate break;
1310Sstevel@tonic-gate case FAILED:
1320Sstevel@tonic-gate case NOTRUNNING:
1330Sstevel@tonic-gate sp->sc_rscnt = 0; /* fresh start in life */
1340Sstevel@tonic-gate if (ret = startpm(sp)) {
1350Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1360Sstevel@tonic-gate if (ret == -1)
1370Sstevel@tonic-gate ak->ak_resp = AK_PMLOCK;
1380Sstevel@tonic-gate else
1390Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL;
1400Sstevel@tonic-gate ak->ak_size = 0;
1410Sstevel@tonic-gate sendack(ak);
1420Sstevel@tonic-gate break;
1430Sstevel@tonic-gate }
1440Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1450Sstevel@tonic-gate ak->ak_resp = AK_ACK;
1460Sstevel@tonic-gate ak->ak_size = 0;
1470Sstevel@tonic-gate sendack(ak);
1480Sstevel@tonic-gate break;
1490Sstevel@tonic-gate case ENABLED:
1500Sstevel@tonic-gate case DISABLED:
1510Sstevel@tonic-gate case STARTING:
1520Sstevel@tonic-gate case STOPPING:
1530Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1540Sstevel@tonic-gate ak->ak_resp = AK_PMRUN;
1550Sstevel@tonic-gate ak->ak_size = 0;
1560Sstevel@tonic-gate sendack(ak);
1570Sstevel@tonic-gate break;
1580Sstevel@tonic-gate }
1590Sstevel@tonic-gate break;
1600Sstevel@tonic-gate
1610Sstevel@tonic-gate /*
1620Sstevel@tonic-gate * request to kill a port monitor
1630Sstevel@tonic-gate */
1640Sstevel@tonic-gate
1650Sstevel@tonic-gate case AC_KILL:
1660Sstevel@tonic-gate # ifdef DEBUG
1670Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_KILL for <%s>", ap->ac_tag);
1680Sstevel@tonic-gate log(Scratch);
1690Sstevel@tonic-gate # endif
1700Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) {
1710Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1720Sstevel@tonic-gate ak->ak_resp = AK_NOPM;
1730Sstevel@tonic-gate ak->ak_size = 0;
1740Sstevel@tonic-gate sendack(ak);
1750Sstevel@tonic-gate break;
1760Sstevel@tonic-gate }
1770Sstevel@tonic-gate switch (sp->sc_sstate) {
1780Sstevel@tonic-gate case UNKNOWN:
1790Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1800Sstevel@tonic-gate ak->ak_resp = AK_RECOVER;
1810Sstevel@tonic-gate ak->ak_size = 0;
1820Sstevel@tonic-gate sendack(ak);
1830Sstevel@tonic-gate break;
1840Sstevel@tonic-gate case NOTRUNNING:
1850Sstevel@tonic-gate case FAILED:
1860Sstevel@tonic-gate case STOPPING:
1870Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
1880Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN;
1890Sstevel@tonic-gate ak->ak_size = 0;
1900Sstevel@tonic-gate sendack(ak);
1910Sstevel@tonic-gate break;
1920Sstevel@tonic-gate case STARTING:
1930Sstevel@tonic-gate case ENABLED:
1940Sstevel@tonic-gate case DISABLED:
1950Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, NULL, &cset);
1960Sstevel@tonic-gate tset = cset;
1970Sstevel@tonic-gate (void) sigaddset(&tset, SIGALRM);
1980Sstevel@tonic-gate (void) sigaddset(&tset, SIGCLD);
1990Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &tset, NULL);
2000Sstevel@tonic-gate if (sendsig(sp, SIGTERM)) {
2010Sstevel@tonic-gate (void) sprintf(Scratch, "could not send SIGTERM to <%s>", sp->sc_tag);
2020Sstevel@tonic-gate log(Scratch);
2030Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2040Sstevel@tonic-gate ak->ak_resp = AK_NOCONTACT;
2050Sstevel@tonic-gate ak->ak_size = 0;
2060Sstevel@tonic-gate sendack(ak);
2070Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &cset, NULL);
2080Sstevel@tonic-gate break;
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate /* signal sent ok */
2110Sstevel@tonic-gate sp->sc_lstate = NOTRUNNING;
2120Sstevel@tonic-gate sp->sc_sstate = NOTRUNNING;
2130Sstevel@tonic-gate sp->sc_pstate = STOPPING;
2140Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2150Sstevel@tonic-gate ak->ak_resp = AK_ACK;
2160Sstevel@tonic-gate ak->ak_size = 0;
2170Sstevel@tonic-gate sendack(ak);
2180Sstevel@tonic-gate (void) sprintf(Scratch, "terminating <%s>", sp->sc_tag);
2190Sstevel@tonic-gate log(Scratch);
2200Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &cset, NULL);
2210Sstevel@tonic-gate break;
2220Sstevel@tonic-gate }
2230Sstevel@tonic-gate break;
2240Sstevel@tonic-gate
2250Sstevel@tonic-gate /*
2260Sstevel@tonic-gate * request to enable a port monitor
2270Sstevel@tonic-gate */
2280Sstevel@tonic-gate
2290Sstevel@tonic-gate case AC_ENABLE:
2300Sstevel@tonic-gate # ifdef DEBUG
2310Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_ENABLE for <%s>", ap->ac_tag);
2320Sstevel@tonic-gate log(Scratch);
2330Sstevel@tonic-gate # endif
2340Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) {
2350Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2360Sstevel@tonic-gate ak->ak_resp = AK_NOPM;
2370Sstevel@tonic-gate ak->ak_size = 0;
2380Sstevel@tonic-gate sendack(ak);
2390Sstevel@tonic-gate break;
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate switch (sp->sc_sstate) {
2420Sstevel@tonic-gate case UNKNOWN:
2430Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2440Sstevel@tonic-gate ak->ak_resp = AK_RECOVER;
2450Sstevel@tonic-gate ak->ak_size = 0;
2460Sstevel@tonic-gate sendack(ak);
2470Sstevel@tonic-gate break;
2480Sstevel@tonic-gate case NOTRUNNING:
2490Sstevel@tonic-gate case FAILED:
2500Sstevel@tonic-gate case STOPPING:
2510Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2520Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN;
2530Sstevel@tonic-gate ak->ak_size = 0;
2540Sstevel@tonic-gate sendack(ak);
2550Sstevel@tonic-gate break;
2560Sstevel@tonic-gate case STARTING:
2570Sstevel@tonic-gate case DISABLED:
2580Sstevel@tonic-gate sacmsg.sc_type = SC_ENABLE;
2590Sstevel@tonic-gate sacmsg.sc_size = 0;
2600Sstevel@tonic-gate sp->sc_sstate = ENABLED;
2610Sstevel@tonic-gate sp->sc_lstate = ENABLED;
2620Sstevel@tonic-gate sendpmmsg(sp, &sacmsg);
2630Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2640Sstevel@tonic-gate ak->ak_resp = AK_ACK;
2650Sstevel@tonic-gate ak->ak_size = 0;
2660Sstevel@tonic-gate sendack(ak);
2670Sstevel@tonic-gate break;
2680Sstevel@tonic-gate case ENABLED:
2690Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2700Sstevel@tonic-gate ak->ak_resp = AK_ACK;
2710Sstevel@tonic-gate ak->ak_size = 0;
2720Sstevel@tonic-gate sendack(ak);
2730Sstevel@tonic-gate break;
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate break;
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate * request to disable a port monitor
2790Sstevel@tonic-gate */
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate case AC_DISABLE:
2820Sstevel@tonic-gate # ifdef DEBUG
2830Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_DISABLE for <%s>", ap->ac_tag);
2840Sstevel@tonic-gate log(Scratch);
2850Sstevel@tonic-gate # endif
2860Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) {
2870Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2880Sstevel@tonic-gate ak->ak_resp = AK_NOPM;
2890Sstevel@tonic-gate ak->ak_size = 0;
2900Sstevel@tonic-gate sendack(ak);
2910Sstevel@tonic-gate break;
2920Sstevel@tonic-gate }
2930Sstevel@tonic-gate switch (sp->sc_sstate) {
2940Sstevel@tonic-gate case UNKNOWN:
2950Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
2960Sstevel@tonic-gate ak->ak_resp = AK_RECOVER;
2970Sstevel@tonic-gate ak->ak_size = 0;
2980Sstevel@tonic-gate sendack(ak);
2990Sstevel@tonic-gate break;
3000Sstevel@tonic-gate case NOTRUNNING:
3010Sstevel@tonic-gate case FAILED:
3020Sstevel@tonic-gate case STOPPING:
3030Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3040Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN;
3050Sstevel@tonic-gate ak->ak_size = 0;
3060Sstevel@tonic-gate sendack(ak);
3070Sstevel@tonic-gate break;
3080Sstevel@tonic-gate case STARTING:
3090Sstevel@tonic-gate case ENABLED:
3100Sstevel@tonic-gate sacmsg.sc_type = SC_DISABLE;
3110Sstevel@tonic-gate sacmsg.sc_size = 0;
3120Sstevel@tonic-gate sp->sc_sstate = DISABLED;
3130Sstevel@tonic-gate sp->sc_lstate = DISABLED;
3140Sstevel@tonic-gate sendpmmsg(sp, &sacmsg);
3150Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3160Sstevel@tonic-gate ak->ak_resp = AK_ACK;
3170Sstevel@tonic-gate ak->ak_size = 0;
3180Sstevel@tonic-gate sendack(ak);
3190Sstevel@tonic-gate break;
3200Sstevel@tonic-gate case DISABLED:
3210Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3220Sstevel@tonic-gate ak->ak_resp = AK_ACK;
3230Sstevel@tonic-gate ak->ak_size = 0;
3240Sstevel@tonic-gate sendack(ak);
3250Sstevel@tonic-gate break;
3260Sstevel@tonic-gate }
3270Sstevel@tonic-gate break;
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate /*
3300Sstevel@tonic-gate * request for port monitor status information
3310Sstevel@tonic-gate */
3320Sstevel@tonic-gate
3330Sstevel@tonic-gate case AC_STATUS:
3340Sstevel@tonic-gate # ifdef DEBUG
3350Sstevel@tonic-gate log("Got AC_STATUS");
3360Sstevel@tonic-gate # endif
3370Sstevel@tonic-gate /* get all the info in one convenient place */
3380Sstevel@tonic-gate data = dump_table();
3390Sstevel@tonic-gate if ((data == NULL) && (Nentries > 0)) {
3400Sstevel@tonic-gate /* something bad happened in dump_table */
3410Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3420Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL;
3430Sstevel@tonic-gate ak->ak_size = 0;
3440Sstevel@tonic-gate sendack(ak);
3450Sstevel@tonic-gate break;
3460Sstevel@tonic-gate }
3470Sstevel@tonic-gate /* count how big it is */
3480Sstevel@tonic-gate ak->ak_size = 0;
3490Sstevel@tonic-gate for (i = 0; i < Nentries; ++i)
3500Sstevel@tonic-gate ak->ak_size += strlen(data[i]);
3510Sstevel@tonic-gate # ifdef DEBUG
3520Sstevel@tonic-gate (void) sprintf(Scratch, "ak_size is %d", ak->ak_size);
3530Sstevel@tonic-gate debug(Scratch);
3540Sstevel@tonic-gate # endif
3550Sstevel@tonic-gate /* get a contiguous chunk */
3560Sstevel@tonic-gate if ((p = malloc((unsigned) (ak->ak_size + 1))) == NULL) {
3570Sstevel@tonic-gate error(E_MALLOC, CONT);
3580Sstevel@tonic-gate for (i = 0; i < Nentries; ++i)
3590Sstevel@tonic-gate free(data[i]);
3600Sstevel@tonic-gate free((char *) data);
3610Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3620Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL;
3630Sstevel@tonic-gate ak->ak_size = 0;
3640Sstevel@tonic-gate sendack(ak);
3650Sstevel@tonic-gate break;
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate /* condense the data into the contiguous chunk */
3680Sstevel@tonic-gate *p = '\0';
3690Sstevel@tonic-gate for (i = 0; i < Nentries; ++i) {
3700Sstevel@tonic-gate (void) strcat(p, data[i]);
3710Sstevel@tonic-gate free(data[i]);
3720Sstevel@tonic-gate }
3730Sstevel@tonic-gate # ifdef DEBUG
3740Sstevel@tonic-gate debug(p);
3750Sstevel@tonic-gate # endif
3760Sstevel@tonic-gate if (data)
3770Sstevel@tonic-gate free((char *) data);
3780Sstevel@tonic-gate /* ak->ak_size was set above */
3790Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3800Sstevel@tonic-gate ak->ak_resp = AK_ACK;
3810Sstevel@tonic-gate sendack(ak);
3820Sstevel@tonic-gate if (ak->ak_size)
3830Sstevel@tonic-gate if (write(Cfd, p, (unsigned) ak->ak_size) != ak->ak_size)
3840Sstevel@tonic-gate log("could not send info");
3850Sstevel@tonic-gate free(p);
3860Sstevel@tonic-gate break;
3870Sstevel@tonic-gate
3880Sstevel@tonic-gate /*
3890Sstevel@tonic-gate * request for sac to read sactab
3900Sstevel@tonic-gate */
3910Sstevel@tonic-gate
3920Sstevel@tonic-gate case AC_SACREAD:
3930Sstevel@tonic-gate # ifdef DEBUG
3940Sstevel@tonic-gate log("Got AC_SACREAD");
3950Sstevel@tonic-gate # endif
3960Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
3970Sstevel@tonic-gate ak->ak_resp = AK_ACK;
3980Sstevel@tonic-gate ak->ak_size = 0;
3990Sstevel@tonic-gate read_table(TRUE);
4000Sstevel@tonic-gate sendack(ak);
4010Sstevel@tonic-gate break;
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate /*
4040Sstevel@tonic-gate * request for port monitor to read _pmtab
4050Sstevel@tonic-gate */
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate case AC_PMREAD:
4080Sstevel@tonic-gate # ifdef DEBUG
4090Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_PMREAD for <%s>", ap->ac_tag);
4100Sstevel@tonic-gate log(Scratch);
4110Sstevel@tonic-gate # endif
4120Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) {
4130Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
4140Sstevel@tonic-gate ak->ak_resp = AK_NOPM;
4150Sstevel@tonic-gate ak->ak_size = 0;
4160Sstevel@tonic-gate sendack(ak);
4170Sstevel@tonic-gate break;
4180Sstevel@tonic-gate }
4190Sstevel@tonic-gate switch (sp->sc_sstate) {
4200Sstevel@tonic-gate case UNKNOWN:
4210Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
4220Sstevel@tonic-gate ak->ak_resp = AK_RECOVER;
4230Sstevel@tonic-gate ak->ak_size = 0;
4240Sstevel@tonic-gate sendack(ak);
4250Sstevel@tonic-gate break;
4260Sstevel@tonic-gate case NOTRUNNING:
4270Sstevel@tonic-gate case FAILED:
4280Sstevel@tonic-gate case STOPPING:
4290Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
4300Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN;
4310Sstevel@tonic-gate ak->ak_size = 0;
4320Sstevel@tonic-gate sendack(ak);
4330Sstevel@tonic-gate break;
4340Sstevel@tonic-gate case STARTING:
4350Sstevel@tonic-gate case ENABLED:
4360Sstevel@tonic-gate case DISABLED:
4370Sstevel@tonic-gate sacmsg.sc_type = SC_READDB;
4380Sstevel@tonic-gate sacmsg.sc_size = 0;
4390Sstevel@tonic-gate sendpmmsg(sp, &sacmsg);
4400Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
4410Sstevel@tonic-gate ak->ak_resp = AK_ACK;
4420Sstevel@tonic-gate ak->ak_size = 0;
4430Sstevel@tonic-gate sendack(ak);
4440Sstevel@tonic-gate break;
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate break;
4470Sstevel@tonic-gate /*
4480Sstevel@tonic-gate * garbled message
4490Sstevel@tonic-gate */
4500Sstevel@tonic-gate
4510Sstevel@tonic-gate default:
4520Sstevel@tonic-gate (void) sprintf(Scratch, "Got unknown message for <%s>", ap->ac_tag);
4530Sstevel@tonic-gate log(Scratch);
4540Sstevel@tonic-gate ak->ak_pid = ap->ac_pid;
4550Sstevel@tonic-gate ak->ak_resp = AK_UNKNOWN;
4560Sstevel@tonic-gate ak->ak_size = 0;
4570Sstevel@tonic-gate sendack(ak);
4580Sstevel@tonic-gate break;
4590Sstevel@tonic-gate }
4600Sstevel@tonic-gate break;
4610Sstevel@tonic-gate default:
4620Sstevel@tonic-gate error(E_POLL, EXIT);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate
4670Sstevel@tonic-gate /*
4680Sstevel@tonic-gate * sendack - send a response to the administrative command
4690Sstevel@tonic-gate *
4700Sstevel@tonic-gate * args: ap - pointer to acknowlegment message
4710Sstevel@tonic-gate */
4720Sstevel@tonic-gate
4730Sstevel@tonic-gate void
sendack(ap)4740Sstevel@tonic-gate sendack(ap)
4750Sstevel@tonic-gate struct admack *ap;
4760Sstevel@tonic-gate {
4770Sstevel@tonic-gate # ifdef DEBUG
4780Sstevel@tonic-gate debug("in sendack");
4790Sstevel@tonic-gate # endif
4800Sstevel@tonic-gate if (write(Cfd, ap, sizeof(struct admack)) != sizeof(struct admack))
4810Sstevel@tonic-gate log("Could not send ack");
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate /*
4860Sstevel@tonic-gate * sendpmmsg - send a message to a PM. Note: sc_size is always 0 in
4870Sstevel@tonic-gate * this version so just send the header.
4880Sstevel@tonic-gate *
4890Sstevel@tonic-gate * args: sp - pointer to sac's port monitor information for
4900Sstevel@tonic-gate * designated port monitor
4910Sstevel@tonic-gate * sm - pointer to message to send
4920Sstevel@tonic-gate */
4930Sstevel@tonic-gate
4940Sstevel@tonic-gate void
sendpmmsg(sp,sm)4950Sstevel@tonic-gate sendpmmsg(sp, sm)
4960Sstevel@tonic-gate register struct sactab *sp;
4970Sstevel@tonic-gate register struct sacmsg *sm;
4980Sstevel@tonic-gate {
4990Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
5000Sstevel@tonic-gate
5010Sstevel@tonic-gate # ifdef DEBUG
5020Sstevel@tonic-gate debug("in sendpmmsg");
5030Sstevel@tonic-gate # endif
5040Sstevel@tonic-gate if (write(sp->sc_fd, sm, sizeof(struct sacmsg)) != sizeof(struct sacmsg)) {
5050Sstevel@tonic-gate (void) sprintf(buf, "message to <%s> failed", sp->sc_tag);
5060Sstevel@tonic-gate log(buf);
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate /*
5110Sstevel@tonic-gate * sendsig - send a signal to the port monitor
5120Sstevel@tonic-gate *
5130Sstevel@tonic-gate * args: sp - pointer to sac's port monitor infomation for
5140Sstevel@tonic-gate * designated port monitor
5150Sstevel@tonic-gate * signo - signal number to send
5160Sstevel@tonic-gate */
5170Sstevel@tonic-gate
518*334Sdp int
sendsig(struct sactab * sp,int signo)519*334Sdp sendsig(struct sactab *sp, int signo)
5200Sstevel@tonic-gate {
5210Sstevel@tonic-gate pid_t pid; /* pid of designated port monitor */
5220Sstevel@tonic-gate pid_t checklock();
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate # ifdef DEBUG
5250Sstevel@tonic-gate (void) sprintf(Scratch, "in sendsig - sending signo %d to %s", signo, sp->sc_tag);
5260Sstevel@tonic-gate debug(Scratch);
5270Sstevel@tonic-gate # endif
5280Sstevel@tonic-gate if (pid = checklock(sp)) {
5290Sstevel@tonic-gate if (kill(pid, signo) < 0) {
5300Sstevel@tonic-gate # ifdef DEBUG
5310Sstevel@tonic-gate debug("in sendsig - kill failed");
5320Sstevel@tonic-gate # endif
5330Sstevel@tonic-gate return(-1);
5340Sstevel@tonic-gate }
5350Sstevel@tonic-gate else
5360Sstevel@tonic-gate return(0);
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate else {
5390Sstevel@tonic-gate # ifdef DEBUG
5400Sstevel@tonic-gate debug("in sendsig - checklock failed");
5410Sstevel@tonic-gate # endif
5420Sstevel@tonic-gate return(-1);
5430Sstevel@tonic-gate }
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate
5470Sstevel@tonic-gate /*
5480Sstevel@tonic-gate * checklock - check to see if a _pid file is locked
5490Sstevel@tonic-gate * if so, return pid in file, else 0
5500Sstevel@tonic-gate *
5510Sstevel@tonic-gate * args: sp - pointer to sac's port monitor infomation for
5520Sstevel@tonic-gate * designated port monitor
5530Sstevel@tonic-gate */
5540Sstevel@tonic-gate
5550Sstevel@tonic-gate pid_t
checklock(sp)5560Sstevel@tonic-gate checklock(sp)
5570Sstevel@tonic-gate register struct sactab *sp;
5580Sstevel@tonic-gate {
5590Sstevel@tonic-gate int fd; /* scratch file descriptor */
5600Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
5610Sstevel@tonic-gate int ret; /* return value */
5620Sstevel@tonic-gate
5630Sstevel@tonic-gate # ifdef DEBUG
5640Sstevel@tonic-gate debug("in checklock");
5650Sstevel@tonic-gate # endif
5660Sstevel@tonic-gate (void) sprintf(Scratch, "%s/%s/_pid", HOME, sp->sc_tag);
5670Sstevel@tonic-gate fd = open(Scratch, O_RDONLY);
5680Sstevel@tonic-gate if (fd < 0) {
5690Sstevel@tonic-gate (void) sprintf(Scratch, "can not open _pid file for <%s>", sp->sc_tag);
5700Sstevel@tonic-gate log(Scratch);
5710Sstevel@tonic-gate return((pid_t)0);
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate if (lockf(fd, F_TEST, 0) < 0) {
5740Sstevel@tonic-gate if ((ret = read(fd, buf, SIZE - 1)) < 0) {
5750Sstevel@tonic-gate (void) close(fd);
5760Sstevel@tonic-gate return((pid_t)0);
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate (void) close(fd);
5790Sstevel@tonic-gate /* in case pid wasn't null-terminated */
5800Sstevel@tonic-gate buf[ret] = '\0';
5810Sstevel@tonic-gate return((pid_t)atol(buf));
5820Sstevel@tonic-gate }
5830Sstevel@tonic-gate (void) close(fd);
5840Sstevel@tonic-gate return((pid_t)0);
5850Sstevel@tonic-gate }
586