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