1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.9*/ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate 29*7c478bd9Sstevel@tonic-gate # include <stdio.h> 30*7c478bd9Sstevel@tonic-gate # include <unistd.h> 31*7c478bd9Sstevel@tonic-gate # include <fcntl.h> 32*7c478bd9Sstevel@tonic-gate # include <sys/types.h> 33*7c478bd9Sstevel@tonic-gate # include <sys/stropts.h> 34*7c478bd9Sstevel@tonic-gate # include <signal.h> 35*7c478bd9Sstevel@tonic-gate # include <sys/stat.h> 36*7c478bd9Sstevel@tonic-gate # include <poll.h> 37*7c478bd9Sstevel@tonic-gate # include "misc.h" 38*7c478bd9Sstevel@tonic-gate # include "msgs.h" 39*7c478bd9Sstevel@tonic-gate # include "extern.h" 40*7c478bd9Sstevel@tonic-gate # include <sac.h> 41*7c478bd9Sstevel@tonic-gate # include "adm.h" 42*7c478bd9Sstevel@tonic-gate # include "structs.h" 43*7c478bd9Sstevel@tonic-gate 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * findpm - find a port monitor entry 47*7c478bd9Sstevel@tonic-gate * 48*7c478bd9Sstevel@tonic-gate * args: tag - tag of desired port monitor 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate struct sactab * 53*7c478bd9Sstevel@tonic-gate findpm(tag) 54*7c478bd9Sstevel@tonic-gate register char *tag; 55*7c478bd9Sstevel@tonic-gate { 56*7c478bd9Sstevel@tonic-gate register struct sactab *sp; /* working pointer */ 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate for (sp = Sactab; sp; sp = sp->sc_next) { 59*7c478bd9Sstevel@tonic-gate if (!strcmp(tag, sp->sc_tag)) 60*7c478bd9Sstevel@tonic-gate return(sp); 61*7c478bd9Sstevel@tonic-gate } 62*7c478bd9Sstevel@tonic-gate return(NULL); 63*7c478bd9Sstevel@tonic-gate } 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate /* 67*7c478bd9Sstevel@tonic-gate * sigpoll - handle messages coming in on the command pipe (SIGPOLL signal 68*7c478bd9Sstevel@tonic-gate * handler) 69*7c478bd9Sstevel@tonic-gate */ 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate void 73*7c478bd9Sstevel@tonic-gate sigpoll() 74*7c478bd9Sstevel@tonic-gate { 75*7c478bd9Sstevel@tonic-gate struct pollfd fds; /* array of fds to poll */ 76*7c478bd9Sstevel@tonic-gate struct admcmd cmd; /* incoming command */ 77*7c478bd9Sstevel@tonic-gate register struct admcmd *ap = &cmd; /* and a pointer to it */ 78*7c478bd9Sstevel@tonic-gate struct admack ack; /* acknowledgment */ 79*7c478bd9Sstevel@tonic-gate register struct admack *ak = &ack; /* and a pointer to it */ 80*7c478bd9Sstevel@tonic-gate register struct sactab *sp; /* working pointer */ 81*7c478bd9Sstevel@tonic-gate struct sacmsg sacmsg; /* message to port monitor */ 82*7c478bd9Sstevel@tonic-gate char **data; /* "dumped" sactab */ 83*7c478bd9Sstevel@tonic-gate char *p; /* scratch pointer */ 84*7c478bd9Sstevel@tonic-gate register int i; /* loop control variable */ 85*7c478bd9Sstevel@tonic-gate int ret; /* return value */ 86*7c478bd9Sstevel@tonic-gate sigset_t cset; /* for signal handling */ 87*7c478bd9Sstevel@tonic-gate sigset_t tset; /* for signal handling */ 88*7c478bd9Sstevel@tonic-gate 89*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 90*7c478bd9Sstevel@tonic-gate debug("in sigpoll"); 91*7c478bd9Sstevel@tonic-gate # endif 92*7c478bd9Sstevel@tonic-gate fds.fd = Cfd; 93*7c478bd9Sstevel@tonic-gate fds.events = POLLIN; 94*7c478bd9Sstevel@tonic-gate fds.revents = 0; 95*7c478bd9Sstevel@tonic-gate if (poll(&fds, 1, 0) < 0) 96*7c478bd9Sstevel@tonic-gate error(E_POLL, EXIT); 97*7c478bd9Sstevel@tonic-gate switch (fds.revents) { 98*7c478bd9Sstevel@tonic-gate case POLLIN: 99*7c478bd9Sstevel@tonic-gate if (read(Cfd, ap, sizeof(struct admcmd)) < 0) { 100*7c478bd9Sstevel@tonic-gate error(E_READ, EXIT); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate switch (ap->ac_mtype) { 103*7c478bd9Sstevel@tonic-gate 104*7c478bd9Sstevel@tonic-gate /* 105*7c478bd9Sstevel@tonic-gate * request to start a port monitor 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate 108*7c478bd9Sstevel@tonic-gate case AC_START: 109*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 110*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_START for <%s>", ap->ac_tag); 111*7c478bd9Sstevel@tonic-gate log(Scratch); 112*7c478bd9Sstevel@tonic-gate # endif 113*7c478bd9Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) { 114*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 115*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOPM; 116*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 117*7c478bd9Sstevel@tonic-gate sendack(ak); 118*7c478bd9Sstevel@tonic-gate break; 119*7c478bd9Sstevel@tonic-gate } 120*7c478bd9Sstevel@tonic-gate switch (sp->sc_sstate) { 121*7c478bd9Sstevel@tonic-gate case UNKNOWN: 122*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 123*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_RECOVER; 124*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 125*7c478bd9Sstevel@tonic-gate sendack(ak); 126*7c478bd9Sstevel@tonic-gate break; 127*7c478bd9Sstevel@tonic-gate case FAILED: 128*7c478bd9Sstevel@tonic-gate case NOTRUNNING: 129*7c478bd9Sstevel@tonic-gate sp->sc_rscnt = 0; /* fresh start in life */ 130*7c478bd9Sstevel@tonic-gate if (ret = startpm(sp)) { 131*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 132*7c478bd9Sstevel@tonic-gate if (ret == -1) 133*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMLOCK; 134*7c478bd9Sstevel@tonic-gate else 135*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL; 136*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 137*7c478bd9Sstevel@tonic-gate sendack(ak); 138*7c478bd9Sstevel@tonic-gate break; 139*7c478bd9Sstevel@tonic-gate } 140*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 141*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 142*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 143*7c478bd9Sstevel@tonic-gate sendack(ak); 144*7c478bd9Sstevel@tonic-gate break; 145*7c478bd9Sstevel@tonic-gate case ENABLED: 146*7c478bd9Sstevel@tonic-gate case DISABLED: 147*7c478bd9Sstevel@tonic-gate case STARTING: 148*7c478bd9Sstevel@tonic-gate case STOPPING: 149*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 150*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMRUN; 151*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 152*7c478bd9Sstevel@tonic-gate sendack(ak); 153*7c478bd9Sstevel@tonic-gate break; 154*7c478bd9Sstevel@tonic-gate } 155*7c478bd9Sstevel@tonic-gate break; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate /* 158*7c478bd9Sstevel@tonic-gate * request to kill a port monitor 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate case AC_KILL: 162*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 163*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_KILL for <%s>", ap->ac_tag); 164*7c478bd9Sstevel@tonic-gate log(Scratch); 165*7c478bd9Sstevel@tonic-gate # endif 166*7c478bd9Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) { 167*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 168*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOPM; 169*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 170*7c478bd9Sstevel@tonic-gate sendack(ak); 171*7c478bd9Sstevel@tonic-gate break; 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate switch (sp->sc_sstate) { 174*7c478bd9Sstevel@tonic-gate case UNKNOWN: 175*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 176*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_RECOVER; 177*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 178*7c478bd9Sstevel@tonic-gate sendack(ak); 179*7c478bd9Sstevel@tonic-gate break; 180*7c478bd9Sstevel@tonic-gate case NOTRUNNING: 181*7c478bd9Sstevel@tonic-gate case FAILED: 182*7c478bd9Sstevel@tonic-gate case STOPPING: 183*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 184*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN; 185*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 186*7c478bd9Sstevel@tonic-gate sendack(ak); 187*7c478bd9Sstevel@tonic-gate break; 188*7c478bd9Sstevel@tonic-gate case STARTING: 189*7c478bd9Sstevel@tonic-gate case ENABLED: 190*7c478bd9Sstevel@tonic-gate case DISABLED: 191*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, NULL, &cset); 192*7c478bd9Sstevel@tonic-gate tset = cset; 193*7c478bd9Sstevel@tonic-gate (void) sigaddset(&tset, SIGALRM); 194*7c478bd9Sstevel@tonic-gate (void) sigaddset(&tset, SIGCLD); 195*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &tset, NULL); 196*7c478bd9Sstevel@tonic-gate if (sendsig(sp, SIGTERM)) { 197*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "could not send SIGTERM to <%s>", sp->sc_tag); 198*7c478bd9Sstevel@tonic-gate log(Scratch); 199*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 200*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOCONTACT; 201*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 202*7c478bd9Sstevel@tonic-gate sendack(ak); 203*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &cset, NULL); 204*7c478bd9Sstevel@tonic-gate break; 205*7c478bd9Sstevel@tonic-gate } 206*7c478bd9Sstevel@tonic-gate /* signal sent ok */ 207*7c478bd9Sstevel@tonic-gate sp->sc_lstate = NOTRUNNING; 208*7c478bd9Sstevel@tonic-gate sp->sc_sstate = NOTRUNNING; 209*7c478bd9Sstevel@tonic-gate sp->sc_pstate = STOPPING; 210*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 211*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 212*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 213*7c478bd9Sstevel@tonic-gate sendack(ak); 214*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "terminating <%s>", sp->sc_tag); 215*7c478bd9Sstevel@tonic-gate log(Scratch); 216*7c478bd9Sstevel@tonic-gate (void) sigprocmask(SIG_SETMASK, &cset, NULL); 217*7c478bd9Sstevel@tonic-gate break; 218*7c478bd9Sstevel@tonic-gate } 219*7c478bd9Sstevel@tonic-gate break; 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /* 222*7c478bd9Sstevel@tonic-gate * request to enable a port monitor 223*7c478bd9Sstevel@tonic-gate */ 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate case AC_ENABLE: 226*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 227*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_ENABLE for <%s>", ap->ac_tag); 228*7c478bd9Sstevel@tonic-gate log(Scratch); 229*7c478bd9Sstevel@tonic-gate # endif 230*7c478bd9Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) { 231*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 232*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOPM; 233*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 234*7c478bd9Sstevel@tonic-gate sendack(ak); 235*7c478bd9Sstevel@tonic-gate break; 236*7c478bd9Sstevel@tonic-gate } 237*7c478bd9Sstevel@tonic-gate switch (sp->sc_sstate) { 238*7c478bd9Sstevel@tonic-gate case UNKNOWN: 239*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 240*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_RECOVER; 241*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 242*7c478bd9Sstevel@tonic-gate sendack(ak); 243*7c478bd9Sstevel@tonic-gate break; 244*7c478bd9Sstevel@tonic-gate case NOTRUNNING: 245*7c478bd9Sstevel@tonic-gate case FAILED: 246*7c478bd9Sstevel@tonic-gate case STOPPING: 247*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 248*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN; 249*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 250*7c478bd9Sstevel@tonic-gate sendack(ak); 251*7c478bd9Sstevel@tonic-gate break; 252*7c478bd9Sstevel@tonic-gate case STARTING: 253*7c478bd9Sstevel@tonic-gate case DISABLED: 254*7c478bd9Sstevel@tonic-gate sacmsg.sc_type = SC_ENABLE; 255*7c478bd9Sstevel@tonic-gate sacmsg.sc_size = 0; 256*7c478bd9Sstevel@tonic-gate sp->sc_sstate = ENABLED; 257*7c478bd9Sstevel@tonic-gate sp->sc_lstate = ENABLED; 258*7c478bd9Sstevel@tonic-gate sendpmmsg(sp, &sacmsg); 259*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 260*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 261*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 262*7c478bd9Sstevel@tonic-gate sendack(ak); 263*7c478bd9Sstevel@tonic-gate break; 264*7c478bd9Sstevel@tonic-gate case ENABLED: 265*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 266*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 267*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 268*7c478bd9Sstevel@tonic-gate sendack(ak); 269*7c478bd9Sstevel@tonic-gate break; 270*7c478bd9Sstevel@tonic-gate } 271*7c478bd9Sstevel@tonic-gate break; 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * request to disable a port monitor 275*7c478bd9Sstevel@tonic-gate */ 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate case AC_DISABLE: 278*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 279*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_DISABLE for <%s>", ap->ac_tag); 280*7c478bd9Sstevel@tonic-gate log(Scratch); 281*7c478bd9Sstevel@tonic-gate # endif 282*7c478bd9Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) { 283*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 284*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOPM; 285*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 286*7c478bd9Sstevel@tonic-gate sendack(ak); 287*7c478bd9Sstevel@tonic-gate break; 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate switch (sp->sc_sstate) { 290*7c478bd9Sstevel@tonic-gate case UNKNOWN: 291*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 292*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_RECOVER; 293*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 294*7c478bd9Sstevel@tonic-gate sendack(ak); 295*7c478bd9Sstevel@tonic-gate break; 296*7c478bd9Sstevel@tonic-gate case NOTRUNNING: 297*7c478bd9Sstevel@tonic-gate case FAILED: 298*7c478bd9Sstevel@tonic-gate case STOPPING: 299*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 300*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN; 301*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 302*7c478bd9Sstevel@tonic-gate sendack(ak); 303*7c478bd9Sstevel@tonic-gate break; 304*7c478bd9Sstevel@tonic-gate case STARTING: 305*7c478bd9Sstevel@tonic-gate case ENABLED: 306*7c478bd9Sstevel@tonic-gate sacmsg.sc_type = SC_DISABLE; 307*7c478bd9Sstevel@tonic-gate sacmsg.sc_size = 0; 308*7c478bd9Sstevel@tonic-gate sp->sc_sstate = DISABLED; 309*7c478bd9Sstevel@tonic-gate sp->sc_lstate = DISABLED; 310*7c478bd9Sstevel@tonic-gate sendpmmsg(sp, &sacmsg); 311*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 312*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 313*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 314*7c478bd9Sstevel@tonic-gate sendack(ak); 315*7c478bd9Sstevel@tonic-gate break; 316*7c478bd9Sstevel@tonic-gate case DISABLED: 317*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 318*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 319*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 320*7c478bd9Sstevel@tonic-gate sendack(ak); 321*7c478bd9Sstevel@tonic-gate break; 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate break; 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate /* 326*7c478bd9Sstevel@tonic-gate * request for port monitor status information 327*7c478bd9Sstevel@tonic-gate */ 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate case AC_STATUS: 330*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 331*7c478bd9Sstevel@tonic-gate log("Got AC_STATUS"); 332*7c478bd9Sstevel@tonic-gate # endif 333*7c478bd9Sstevel@tonic-gate /* get all the info in one convenient place */ 334*7c478bd9Sstevel@tonic-gate data = dump_table(); 335*7c478bd9Sstevel@tonic-gate if ((data == NULL) && (Nentries > 0)) { 336*7c478bd9Sstevel@tonic-gate /* something bad happened in dump_table */ 337*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 338*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL; 339*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 340*7c478bd9Sstevel@tonic-gate sendack(ak); 341*7c478bd9Sstevel@tonic-gate break; 342*7c478bd9Sstevel@tonic-gate } 343*7c478bd9Sstevel@tonic-gate /* count how big it is */ 344*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 345*7c478bd9Sstevel@tonic-gate for (i = 0; i < Nentries; ++i) 346*7c478bd9Sstevel@tonic-gate ak->ak_size += strlen(data[i]); 347*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 348*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "ak_size is %d", ak->ak_size); 349*7c478bd9Sstevel@tonic-gate debug(Scratch); 350*7c478bd9Sstevel@tonic-gate # endif 351*7c478bd9Sstevel@tonic-gate /* get a contiguous chunk */ 352*7c478bd9Sstevel@tonic-gate if ((p = malloc((unsigned) (ak->ak_size + 1))) == NULL) { 353*7c478bd9Sstevel@tonic-gate error(E_MALLOC, CONT); 354*7c478bd9Sstevel@tonic-gate for (i = 0; i < Nentries; ++i) 355*7c478bd9Sstevel@tonic-gate free(data[i]); 356*7c478bd9Sstevel@tonic-gate free((char *) data); 357*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 358*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_REQFAIL; 359*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 360*7c478bd9Sstevel@tonic-gate sendack(ak); 361*7c478bd9Sstevel@tonic-gate break; 362*7c478bd9Sstevel@tonic-gate } 363*7c478bd9Sstevel@tonic-gate /* condense the data into the contiguous chunk */ 364*7c478bd9Sstevel@tonic-gate *p = '\0'; 365*7c478bd9Sstevel@tonic-gate for (i = 0; i < Nentries; ++i) { 366*7c478bd9Sstevel@tonic-gate (void) strcat(p, data[i]); 367*7c478bd9Sstevel@tonic-gate free(data[i]); 368*7c478bd9Sstevel@tonic-gate } 369*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 370*7c478bd9Sstevel@tonic-gate debug(p); 371*7c478bd9Sstevel@tonic-gate # endif 372*7c478bd9Sstevel@tonic-gate if (data) 373*7c478bd9Sstevel@tonic-gate free((char *) data); 374*7c478bd9Sstevel@tonic-gate /* ak->ak_size was set above */ 375*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 376*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 377*7c478bd9Sstevel@tonic-gate sendack(ak); 378*7c478bd9Sstevel@tonic-gate if (ak->ak_size) 379*7c478bd9Sstevel@tonic-gate if (write(Cfd, p, (unsigned) ak->ak_size) != ak->ak_size) 380*7c478bd9Sstevel@tonic-gate log("could not send info"); 381*7c478bd9Sstevel@tonic-gate free(p); 382*7c478bd9Sstevel@tonic-gate break; 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate /* 385*7c478bd9Sstevel@tonic-gate * request for sac to read sactab 386*7c478bd9Sstevel@tonic-gate */ 387*7c478bd9Sstevel@tonic-gate 388*7c478bd9Sstevel@tonic-gate case AC_SACREAD: 389*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 390*7c478bd9Sstevel@tonic-gate log("Got AC_SACREAD"); 391*7c478bd9Sstevel@tonic-gate # endif 392*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 393*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 394*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 395*7c478bd9Sstevel@tonic-gate read_table(TRUE); 396*7c478bd9Sstevel@tonic-gate sendack(ak); 397*7c478bd9Sstevel@tonic-gate break; 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* 400*7c478bd9Sstevel@tonic-gate * request for port monitor to read _pmtab 401*7c478bd9Sstevel@tonic-gate */ 402*7c478bd9Sstevel@tonic-gate 403*7c478bd9Sstevel@tonic-gate case AC_PMREAD: 404*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 405*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got AC_PMREAD for <%s>", ap->ac_tag); 406*7c478bd9Sstevel@tonic-gate log(Scratch); 407*7c478bd9Sstevel@tonic-gate # endif 408*7c478bd9Sstevel@tonic-gate if ((sp = findpm(ap->ac_tag)) == NULL) { 409*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 410*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_NOPM; 411*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 412*7c478bd9Sstevel@tonic-gate sendack(ak); 413*7c478bd9Sstevel@tonic-gate break; 414*7c478bd9Sstevel@tonic-gate } 415*7c478bd9Sstevel@tonic-gate switch (sp->sc_sstate) { 416*7c478bd9Sstevel@tonic-gate case UNKNOWN: 417*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 418*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_RECOVER; 419*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 420*7c478bd9Sstevel@tonic-gate sendack(ak); 421*7c478bd9Sstevel@tonic-gate break; 422*7c478bd9Sstevel@tonic-gate case NOTRUNNING: 423*7c478bd9Sstevel@tonic-gate case FAILED: 424*7c478bd9Sstevel@tonic-gate case STOPPING: 425*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 426*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_PMNOTRUN; 427*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 428*7c478bd9Sstevel@tonic-gate sendack(ak); 429*7c478bd9Sstevel@tonic-gate break; 430*7c478bd9Sstevel@tonic-gate case STARTING: 431*7c478bd9Sstevel@tonic-gate case ENABLED: 432*7c478bd9Sstevel@tonic-gate case DISABLED: 433*7c478bd9Sstevel@tonic-gate sacmsg.sc_type = SC_READDB; 434*7c478bd9Sstevel@tonic-gate sacmsg.sc_size = 0; 435*7c478bd9Sstevel@tonic-gate sendpmmsg(sp, &sacmsg); 436*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 437*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_ACK; 438*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 439*7c478bd9Sstevel@tonic-gate sendack(ak); 440*7c478bd9Sstevel@tonic-gate break; 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate break; 443*7c478bd9Sstevel@tonic-gate /* 444*7c478bd9Sstevel@tonic-gate * garbled message 445*7c478bd9Sstevel@tonic-gate */ 446*7c478bd9Sstevel@tonic-gate 447*7c478bd9Sstevel@tonic-gate default: 448*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "Got unknown message for <%s>", ap->ac_tag); 449*7c478bd9Sstevel@tonic-gate log(Scratch); 450*7c478bd9Sstevel@tonic-gate ak->ak_pid = ap->ac_pid; 451*7c478bd9Sstevel@tonic-gate ak->ak_resp = AK_UNKNOWN; 452*7c478bd9Sstevel@tonic-gate ak->ak_size = 0; 453*7c478bd9Sstevel@tonic-gate sendack(ak); 454*7c478bd9Sstevel@tonic-gate break; 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate break; 457*7c478bd9Sstevel@tonic-gate default: 458*7c478bd9Sstevel@tonic-gate error(E_POLL, EXIT); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate 463*7c478bd9Sstevel@tonic-gate /* 464*7c478bd9Sstevel@tonic-gate * sendack - send a response to the administrative command 465*7c478bd9Sstevel@tonic-gate * 466*7c478bd9Sstevel@tonic-gate * args: ap - pointer to acknowlegment message 467*7c478bd9Sstevel@tonic-gate */ 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate void 470*7c478bd9Sstevel@tonic-gate sendack(ap) 471*7c478bd9Sstevel@tonic-gate struct admack *ap; 472*7c478bd9Sstevel@tonic-gate { 473*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 474*7c478bd9Sstevel@tonic-gate debug("in sendack"); 475*7c478bd9Sstevel@tonic-gate # endif 476*7c478bd9Sstevel@tonic-gate if (write(Cfd, ap, sizeof(struct admack)) != sizeof(struct admack)) 477*7c478bd9Sstevel@tonic-gate log("Could not send ack"); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate /* 482*7c478bd9Sstevel@tonic-gate * sendpmmsg - send a message to a PM. Note: sc_size is always 0 in 483*7c478bd9Sstevel@tonic-gate * this version so just send the header. 484*7c478bd9Sstevel@tonic-gate * 485*7c478bd9Sstevel@tonic-gate * args: sp - pointer to sac's port monitor information for 486*7c478bd9Sstevel@tonic-gate * designated port monitor 487*7c478bd9Sstevel@tonic-gate * sm - pointer to message to send 488*7c478bd9Sstevel@tonic-gate */ 489*7c478bd9Sstevel@tonic-gate 490*7c478bd9Sstevel@tonic-gate void 491*7c478bd9Sstevel@tonic-gate sendpmmsg(sp, sm) 492*7c478bd9Sstevel@tonic-gate register struct sactab *sp; 493*7c478bd9Sstevel@tonic-gate register struct sacmsg *sm; 494*7c478bd9Sstevel@tonic-gate { 495*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 498*7c478bd9Sstevel@tonic-gate debug("in sendpmmsg"); 499*7c478bd9Sstevel@tonic-gate # endif 500*7c478bd9Sstevel@tonic-gate if (write(sp->sc_fd, sm, sizeof(struct sacmsg)) != sizeof(struct sacmsg)) { 501*7c478bd9Sstevel@tonic-gate (void) sprintf(buf, "message to <%s> failed", sp->sc_tag); 502*7c478bd9Sstevel@tonic-gate log(buf); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* 507*7c478bd9Sstevel@tonic-gate * sendsig - send a signal to the port monitor 508*7c478bd9Sstevel@tonic-gate * 509*7c478bd9Sstevel@tonic-gate * args: sp - pointer to sac's port monitor infomation for 510*7c478bd9Sstevel@tonic-gate * designated port monitor 511*7c478bd9Sstevel@tonic-gate * signo - signal number to send 512*7c478bd9Sstevel@tonic-gate */ 513*7c478bd9Sstevel@tonic-gate 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate sendsig(sp, signo) 516*7c478bd9Sstevel@tonic-gate register struct sactab *sp; 517*7c478bd9Sstevel@tonic-gate int signo; 518*7c478bd9Sstevel@tonic-gate { 519*7c478bd9Sstevel@tonic-gate pid_t pid; /* pid of designated port monitor */ 520*7c478bd9Sstevel@tonic-gate pid_t checklock(); 521*7c478bd9Sstevel@tonic-gate 522*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 523*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "in sendsig - sending signo %d to %s", signo, sp->sc_tag); 524*7c478bd9Sstevel@tonic-gate debug(Scratch); 525*7c478bd9Sstevel@tonic-gate # endif 526*7c478bd9Sstevel@tonic-gate if (pid = checklock(sp)) { 527*7c478bd9Sstevel@tonic-gate if (kill(pid, signo) < 0) { 528*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 529*7c478bd9Sstevel@tonic-gate debug("in sendsig - kill failed"); 530*7c478bd9Sstevel@tonic-gate # endif 531*7c478bd9Sstevel@tonic-gate return(-1); 532*7c478bd9Sstevel@tonic-gate } 533*7c478bd9Sstevel@tonic-gate else 534*7c478bd9Sstevel@tonic-gate return(0); 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate else { 537*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 538*7c478bd9Sstevel@tonic-gate debug("in sendsig - checklock failed"); 539*7c478bd9Sstevel@tonic-gate # endif 540*7c478bd9Sstevel@tonic-gate return(-1); 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate } 543*7c478bd9Sstevel@tonic-gate 544*7c478bd9Sstevel@tonic-gate 545*7c478bd9Sstevel@tonic-gate /* 546*7c478bd9Sstevel@tonic-gate * checklock - check to see if a _pid file is locked 547*7c478bd9Sstevel@tonic-gate * if so, return pid in file, else 0 548*7c478bd9Sstevel@tonic-gate * 549*7c478bd9Sstevel@tonic-gate * args: sp - pointer to sac's port monitor infomation for 550*7c478bd9Sstevel@tonic-gate * designated port monitor 551*7c478bd9Sstevel@tonic-gate */ 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate pid_t 554*7c478bd9Sstevel@tonic-gate checklock(sp) 555*7c478bd9Sstevel@tonic-gate register struct sactab *sp; 556*7c478bd9Sstevel@tonic-gate { 557*7c478bd9Sstevel@tonic-gate int fd; /* scratch file descriptor */ 558*7c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */ 559*7c478bd9Sstevel@tonic-gate int ret; /* return value */ 560*7c478bd9Sstevel@tonic-gate 561*7c478bd9Sstevel@tonic-gate # ifdef DEBUG 562*7c478bd9Sstevel@tonic-gate debug("in checklock"); 563*7c478bd9Sstevel@tonic-gate # endif 564*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "%s/%s/_pid", HOME, sp->sc_tag); 565*7c478bd9Sstevel@tonic-gate fd = open(Scratch, O_RDONLY); 566*7c478bd9Sstevel@tonic-gate if (fd < 0) { 567*7c478bd9Sstevel@tonic-gate (void) sprintf(Scratch, "can not open _pid file for <%s>", sp->sc_tag); 568*7c478bd9Sstevel@tonic-gate log(Scratch); 569*7c478bd9Sstevel@tonic-gate return((pid_t)0); 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate if (lockf(fd, F_TEST, 0) < 0) { 572*7c478bd9Sstevel@tonic-gate if ((ret = read(fd, buf, SIZE - 1)) < 0) { 573*7c478bd9Sstevel@tonic-gate (void) close(fd); 574*7c478bd9Sstevel@tonic-gate return((pid_t)0); 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate (void) close(fd); 577*7c478bd9Sstevel@tonic-gate /* in case pid wasn't null-terminated */ 578*7c478bd9Sstevel@tonic-gate buf[ret] = '\0'; 579*7c478bd9Sstevel@tonic-gate return((pid_t)atol(buf)); 580*7c478bd9Sstevel@tonic-gate } 581*7c478bd9Sstevel@tonic-gate (void) close(fd); 582*7c478bd9Sstevel@tonic-gate return((pid_t)0); 583*7c478bd9Sstevel@tonic-gate } 584