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 /*
23*34e48580Sdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
247c478bd9Sstevel@tonic-gate * Use is subject to license terms.
257c478bd9Sstevel@tonic-gate */
267c478bd9Sstevel@tonic-gate
277c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
287c478bd9Sstevel@tonic-gate /* All Rights Reserved */
297c478bd9Sstevel@tonic-gate
307c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
317c478bd9Sstevel@tonic-gate
327c478bd9Sstevel@tonic-gate #include <stdio.h>
33*34e48580Sdp #include <stdlib.h>
34*34e48580Sdp #include <strings.h>
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include <unistd.h>
387c478bd9Sstevel@tonic-gate #include "extern.h"
397c478bd9Sstevel@tonic-gate #include "misc.h"
407c478bd9Sstevel@tonic-gate #include <sac.h>
417c478bd9Sstevel@tonic-gate #include "structs.h"
427c478bd9Sstevel@tonic-gate
437c478bd9Sstevel@tonic-gate #define ADD 0x1 /* -a or other required options seen */
447c478bd9Sstevel@tonic-gate #define REMOVE 0x2 /* -r seen */
457c478bd9Sstevel@tonic-gate #define ENABLE 0x4 /* -e seen */
467c478bd9Sstevel@tonic-gate #define DISABLE 0x8 /* -d seen */
477c478bd9Sstevel@tonic-gate #define PLIST 0x10 /* -l seen */
487c478bd9Sstevel@tonic-gate #define LIST 0x20 /* -L seen */
497c478bd9Sstevel@tonic-gate #define CONFIG 0x40 /* -g seen */
507c478bd9Sstevel@tonic-gate
517c478bd9Sstevel@tonic-gate # define U_FLAG 0x1 /* -fu seen */
527c478bd9Sstevel@tonic-gate # define X_FLAG 0x2 /* -fx seen */
537c478bd9Sstevel@tonic-gate
547c478bd9Sstevel@tonic-gate /*
557c478bd9Sstevel@tonic-gate * functions
567c478bd9Sstevel@tonic-gate */
577c478bd9Sstevel@tonic-gate
587c478bd9Sstevel@tonic-gate char *pflags();
597c478bd9Sstevel@tonic-gate char *pspec();
607c478bd9Sstevel@tonic-gate struct taglist *find_type();
617c478bd9Sstevel@tonic-gate void usage();
627c478bd9Sstevel@tonic-gate void parseline();
637c478bd9Sstevel@tonic-gate void add_svc();
647c478bd9Sstevel@tonic-gate void rem_svc();
657c478bd9Sstevel@tonic-gate void ed_svc();
667c478bd9Sstevel@tonic-gate void list_svcs();
677c478bd9Sstevel@tonic-gate void doconf();
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate /*
707c478bd9Sstevel@tonic-gate * format of a _pmtab entry - used to hold parsed info
717c478bd9Sstevel@tonic-gate */
727c478bd9Sstevel@tonic-gate
737c478bd9Sstevel@tonic-gate struct pmtab {
747c478bd9Sstevel@tonic-gate char *p_tag; /* service tag */
757c478bd9Sstevel@tonic-gate long p_flags; /* flags */
767c478bd9Sstevel@tonic-gate char *p_id; /* logname to start service as */
777c478bd9Sstevel@tonic-gate char *p_res1; /* reserved field */
787c478bd9Sstevel@tonic-gate char *p_res2; /* reserved field */
797c478bd9Sstevel@tonic-gate char *p_res3; /* reserved field */
807c478bd9Sstevel@tonic-gate char *p_pmspec; /* port monitor specific info */
817c478bd9Sstevel@tonic-gate };
827c478bd9Sstevel@tonic-gate
837c478bd9Sstevel@tonic-gate /*
847c478bd9Sstevel@tonic-gate * format of a tag list, which is a list of port monitor tags of
857c478bd9Sstevel@tonic-gate * a designated type
867c478bd9Sstevel@tonic-gate */
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate struct taglist {
897c478bd9Sstevel@tonic-gate struct taglist *t_next; /* next in list */
907c478bd9Sstevel@tonic-gate char t_tag[PMTAGSIZE + 1]; /* PM tag */
917c478bd9Sstevel@tonic-gate char t_type[PMTYPESIZE + 1]; /* PM type */
927c478bd9Sstevel@tonic-gate };
937c478bd9Sstevel@tonic-gate
947c478bd9Sstevel@tonic-gate /*
957c478bd9Sstevel@tonic-gate * common error messages
967c478bd9Sstevel@tonic-gate */
977c478bd9Sstevel@tonic-gate
987c478bd9Sstevel@tonic-gate # define NOTPRIV "User not privileged for operation"
997c478bd9Sstevel@tonic-gate # define BADINP "Embedded newlines not allowed"
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate int Saferrno; /* internal `errno' for exit */
1027c478bd9Sstevel@tonic-gate
1037c478bd9Sstevel@tonic-gate
1047c478bd9Sstevel@tonic-gate /*
1057c478bd9Sstevel@tonic-gate * main - scan args for pmadm and call appropriate handling code
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate
108*34e48580Sdp int
main(int argc,char * argv[])109*34e48580Sdp main(int argc, char *argv[])
1107c478bd9Sstevel@tonic-gate {
1117c478bd9Sstevel@tonic-gate int c; /* option letter */
1127c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */
1137c478bd9Sstevel@tonic-gate uid_t uid; /* invoker's real uid */
1147c478bd9Sstevel@tonic-gate int flag = 0; /* flag to record requested operations */
1157c478bd9Sstevel@tonic-gate int errflg = 0; /* error indicator */
1167c478bd9Sstevel@tonic-gate int badcnt = 0; /* count of bad args to -f */
1177c478bd9Sstevel@tonic-gate int version = -1; /* argument to -v */
1187c478bd9Sstevel@tonic-gate int sawaflag = 0; /* true if actually saw -a */
1197c478bd9Sstevel@tonic-gate int conflag = 0; /* true if output should be in condensed form */
1207c478bd9Sstevel@tonic-gate long flags = 0; /* arguments to -f */
1217c478bd9Sstevel@tonic-gate char *pmtag = NULL; /* argument to -p */
1227c478bd9Sstevel@tonic-gate char *type = NULL; /* argument to -t */
1237c478bd9Sstevel@tonic-gate char *script = NULL; /* argument to -z */
1247c478bd9Sstevel@tonic-gate char *comment = " "; /* argument to -y */
1257c478bd9Sstevel@tonic-gate char *id = NULL; /* argument to -i */
1267c478bd9Sstevel@tonic-gate char *svctag = NULL; /* argument to -s */
1277c478bd9Sstevel@tonic-gate char *pmspec = NULL; /* argument to -m */
1287c478bd9Sstevel@tonic-gate char badargs[SIZE]; /* place to hold bad args to -f */
1297c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
1307c478bd9Sstevel@tonic-gate register char *p; /* scratch pointer */
1317c478bd9Sstevel@tonic-gate
1327c478bd9Sstevel@tonic-gate if (argc == 1)
1337c478bd9Sstevel@tonic-gate usage(argv[0]);
1347c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "adef:gi:Llm:p:rs:t:v:y:z:")) != -1) {
1357c478bd9Sstevel@tonic-gate switch (c) {
1367c478bd9Sstevel@tonic-gate case 'a':
1377c478bd9Sstevel@tonic-gate flag |= ADD;
1387c478bd9Sstevel@tonic-gate sawaflag = 1;
1397c478bd9Sstevel@tonic-gate break;
1407c478bd9Sstevel@tonic-gate case 'd':
1417c478bd9Sstevel@tonic-gate flag |= DISABLE;
1427c478bd9Sstevel@tonic-gate break;
1437c478bd9Sstevel@tonic-gate case 'e':
1447c478bd9Sstevel@tonic-gate flag |= ENABLE;
1457c478bd9Sstevel@tonic-gate break;
1467c478bd9Sstevel@tonic-gate case 'f':
1477c478bd9Sstevel@tonic-gate flag |= ADD;
1487c478bd9Sstevel@tonic-gate while (*optarg) {
1497c478bd9Sstevel@tonic-gate switch (*optarg++) {
1507c478bd9Sstevel@tonic-gate case 'u':
1517c478bd9Sstevel@tonic-gate flags |= U_FLAG;
1527c478bd9Sstevel@tonic-gate break;
1537c478bd9Sstevel@tonic-gate case 'x':
1547c478bd9Sstevel@tonic-gate flags |= X_FLAG;
1557c478bd9Sstevel@tonic-gate break;
1567c478bd9Sstevel@tonic-gate default:
1577c478bd9Sstevel@tonic-gate badargs[badcnt++] = *(optarg - 1);
1587c478bd9Sstevel@tonic-gate break;
1597c478bd9Sstevel@tonic-gate }
1607c478bd9Sstevel@tonic-gate }
1617c478bd9Sstevel@tonic-gate /* null terminate just in case anything is there */
1627c478bd9Sstevel@tonic-gate badargs[badcnt] = '\0';
1637c478bd9Sstevel@tonic-gate break;
1647c478bd9Sstevel@tonic-gate case 'g':
1657c478bd9Sstevel@tonic-gate flag |= CONFIG;
1667c478bd9Sstevel@tonic-gate break;
1677c478bd9Sstevel@tonic-gate case 'i':
1687c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1697c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
1707c478bd9Sstevel@tonic-gate error(BADINP);
1717c478bd9Sstevel@tonic-gate }
1727c478bd9Sstevel@tonic-gate flag |= ADD;
1737c478bd9Sstevel@tonic-gate id = optarg;
1747c478bd9Sstevel@tonic-gate break;
1757c478bd9Sstevel@tonic-gate case 'L':
1767c478bd9Sstevel@tonic-gate flag |= LIST;
1777c478bd9Sstevel@tonic-gate break;
1787c478bd9Sstevel@tonic-gate case 'l':
1797c478bd9Sstevel@tonic-gate flag |= PLIST;
1807c478bd9Sstevel@tonic-gate break;
1817c478bd9Sstevel@tonic-gate case 'm':
1827c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1837c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
1847c478bd9Sstevel@tonic-gate error(BADINP);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate if (*optarg == '\0') {
1877c478bd9Sstevel@tonic-gate /* this will generate a usage message below */
1887c478bd9Sstevel@tonic-gate errflg++;
1897c478bd9Sstevel@tonic-gate break;
1907c478bd9Sstevel@tonic-gate }
1917c478bd9Sstevel@tonic-gate flag |= ADD;
1927c478bd9Sstevel@tonic-gate pmspec = optarg;
1937c478bd9Sstevel@tonic-gate break;
1947c478bd9Sstevel@tonic-gate case 'p':
1957c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1967c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
1977c478bd9Sstevel@tonic-gate error(BADINP);
1987c478bd9Sstevel@tonic-gate }
1997c478bd9Sstevel@tonic-gate pmtag = optarg;
2007c478bd9Sstevel@tonic-gate if (strlen(pmtag) > PMTAGSIZE) {
2017c478bd9Sstevel@tonic-gate pmtag[PMTAGSIZE] = '\0';
2027c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag);
2037c478bd9Sstevel@tonic-gate }
2047c478bd9Sstevel@tonic-gate for (p = pmtag; *p; p++) {
2057c478bd9Sstevel@tonic-gate if (!isalnum(*p)) {
2067c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2077c478bd9Sstevel@tonic-gate error("port monitor tag must be alphanumeric");
2087c478bd9Sstevel@tonic-gate }
2097c478bd9Sstevel@tonic-gate }
2107c478bd9Sstevel@tonic-gate break;
2117c478bd9Sstevel@tonic-gate case 'r':
2127c478bd9Sstevel@tonic-gate flag |= REMOVE;
2137c478bd9Sstevel@tonic-gate break;
2147c478bd9Sstevel@tonic-gate case 's':
2157c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2167c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2177c478bd9Sstevel@tonic-gate error(BADINP);
2187c478bd9Sstevel@tonic-gate }
2197c478bd9Sstevel@tonic-gate svctag = optarg;
2207c478bd9Sstevel@tonic-gate if (strlen(svctag) > SVCTAGSIZE) {
2217c478bd9Sstevel@tonic-gate svctag[SVCTAGSIZE] = '\0';
2227c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "svctag too long, truncated to <%s>\n", svctag);
2237c478bd9Sstevel@tonic-gate }
2247c478bd9Sstevel@tonic-gate for (p = svctag; *p; p++) {
2257c478bd9Sstevel@tonic-gate if (!isalnum(*p)) {
2267c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2277c478bd9Sstevel@tonic-gate error("service tag must be alphanumeric");
2287c478bd9Sstevel@tonic-gate }
2297c478bd9Sstevel@tonic-gate }
2307c478bd9Sstevel@tonic-gate break;
2317c478bd9Sstevel@tonic-gate case 't':
2327c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2337c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2347c478bd9Sstevel@tonic-gate error(BADINP);
2357c478bd9Sstevel@tonic-gate }
2367c478bd9Sstevel@tonic-gate type = optarg;
2377c478bd9Sstevel@tonic-gate if (strlen(type) > PMTYPESIZE) {
2387c478bd9Sstevel@tonic-gate type[PMTYPESIZE] = '\0';
2397c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "type too long, truncated to <%s>\n", type);
2407c478bd9Sstevel@tonic-gate }
2417c478bd9Sstevel@tonic-gate for (p = type; *p; p++) {
2427c478bd9Sstevel@tonic-gate if (!isalnum(*p)) {
2437c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2447c478bd9Sstevel@tonic-gate error("port monitor type must be alphanumeric");
2457c478bd9Sstevel@tonic-gate }
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate break;
2487c478bd9Sstevel@tonic-gate case 'v':
2497c478bd9Sstevel@tonic-gate flag |= ADD;
2507c478bd9Sstevel@tonic-gate version = atoi(optarg);
2517c478bd9Sstevel@tonic-gate if (version < 0) {
2527c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2537c478bd9Sstevel@tonic-gate error("version number can not be negative");
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate break;
2567c478bd9Sstevel@tonic-gate case 'y':
2577c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2587c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2597c478bd9Sstevel@tonic-gate error(BADINP);
2607c478bd9Sstevel@tonic-gate }
2617c478bd9Sstevel@tonic-gate flag |= ADD;
2627c478bd9Sstevel@tonic-gate comment = optarg;
2637c478bd9Sstevel@tonic-gate break;
2647c478bd9Sstevel@tonic-gate case 'z':
2657c478bd9Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2667c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2677c478bd9Sstevel@tonic-gate error(BADINP);
2687c478bd9Sstevel@tonic-gate }
2697c478bd9Sstevel@tonic-gate script = optarg;
2707c478bd9Sstevel@tonic-gate break;
2717c478bd9Sstevel@tonic-gate case '?':
2727c478bd9Sstevel@tonic-gate errflg++;
2737c478bd9Sstevel@tonic-gate }
2747c478bd9Sstevel@tonic-gate }
2757c478bd9Sstevel@tonic-gate if (errflg || (optind < argc))
2767c478bd9Sstevel@tonic-gate usage(argv[0]);
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate if (badcnt) {
2797c478bd9Sstevel@tonic-gate /* bad flags were given to -f */
2807c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s are not valid arguments for \"-f\"", badargs);
2817c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
2827c478bd9Sstevel@tonic-gate error(buf);
2837c478bd9Sstevel@tonic-gate }
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate uid = getuid();
2867c478bd9Sstevel@tonic-gate
2877c478bd9Sstevel@tonic-gate /*
2887c478bd9Sstevel@tonic-gate * don't do anything if _sactab isn't the version we understand
2897c478bd9Sstevel@tonic-gate */
2907c478bd9Sstevel@tonic-gate
2917c478bd9Sstevel@tonic-gate if ((ret = check_version(VERSION, SACTAB)) == 1) {
2927c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
2937c478bd9Sstevel@tonic-gate error("_sactab version number is incorrect");
2947c478bd9Sstevel@tonic-gate }
2957c478bd9Sstevel@tonic-gate else if (ret == 2) {
2967c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", SACTAB);
2977c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
2987c478bd9Sstevel@tonic-gate error(buf);
2997c478bd9Sstevel@tonic-gate }
3007c478bd9Sstevel@tonic-gate else if (ret == 3) {
3017c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", SACTAB);
3027c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
3037c478bd9Sstevel@tonic-gate error(buf);
3047c478bd9Sstevel@tonic-gate }
3057c478bd9Sstevel@tonic-gate
3067c478bd9Sstevel@tonic-gate switch (flag) {
3077c478bd9Sstevel@tonic-gate case ADD:
3087c478bd9Sstevel@tonic-gate if (uid) {
3097c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV;
3107c478bd9Sstevel@tonic-gate error(NOTPRIV);
3117c478bd9Sstevel@tonic-gate }
3127c478bd9Sstevel@tonic-gate if (!sawaflag || (pmtag && type) || (!pmtag && !type) || !svctag || !id || !pmspec || (version < 0))
3137c478bd9Sstevel@tonic-gate usage(argv[0]);
3147c478bd9Sstevel@tonic-gate add_svc(pmtag, type, svctag, id, pmspec, flags, version, comment, script);
3157c478bd9Sstevel@tonic-gate break;
3167c478bd9Sstevel@tonic-gate case REMOVE:
3177c478bd9Sstevel@tonic-gate if (uid) {
3187c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV;
3197c478bd9Sstevel@tonic-gate error(NOTPRIV);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3227c478bd9Sstevel@tonic-gate usage(argv[0]);
3237c478bd9Sstevel@tonic-gate rem_svc(pmtag, svctag);
3247c478bd9Sstevel@tonic-gate break;
3257c478bd9Sstevel@tonic-gate case ENABLE:
3267c478bd9Sstevel@tonic-gate if (uid) {
3277c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV;
3287c478bd9Sstevel@tonic-gate error(NOTPRIV);
3297c478bd9Sstevel@tonic-gate }
3307c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3317c478bd9Sstevel@tonic-gate usage(argv[0]);
3327c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, ENABLE);
3337c478bd9Sstevel@tonic-gate break;
3347c478bd9Sstevel@tonic-gate case DISABLE:
3357c478bd9Sstevel@tonic-gate if (uid) {
3367c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV;
3377c478bd9Sstevel@tonic-gate error(NOTPRIV);
3387c478bd9Sstevel@tonic-gate }
3397c478bd9Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3407c478bd9Sstevel@tonic-gate usage(argv[0]);
3417c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, DISABLE);
3427c478bd9Sstevel@tonic-gate break;
3437c478bd9Sstevel@tonic-gate case LIST:
3447c478bd9Sstevel@tonic-gate conflag = 1;
3457c478bd9Sstevel@tonic-gate /* fall through */
3467c478bd9Sstevel@tonic-gate case PLIST:
3477c478bd9Sstevel@tonic-gate if ((pmtag && type) || script)
3487c478bd9Sstevel@tonic-gate usage(argv[0]);
3497c478bd9Sstevel@tonic-gate list_svcs(pmtag, type, svctag, conflag);
3507c478bd9Sstevel@tonic-gate break;
3517c478bd9Sstevel@tonic-gate case CONFIG:
3527c478bd9Sstevel@tonic-gate if (script && uid) {
3537c478bd9Sstevel@tonic-gate Saferrno = E_NOPRIV;
3547c478bd9Sstevel@tonic-gate error(NOTPRIV);
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate if ((pmtag && type) || (!pmtag && !type) || !svctag || (type && !script))
3577c478bd9Sstevel@tonic-gate usage(argv[0]);
3587c478bd9Sstevel@tonic-gate doconf(script, pmtag, type, svctag);
3597c478bd9Sstevel@tonic-gate break;
3607c478bd9Sstevel@tonic-gate default:
3617c478bd9Sstevel@tonic-gate /* we only get here if more than one flag bit was set */
3627c478bd9Sstevel@tonic-gate usage(argv[0]);
3637c478bd9Sstevel@tonic-gate /* NOTREACHED */
3647c478bd9Sstevel@tonic-gate }
3657c478bd9Sstevel@tonic-gate quit();
3667c478bd9Sstevel@tonic-gate /* NOTREACHED */
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate
3697c478bd9Sstevel@tonic-gate
3707c478bd9Sstevel@tonic-gate /*
3717c478bd9Sstevel@tonic-gate * usage - print out a usage message
3727c478bd9Sstevel@tonic-gate *
3737c478bd9Sstevel@tonic-gate * args: cmdname - the name command was invoked with
3747c478bd9Sstevel@tonic-gate */
3757c478bd9Sstevel@tonic-gate
3767c478bd9Sstevel@tonic-gate void
usage(cmdname)3777c478bd9Sstevel@tonic-gate usage(cmdname)
3787c478bd9Sstevel@tonic-gate char *cmdname;
3797c478bd9Sstevel@tonic-gate {
3807c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Usage:\t%s -a [ -p pmtag | -t type ] -s svctag -i id -m \"pmspecific\"\n", cmdname);
3817c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t\t-v version [ -f xu ] [ -y comment ] [ -z script]\n");
3827c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -r -p pmtag -s svctag\n", cmdname);
3837c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -e -p pmtag -s svctag\n", cmdname);
3847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -d -p pmtag -s svctag\n", cmdname);
3857c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
3867c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
3877c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -p pmtag -s svctag [ -z script ]\n", cmdname);
3887c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -s svctag -t type -z script\n", cmdname);
3897c478bd9Sstevel@tonic-gate Saferrno = E_BADARGS;
3907c478bd9Sstevel@tonic-gate quit();
3917c478bd9Sstevel@tonic-gate }
3927c478bd9Sstevel@tonic-gate
3937c478bd9Sstevel@tonic-gate
3947c478bd9Sstevel@tonic-gate /*
3957c478bd9Sstevel@tonic-gate * add_svc - add a service entry
3967c478bd9Sstevel@tonic-gate *
3977c478bd9Sstevel@tonic-gate * args: tag - port monitor's tag (may be null)
3987c478bd9Sstevel@tonic-gate * type - port monitor's type (may be null)
3997c478bd9Sstevel@tonic-gate * svctag - service's tag
4007c478bd9Sstevel@tonic-gate * id - identity under which service should run
4017c478bd9Sstevel@tonic-gate * pmspec - uninterpreted port monitor-specific info
4027c478bd9Sstevel@tonic-gate * flags - service flags
4037c478bd9Sstevel@tonic-gate * version - version number of port monitor's pmtab
4047c478bd9Sstevel@tonic-gate * comment - comment describing service
4057c478bd9Sstevel@tonic-gate * script - service's configuration script
4067c478bd9Sstevel@tonic-gate */
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate void
add_svc(tag,type,svctag,id,pmspec,flags,version,comment,script)4097c478bd9Sstevel@tonic-gate add_svc(tag, type, svctag, id, pmspec, flags, version, comment, script)
4107c478bd9Sstevel@tonic-gate char *tag;
4117c478bd9Sstevel@tonic-gate char *type;
4127c478bd9Sstevel@tonic-gate char *svctag;
4137c478bd9Sstevel@tonic-gate char *id;
4147c478bd9Sstevel@tonic-gate char *pmspec;
4157c478bd9Sstevel@tonic-gate long flags;
4167c478bd9Sstevel@tonic-gate int version;
4177c478bd9Sstevel@tonic-gate char *comment;
4187c478bd9Sstevel@tonic-gate char *script;
4197c478bd9Sstevel@tonic-gate {
4207c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
4217c478bd9Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */
4227c478bd9Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */
4237c478bd9Sstevel@tonic-gate int ret; /* return code from check_version */
4247c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
4257c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */
4267c478bd9Sstevel@tonic-gate int added; /* count number added */
4277c478bd9Sstevel@tonic-gate
4287c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r");
4297c478bd9Sstevel@tonic-gate if (fp == NULL) {
4307c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
4317c478bd9Sstevel@tonic-gate error("Could not open _sactab");
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) {
4347c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag);
4357c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
4367c478bd9Sstevel@tonic-gate error(buf);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) {
4397c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
4407c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
4417c478bd9Sstevel@tonic-gate error(buf);
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate (void) fclose(fp);
4447c478bd9Sstevel@tonic-gate
4457c478bd9Sstevel@tonic-gate if (tag) {
4467c478bd9Sstevel@tonic-gate
4477c478bd9Sstevel@tonic-gate /*
4487c478bd9Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a
4497c478bd9Sstevel@tonic-gate * type specification. Build the 'list' here.
4507c478bd9Sstevel@tonic-gate */
4517c478bd9Sstevel@tonic-gate
4527c478bd9Sstevel@tonic-gate tp = &tl;
4537c478bd9Sstevel@tonic-gate tp->t_next = NULL;
4547c478bd9Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag);
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate
4577c478bd9Sstevel@tonic-gate added = 0;
4587c478bd9Sstevel@tonic-gate while (tp) {
4597c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
4607c478bd9Sstevel@tonic-gate if ((ret = check_version(version, fname)) == 1) {
4617c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s version number is incorrect", fname);
4627c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
4637c478bd9Sstevel@tonic-gate error(buf);
4647c478bd9Sstevel@tonic-gate }
4657c478bd9Sstevel@tonic-gate else if (ret == 2) {
4667c478bd9Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", fname);
4677c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
4687c478bd9Sstevel@tonic-gate error(buf);
4697c478bd9Sstevel@tonic-gate }
4707c478bd9Sstevel@tonic-gate else if (ret == 3) {
4717c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", fname);
4727c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
4737c478bd9Sstevel@tonic-gate error(buf);
4747c478bd9Sstevel@tonic-gate }
4757c478bd9Sstevel@tonic-gate fp = fopen(fname, "r");
4767c478bd9Sstevel@tonic-gate if (fp == NULL) {
4777c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
4787c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
4797c478bd9Sstevel@tonic-gate error(buf);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate if (find_svc(fp, tp->t_tag, svctag)) {
4827c478bd9Sstevel@tonic-gate if (tag) {
4837c478bd9Sstevel@tonic-gate /* special case of tag only */
4847c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s already exists under %s", svctag, tag);
4857c478bd9Sstevel@tonic-gate Saferrno = E_DUP;
4867c478bd9Sstevel@tonic-gate error(buf);
4877c478bd9Sstevel@tonic-gate }
4887c478bd9Sstevel@tonic-gate else {
4897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s already exists under %s - ignoring\n", svctag, tp->t_tag);
4907c478bd9Sstevel@tonic-gate tp = tp->t_next;
4917c478bd9Sstevel@tonic-gate (void) fclose(fp);
4927c478bd9Sstevel@tonic-gate continue;
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate }
4957c478bd9Sstevel@tonic-gate (void) fclose(fp);
4967c478bd9Sstevel@tonic-gate
4977c478bd9Sstevel@tonic-gate /*
4987c478bd9Sstevel@tonic-gate * put in the config script, if specified
4997c478bd9Sstevel@tonic-gate */
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate if (script) {
5027c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
5037c478bd9Sstevel@tonic-gate if (do_config(script, fname)) {
5047c478bd9Sstevel@tonic-gate /* do_config put out any messages */
5057c478bd9Sstevel@tonic-gate tp = tp->t_next;
5067c478bd9Sstevel@tonic-gate continue;
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
5107c478bd9Sstevel@tonic-gate /*
5117c478bd9Sstevel@tonic-gate * add the line
5127c478bd9Sstevel@tonic-gate */
5137c478bd9Sstevel@tonic-gate
5147c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
5157c478bd9Sstevel@tonic-gate fp = fopen(fname, "a");
5167c478bd9Sstevel@tonic-gate if (fp == NULL) {
5177c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
5187c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
5197c478bd9Sstevel@tonic-gate error(buf);
5207c478bd9Sstevel@tonic-gate }
5217c478bd9Sstevel@tonic-gate (void) fprintf(fp, "%s:%s:%s:reserved:reserved:reserved:%s#%s\n",
5227c478bd9Sstevel@tonic-gate svctag, (flags ? pflags(flags, FALSE) : ""), id, pmspec,
5237c478bd9Sstevel@tonic-gate (comment ? comment : ""));
5247c478bd9Sstevel@tonic-gate (void) fclose(fp);
5257c478bd9Sstevel@tonic-gate added++;
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate /*
5287c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
5297c478bd9Sstevel@tonic-gate */
5307c478bd9Sstevel@tonic-gate
5317c478bd9Sstevel@tonic-gate (void) tell_sac(tp->t_tag);
5327c478bd9Sstevel@tonic-gate tp = tp->t_next;
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate if (added == 0) {
5357c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
5367c478bd9Sstevel@tonic-gate error("No services added");
5377c478bd9Sstevel@tonic-gate }
5387c478bd9Sstevel@tonic-gate return;
5397c478bd9Sstevel@tonic-gate }
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate
5427c478bd9Sstevel@tonic-gate /*
5437c478bd9Sstevel@tonic-gate * rem_svc - remove a service
5447c478bd9Sstevel@tonic-gate *
5457c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
5467c478bd9Sstevel@tonic-gate * svctag - tag of the service to be removed
5477c478bd9Sstevel@tonic-gate */
5487c478bd9Sstevel@tonic-gate
5497c478bd9Sstevel@tonic-gate void
rem_svc(pmtag,svctag)5507c478bd9Sstevel@tonic-gate rem_svc(pmtag, svctag)
5517c478bd9Sstevel@tonic-gate char *pmtag;
5527c478bd9Sstevel@tonic-gate char *svctag;
5537c478bd9Sstevel@tonic-gate {
5547c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
5557c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */
5567c478bd9Sstevel@tonic-gate int line; /* line number entry is on */
5577c478bd9Sstevel@tonic-gate char *tname; /* temp file name */
5587c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
5597c478bd9Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r");
5627c478bd9Sstevel@tonic-gate if (fp == NULL) {
5637c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
5647c478bd9Sstevel@tonic-gate error("Could not open _sactab");
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) {
5677c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
5687c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
5697c478bd9Sstevel@tonic-gate error(buf);
5707c478bd9Sstevel@tonic-gate }
5717c478bd9Sstevel@tonic-gate (void) fclose(fp);
5727c478bd9Sstevel@tonic-gate
5737c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag);
5747c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname);
5757c478bd9Sstevel@tonic-gate fp = fopen(buf, "r");
5767c478bd9Sstevel@tonic-gate if (fp == NULL) {
5777c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname);
5787c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
5797c478bd9Sstevel@tonic-gate error(buf);
5807c478bd9Sstevel@tonic-gate }
5817c478bd9Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) {
5827c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
5837c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
5847c478bd9Sstevel@tonic-gate error(buf);
5857c478bd9Sstevel@tonic-gate }
5867c478bd9Sstevel@tonic-gate tname = make_tempname(fname);
5877c478bd9Sstevel@tonic-gate tfp = open_temp(tname);
5887c478bd9Sstevel@tonic-gate if (line != 1) {
5897c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) {
5907c478bd9Sstevel@tonic-gate (void) unlink(tname);
5917c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
5927c478bd9Sstevel@tonic-gate error("error accessing temp file");
5937c478bd9Sstevel@tonic-gate }
5947c478bd9Sstevel@tonic-gate }
5957c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) {
5967c478bd9Sstevel@tonic-gate (void) unlink(tname);
5977c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
5987c478bd9Sstevel@tonic-gate error("error accessing temp file");
5997c478bd9Sstevel@tonic-gate }
6007c478bd9Sstevel@tonic-gate (void) fclose(fp);
6017c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) {
6027c478bd9Sstevel@tonic-gate (void) unlink(tname);
6037c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
6047c478bd9Sstevel@tonic-gate error("error closing tempfile");
6057c478bd9Sstevel@tonic-gate }
6067c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */
6077c478bd9Sstevel@tonic-gate replace(fname, tname);
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate /*
6107c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
6117c478bd9Sstevel@tonic-gate */
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate if (tell_sac(pmtag)) {
6147c478bd9Sstevel@tonic-gate
6157c478bd9Sstevel@tonic-gate /*
6167c478bd9Sstevel@tonic-gate * if we got rid of the service, try to remove the config script too.
6177c478bd9Sstevel@tonic-gate * Don't check return status since it may not have existed anyhow.
6187c478bd9Sstevel@tonic-gate */
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/%s", HOME, pmtag, svctag);
6217c478bd9Sstevel@tonic-gate (void) unlink(buf);
6227c478bd9Sstevel@tonic-gate return;
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate }
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate
6287c478bd9Sstevel@tonic-gate /*
6297c478bd9Sstevel@tonic-gate * ed_svc - enable or disable a particular service
6307c478bd9Sstevel@tonic-gate *
6317c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
6327c478bd9Sstevel@tonic-gate * svctag - tag of service to be enabled or disabled
6337c478bd9Sstevel@tonic-gate * flag - operation to perform (ENABLE or DISABLE)
6347c478bd9Sstevel@tonic-gate */
6357c478bd9Sstevel@tonic-gate
6367c478bd9Sstevel@tonic-gate void
ed_svc(pmtag,svctag,flag)6377c478bd9Sstevel@tonic-gate ed_svc(pmtag, svctag, flag)
6387c478bd9Sstevel@tonic-gate char *pmtag;
6397c478bd9Sstevel@tonic-gate char *svctag;
6407c478bd9Sstevel@tonic-gate int flag;
6417c478bd9Sstevel@tonic-gate {
6427c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
6437c478bd9Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */
6447c478bd9Sstevel@tonic-gate int line; /* line number entry is on */
6457c478bd9Sstevel@tonic-gate register char *from; /* working pointer */
6467c478bd9Sstevel@tonic-gate register char *to; /* working pointer */
6477c478bd9Sstevel@tonic-gate char *tname; /* temp file name */
6487c478bd9Sstevel@tonic-gate char *p; /* scratch pointer */
6497c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
6507c478bd9Sstevel@tonic-gate char tbuf[SIZE]; /* scratch buffer */
6517c478bd9Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */
6527c478bd9Sstevel@tonic-gate
6537c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r");
6547c478bd9Sstevel@tonic-gate if (fp == NULL) {
6557c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
6567c478bd9Sstevel@tonic-gate error("Could not open _sactab");
6577c478bd9Sstevel@tonic-gate }
6587c478bd9Sstevel@tonic-gate if (!find_pm(fp, pmtag)) {
6597c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
6607c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
6617c478bd9Sstevel@tonic-gate error(buf);
6627c478bd9Sstevel@tonic-gate }
6637c478bd9Sstevel@tonic-gate (void) fclose(fp);
6647c478bd9Sstevel@tonic-gate
6657c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag);
6667c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname);
6677c478bd9Sstevel@tonic-gate fp = fopen(buf, "r");
6687c478bd9Sstevel@tonic-gate if (fp == NULL) {
6697c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname);
6707c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
6717c478bd9Sstevel@tonic-gate error(buf);
6727c478bd9Sstevel@tonic-gate }
6737c478bd9Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) {
6747c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
6757c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
6767c478bd9Sstevel@tonic-gate error(buf);
6777c478bd9Sstevel@tonic-gate }
6787c478bd9Sstevel@tonic-gate tname = make_tempname(fname);
6797c478bd9Sstevel@tonic-gate tfp = open_temp(tname);
6807c478bd9Sstevel@tonic-gate if (line != 1) {
6817c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) {
6827c478bd9Sstevel@tonic-gate (void) unlink(tname);
6837c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
6847c478bd9Sstevel@tonic-gate error("error accessing temp file");
6857c478bd9Sstevel@tonic-gate }
6867c478bd9Sstevel@tonic-gate }
6877c478bd9Sstevel@tonic-gate
6887c478bd9Sstevel@tonic-gate /*
6897c478bd9Sstevel@tonic-gate * Note: find_svc above has already read and parsed this entry, thus
6907c478bd9Sstevel@tonic-gate * we know it to be well-formed, so just change the flags as appropriate
6917c478bd9Sstevel@tonic-gate */
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate if (fgets(buf, SIZE, fp) == NULL) {
6947c478bd9Sstevel@tonic-gate (void) unlink(tname);
6957c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
6967c478bd9Sstevel@tonic-gate error("error accessing temp file");
6977c478bd9Sstevel@tonic-gate }
6987c478bd9Sstevel@tonic-gate from = buf;
6997c478bd9Sstevel@tonic-gate to = tbuf;
7007c478bd9Sstevel@tonic-gate
7017c478bd9Sstevel@tonic-gate /*
7027c478bd9Sstevel@tonic-gate * copy initial portion of entry
7037c478bd9Sstevel@tonic-gate */
7047c478bd9Sstevel@tonic-gate
7057c478bd9Sstevel@tonic-gate p = strchr(from, DELIMC);
7067c478bd9Sstevel@tonic-gate for ( ; from <= p; )
7077c478bd9Sstevel@tonic-gate *to++ = *from++;
7087c478bd9Sstevel@tonic-gate
7097c478bd9Sstevel@tonic-gate /*
7107c478bd9Sstevel@tonic-gate * isolate and fix the flags
7117c478bd9Sstevel@tonic-gate */
7127c478bd9Sstevel@tonic-gate
7137c478bd9Sstevel@tonic-gate p = strchr(from, DELIMC);
7147c478bd9Sstevel@tonic-gate for ( ; from < p; ) {
7157c478bd9Sstevel@tonic-gate if (*from == 'x') {
7167c478bd9Sstevel@tonic-gate from++;
7177c478bd9Sstevel@tonic-gate continue;
7187c478bd9Sstevel@tonic-gate }
7197c478bd9Sstevel@tonic-gate *to++ = *from++;
7207c478bd9Sstevel@tonic-gate }
7217c478bd9Sstevel@tonic-gate
7227c478bd9Sstevel@tonic-gate /*
7237c478bd9Sstevel@tonic-gate * above we removed x flag, if this was a disable operation, stick it in
7247c478bd9Sstevel@tonic-gate * and also copy the field delimiter
7257c478bd9Sstevel@tonic-gate */
7267c478bd9Sstevel@tonic-gate
7277c478bd9Sstevel@tonic-gate if (flag == DISABLE)
7287c478bd9Sstevel@tonic-gate *to++ = 'x';
7297c478bd9Sstevel@tonic-gate *to++ = *from++;
7307c478bd9Sstevel@tonic-gate
7317c478bd9Sstevel@tonic-gate /*
7327c478bd9Sstevel@tonic-gate * copy the rest of the line
7337c478bd9Sstevel@tonic-gate */
7347c478bd9Sstevel@tonic-gate
7357c478bd9Sstevel@tonic-gate for ( ; from < &buf[SIZE - 1] ;)
7367c478bd9Sstevel@tonic-gate *to++ = *from++;
7377c478bd9Sstevel@tonic-gate /*** *to = '\0'; BUG: Don't uncomment it ****/
7387c478bd9Sstevel@tonic-gate
7397c478bd9Sstevel@tonic-gate (void) fprintf(tfp, "%s", tbuf);
7407c478bd9Sstevel@tonic-gate
7417c478bd9Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) {
7427c478bd9Sstevel@tonic-gate (void) unlink(tname);
7437c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
7447c478bd9Sstevel@tonic-gate error("error accessing temp file");
7457c478bd9Sstevel@tonic-gate }
7467c478bd9Sstevel@tonic-gate (void) fclose(fp);
7477c478bd9Sstevel@tonic-gate if (fclose(tfp) == EOF) {
7487c478bd9Sstevel@tonic-gate (void) unlink(tname);
7497c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
7507c478bd9Sstevel@tonic-gate error("error closing tempfile");
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate /* note - replace only returns if successful */
7537c478bd9Sstevel@tonic-gate replace(fname, tname);
7547c478bd9Sstevel@tonic-gate
7557c478bd9Sstevel@tonic-gate
7567c478bd9Sstevel@tonic-gate /*
7577c478bd9Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
7587c478bd9Sstevel@tonic-gate */
7597c478bd9Sstevel@tonic-gate
7607c478bd9Sstevel@tonic-gate (void) tell_sac(pmtag);
7617c478bd9Sstevel@tonic-gate }
7627c478bd9Sstevel@tonic-gate
7637c478bd9Sstevel@tonic-gate
7647c478bd9Sstevel@tonic-gate /*
7657c478bd9Sstevel@tonic-gate * doconf - take a config script and have it put where it belongs or
7667c478bd9Sstevel@tonic-gate * output an existing one
7677c478bd9Sstevel@tonic-gate *
7687c478bd9Sstevel@tonic-gate * args: script - name of file containing script (if NULL, means
7697c478bd9Sstevel@tonic-gate * output existing one instead)
7707c478bd9Sstevel@tonic-gate * tag - tag of port monitor that is responsible for the
7717c478bd9Sstevel@tonic-gate * designated service (may be null)
7727c478bd9Sstevel@tonic-gate * type - type of port monitor that is responsible for the
7737c478bd9Sstevel@tonic-gate * designated service (may be null)
7747c478bd9Sstevel@tonic-gate * svctag - tag of service whose config script we're operating on
7757c478bd9Sstevel@tonic-gate */
7767c478bd9Sstevel@tonic-gate
7777c478bd9Sstevel@tonic-gate void
doconf(script,tag,type,svctag)7787c478bd9Sstevel@tonic-gate doconf(script, tag, type, svctag)
7797c478bd9Sstevel@tonic-gate char *script;
7807c478bd9Sstevel@tonic-gate char *tag;
7817c478bd9Sstevel@tonic-gate char *type;
7827c478bd9Sstevel@tonic-gate char *svctag;
7837c478bd9Sstevel@tonic-gate {
7847c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
7857c478bd9Sstevel@tonic-gate int added; /* count of config scripts added */
7867c478bd9Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */
7877c478bd9Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */
7887c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
7897c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for names */
7907c478bd9Sstevel@tonic-gate
7917c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r");
7927c478bd9Sstevel@tonic-gate if (fp == NULL) {
7937c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
7947c478bd9Sstevel@tonic-gate error("Could not open _sactab");
7957c478bd9Sstevel@tonic-gate }
7967c478bd9Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) {
7977c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag);
7987c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
7997c478bd9Sstevel@tonic-gate error(buf);
8007c478bd9Sstevel@tonic-gate }
8017c478bd9Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) {
8027c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
8037c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
8047c478bd9Sstevel@tonic-gate error(buf);
8057c478bd9Sstevel@tonic-gate }
8067c478bd9Sstevel@tonic-gate (void) fclose(fp);
8077c478bd9Sstevel@tonic-gate
8087c478bd9Sstevel@tonic-gate if (tag) {
8097c478bd9Sstevel@tonic-gate
8107c478bd9Sstevel@tonic-gate /*
8117c478bd9Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a
8127c478bd9Sstevel@tonic-gate * type specification. Build the 'list' here.
8137c478bd9Sstevel@tonic-gate */
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate tp = &tl;
8167c478bd9Sstevel@tonic-gate tp->t_next = NULL;
8177c478bd9Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag);
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate
8207c478bd9Sstevel@tonic-gate added = 0;
8217c478bd9Sstevel@tonic-gate while (tp) {
8227c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
8237c478bd9Sstevel@tonic-gate fp = fopen(fname, "r");
8247c478bd9Sstevel@tonic-gate if (fp == NULL) {
8257c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
8267c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
8277c478bd9Sstevel@tonic-gate error(buf);
8287c478bd9Sstevel@tonic-gate }
8297c478bd9Sstevel@tonic-gate if (!find_svc(fp, tp->t_tag, svctag)) {
8307c478bd9Sstevel@tonic-gate if (tag) {
8317c478bd9Sstevel@tonic-gate /* special case of tag only */
8327c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, tag);
8337c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
8347c478bd9Sstevel@tonic-gate error(buf);
8357c478bd9Sstevel@tonic-gate }
8367c478bd9Sstevel@tonic-gate else {
8377c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s does not exist under %s - ignoring\n", svctag, tp->t_tag);
8387c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
8397c478bd9Sstevel@tonic-gate tp = tp->t_next;
8407c478bd9Sstevel@tonic-gate (void) fclose(fp);
8417c478bd9Sstevel@tonic-gate continue;
8427c478bd9Sstevel@tonic-gate }
8437c478bd9Sstevel@tonic-gate }
8447c478bd9Sstevel@tonic-gate (void) fclose(fp);
8457c478bd9Sstevel@tonic-gate
8467c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
8477c478bd9Sstevel@tonic-gate
8487c478bd9Sstevel@tonic-gate /*
8497c478bd9Sstevel@tonic-gate * do_config does all the real work (keep track if any errors occurred)
8507c478bd9Sstevel@tonic-gate */
8517c478bd9Sstevel@tonic-gate
8527c478bd9Sstevel@tonic-gate if (do_config(script, fname) == 0)
8537c478bd9Sstevel@tonic-gate added++;
8547c478bd9Sstevel@tonic-gate tp = tp->t_next;
8557c478bd9Sstevel@tonic-gate }
8567c478bd9Sstevel@tonic-gate if (added == 0) {
8577c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
8587c478bd9Sstevel@tonic-gate error("No configuration scripts installed");
8597c478bd9Sstevel@tonic-gate }
8607c478bd9Sstevel@tonic-gate return;
8617c478bd9Sstevel@tonic-gate }
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate
8647c478bd9Sstevel@tonic-gate /*
8657c478bd9Sstevel@tonic-gate * tell_sac - use sacadm to tell the sac to tell a port monitor to read
8667c478bd9Sstevel@tonic-gate * its _pmtab. Return TRUE on success, FALSE on failure.
8677c478bd9Sstevel@tonic-gate *
8687c478bd9Sstevel@tonic-gate * args: tag - tag of port monitor to be notified
8697c478bd9Sstevel@tonic-gate */
8707c478bd9Sstevel@tonic-gate
8717c478bd9Sstevel@tonic-gate
872*34e48580Sdp int
tell_sac(char * tag)873*34e48580Sdp tell_sac(char *tag)
8747c478bd9Sstevel@tonic-gate {
8757c478bd9Sstevel@tonic-gate pid_t pid; /* returned pid from fork */
8767c478bd9Sstevel@tonic-gate int status; /* return status from sacadm child */
8777c478bd9Sstevel@tonic-gate
8787c478bd9Sstevel@tonic-gate if ((pid = fork()) < 0) {
8797c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - fork failed - could not notify <%s> about modified table\n", tag);
8807c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command \"sacadm -x -p %s\"\n", tag);
8817c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
8827c478bd9Sstevel@tonic-gate return(FALSE);
8837c478bd9Sstevel@tonic-gate }
8847c478bd9Sstevel@tonic-gate else if (pid) {
8857c478bd9Sstevel@tonic-gate /* parent */
8867c478bd9Sstevel@tonic-gate (void) wait(&status);
8877c478bd9Sstevel@tonic-gate if (status) {
8887c478bd9Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_PMNOTRUN) {
8897c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "warning - port monitor, %s is not running\n", tag);
8907c478bd9Sstevel@tonic-gate return (FALSE);
8917c478bd9Sstevel@tonic-gate }
8927c478bd9Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_SACNOTRUN) {
8937c478bd9Sstevel@tonic-gate Saferrno = E_SACNOTRUN;
8947c478bd9Sstevel@tonic-gate } else {
8957c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
8967c478bd9Sstevel@tonic-gate }
8977c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
8987c478bd9Sstevel@tonic-gate "warning - could not notify <%s> about modified"
8997c478bd9Sstevel@tonic-gate " table\n", tag);
9007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command"
9017c478bd9Sstevel@tonic-gate " \"sacadm -x -p %s\"\n", tag);
9027c478bd9Sstevel@tonic-gate return(FALSE);
9037c478bd9Sstevel@tonic-gate }
9047c478bd9Sstevel@tonic-gate else {
9057c478bd9Sstevel@tonic-gate return(TRUE);
9067c478bd9Sstevel@tonic-gate }
9077c478bd9Sstevel@tonic-gate }
9087c478bd9Sstevel@tonic-gate else {
9097c478bd9Sstevel@tonic-gate /* set IFS for security */
9107c478bd9Sstevel@tonic-gate (void) putenv("IFS=\" \"");
9117c478bd9Sstevel@tonic-gate /* muffle sacadm warning messages */
9127c478bd9Sstevel@tonic-gate (void) fclose(stderr);
9137c478bd9Sstevel@tonic-gate (void) fopen("/dev/null", "w");
9147c478bd9Sstevel@tonic-gate (void) execl("/usr/sbin/sacadm", "sacadm", "-x", "-p", tag, 0);
9157c478bd9Sstevel@tonic-gate
9167c478bd9Sstevel@tonic-gate /*
9177c478bd9Sstevel@tonic-gate * if we got here, it didn't work, exit status will clue in parent to
9187c478bd9Sstevel@tonic-gate * put out the warning
9197c478bd9Sstevel@tonic-gate */
9207c478bd9Sstevel@tonic-gate
9217c478bd9Sstevel@tonic-gate exit(1);
9227c478bd9Sstevel@tonic-gate }
9237c478bd9Sstevel@tonic-gate /* NOTREACHED */
9247c478bd9Sstevel@tonic-gate }
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate
9277c478bd9Sstevel@tonic-gate /*
9287c478bd9Sstevel@tonic-gate * list_svcs - list information about services
9297c478bd9Sstevel@tonic-gate *
9307c478bd9Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
9317c478bd9Sstevel@tonic-gate * (may be null)
9327c478bd9Sstevel@tonic-gate * type - type of port monitor responsible for the service
9337c478bd9Sstevel@tonic-gate * (may be null)
9347c478bd9Sstevel@tonic-gate * svctag - tag of service to be listed (may be null)
9357c478bd9Sstevel@tonic-gate * oflag - true if output should be easily parseable
9367c478bd9Sstevel@tonic-gate */
9377c478bd9Sstevel@tonic-gate
9387c478bd9Sstevel@tonic-gate void
list_svcs(pmtag,type,svctag,oflag)9397c478bd9Sstevel@tonic-gate list_svcs(pmtag, type, svctag, oflag)
9407c478bd9Sstevel@tonic-gate char *pmtag;
9417c478bd9Sstevel@tonic-gate char *type;
9427c478bd9Sstevel@tonic-gate char *svctag;
9437c478bd9Sstevel@tonic-gate {
9447c478bd9Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
9457c478bd9Sstevel@tonic-gate register struct taglist *tp; /* pointer to PM list */
9467c478bd9Sstevel@tonic-gate int nprint = 0; /* count # of svcs printed */
9477c478bd9Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */
9487c478bd9Sstevel@tonic-gate register struct pmtab *pp = &pmtab; /* and a pointer to it */
9497c478bd9Sstevel@tonic-gate register char *p; /* working pointer */
9507c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
9517c478bd9Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */
9527c478bd9Sstevel@tonic-gate
9537c478bd9Sstevel@tonic-gate fp = fopen(SACTAB, "r");
9547c478bd9Sstevel@tonic-gate if (fp == NULL) {
9557c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
9567c478bd9Sstevel@tonic-gate error("Could not open _sactab");
9577c478bd9Sstevel@tonic-gate }
9587c478bd9Sstevel@tonic-gate if (pmtag && !find_pm(fp, pmtag)) {
9597c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
9607c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
9617c478bd9Sstevel@tonic-gate error(buf);
9627c478bd9Sstevel@tonic-gate }
9637c478bd9Sstevel@tonic-gate rewind(fp);
9647c478bd9Sstevel@tonic-gate if (type) {
9657c478bd9Sstevel@tonic-gate tp = find_type(fp, type);
9667c478bd9Sstevel@tonic-gate if (tp == NULL) {
9677c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
9687c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
9697c478bd9Sstevel@tonic-gate error(buf);
9707c478bd9Sstevel@tonic-gate }
9717c478bd9Sstevel@tonic-gate }
9727c478bd9Sstevel@tonic-gate else
9737c478bd9Sstevel@tonic-gate tp = find_type(fp, NULL);
9747c478bd9Sstevel@tonic-gate (void) fclose(fp);
9757c478bd9Sstevel@tonic-gate
9767c478bd9Sstevel@tonic-gate while (tp) {
9777c478bd9Sstevel@tonic-gate if (pmtag && strcmp(tp->t_tag, pmtag)) {
9787c478bd9Sstevel@tonic-gate /* not interested in this port monitor */
9797c478bd9Sstevel@tonic-gate tp = tp->t_next;
9807c478bd9Sstevel@tonic-gate continue;
9817c478bd9Sstevel@tonic-gate }
9827c478bd9Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
9837c478bd9Sstevel@tonic-gate fp = fopen(fname, "r");
9847c478bd9Sstevel@tonic-gate if (fp == NULL) {
9857c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
9867c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
9877c478bd9Sstevel@tonic-gate error(buf);
9887c478bd9Sstevel@tonic-gate }
9897c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
9907c478bd9Sstevel@tonic-gate p = trim(buf);
9917c478bd9Sstevel@tonic-gate if (*p == '\0')
9927c478bd9Sstevel@tonic-gate continue;
9937c478bd9Sstevel@tonic-gate parseline(p, pp, tp->t_tag);
9947c478bd9Sstevel@tonic-gate if (!svctag || !strcmp(pp->p_tag, svctag)) {
9957c478bd9Sstevel@tonic-gate if (oflag) {
9967c478bd9Sstevel@tonic-gate (void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s#%s\n",
9977c478bd9Sstevel@tonic-gate tp->t_tag, tp->t_type, pp->p_tag,
9987c478bd9Sstevel@tonic-gate pflags(pp->p_flags, FALSE),
9997c478bd9Sstevel@tonic-gate pp->p_id, pp->p_res1, pp->p_res2,
10007c478bd9Sstevel@tonic-gate pp->p_res3,pp->p_pmspec, Comment);
10017c478bd9Sstevel@tonic-gate }
10027c478bd9Sstevel@tonic-gate else {
10037c478bd9Sstevel@tonic-gate if (nprint == 0) {
10047c478bd9Sstevel@tonic-gate (void) printf("PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>\n");
10057c478bd9Sstevel@tonic-gate }
10067c478bd9Sstevel@tonic-gate (void) printf("%-14s %-14s %-14s %-4s %-8s %s #%s\n", tp->t_tag, tp->t_type, pp->p_tag,
10077c478bd9Sstevel@tonic-gate pflags(pp->p_flags, TRUE), pp->p_id, pspec(pp->p_pmspec), Comment);
10087c478bd9Sstevel@tonic-gate }
10097c478bd9Sstevel@tonic-gate nprint++;
10107c478bd9Sstevel@tonic-gate }
10117c478bd9Sstevel@tonic-gate }
10127c478bd9Sstevel@tonic-gate if (!feof(fp)) {
10137c478bd9Sstevel@tonic-gate (void) sprintf(buf, "error reading %s", fname);
10147c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
10157c478bd9Sstevel@tonic-gate error(buf);
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate else {
10187c478bd9Sstevel@tonic-gate (void) fclose(fp);
10197c478bd9Sstevel@tonic-gate tp = tp->t_next;
10207c478bd9Sstevel@tonic-gate }
10217c478bd9Sstevel@tonic-gate }
10227c478bd9Sstevel@tonic-gate /* if we didn't find any valid ones, indicate an error */
10237c478bd9Sstevel@tonic-gate if (nprint == 0) {
10247c478bd9Sstevel@tonic-gate if (svctag)
10257c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Service <%s> does not exist\n", svctag);
10267c478bd9Sstevel@tonic-gate else
10277c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "No services defined\n");
10287c478bd9Sstevel@tonic-gate Saferrno = E_NOEXIST;
10297c478bd9Sstevel@tonic-gate }
10307c478bd9Sstevel@tonic-gate return;
10317c478bd9Sstevel@tonic-gate }
10327c478bd9Sstevel@tonic-gate
10337c478bd9Sstevel@tonic-gate
10347c478bd9Sstevel@tonic-gate /*
10357c478bd9Sstevel@tonic-gate * find_svc - find an entry in _pmtab for a particular service tag
10367c478bd9Sstevel@tonic-gate *
10377c478bd9Sstevel@tonic-gate * args: fp - file pointer for _pmtab
10387c478bd9Sstevel@tonic-gate * tag - port monitor tag (for error reporting)
10397c478bd9Sstevel@tonic-gate * svctag - tag of service we're looking for
10407c478bd9Sstevel@tonic-gate */
10417c478bd9Sstevel@tonic-gate
1042*34e48580Sdp int
find_svc(FILE * fp,char * tag,char * svctag)1043*34e48580Sdp find_svc(FILE *fp, char *tag, char *svctag)
10447c478bd9Sstevel@tonic-gate {
10457c478bd9Sstevel@tonic-gate register char *p; /* working pointer */
10467c478bd9Sstevel@tonic-gate int line = 0; /* line number we found entry on */
10477c478bd9Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */
10487c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* scratch buffer */
10497c478bd9Sstevel@tonic-gate
10507c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
10517c478bd9Sstevel@tonic-gate line++;
10527c478bd9Sstevel@tonic-gate p = trim(buf);
10537c478bd9Sstevel@tonic-gate if (*p == '\0')
10547c478bd9Sstevel@tonic-gate continue;
10557c478bd9Sstevel@tonic-gate parseline(p, &pmtab, tag);
10567c478bd9Sstevel@tonic-gate if (!(strcmp(pmtab.p_tag, svctag)))
10577c478bd9Sstevel@tonic-gate return(line);
10587c478bd9Sstevel@tonic-gate }
10597c478bd9Sstevel@tonic-gate if (!feof(fp)) {
10607c478bd9Sstevel@tonic-gate (void) sprintf(buf, "error reading %s/%s/_pmtab", HOME, tag);
10617c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
10627c478bd9Sstevel@tonic-gate error(buf);
10637c478bd9Sstevel@tonic-gate /* NOTREACHED */
1064*34e48580Sdp return (0);
1065*34e48580Sdp } else
1066*34e48580Sdp return (0);
10677c478bd9Sstevel@tonic-gate }
10687c478bd9Sstevel@tonic-gate
10697c478bd9Sstevel@tonic-gate
10707c478bd9Sstevel@tonic-gate /*
10717c478bd9Sstevel@tonic-gate * parseline - parse a line from _pmtab. This routine will return if the
10727c478bd9Sstevel@tonic-gate * parse wa successful, otherwise it will output an error and
10737c478bd9Sstevel@tonic-gate * exit.
10747c478bd9Sstevel@tonic-gate *
10757c478bd9Sstevel@tonic-gate * args: p - pointer to the data read from the file (note - this is
10767c478bd9Sstevel@tonic-gate * a static data region, so we can point into it)
10777c478bd9Sstevel@tonic-gate * pp - pointer to a structure in which the separated fields
10787c478bd9Sstevel@tonic-gate * are placed
10797c478bd9Sstevel@tonic-gate * tag - port monitor tag (for error reporting)
10807c478bd9Sstevel@tonic-gate *
10817c478bd9Sstevel@tonic-gate * A line in the file has the following format:
10827c478bd9Sstevel@tonic-gate *
10837c478bd9Sstevel@tonic-gate * tag:flags:identity:reserved:reserved:reserved:PM_spec_info # comment
10847c478bd9Sstevel@tonic-gate */
10857c478bd9Sstevel@tonic-gate
10867c478bd9Sstevel@tonic-gate
10877c478bd9Sstevel@tonic-gate void
parseline(p,pp,tag)10887c478bd9Sstevel@tonic-gate parseline(p, pp, tag)
10897c478bd9Sstevel@tonic-gate register char *p;
10907c478bd9Sstevel@tonic-gate register struct pmtab *pp;
10917c478bd9Sstevel@tonic-gate char *tag;
10927c478bd9Sstevel@tonic-gate {
10937c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
10947c478bd9Sstevel@tonic-gate
10957c478bd9Sstevel@tonic-gate /*
10967c478bd9Sstevel@tonic-gate * get the service tag
10977c478bd9Sstevel@tonic-gate */
10987c478bd9Sstevel@tonic-gate
10997c478bd9Sstevel@tonic-gate p = nexttok(p, DELIM, FALSE);
11007c478bd9Sstevel@tonic-gate if (p == NULL) {
11017c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11027c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11037c478bd9Sstevel@tonic-gate error(buf);
11047c478bd9Sstevel@tonic-gate }
11057c478bd9Sstevel@tonic-gate if (strlen(p) > PMTAGSIZE) {
11067c478bd9Sstevel@tonic-gate p[PMTAGSIZE] = '\0';
11077c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>", p);
11087c478bd9Sstevel@tonic-gate }
11097c478bd9Sstevel@tonic-gate pp->p_tag = p;
11107c478bd9Sstevel@tonic-gate
11117c478bd9Sstevel@tonic-gate /*
11127c478bd9Sstevel@tonic-gate * get the flags
11137c478bd9Sstevel@tonic-gate */
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11167c478bd9Sstevel@tonic-gate if (p == NULL) {
11177c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11187c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11197c478bd9Sstevel@tonic-gate error(buf);
11207c478bd9Sstevel@tonic-gate }
11217c478bd9Sstevel@tonic-gate pp->p_flags = 0;
11227c478bd9Sstevel@tonic-gate while (*p) {
11237c478bd9Sstevel@tonic-gate switch (*p++) {
11247c478bd9Sstevel@tonic-gate case 'u':
11257c478bd9Sstevel@tonic-gate pp->p_flags |= U_FLAG;
11267c478bd9Sstevel@tonic-gate break;
11277c478bd9Sstevel@tonic-gate case 'x':
11287c478bd9Sstevel@tonic-gate pp->p_flags |= X_FLAG;
11297c478bd9Sstevel@tonic-gate break;
11307c478bd9Sstevel@tonic-gate default:
11317c478bd9Sstevel@tonic-gate (void) sprintf(buf, "Unrecognized flag <%c>", *(p - 1));
11327c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11337c478bd9Sstevel@tonic-gate error(buf);
11347c478bd9Sstevel@tonic-gate break;
11357c478bd9Sstevel@tonic-gate }
11367c478bd9Sstevel@tonic-gate }
11377c478bd9Sstevel@tonic-gate
11387c478bd9Sstevel@tonic-gate /*
11397c478bd9Sstevel@tonic-gate * get the identity
11407c478bd9Sstevel@tonic-gate */
11417c478bd9Sstevel@tonic-gate
11427c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11437c478bd9Sstevel@tonic-gate if (p == NULL) {
11447c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11457c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11467c478bd9Sstevel@tonic-gate error(buf);
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate pp->p_id = p;
11497c478bd9Sstevel@tonic-gate
11507c478bd9Sstevel@tonic-gate /*
11517c478bd9Sstevel@tonic-gate * get the first reserved field
11527c478bd9Sstevel@tonic-gate */
11537c478bd9Sstevel@tonic-gate
11547c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11557c478bd9Sstevel@tonic-gate if (p == NULL) {
11567c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11577c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11587c478bd9Sstevel@tonic-gate error(buf);
11597c478bd9Sstevel@tonic-gate }
11607c478bd9Sstevel@tonic-gate pp->p_res1 = p;
11617c478bd9Sstevel@tonic-gate
11627c478bd9Sstevel@tonic-gate /*
11637c478bd9Sstevel@tonic-gate * get the second reserved field
11647c478bd9Sstevel@tonic-gate */
11657c478bd9Sstevel@tonic-gate
11667c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11677c478bd9Sstevel@tonic-gate if (p == NULL) {
11687c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11697c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11707c478bd9Sstevel@tonic-gate error(buf);
11717c478bd9Sstevel@tonic-gate }
11727c478bd9Sstevel@tonic-gate pp->p_res2 = p;
11737c478bd9Sstevel@tonic-gate
11747c478bd9Sstevel@tonic-gate /*
11757c478bd9Sstevel@tonic-gate * get the third reserved field
11767c478bd9Sstevel@tonic-gate */
11777c478bd9Sstevel@tonic-gate
11787c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11797c478bd9Sstevel@tonic-gate if (p == NULL) {
11807c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11817c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11827c478bd9Sstevel@tonic-gate error(buf);
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate pp->p_res3 = p;
11857c478bd9Sstevel@tonic-gate
11867c478bd9Sstevel@tonic-gate /*
11877c478bd9Sstevel@tonic-gate * the rest is the port monitor specific info
11887c478bd9Sstevel@tonic-gate */
11897c478bd9Sstevel@tonic-gate
11907c478bd9Sstevel@tonic-gate p = nexttok(NULL, DELIM, TRUE);
11917c478bd9Sstevel@tonic-gate if (p == NULL) {
11927c478bd9Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11937c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
11947c478bd9Sstevel@tonic-gate error(buf);
11957c478bd9Sstevel@tonic-gate }
11967c478bd9Sstevel@tonic-gate pp->p_pmspec = p;
11977c478bd9Sstevel@tonic-gate return;
11987c478bd9Sstevel@tonic-gate }
11997c478bd9Sstevel@tonic-gate
12007c478bd9Sstevel@tonic-gate
12017c478bd9Sstevel@tonic-gate /*
12027c478bd9Sstevel@tonic-gate * pspec - format port monitor specific information
12037c478bd9Sstevel@tonic-gate *
12047c478bd9Sstevel@tonic-gate * args: spec - port monitor specific info, separated by
12057c478bd9Sstevel@tonic-gate * field separater character (may be escaped by \)
12067c478bd9Sstevel@tonic-gate */
12077c478bd9Sstevel@tonic-gate
12087c478bd9Sstevel@tonic-gate char *
pspec(spec)12097c478bd9Sstevel@tonic-gate pspec(spec)
12107c478bd9Sstevel@tonic-gate char *spec;
12117c478bd9Sstevel@tonic-gate {
12127c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* returned string */
12137c478bd9Sstevel@tonic-gate register char *from; /* working pointer */
12147c478bd9Sstevel@tonic-gate register char *to; /* working pointer */
12157c478bd9Sstevel@tonic-gate int newflag; /* flag indicating new field */
12167c478bd9Sstevel@tonic-gate
12177c478bd9Sstevel@tonic-gate to = buf;
12187c478bd9Sstevel@tonic-gate from = spec;
12197c478bd9Sstevel@tonic-gate newflag = 1;
12207c478bd9Sstevel@tonic-gate while (*from) {
12217c478bd9Sstevel@tonic-gate switch (*from) {
12227c478bd9Sstevel@tonic-gate case ':':
12237c478bd9Sstevel@tonic-gate if (newflag) {
12247c478bd9Sstevel@tonic-gate *to++ = '-';
12257c478bd9Sstevel@tonic-gate }
12267c478bd9Sstevel@tonic-gate *to++ = ' ';
12277c478bd9Sstevel@tonic-gate from++;
12287c478bd9Sstevel@tonic-gate newflag = 1;
12297c478bd9Sstevel@tonic-gate break;
12307c478bd9Sstevel@tonic-gate case '\\':
12317c478bd9Sstevel@tonic-gate if (*(from + 1) == ':') {
12327c478bd9Sstevel@tonic-gate *to++ = ':';
12337c478bd9Sstevel@tonic-gate /* skip over \: */
12347c478bd9Sstevel@tonic-gate from += 2;
12357c478bd9Sstevel@tonic-gate }
12367c478bd9Sstevel@tonic-gate else
12377c478bd9Sstevel@tonic-gate *to++ = *from++;
12387c478bd9Sstevel@tonic-gate newflag = 0;
12397c478bd9Sstevel@tonic-gate break;
12407c478bd9Sstevel@tonic-gate default:
12417c478bd9Sstevel@tonic-gate newflag = 0;
12427c478bd9Sstevel@tonic-gate *to++ = *from++;
12437c478bd9Sstevel@tonic-gate }
12447c478bd9Sstevel@tonic-gate }
12457c478bd9Sstevel@tonic-gate *to = '\0';
12467c478bd9Sstevel@tonic-gate return(buf);
12477c478bd9Sstevel@tonic-gate }
12487c478bd9Sstevel@tonic-gate
12497c478bd9Sstevel@tonic-gate
12507c478bd9Sstevel@tonic-gate /*
12517c478bd9Sstevel@tonic-gate * pflags - put service flags into intelligible form for output
12527c478bd9Sstevel@tonic-gate *
12537c478bd9Sstevel@tonic-gate * args: flags - binary representation of flags
12547c478bd9Sstevel@tonic-gate * dflag - true if a "-" should be returned if no flags
12557c478bd9Sstevel@tonic-gate */
12567c478bd9Sstevel@tonic-gate
12577c478bd9Sstevel@tonic-gate char *
pflags(flags,dflag)12587c478bd9Sstevel@tonic-gate pflags(flags, dflag)
12597c478bd9Sstevel@tonic-gate long flags;
12607c478bd9Sstevel@tonic-gate int dflag;
12617c478bd9Sstevel@tonic-gate {
12627c478bd9Sstevel@tonic-gate register int i; /* scratch counter */
12637c478bd9Sstevel@tonic-gate static char buf[SIZE]; /* formatted flags */
12647c478bd9Sstevel@tonic-gate
12657c478bd9Sstevel@tonic-gate if (flags == 0) {
12667c478bd9Sstevel@tonic-gate if (dflag)
12677c478bd9Sstevel@tonic-gate return("-");
12687c478bd9Sstevel@tonic-gate else
12697c478bd9Sstevel@tonic-gate return("");
12707c478bd9Sstevel@tonic-gate }
12717c478bd9Sstevel@tonic-gate i = 0;
12727c478bd9Sstevel@tonic-gate if (flags & U_FLAG) {
12737c478bd9Sstevel@tonic-gate buf[i++] = 'u';
12747c478bd9Sstevel@tonic-gate flags &= ~U_FLAG;
12757c478bd9Sstevel@tonic-gate }
12767c478bd9Sstevel@tonic-gate if (flags & X_FLAG) {
12777c478bd9Sstevel@tonic-gate buf[i++] = 'x';
12787c478bd9Sstevel@tonic-gate flags &= ~X_FLAG;
12797c478bd9Sstevel@tonic-gate }
12807c478bd9Sstevel@tonic-gate if (flags) {
12817c478bd9Sstevel@tonic-gate Saferrno = E_SAFERR;
12827c478bd9Sstevel@tonic-gate error("Internal error in pflags");
12837c478bd9Sstevel@tonic-gate }
12847c478bd9Sstevel@tonic-gate buf[i] = '\0';
12857c478bd9Sstevel@tonic-gate return(buf);
12867c478bd9Sstevel@tonic-gate }
12877c478bd9Sstevel@tonic-gate
12887c478bd9Sstevel@tonic-gate
12897c478bd9Sstevel@tonic-gate /*
12907c478bd9Sstevel@tonic-gate * find_type - find entries in _sactab for a particular port monitor type
12917c478bd9Sstevel@tonic-gate *
12927c478bd9Sstevel@tonic-gate * args: fp - file pointer for _sactab
12937c478bd9Sstevel@tonic-gate * type - type of port monitor we're looking for (if type is
12947c478bd9Sstevel@tonic-gate * null, it means find all PMs)
12957c478bd9Sstevel@tonic-gate */
12967c478bd9Sstevel@tonic-gate
12977c478bd9Sstevel@tonic-gate struct taglist *
find_type(fp,type)12987c478bd9Sstevel@tonic-gate find_type(fp, type)
12997c478bd9Sstevel@tonic-gate FILE *fp;
13007c478bd9Sstevel@tonic-gate char *type;
13017c478bd9Sstevel@tonic-gate {
13027c478bd9Sstevel@tonic-gate register char *p; /* working pointer */
13037c478bd9Sstevel@tonic-gate struct sactab stab; /* place to hold parsed info */
13047c478bd9Sstevel@tonic-gate register struct sactab *sp = &stab; /* and a pointer to it */
13057c478bd9Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
13067c478bd9Sstevel@tonic-gate struct taglist *thead; /* linked list of tags */
13077c478bd9Sstevel@tonic-gate register struct taglist *temp; /* scratch pointer */
13087c478bd9Sstevel@tonic-gate
13097c478bd9Sstevel@tonic-gate thead = NULL;
13107c478bd9Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
13117c478bd9Sstevel@tonic-gate p = trim(buf);
13127c478bd9Sstevel@tonic-gate if (*p == '\0')
13137c478bd9Sstevel@tonic-gate continue;
13147c478bd9Sstevel@tonic-gate parse(p, sp);
13157c478bd9Sstevel@tonic-gate if ((type == NULL) || !(strcmp(sp->sc_type, type))) {
13167c478bd9Sstevel@tonic-gate temp = (struct taglist *) malloc(sizeof(struct taglist));
13177c478bd9Sstevel@tonic-gate if (temp == NULL) {
13187c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
13197c478bd9Sstevel@tonic-gate error("malloc failed");
13207c478bd9Sstevel@tonic-gate }
13217c478bd9Sstevel@tonic-gate temp->t_next = thead;
13227c478bd9Sstevel@tonic-gate (void) strcpy(temp->t_tag, sp->sc_tag);
13237c478bd9Sstevel@tonic-gate (void) strcpy(temp->t_type, sp->sc_type);
13247c478bd9Sstevel@tonic-gate thead = temp;
13257c478bd9Sstevel@tonic-gate }
13267c478bd9Sstevel@tonic-gate }
13277c478bd9Sstevel@tonic-gate if (!feof(fp)) {
13287c478bd9Sstevel@tonic-gate Saferrno = E_SYSERR;
13297c478bd9Sstevel@tonic-gate error("error reading _sactab");
13307c478bd9Sstevel@tonic-gate /* NOTREACHED */
1331*34e48580Sdp return (0);
1332*34e48580Sdp } else
1333*34e48580Sdp return (thead ? thead : NULL);
13347c478bd9Sstevel@tonic-gate }
1335