10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
220Sstevel@tonic-gate /*
23*334Sdp * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
240Sstevel@tonic-gate * Use is subject to license terms.
250Sstevel@tonic-gate */
260Sstevel@tonic-gate
270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
310Sstevel@tonic-gate
32*334Sdp #include <stdio.h>
33*334Sdp #include <stdlib.h>
34*334Sdp #include <strings.h>
35*334Sdp #include <sys/types.h>
36*334Sdp #include <sys/stat.h>
37*334Sdp #include <unistd.h>
38*334Sdp #include "extern.h"
39*334Sdp #include "misc.h"
40*334Sdp #include <sac.h>
41*334Sdp #include "structs.h"
420Sstevel@tonic-gate
43*334Sdp #define ADD 0x1 /* -a or other required options seen */
44*334Sdp #define REMOVE 0x2 /* -r seen */
45*334Sdp #define ENABLE 0x4 /* -e seen */
46*334Sdp #define DISABLE 0x8 /* -d seen */
47*334Sdp #define PLIST 0x10 /* -l seen */
48*334Sdp #define LIST 0x20 /* -L seen */
49*334Sdp #define CONFIG 0x40 /* -g seen */
500Sstevel@tonic-gate
510Sstevel@tonic-gate # define U_FLAG 0x1 /* -fu seen */
520Sstevel@tonic-gate # define X_FLAG 0x2 /* -fx seen */
530Sstevel@tonic-gate
540Sstevel@tonic-gate /*
550Sstevel@tonic-gate * functions
560Sstevel@tonic-gate */
570Sstevel@tonic-gate
580Sstevel@tonic-gate char *pflags();
590Sstevel@tonic-gate char *pspec();
600Sstevel@tonic-gate struct taglist *find_type();
610Sstevel@tonic-gate void usage();
620Sstevel@tonic-gate void parseline();
630Sstevel@tonic-gate void add_svc();
640Sstevel@tonic-gate void rem_svc();
650Sstevel@tonic-gate void ed_svc();
660Sstevel@tonic-gate void list_svcs();
670Sstevel@tonic-gate void doconf();
680Sstevel@tonic-gate
690Sstevel@tonic-gate /*
700Sstevel@tonic-gate * format of a _pmtab entry - used to hold parsed info
710Sstevel@tonic-gate */
720Sstevel@tonic-gate
730Sstevel@tonic-gate struct pmtab {
740Sstevel@tonic-gate char *p_tag; /* service tag */
750Sstevel@tonic-gate long p_flags; /* flags */
760Sstevel@tonic-gate char *p_id; /* logname to start service as */
770Sstevel@tonic-gate char *p_res1; /* reserved field */
780Sstevel@tonic-gate char *p_res2; /* reserved field */
790Sstevel@tonic-gate char *p_res3; /* reserved field */
800Sstevel@tonic-gate char *p_pmspec; /* port monitor specific info */
810Sstevel@tonic-gate };
820Sstevel@tonic-gate
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate * format of a tag list, which is a list of port monitor tags of
850Sstevel@tonic-gate * a designated type
860Sstevel@tonic-gate */
870Sstevel@tonic-gate
880Sstevel@tonic-gate struct taglist {
890Sstevel@tonic-gate struct taglist *t_next; /* next in list */
900Sstevel@tonic-gate char t_tag[PMTAGSIZE + 1]; /* PM tag */
910Sstevel@tonic-gate char t_type[PMTYPESIZE + 1]; /* PM type */
920Sstevel@tonic-gate };
930Sstevel@tonic-gate
940Sstevel@tonic-gate /*
950Sstevel@tonic-gate * common error messages
960Sstevel@tonic-gate */
970Sstevel@tonic-gate
980Sstevel@tonic-gate # define NOTPRIV "User not privileged for operation"
990Sstevel@tonic-gate # define BADINP "Embedded newlines not allowed"
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate int Saferrno; /* internal `errno' for exit */
1020Sstevel@tonic-gate
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate /*
1050Sstevel@tonic-gate * main - scan args for pmadm and call appropriate handling code
1060Sstevel@tonic-gate */
1070Sstevel@tonic-gate
108*334Sdp int
main(int argc,char * argv[])109*334Sdp main(int argc, char *argv[])
1100Sstevel@tonic-gate {
1110Sstevel@tonic-gate int c; /* option letter */
1120Sstevel@tonic-gate int ret; /* return code from check_version */
1130Sstevel@tonic-gate uid_t uid; /* invoker's real uid */
1140Sstevel@tonic-gate int flag = 0; /* flag to record requested operations */
1150Sstevel@tonic-gate int errflg = 0; /* error indicator */
1160Sstevel@tonic-gate int badcnt = 0; /* count of bad args to -f */
1170Sstevel@tonic-gate int version = -1; /* argument to -v */
1180Sstevel@tonic-gate int sawaflag = 0; /* true if actually saw -a */
1190Sstevel@tonic-gate int conflag = 0; /* true if output should be in condensed form */
1200Sstevel@tonic-gate long flags = 0; /* arguments to -f */
1210Sstevel@tonic-gate char *pmtag = NULL; /* argument to -p */
1220Sstevel@tonic-gate char *type = NULL; /* argument to -t */
1230Sstevel@tonic-gate char *script = NULL; /* argument to -z */
1240Sstevel@tonic-gate char *comment = " "; /* argument to -y */
1250Sstevel@tonic-gate char *id = NULL; /* argument to -i */
1260Sstevel@tonic-gate char *svctag = NULL; /* argument to -s */
1270Sstevel@tonic-gate char *pmspec = NULL; /* argument to -m */
1280Sstevel@tonic-gate char badargs[SIZE]; /* place to hold bad args to -f */
1290Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
1300Sstevel@tonic-gate register char *p; /* scratch pointer */
1310Sstevel@tonic-gate
1320Sstevel@tonic-gate if (argc == 1)
1330Sstevel@tonic-gate usage(argv[0]);
1340Sstevel@tonic-gate while ((c = getopt(argc, argv, "adef:gi:Llm:p:rs:t:v:y:z:")) != -1) {
1350Sstevel@tonic-gate switch (c) {
1360Sstevel@tonic-gate case 'a':
1370Sstevel@tonic-gate flag |= ADD;
1380Sstevel@tonic-gate sawaflag = 1;
1390Sstevel@tonic-gate break;
1400Sstevel@tonic-gate case 'd':
1410Sstevel@tonic-gate flag |= DISABLE;
1420Sstevel@tonic-gate break;
1430Sstevel@tonic-gate case 'e':
1440Sstevel@tonic-gate flag |= ENABLE;
1450Sstevel@tonic-gate break;
1460Sstevel@tonic-gate case 'f':
1470Sstevel@tonic-gate flag |= ADD;
1480Sstevel@tonic-gate while (*optarg) {
1490Sstevel@tonic-gate switch (*optarg++) {
1500Sstevel@tonic-gate case 'u':
1510Sstevel@tonic-gate flags |= U_FLAG;
1520Sstevel@tonic-gate break;
1530Sstevel@tonic-gate case 'x':
1540Sstevel@tonic-gate flags |= X_FLAG;
1550Sstevel@tonic-gate break;
1560Sstevel@tonic-gate default:
1570Sstevel@tonic-gate badargs[badcnt++] = *(optarg - 1);
1580Sstevel@tonic-gate break;
1590Sstevel@tonic-gate }
1600Sstevel@tonic-gate }
1610Sstevel@tonic-gate /* null terminate just in case anything is there */
1620Sstevel@tonic-gate badargs[badcnt] = '\0';
1630Sstevel@tonic-gate break;
1640Sstevel@tonic-gate case 'g':
1650Sstevel@tonic-gate flag |= CONFIG;
1660Sstevel@tonic-gate break;
1670Sstevel@tonic-gate case 'i':
1680Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1690Sstevel@tonic-gate Saferrno = E_BADARGS;
1700Sstevel@tonic-gate error(BADINP);
1710Sstevel@tonic-gate }
1720Sstevel@tonic-gate flag |= ADD;
1730Sstevel@tonic-gate id = optarg;
1740Sstevel@tonic-gate break;
1750Sstevel@tonic-gate case 'L':
1760Sstevel@tonic-gate flag |= LIST;
1770Sstevel@tonic-gate break;
1780Sstevel@tonic-gate case 'l':
1790Sstevel@tonic-gate flag |= PLIST;
1800Sstevel@tonic-gate break;
1810Sstevel@tonic-gate case 'm':
1820Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1830Sstevel@tonic-gate Saferrno = E_BADARGS;
1840Sstevel@tonic-gate error(BADINP);
1850Sstevel@tonic-gate }
1860Sstevel@tonic-gate if (*optarg == '\0') {
1870Sstevel@tonic-gate /* this will generate a usage message below */
1880Sstevel@tonic-gate errflg++;
1890Sstevel@tonic-gate break;
1900Sstevel@tonic-gate }
1910Sstevel@tonic-gate flag |= ADD;
1920Sstevel@tonic-gate pmspec = optarg;
1930Sstevel@tonic-gate break;
1940Sstevel@tonic-gate case 'p':
1950Sstevel@tonic-gate if (strchr(optarg, '\n')) {
1960Sstevel@tonic-gate Saferrno = E_BADARGS;
1970Sstevel@tonic-gate error(BADINP);
1980Sstevel@tonic-gate }
1990Sstevel@tonic-gate pmtag = optarg;
2000Sstevel@tonic-gate if (strlen(pmtag) > PMTAGSIZE) {
2010Sstevel@tonic-gate pmtag[PMTAGSIZE] = '\0';
2020Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate for (p = pmtag; *p; p++) {
2050Sstevel@tonic-gate if (!isalnum(*p)) {
2060Sstevel@tonic-gate Saferrno = E_BADARGS;
2070Sstevel@tonic-gate error("port monitor tag must be alphanumeric");
2080Sstevel@tonic-gate }
2090Sstevel@tonic-gate }
2100Sstevel@tonic-gate break;
2110Sstevel@tonic-gate case 'r':
2120Sstevel@tonic-gate flag |= REMOVE;
2130Sstevel@tonic-gate break;
2140Sstevel@tonic-gate case 's':
2150Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2160Sstevel@tonic-gate Saferrno = E_BADARGS;
2170Sstevel@tonic-gate error(BADINP);
2180Sstevel@tonic-gate }
2190Sstevel@tonic-gate svctag = optarg;
2200Sstevel@tonic-gate if (strlen(svctag) > SVCTAGSIZE) {
2210Sstevel@tonic-gate svctag[SVCTAGSIZE] = '\0';
2220Sstevel@tonic-gate (void) fprintf(stderr, "svctag too long, truncated to <%s>\n", svctag);
2230Sstevel@tonic-gate }
2240Sstevel@tonic-gate for (p = svctag; *p; p++) {
2250Sstevel@tonic-gate if (!isalnum(*p)) {
2260Sstevel@tonic-gate Saferrno = E_BADARGS;
2270Sstevel@tonic-gate error("service tag must be alphanumeric");
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate }
2300Sstevel@tonic-gate break;
2310Sstevel@tonic-gate case 't':
2320Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2330Sstevel@tonic-gate Saferrno = E_BADARGS;
2340Sstevel@tonic-gate error(BADINP);
2350Sstevel@tonic-gate }
2360Sstevel@tonic-gate type = optarg;
2370Sstevel@tonic-gate if (strlen(type) > PMTYPESIZE) {
2380Sstevel@tonic-gate type[PMTYPESIZE] = '\0';
2390Sstevel@tonic-gate (void) fprintf(stderr, "type too long, truncated to <%s>\n", type);
2400Sstevel@tonic-gate }
2410Sstevel@tonic-gate for (p = type; *p; p++) {
2420Sstevel@tonic-gate if (!isalnum(*p)) {
2430Sstevel@tonic-gate Saferrno = E_BADARGS;
2440Sstevel@tonic-gate error("port monitor type must be alphanumeric");
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate }
2470Sstevel@tonic-gate break;
2480Sstevel@tonic-gate case 'v':
2490Sstevel@tonic-gate flag |= ADD;
2500Sstevel@tonic-gate version = atoi(optarg);
2510Sstevel@tonic-gate if (version < 0) {
2520Sstevel@tonic-gate Saferrno = E_BADARGS;
2530Sstevel@tonic-gate error("version number can not be negative");
2540Sstevel@tonic-gate }
2550Sstevel@tonic-gate break;
2560Sstevel@tonic-gate case 'y':
2570Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2580Sstevel@tonic-gate Saferrno = E_BADARGS;
2590Sstevel@tonic-gate error(BADINP);
2600Sstevel@tonic-gate }
2610Sstevel@tonic-gate flag |= ADD;
2620Sstevel@tonic-gate comment = optarg;
2630Sstevel@tonic-gate break;
2640Sstevel@tonic-gate case 'z':
2650Sstevel@tonic-gate if (strchr(optarg, '\n')) {
2660Sstevel@tonic-gate Saferrno = E_BADARGS;
2670Sstevel@tonic-gate error(BADINP);
2680Sstevel@tonic-gate }
2690Sstevel@tonic-gate script = optarg;
2700Sstevel@tonic-gate break;
2710Sstevel@tonic-gate case '?':
2720Sstevel@tonic-gate errflg++;
2730Sstevel@tonic-gate }
2740Sstevel@tonic-gate }
2750Sstevel@tonic-gate if (errflg || (optind < argc))
2760Sstevel@tonic-gate usage(argv[0]);
2770Sstevel@tonic-gate
2780Sstevel@tonic-gate if (badcnt) {
2790Sstevel@tonic-gate /* bad flags were given to -f */
2800Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s are not valid arguments for \"-f\"", badargs);
2810Sstevel@tonic-gate Saferrno = E_BADARGS;
2820Sstevel@tonic-gate error(buf);
2830Sstevel@tonic-gate }
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate uid = getuid();
2860Sstevel@tonic-gate
2870Sstevel@tonic-gate /*
2880Sstevel@tonic-gate * don't do anything if _sactab isn't the version we understand
2890Sstevel@tonic-gate */
2900Sstevel@tonic-gate
2910Sstevel@tonic-gate if ((ret = check_version(VERSION, SACTAB)) == 1) {
2920Sstevel@tonic-gate Saferrno = E_SAFERR;
2930Sstevel@tonic-gate error("_sactab version number is incorrect");
2940Sstevel@tonic-gate }
2950Sstevel@tonic-gate else if (ret == 2) {
2960Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", SACTAB);
2970Sstevel@tonic-gate Saferrno = E_SYSERR;
2980Sstevel@tonic-gate error(buf);
2990Sstevel@tonic-gate }
3000Sstevel@tonic-gate else if (ret == 3) {
3010Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", SACTAB);
3020Sstevel@tonic-gate Saferrno = E_SAFERR;
3030Sstevel@tonic-gate error(buf);
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate switch (flag) {
3070Sstevel@tonic-gate case ADD:
3080Sstevel@tonic-gate if (uid) {
3090Sstevel@tonic-gate Saferrno = E_NOPRIV;
3100Sstevel@tonic-gate error(NOTPRIV);
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate if (!sawaflag || (pmtag && type) || (!pmtag && !type) || !svctag || !id || !pmspec || (version < 0))
3130Sstevel@tonic-gate usage(argv[0]);
3140Sstevel@tonic-gate add_svc(pmtag, type, svctag, id, pmspec, flags, version, comment, script);
3150Sstevel@tonic-gate break;
3160Sstevel@tonic-gate case REMOVE:
3170Sstevel@tonic-gate if (uid) {
3180Sstevel@tonic-gate Saferrno = E_NOPRIV;
3190Sstevel@tonic-gate error(NOTPRIV);
3200Sstevel@tonic-gate }
3210Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3220Sstevel@tonic-gate usage(argv[0]);
3230Sstevel@tonic-gate rem_svc(pmtag, svctag);
3240Sstevel@tonic-gate break;
3250Sstevel@tonic-gate case ENABLE:
3260Sstevel@tonic-gate if (uid) {
3270Sstevel@tonic-gate Saferrno = E_NOPRIV;
3280Sstevel@tonic-gate error(NOTPRIV);
3290Sstevel@tonic-gate }
3300Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3310Sstevel@tonic-gate usage(argv[0]);
3320Sstevel@tonic-gate ed_svc(pmtag, svctag, ENABLE);
3330Sstevel@tonic-gate break;
3340Sstevel@tonic-gate case DISABLE:
3350Sstevel@tonic-gate if (uid) {
3360Sstevel@tonic-gate Saferrno = E_NOPRIV;
3370Sstevel@tonic-gate error(NOTPRIV);
3380Sstevel@tonic-gate }
3390Sstevel@tonic-gate if (!pmtag || !svctag || type || script)
3400Sstevel@tonic-gate usage(argv[0]);
3410Sstevel@tonic-gate ed_svc(pmtag, svctag, DISABLE);
3420Sstevel@tonic-gate break;
3430Sstevel@tonic-gate case LIST:
3440Sstevel@tonic-gate conflag = 1;
3450Sstevel@tonic-gate /* fall through */
3460Sstevel@tonic-gate case PLIST:
3470Sstevel@tonic-gate if ((pmtag && type) || script)
3480Sstevel@tonic-gate usage(argv[0]);
3490Sstevel@tonic-gate list_svcs(pmtag, type, svctag, conflag);
3500Sstevel@tonic-gate break;
3510Sstevel@tonic-gate case CONFIG:
3520Sstevel@tonic-gate if (script && uid) {
3530Sstevel@tonic-gate Saferrno = E_NOPRIV;
3540Sstevel@tonic-gate error(NOTPRIV);
3550Sstevel@tonic-gate }
3560Sstevel@tonic-gate if ((pmtag && type) || (!pmtag && !type) || !svctag || (type && !script))
3570Sstevel@tonic-gate usage(argv[0]);
3580Sstevel@tonic-gate doconf(script, pmtag, type, svctag);
3590Sstevel@tonic-gate break;
3600Sstevel@tonic-gate default:
3610Sstevel@tonic-gate /* we only get here if more than one flag bit was set */
3620Sstevel@tonic-gate usage(argv[0]);
3630Sstevel@tonic-gate /* NOTREACHED */
3640Sstevel@tonic-gate }
3650Sstevel@tonic-gate quit();
3660Sstevel@tonic-gate /* NOTREACHED */
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /*
3710Sstevel@tonic-gate * usage - print out a usage message
3720Sstevel@tonic-gate *
3730Sstevel@tonic-gate * args: cmdname - the name command was invoked with
3740Sstevel@tonic-gate */
3750Sstevel@tonic-gate
3760Sstevel@tonic-gate void
usage(cmdname)3770Sstevel@tonic-gate usage(cmdname)
3780Sstevel@tonic-gate char *cmdname;
3790Sstevel@tonic-gate {
3800Sstevel@tonic-gate (void) fprintf(stderr, "Usage:\t%s -a [ -p pmtag | -t type ] -s svctag -i id -m \"pmspecific\"\n", cmdname);
3810Sstevel@tonic-gate (void) fprintf(stderr, "\t\t-v version [ -f xu ] [ -y comment ] [ -z script]\n");
3820Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -r -p pmtag -s svctag\n", cmdname);
3830Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -e -p pmtag -s svctag\n", cmdname);
3840Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -d -p pmtag -s svctag\n", cmdname);
3850Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
3860Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
3870Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -p pmtag -s svctag [ -z script ]\n", cmdname);
3880Sstevel@tonic-gate (void) fprintf(stderr, "\t%s -g -s svctag -t type -z script\n", cmdname);
3890Sstevel@tonic-gate Saferrno = E_BADARGS;
3900Sstevel@tonic-gate quit();
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate
3930Sstevel@tonic-gate
3940Sstevel@tonic-gate /*
3950Sstevel@tonic-gate * add_svc - add a service entry
3960Sstevel@tonic-gate *
3970Sstevel@tonic-gate * args: tag - port monitor's tag (may be null)
3980Sstevel@tonic-gate * type - port monitor's type (may be null)
3990Sstevel@tonic-gate * svctag - service's tag
4000Sstevel@tonic-gate * id - identity under which service should run
4010Sstevel@tonic-gate * pmspec - uninterpreted port monitor-specific info
4020Sstevel@tonic-gate * flags - service flags
4030Sstevel@tonic-gate * version - version number of port monitor's pmtab
4040Sstevel@tonic-gate * comment - comment describing service
4050Sstevel@tonic-gate * script - service's configuration script
4060Sstevel@tonic-gate */
4070Sstevel@tonic-gate
4080Sstevel@tonic-gate void
add_svc(tag,type,svctag,id,pmspec,flags,version,comment,script)4090Sstevel@tonic-gate add_svc(tag, type, svctag, id, pmspec, flags, version, comment, script)
4100Sstevel@tonic-gate char *tag;
4110Sstevel@tonic-gate char *type;
4120Sstevel@tonic-gate char *svctag;
4130Sstevel@tonic-gate char *id;
4140Sstevel@tonic-gate char *pmspec;
4150Sstevel@tonic-gate long flags;
4160Sstevel@tonic-gate int version;
4170Sstevel@tonic-gate char *comment;
4180Sstevel@tonic-gate char *script;
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
4210Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */
4220Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */
4230Sstevel@tonic-gate int ret; /* return code from check_version */
4240Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
4250Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */
4260Sstevel@tonic-gate int added; /* count number added */
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate fp = fopen(SACTAB, "r");
4290Sstevel@tonic-gate if (fp == NULL) {
4300Sstevel@tonic-gate Saferrno = E_SYSERR;
4310Sstevel@tonic-gate error("Could not open _sactab");
4320Sstevel@tonic-gate }
4330Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) {
4340Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag);
4350Sstevel@tonic-gate Saferrno = E_NOEXIST;
4360Sstevel@tonic-gate error(buf);
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) {
4390Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
4400Sstevel@tonic-gate Saferrno = E_NOEXIST;
4410Sstevel@tonic-gate error(buf);
4420Sstevel@tonic-gate }
4430Sstevel@tonic-gate (void) fclose(fp);
4440Sstevel@tonic-gate
4450Sstevel@tonic-gate if (tag) {
4460Sstevel@tonic-gate
4470Sstevel@tonic-gate /*
4480Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a
4490Sstevel@tonic-gate * type specification. Build the 'list' here.
4500Sstevel@tonic-gate */
4510Sstevel@tonic-gate
4520Sstevel@tonic-gate tp = &tl;
4530Sstevel@tonic-gate tp->t_next = NULL;
4540Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag);
4550Sstevel@tonic-gate }
4560Sstevel@tonic-gate
4570Sstevel@tonic-gate added = 0;
4580Sstevel@tonic-gate while (tp) {
4590Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
4600Sstevel@tonic-gate if ((ret = check_version(version, fname)) == 1) {
4610Sstevel@tonic-gate (void) sprintf(buf, "%s version number is incorrect", fname);
4620Sstevel@tonic-gate Saferrno = E_SAFERR;
4630Sstevel@tonic-gate error(buf);
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate else if (ret == 2) {
4660Sstevel@tonic-gate (void) sprintf(buf, "could not open %s", fname);
4670Sstevel@tonic-gate Saferrno = E_SYSERR;
4680Sstevel@tonic-gate error(buf);
4690Sstevel@tonic-gate }
4700Sstevel@tonic-gate else if (ret == 3) {
4710Sstevel@tonic-gate (void) sprintf(buf, "%s file is corrupt", fname);
4720Sstevel@tonic-gate Saferrno = E_SAFERR;
4730Sstevel@tonic-gate error(buf);
4740Sstevel@tonic-gate }
4750Sstevel@tonic-gate fp = fopen(fname, "r");
4760Sstevel@tonic-gate if (fp == NULL) {
4770Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
4780Sstevel@tonic-gate Saferrno = E_SYSERR;
4790Sstevel@tonic-gate error(buf);
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate if (find_svc(fp, tp->t_tag, svctag)) {
4820Sstevel@tonic-gate if (tag) {
4830Sstevel@tonic-gate /* special case of tag only */
4840Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s already exists under %s", svctag, tag);
4850Sstevel@tonic-gate Saferrno = E_DUP;
4860Sstevel@tonic-gate error(buf);
4870Sstevel@tonic-gate }
4880Sstevel@tonic-gate else {
4890Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s already exists under %s - ignoring\n", svctag, tp->t_tag);
4900Sstevel@tonic-gate tp = tp->t_next;
4910Sstevel@tonic-gate (void) fclose(fp);
4920Sstevel@tonic-gate continue;
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate }
4950Sstevel@tonic-gate (void) fclose(fp);
4960Sstevel@tonic-gate
4970Sstevel@tonic-gate /*
4980Sstevel@tonic-gate * put in the config script, if specified
4990Sstevel@tonic-gate */
5000Sstevel@tonic-gate
5010Sstevel@tonic-gate if (script) {
5020Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
5030Sstevel@tonic-gate if (do_config(script, fname)) {
5040Sstevel@tonic-gate /* do_config put out any messages */
5050Sstevel@tonic-gate tp = tp->t_next;
5060Sstevel@tonic-gate continue;
5070Sstevel@tonic-gate }
5080Sstevel@tonic-gate }
5090Sstevel@tonic-gate
5100Sstevel@tonic-gate /*
5110Sstevel@tonic-gate * add the line
5120Sstevel@tonic-gate */
5130Sstevel@tonic-gate
5140Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
5150Sstevel@tonic-gate fp = fopen(fname, "a");
5160Sstevel@tonic-gate if (fp == NULL) {
5170Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
5180Sstevel@tonic-gate Saferrno = E_SYSERR;
5190Sstevel@tonic-gate error(buf);
5200Sstevel@tonic-gate }
5210Sstevel@tonic-gate (void) fprintf(fp, "%s:%s:%s:reserved:reserved:reserved:%s#%s\n",
5220Sstevel@tonic-gate svctag, (flags ? pflags(flags, FALSE) : ""), id, pmspec,
5230Sstevel@tonic-gate (comment ? comment : ""));
5240Sstevel@tonic-gate (void) fclose(fp);
5250Sstevel@tonic-gate added++;
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate /*
5280Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
5290Sstevel@tonic-gate */
5300Sstevel@tonic-gate
5310Sstevel@tonic-gate (void) tell_sac(tp->t_tag);
5320Sstevel@tonic-gate tp = tp->t_next;
5330Sstevel@tonic-gate }
5340Sstevel@tonic-gate if (added == 0) {
5350Sstevel@tonic-gate Saferrno = E_SAFERR;
5360Sstevel@tonic-gate error("No services added");
5370Sstevel@tonic-gate }
5380Sstevel@tonic-gate return;
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate
5410Sstevel@tonic-gate
5420Sstevel@tonic-gate /*
5430Sstevel@tonic-gate * rem_svc - remove a service
5440Sstevel@tonic-gate *
5450Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
5460Sstevel@tonic-gate * svctag - tag of the service to be removed
5470Sstevel@tonic-gate */
5480Sstevel@tonic-gate
5490Sstevel@tonic-gate void
rem_svc(pmtag,svctag)5500Sstevel@tonic-gate rem_svc(pmtag, svctag)
5510Sstevel@tonic-gate char *pmtag;
5520Sstevel@tonic-gate char *svctag;
5530Sstevel@tonic-gate {
5540Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
5550Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */
5560Sstevel@tonic-gate int line; /* line number entry is on */
5570Sstevel@tonic-gate char *tname; /* temp file name */
5580Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
5590Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */
5600Sstevel@tonic-gate
5610Sstevel@tonic-gate fp = fopen(SACTAB, "r");
5620Sstevel@tonic-gate if (fp == NULL) {
5630Sstevel@tonic-gate Saferrno = E_SYSERR;
5640Sstevel@tonic-gate error("Could not open _sactab");
5650Sstevel@tonic-gate }
5660Sstevel@tonic-gate if (!find_pm(fp, pmtag)) {
5670Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
5680Sstevel@tonic-gate Saferrno = E_NOEXIST;
5690Sstevel@tonic-gate error(buf);
5700Sstevel@tonic-gate }
5710Sstevel@tonic-gate (void) fclose(fp);
5720Sstevel@tonic-gate
5730Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag);
5740Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname);
5750Sstevel@tonic-gate fp = fopen(buf, "r");
5760Sstevel@tonic-gate if (fp == NULL) {
5770Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname);
5780Sstevel@tonic-gate Saferrno = E_SYSERR;
5790Sstevel@tonic-gate error(buf);
5800Sstevel@tonic-gate }
5810Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) {
5820Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
5830Sstevel@tonic-gate Saferrno = E_NOEXIST;
5840Sstevel@tonic-gate error(buf);
5850Sstevel@tonic-gate }
5860Sstevel@tonic-gate tname = make_tempname(fname);
5870Sstevel@tonic-gate tfp = open_temp(tname);
5880Sstevel@tonic-gate if (line != 1) {
5890Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) {
5900Sstevel@tonic-gate (void) unlink(tname);
5910Sstevel@tonic-gate Saferrno = E_SYSERR;
5920Sstevel@tonic-gate error("error accessing temp file");
5930Sstevel@tonic-gate }
5940Sstevel@tonic-gate }
5950Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) {
5960Sstevel@tonic-gate (void) unlink(tname);
5970Sstevel@tonic-gate Saferrno = E_SYSERR;
5980Sstevel@tonic-gate error("error accessing temp file");
5990Sstevel@tonic-gate }
6000Sstevel@tonic-gate (void) fclose(fp);
6010Sstevel@tonic-gate if (fclose(tfp) == EOF) {
6020Sstevel@tonic-gate (void) unlink(tname);
6030Sstevel@tonic-gate Saferrno = E_SYSERR;
6040Sstevel@tonic-gate error("error closing tempfile");
6050Sstevel@tonic-gate }
6060Sstevel@tonic-gate /* note - replace only returns if successful */
6070Sstevel@tonic-gate replace(fname, tname);
6080Sstevel@tonic-gate
6090Sstevel@tonic-gate /*
6100Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
6110Sstevel@tonic-gate */
6120Sstevel@tonic-gate
6130Sstevel@tonic-gate if (tell_sac(pmtag)) {
6140Sstevel@tonic-gate
6150Sstevel@tonic-gate /*
6160Sstevel@tonic-gate * if we got rid of the service, try to remove the config script too.
6170Sstevel@tonic-gate * Don't check return status since it may not have existed anyhow.
6180Sstevel@tonic-gate */
6190Sstevel@tonic-gate
6200Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/%s", HOME, pmtag, svctag);
6210Sstevel@tonic-gate (void) unlink(buf);
6220Sstevel@tonic-gate return;
6230Sstevel@tonic-gate }
6240Sstevel@tonic-gate }
6250Sstevel@tonic-gate
6260Sstevel@tonic-gate
6270Sstevel@tonic-gate
6280Sstevel@tonic-gate /*
6290Sstevel@tonic-gate * ed_svc - enable or disable a particular service
6300Sstevel@tonic-gate *
6310Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
6320Sstevel@tonic-gate * svctag - tag of service to be enabled or disabled
6330Sstevel@tonic-gate * flag - operation to perform (ENABLE or DISABLE)
6340Sstevel@tonic-gate */
6350Sstevel@tonic-gate
6360Sstevel@tonic-gate void
ed_svc(pmtag,svctag,flag)6370Sstevel@tonic-gate ed_svc(pmtag, svctag, flag)
6380Sstevel@tonic-gate char *pmtag;
6390Sstevel@tonic-gate char *svctag;
6400Sstevel@tonic-gate int flag;
6410Sstevel@tonic-gate {
6420Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
6430Sstevel@tonic-gate FILE *tfp; /* file pointer for temp file */
6440Sstevel@tonic-gate int line; /* line number entry is on */
6450Sstevel@tonic-gate register char *from; /* working pointer */
6460Sstevel@tonic-gate register char *to; /* working pointer */
6470Sstevel@tonic-gate char *tname; /* temp file name */
6480Sstevel@tonic-gate char *p; /* scratch pointer */
6490Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
6500Sstevel@tonic-gate char tbuf[SIZE]; /* scratch buffer */
6510Sstevel@tonic-gate char fname[SIZE]; /* path to correct _pmtab */
6520Sstevel@tonic-gate
6530Sstevel@tonic-gate fp = fopen(SACTAB, "r");
6540Sstevel@tonic-gate if (fp == NULL) {
6550Sstevel@tonic-gate Saferrno = E_SYSERR;
6560Sstevel@tonic-gate error("Could not open _sactab");
6570Sstevel@tonic-gate }
6580Sstevel@tonic-gate if (!find_pm(fp, pmtag)) {
6590Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
6600Sstevel@tonic-gate Saferrno = E_NOEXIST;
6610Sstevel@tonic-gate error(buf);
6620Sstevel@tonic-gate }
6630Sstevel@tonic-gate (void) fclose(fp);
6640Sstevel@tonic-gate
6650Sstevel@tonic-gate (void) sprintf(fname, "%s/_pmtab", pmtag);
6660Sstevel@tonic-gate (void) sprintf(buf, "%s/%s", HOME, fname);
6670Sstevel@tonic-gate fp = fopen(buf, "r");
6680Sstevel@tonic-gate if (fp == NULL) {
6690Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s/%s", HOME, fname);
6700Sstevel@tonic-gate Saferrno = E_SYSERR;
6710Sstevel@tonic-gate error(buf);
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate if ((line = find_svc(fp, pmtag, svctag)) == 0) {
6740Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
6750Sstevel@tonic-gate Saferrno = E_NOEXIST;
6760Sstevel@tonic-gate error(buf);
6770Sstevel@tonic-gate }
6780Sstevel@tonic-gate tname = make_tempname(fname);
6790Sstevel@tonic-gate tfp = open_temp(tname);
6800Sstevel@tonic-gate if (line != 1) {
6810Sstevel@tonic-gate if (copy_file(fp, tfp, 1, line - 1)) {
6820Sstevel@tonic-gate (void) unlink(tname);
6830Sstevel@tonic-gate Saferrno = E_SYSERR;
6840Sstevel@tonic-gate error("error accessing temp file");
6850Sstevel@tonic-gate }
6860Sstevel@tonic-gate }
6870Sstevel@tonic-gate
6880Sstevel@tonic-gate /*
6890Sstevel@tonic-gate * Note: find_svc above has already read and parsed this entry, thus
6900Sstevel@tonic-gate * we know it to be well-formed, so just change the flags as appropriate
6910Sstevel@tonic-gate */
6920Sstevel@tonic-gate
6930Sstevel@tonic-gate if (fgets(buf, SIZE, fp) == NULL) {
6940Sstevel@tonic-gate (void) unlink(tname);
6950Sstevel@tonic-gate Saferrno = E_SYSERR;
6960Sstevel@tonic-gate error("error accessing temp file");
6970Sstevel@tonic-gate }
6980Sstevel@tonic-gate from = buf;
6990Sstevel@tonic-gate to = tbuf;
7000Sstevel@tonic-gate
7010Sstevel@tonic-gate /*
7020Sstevel@tonic-gate * copy initial portion of entry
7030Sstevel@tonic-gate */
7040Sstevel@tonic-gate
7050Sstevel@tonic-gate p = strchr(from, DELIMC);
7060Sstevel@tonic-gate for ( ; from <= p; )
7070Sstevel@tonic-gate *to++ = *from++;
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate /*
7100Sstevel@tonic-gate * isolate and fix the flags
7110Sstevel@tonic-gate */
7120Sstevel@tonic-gate
7130Sstevel@tonic-gate p = strchr(from, DELIMC);
7140Sstevel@tonic-gate for ( ; from < p; ) {
7150Sstevel@tonic-gate if (*from == 'x') {
7160Sstevel@tonic-gate from++;
7170Sstevel@tonic-gate continue;
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate *to++ = *from++;
7200Sstevel@tonic-gate }
7210Sstevel@tonic-gate
7220Sstevel@tonic-gate /*
7230Sstevel@tonic-gate * above we removed x flag, if this was a disable operation, stick it in
7240Sstevel@tonic-gate * and also copy the field delimiter
7250Sstevel@tonic-gate */
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate if (flag == DISABLE)
7280Sstevel@tonic-gate *to++ = 'x';
7290Sstevel@tonic-gate *to++ = *from++;
7300Sstevel@tonic-gate
7310Sstevel@tonic-gate /*
7320Sstevel@tonic-gate * copy the rest of the line
7330Sstevel@tonic-gate */
7340Sstevel@tonic-gate
7350Sstevel@tonic-gate for ( ; from < &buf[SIZE - 1] ;)
7360Sstevel@tonic-gate *to++ = *from++;
7370Sstevel@tonic-gate /*** *to = '\0'; BUG: Don't uncomment it ****/
7380Sstevel@tonic-gate
7390Sstevel@tonic-gate (void) fprintf(tfp, "%s", tbuf);
7400Sstevel@tonic-gate
7410Sstevel@tonic-gate if (copy_file(fp, tfp, line + 1, -1)) {
7420Sstevel@tonic-gate (void) unlink(tname);
7430Sstevel@tonic-gate Saferrno = E_SYSERR;
7440Sstevel@tonic-gate error("error accessing temp file");
7450Sstevel@tonic-gate }
7460Sstevel@tonic-gate (void) fclose(fp);
7470Sstevel@tonic-gate if (fclose(tfp) == EOF) {
7480Sstevel@tonic-gate (void) unlink(tname);
7490Sstevel@tonic-gate Saferrno = E_SYSERR;
7500Sstevel@tonic-gate error("error closing tempfile");
7510Sstevel@tonic-gate }
7520Sstevel@tonic-gate /* note - replace only returns if successful */
7530Sstevel@tonic-gate replace(fname, tname);
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate
7560Sstevel@tonic-gate /*
7570Sstevel@tonic-gate * tell the SAC to to tell PM to read _pmtab
7580Sstevel@tonic-gate */
7590Sstevel@tonic-gate
7600Sstevel@tonic-gate (void) tell_sac(pmtag);
7610Sstevel@tonic-gate }
7620Sstevel@tonic-gate
7630Sstevel@tonic-gate
7640Sstevel@tonic-gate /*
7650Sstevel@tonic-gate * doconf - take a config script and have it put where it belongs or
7660Sstevel@tonic-gate * output an existing one
7670Sstevel@tonic-gate *
7680Sstevel@tonic-gate * args: script - name of file containing script (if NULL, means
7690Sstevel@tonic-gate * output existing one instead)
7700Sstevel@tonic-gate * tag - tag of port monitor that is responsible for the
7710Sstevel@tonic-gate * designated service (may be null)
7720Sstevel@tonic-gate * type - type of port monitor that is responsible for the
7730Sstevel@tonic-gate * designated service (may be null)
7740Sstevel@tonic-gate * svctag - tag of service whose config script we're operating on
7750Sstevel@tonic-gate */
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate void
doconf(script,tag,type,svctag)7780Sstevel@tonic-gate doconf(script, tag, type, svctag)
7790Sstevel@tonic-gate char *script;
7800Sstevel@tonic-gate char *tag;
7810Sstevel@tonic-gate char *type;
7820Sstevel@tonic-gate char *svctag;
7830Sstevel@tonic-gate {
7840Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
7850Sstevel@tonic-gate int added; /* count of config scripts added */
7860Sstevel@tonic-gate struct taglist tl; /* 'list' for degenerate case (1 PM) */
7870Sstevel@tonic-gate register struct taglist *tp = NULL; /* working pointer */
7880Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
7890Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for names */
7900Sstevel@tonic-gate
7910Sstevel@tonic-gate fp = fopen(SACTAB, "r");
7920Sstevel@tonic-gate if (fp == NULL) {
7930Sstevel@tonic-gate Saferrno = E_SYSERR;
7940Sstevel@tonic-gate error("Could not open _sactab");
7950Sstevel@tonic-gate }
7960Sstevel@tonic-gate if (tag && !find_pm(fp, tag)) {
7970Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", tag);
7980Sstevel@tonic-gate Saferrno = E_NOEXIST;
7990Sstevel@tonic-gate error(buf);
8000Sstevel@tonic-gate }
8010Sstevel@tonic-gate if (type && !(tp = find_type(fp, type))) {
8020Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
8030Sstevel@tonic-gate Saferrno = E_NOEXIST;
8040Sstevel@tonic-gate error(buf);
8050Sstevel@tonic-gate }
8060Sstevel@tonic-gate (void) fclose(fp);
8070Sstevel@tonic-gate
8080Sstevel@tonic-gate if (tag) {
8090Sstevel@tonic-gate
8100Sstevel@tonic-gate /*
8110Sstevel@tonic-gate * treat the case of 1 PM as a degenerate case of a list of PMs from a
8120Sstevel@tonic-gate * type specification. Build the 'list' here.
8130Sstevel@tonic-gate */
8140Sstevel@tonic-gate
8150Sstevel@tonic-gate tp = &tl;
8160Sstevel@tonic-gate tp->t_next = NULL;
8170Sstevel@tonic-gate (void) strcpy(tp->t_tag, tag);
8180Sstevel@tonic-gate }
8190Sstevel@tonic-gate
8200Sstevel@tonic-gate added = 0;
8210Sstevel@tonic-gate while (tp) {
8220Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
8230Sstevel@tonic-gate fp = fopen(fname, "r");
8240Sstevel@tonic-gate if (fp == NULL) {
8250Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
8260Sstevel@tonic-gate Saferrno = E_SYSERR;
8270Sstevel@tonic-gate error(buf);
8280Sstevel@tonic-gate }
8290Sstevel@tonic-gate if (!find_svc(fp, tp->t_tag, svctag)) {
8300Sstevel@tonic-gate if (tag) {
8310Sstevel@tonic-gate /* special case of tag only */
8320Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, tag);
8330Sstevel@tonic-gate Saferrno = E_NOEXIST;
8340Sstevel@tonic-gate error(buf);
8350Sstevel@tonic-gate }
8360Sstevel@tonic-gate else {
8370Sstevel@tonic-gate (void) fprintf(stderr, "warning - %s does not exist under %s - ignoring\n", svctag, tp->t_tag);
8380Sstevel@tonic-gate Saferrno = E_NOEXIST;
8390Sstevel@tonic-gate tp = tp->t_next;
8400Sstevel@tonic-gate (void) fclose(fp);
8410Sstevel@tonic-gate continue;
8420Sstevel@tonic-gate }
8430Sstevel@tonic-gate }
8440Sstevel@tonic-gate (void) fclose(fp);
8450Sstevel@tonic-gate
8460Sstevel@tonic-gate (void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
8470Sstevel@tonic-gate
8480Sstevel@tonic-gate /*
8490Sstevel@tonic-gate * do_config does all the real work (keep track if any errors occurred)
8500Sstevel@tonic-gate */
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate if (do_config(script, fname) == 0)
8530Sstevel@tonic-gate added++;
8540Sstevel@tonic-gate tp = tp->t_next;
8550Sstevel@tonic-gate }
8560Sstevel@tonic-gate if (added == 0) {
8570Sstevel@tonic-gate Saferrno = E_SAFERR;
8580Sstevel@tonic-gate error("No configuration scripts installed");
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate return;
8610Sstevel@tonic-gate }
8620Sstevel@tonic-gate
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate /*
8650Sstevel@tonic-gate * tell_sac - use sacadm to tell the sac to tell a port monitor to read
8660Sstevel@tonic-gate * its _pmtab. Return TRUE on success, FALSE on failure.
8670Sstevel@tonic-gate *
8680Sstevel@tonic-gate * args: tag - tag of port monitor to be notified
8690Sstevel@tonic-gate */
8700Sstevel@tonic-gate
8710Sstevel@tonic-gate
872*334Sdp int
tell_sac(char * tag)873*334Sdp tell_sac(char *tag)
8740Sstevel@tonic-gate {
8750Sstevel@tonic-gate pid_t pid; /* returned pid from fork */
8760Sstevel@tonic-gate int status; /* return status from sacadm child */
8770Sstevel@tonic-gate
8780Sstevel@tonic-gate if ((pid = fork()) < 0) {
8790Sstevel@tonic-gate (void) fprintf(stderr, "warning - fork failed - could not notify <%s> about modified table\n", tag);
8800Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command \"sacadm -x -p %s\"\n", tag);
8810Sstevel@tonic-gate Saferrno = E_SYSERR;
8820Sstevel@tonic-gate return(FALSE);
8830Sstevel@tonic-gate }
8840Sstevel@tonic-gate else if (pid) {
8850Sstevel@tonic-gate /* parent */
8860Sstevel@tonic-gate (void) wait(&status);
8870Sstevel@tonic-gate if (status) {
8880Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_PMNOTRUN) {
8890Sstevel@tonic-gate (void) fprintf(stderr, "warning - port monitor, %s is not running\n", tag);
8900Sstevel@tonic-gate return (FALSE);
8910Sstevel@tonic-gate }
8920Sstevel@tonic-gate if (((status >> 8) & 0xff) == E_SACNOTRUN) {
8930Sstevel@tonic-gate Saferrno = E_SACNOTRUN;
8940Sstevel@tonic-gate } else {
8950Sstevel@tonic-gate Saferrno = E_SYSERR;
8960Sstevel@tonic-gate }
8970Sstevel@tonic-gate (void) fprintf(stderr,
8980Sstevel@tonic-gate "warning - could not notify <%s> about modified"
8990Sstevel@tonic-gate " table\n", tag);
9000Sstevel@tonic-gate (void) fprintf(stderr, "try executing the command"
9010Sstevel@tonic-gate " \"sacadm -x -p %s\"\n", tag);
9020Sstevel@tonic-gate return(FALSE);
9030Sstevel@tonic-gate }
9040Sstevel@tonic-gate else {
9050Sstevel@tonic-gate return(TRUE);
9060Sstevel@tonic-gate }
9070Sstevel@tonic-gate }
9080Sstevel@tonic-gate else {
9090Sstevel@tonic-gate /* set IFS for security */
9100Sstevel@tonic-gate (void) putenv("IFS=\" \"");
9110Sstevel@tonic-gate /* muffle sacadm warning messages */
9120Sstevel@tonic-gate (void) fclose(stderr);
9130Sstevel@tonic-gate (void) fopen("/dev/null", "w");
9140Sstevel@tonic-gate (void) execl("/usr/sbin/sacadm", "sacadm", "-x", "-p", tag, 0);
9150Sstevel@tonic-gate
9160Sstevel@tonic-gate /*
9170Sstevel@tonic-gate * if we got here, it didn't work, exit status will clue in parent to
9180Sstevel@tonic-gate * put out the warning
9190Sstevel@tonic-gate */
9200Sstevel@tonic-gate
9210Sstevel@tonic-gate exit(1);
9220Sstevel@tonic-gate }
9230Sstevel@tonic-gate /* NOTREACHED */
9240Sstevel@tonic-gate }
9250Sstevel@tonic-gate
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate /*
9280Sstevel@tonic-gate * list_svcs - list information about services
9290Sstevel@tonic-gate *
9300Sstevel@tonic-gate * args: pmtag - tag of port monitor responsible for the service
9310Sstevel@tonic-gate * (may be null)
9320Sstevel@tonic-gate * type - type of port monitor responsible for the service
9330Sstevel@tonic-gate * (may be null)
9340Sstevel@tonic-gate * svctag - tag of service to be listed (may be null)
9350Sstevel@tonic-gate * oflag - true if output should be easily parseable
9360Sstevel@tonic-gate */
9370Sstevel@tonic-gate
9380Sstevel@tonic-gate void
list_svcs(pmtag,type,svctag,oflag)9390Sstevel@tonic-gate list_svcs(pmtag, type, svctag, oflag)
9400Sstevel@tonic-gate char *pmtag;
9410Sstevel@tonic-gate char *type;
9420Sstevel@tonic-gate char *svctag;
9430Sstevel@tonic-gate {
9440Sstevel@tonic-gate FILE *fp; /* scratch file pointer */
9450Sstevel@tonic-gate register struct taglist *tp; /* pointer to PM list */
9460Sstevel@tonic-gate int nprint = 0; /* count # of svcs printed */
9470Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */
9480Sstevel@tonic-gate register struct pmtab *pp = &pmtab; /* and a pointer to it */
9490Sstevel@tonic-gate register char *p; /* working pointer */
9500Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
9510Sstevel@tonic-gate char fname[SIZE]; /* scratch buffer for building names */
9520Sstevel@tonic-gate
9530Sstevel@tonic-gate fp = fopen(SACTAB, "r");
9540Sstevel@tonic-gate if (fp == NULL) {
9550Sstevel@tonic-gate Saferrno = E_SYSERR;
9560Sstevel@tonic-gate error("Could not open _sactab");
9570Sstevel@tonic-gate }
9580Sstevel@tonic-gate if (pmtag && !find_pm(fp, pmtag)) {
9590Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
9600Sstevel@tonic-gate Saferrno = E_NOEXIST;
9610Sstevel@tonic-gate error(buf);
9620Sstevel@tonic-gate }
9630Sstevel@tonic-gate rewind(fp);
9640Sstevel@tonic-gate if (type) {
9650Sstevel@tonic-gate tp = find_type(fp, type);
9660Sstevel@tonic-gate if (tp == NULL) {
9670Sstevel@tonic-gate (void) sprintf(buf, "Invalid request, %s does not exist", type);
9680Sstevel@tonic-gate Saferrno = E_NOEXIST;
9690Sstevel@tonic-gate error(buf);
9700Sstevel@tonic-gate }
9710Sstevel@tonic-gate }
9720Sstevel@tonic-gate else
9730Sstevel@tonic-gate tp = find_type(fp, NULL);
9740Sstevel@tonic-gate (void) fclose(fp);
9750Sstevel@tonic-gate
9760Sstevel@tonic-gate while (tp) {
9770Sstevel@tonic-gate if (pmtag && strcmp(tp->t_tag, pmtag)) {
9780Sstevel@tonic-gate /* not interested in this port monitor */
9790Sstevel@tonic-gate tp = tp->t_next;
9800Sstevel@tonic-gate continue;
9810Sstevel@tonic-gate }
9820Sstevel@tonic-gate (void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
9830Sstevel@tonic-gate fp = fopen(fname, "r");
9840Sstevel@tonic-gate if (fp == NULL) {
9850Sstevel@tonic-gate (void) sprintf(buf, "Could not open %s", fname);
9860Sstevel@tonic-gate Saferrno = E_SYSERR;
9870Sstevel@tonic-gate error(buf);
9880Sstevel@tonic-gate }
9890Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
9900Sstevel@tonic-gate p = trim(buf);
9910Sstevel@tonic-gate if (*p == '\0')
9920Sstevel@tonic-gate continue;
9930Sstevel@tonic-gate parseline(p, pp, tp->t_tag);
9940Sstevel@tonic-gate if (!svctag || !strcmp(pp->p_tag, svctag)) {
9950Sstevel@tonic-gate if (oflag) {
9960Sstevel@tonic-gate (void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s#%s\n",
9970Sstevel@tonic-gate tp->t_tag, tp->t_type, pp->p_tag,
9980Sstevel@tonic-gate pflags(pp->p_flags, FALSE),
9990Sstevel@tonic-gate pp->p_id, pp->p_res1, pp->p_res2,
10000Sstevel@tonic-gate pp->p_res3,pp->p_pmspec, Comment);
10010Sstevel@tonic-gate }
10020Sstevel@tonic-gate else {
10030Sstevel@tonic-gate if (nprint == 0) {
10040Sstevel@tonic-gate (void) printf("PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>\n");
10050Sstevel@tonic-gate }
10060Sstevel@tonic-gate (void) printf("%-14s %-14s %-14s %-4s %-8s %s #%s\n", tp->t_tag, tp->t_type, pp->p_tag,
10070Sstevel@tonic-gate pflags(pp->p_flags, TRUE), pp->p_id, pspec(pp->p_pmspec), Comment);
10080Sstevel@tonic-gate }
10090Sstevel@tonic-gate nprint++;
10100Sstevel@tonic-gate }
10110Sstevel@tonic-gate }
10120Sstevel@tonic-gate if (!feof(fp)) {
10130Sstevel@tonic-gate (void) sprintf(buf, "error reading %s", fname);
10140Sstevel@tonic-gate Saferrno = E_SYSERR;
10150Sstevel@tonic-gate error(buf);
10160Sstevel@tonic-gate }
10170Sstevel@tonic-gate else {
10180Sstevel@tonic-gate (void) fclose(fp);
10190Sstevel@tonic-gate tp = tp->t_next;
10200Sstevel@tonic-gate }
10210Sstevel@tonic-gate }
10220Sstevel@tonic-gate /* if we didn't find any valid ones, indicate an error */
10230Sstevel@tonic-gate if (nprint == 0) {
10240Sstevel@tonic-gate if (svctag)
10250Sstevel@tonic-gate (void) fprintf(stderr, "Service <%s> does not exist\n", svctag);
10260Sstevel@tonic-gate else
10270Sstevel@tonic-gate (void) fprintf(stderr, "No services defined\n");
10280Sstevel@tonic-gate Saferrno = E_NOEXIST;
10290Sstevel@tonic-gate }
10300Sstevel@tonic-gate return;
10310Sstevel@tonic-gate }
10320Sstevel@tonic-gate
10330Sstevel@tonic-gate
10340Sstevel@tonic-gate /*
10350Sstevel@tonic-gate * find_svc - find an entry in _pmtab for a particular service tag
10360Sstevel@tonic-gate *
10370Sstevel@tonic-gate * args: fp - file pointer for _pmtab
10380Sstevel@tonic-gate * tag - port monitor tag (for error reporting)
10390Sstevel@tonic-gate * svctag - tag of service we're looking for
10400Sstevel@tonic-gate */
10410Sstevel@tonic-gate
1042*334Sdp int
find_svc(FILE * fp,char * tag,char * svctag)1043*334Sdp find_svc(FILE *fp, char *tag, char *svctag)
10440Sstevel@tonic-gate {
10450Sstevel@tonic-gate register char *p; /* working pointer */
10460Sstevel@tonic-gate int line = 0; /* line number we found entry on */
10470Sstevel@tonic-gate struct pmtab pmtab; /* place to hold parsed info */
10480Sstevel@tonic-gate static char buf[SIZE]; /* scratch buffer */
10490Sstevel@tonic-gate
10500Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
10510Sstevel@tonic-gate line++;
10520Sstevel@tonic-gate p = trim(buf);
10530Sstevel@tonic-gate if (*p == '\0')
10540Sstevel@tonic-gate continue;
10550Sstevel@tonic-gate parseline(p, &pmtab, tag);
10560Sstevel@tonic-gate if (!(strcmp(pmtab.p_tag, svctag)))
10570Sstevel@tonic-gate return(line);
10580Sstevel@tonic-gate }
10590Sstevel@tonic-gate if (!feof(fp)) {
10600Sstevel@tonic-gate (void) sprintf(buf, "error reading %s/%s/_pmtab", HOME, tag);
10610Sstevel@tonic-gate Saferrno = E_SYSERR;
10620Sstevel@tonic-gate error(buf);
1063*334Sdp /* NOTREACHED */
1064*334Sdp return (0);
1065*334Sdp } else
1066*334Sdp return (0);
10670Sstevel@tonic-gate }
10680Sstevel@tonic-gate
10690Sstevel@tonic-gate
10700Sstevel@tonic-gate /*
10710Sstevel@tonic-gate * parseline - parse a line from _pmtab. This routine will return if the
10720Sstevel@tonic-gate * parse wa successful, otherwise it will output an error and
10730Sstevel@tonic-gate * exit.
10740Sstevel@tonic-gate *
10750Sstevel@tonic-gate * args: p - pointer to the data read from the file (note - this is
10760Sstevel@tonic-gate * a static data region, so we can point into it)
10770Sstevel@tonic-gate * pp - pointer to a structure in which the separated fields
10780Sstevel@tonic-gate * are placed
10790Sstevel@tonic-gate * tag - port monitor tag (for error reporting)
10800Sstevel@tonic-gate *
10810Sstevel@tonic-gate * A line in the file has the following format:
10820Sstevel@tonic-gate *
10830Sstevel@tonic-gate * tag:flags:identity:reserved:reserved:reserved:PM_spec_info # comment
10840Sstevel@tonic-gate */
10850Sstevel@tonic-gate
10860Sstevel@tonic-gate
10870Sstevel@tonic-gate void
parseline(p,pp,tag)10880Sstevel@tonic-gate parseline(p, pp, tag)
10890Sstevel@tonic-gate register char *p;
10900Sstevel@tonic-gate register struct pmtab *pp;
10910Sstevel@tonic-gate char *tag;
10920Sstevel@tonic-gate {
10930Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
10940Sstevel@tonic-gate
10950Sstevel@tonic-gate /*
10960Sstevel@tonic-gate * get the service tag
10970Sstevel@tonic-gate */
10980Sstevel@tonic-gate
10990Sstevel@tonic-gate p = nexttok(p, DELIM, FALSE);
11000Sstevel@tonic-gate if (p == NULL) {
11010Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11020Sstevel@tonic-gate Saferrno = E_SAFERR;
11030Sstevel@tonic-gate error(buf);
11040Sstevel@tonic-gate }
11050Sstevel@tonic-gate if (strlen(p) > PMTAGSIZE) {
11060Sstevel@tonic-gate p[PMTAGSIZE] = '\0';
11070Sstevel@tonic-gate (void) fprintf(stderr, "tag too long, truncated to <%s>", p);
11080Sstevel@tonic-gate }
11090Sstevel@tonic-gate pp->p_tag = p;
11100Sstevel@tonic-gate
11110Sstevel@tonic-gate /*
11120Sstevel@tonic-gate * get the flags
11130Sstevel@tonic-gate */
11140Sstevel@tonic-gate
11150Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11160Sstevel@tonic-gate if (p == NULL) {
11170Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11180Sstevel@tonic-gate Saferrno = E_SAFERR;
11190Sstevel@tonic-gate error(buf);
11200Sstevel@tonic-gate }
11210Sstevel@tonic-gate pp->p_flags = 0;
11220Sstevel@tonic-gate while (*p) {
11230Sstevel@tonic-gate switch (*p++) {
11240Sstevel@tonic-gate case 'u':
11250Sstevel@tonic-gate pp->p_flags |= U_FLAG;
11260Sstevel@tonic-gate break;
11270Sstevel@tonic-gate case 'x':
11280Sstevel@tonic-gate pp->p_flags |= X_FLAG;
11290Sstevel@tonic-gate break;
11300Sstevel@tonic-gate default:
11310Sstevel@tonic-gate (void) sprintf(buf, "Unrecognized flag <%c>", *(p - 1));
11320Sstevel@tonic-gate Saferrno = E_SAFERR;
11330Sstevel@tonic-gate error(buf);
11340Sstevel@tonic-gate break;
11350Sstevel@tonic-gate }
11360Sstevel@tonic-gate }
11370Sstevel@tonic-gate
11380Sstevel@tonic-gate /*
11390Sstevel@tonic-gate * get the identity
11400Sstevel@tonic-gate */
11410Sstevel@tonic-gate
11420Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11430Sstevel@tonic-gate if (p == NULL) {
11440Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11450Sstevel@tonic-gate Saferrno = E_SAFERR;
11460Sstevel@tonic-gate error(buf);
11470Sstevel@tonic-gate }
11480Sstevel@tonic-gate pp->p_id = p;
11490Sstevel@tonic-gate
11500Sstevel@tonic-gate /*
11510Sstevel@tonic-gate * get the first reserved field
11520Sstevel@tonic-gate */
11530Sstevel@tonic-gate
11540Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11550Sstevel@tonic-gate if (p == NULL) {
11560Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11570Sstevel@tonic-gate Saferrno = E_SAFERR;
11580Sstevel@tonic-gate error(buf);
11590Sstevel@tonic-gate }
11600Sstevel@tonic-gate pp->p_res1 = p;
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate /*
11630Sstevel@tonic-gate * get the second reserved field
11640Sstevel@tonic-gate */
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11670Sstevel@tonic-gate if (p == NULL) {
11680Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11690Sstevel@tonic-gate Saferrno = E_SAFERR;
11700Sstevel@tonic-gate error(buf);
11710Sstevel@tonic-gate }
11720Sstevel@tonic-gate pp->p_res2 = p;
11730Sstevel@tonic-gate
11740Sstevel@tonic-gate /*
11750Sstevel@tonic-gate * get the third reserved field
11760Sstevel@tonic-gate */
11770Sstevel@tonic-gate
11780Sstevel@tonic-gate p = nexttok(NULL, DELIM, FALSE);
11790Sstevel@tonic-gate if (p == NULL) {
11800Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11810Sstevel@tonic-gate Saferrno = E_SAFERR;
11820Sstevel@tonic-gate error(buf);
11830Sstevel@tonic-gate }
11840Sstevel@tonic-gate pp->p_res3 = p;
11850Sstevel@tonic-gate
11860Sstevel@tonic-gate /*
11870Sstevel@tonic-gate * the rest is the port monitor specific info
11880Sstevel@tonic-gate */
11890Sstevel@tonic-gate
11900Sstevel@tonic-gate p = nexttok(NULL, DELIM, TRUE);
11910Sstevel@tonic-gate if (p == NULL) {
11920Sstevel@tonic-gate (void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
11930Sstevel@tonic-gate Saferrno = E_SAFERR;
11940Sstevel@tonic-gate error(buf);
11950Sstevel@tonic-gate }
11960Sstevel@tonic-gate pp->p_pmspec = p;
11970Sstevel@tonic-gate return;
11980Sstevel@tonic-gate }
11990Sstevel@tonic-gate
12000Sstevel@tonic-gate
12010Sstevel@tonic-gate /*
12020Sstevel@tonic-gate * pspec - format port monitor specific information
12030Sstevel@tonic-gate *
12040Sstevel@tonic-gate * args: spec - port monitor specific info, separated by
12050Sstevel@tonic-gate * field separater character (may be escaped by \)
12060Sstevel@tonic-gate */
12070Sstevel@tonic-gate
12080Sstevel@tonic-gate char *
pspec(spec)12090Sstevel@tonic-gate pspec(spec)
12100Sstevel@tonic-gate char *spec;
12110Sstevel@tonic-gate {
12120Sstevel@tonic-gate static char buf[SIZE]; /* returned string */
12130Sstevel@tonic-gate register char *from; /* working pointer */
12140Sstevel@tonic-gate register char *to; /* working pointer */
12150Sstevel@tonic-gate int newflag; /* flag indicating new field */
12160Sstevel@tonic-gate
12170Sstevel@tonic-gate to = buf;
12180Sstevel@tonic-gate from = spec;
12190Sstevel@tonic-gate newflag = 1;
12200Sstevel@tonic-gate while (*from) {
12210Sstevel@tonic-gate switch (*from) {
12220Sstevel@tonic-gate case ':':
12230Sstevel@tonic-gate if (newflag) {
12240Sstevel@tonic-gate *to++ = '-';
12250Sstevel@tonic-gate }
12260Sstevel@tonic-gate *to++ = ' ';
12270Sstevel@tonic-gate from++;
12280Sstevel@tonic-gate newflag = 1;
12290Sstevel@tonic-gate break;
12300Sstevel@tonic-gate case '\\':
12310Sstevel@tonic-gate if (*(from + 1) == ':') {
12320Sstevel@tonic-gate *to++ = ':';
12330Sstevel@tonic-gate /* skip over \: */
12340Sstevel@tonic-gate from += 2;
12350Sstevel@tonic-gate }
12360Sstevel@tonic-gate else
12370Sstevel@tonic-gate *to++ = *from++;
12380Sstevel@tonic-gate newflag = 0;
12390Sstevel@tonic-gate break;
12400Sstevel@tonic-gate default:
12410Sstevel@tonic-gate newflag = 0;
12420Sstevel@tonic-gate *to++ = *from++;
12430Sstevel@tonic-gate }
12440Sstevel@tonic-gate }
12450Sstevel@tonic-gate *to = '\0';
12460Sstevel@tonic-gate return(buf);
12470Sstevel@tonic-gate }
12480Sstevel@tonic-gate
12490Sstevel@tonic-gate
12500Sstevel@tonic-gate /*
12510Sstevel@tonic-gate * pflags - put service flags into intelligible form for output
12520Sstevel@tonic-gate *
12530Sstevel@tonic-gate * args: flags - binary representation of flags
12540Sstevel@tonic-gate * dflag - true if a "-" should be returned if no flags
12550Sstevel@tonic-gate */
12560Sstevel@tonic-gate
12570Sstevel@tonic-gate char *
pflags(flags,dflag)12580Sstevel@tonic-gate pflags(flags, dflag)
12590Sstevel@tonic-gate long flags;
12600Sstevel@tonic-gate int dflag;
12610Sstevel@tonic-gate {
12620Sstevel@tonic-gate register int i; /* scratch counter */
12630Sstevel@tonic-gate static char buf[SIZE]; /* formatted flags */
12640Sstevel@tonic-gate
12650Sstevel@tonic-gate if (flags == 0) {
12660Sstevel@tonic-gate if (dflag)
12670Sstevel@tonic-gate return("-");
12680Sstevel@tonic-gate else
12690Sstevel@tonic-gate return("");
12700Sstevel@tonic-gate }
12710Sstevel@tonic-gate i = 0;
12720Sstevel@tonic-gate if (flags & U_FLAG) {
12730Sstevel@tonic-gate buf[i++] = 'u';
12740Sstevel@tonic-gate flags &= ~U_FLAG;
12750Sstevel@tonic-gate }
12760Sstevel@tonic-gate if (flags & X_FLAG) {
12770Sstevel@tonic-gate buf[i++] = 'x';
12780Sstevel@tonic-gate flags &= ~X_FLAG;
12790Sstevel@tonic-gate }
12800Sstevel@tonic-gate if (flags) {
12810Sstevel@tonic-gate Saferrno = E_SAFERR;
12820Sstevel@tonic-gate error("Internal error in pflags");
12830Sstevel@tonic-gate }
12840Sstevel@tonic-gate buf[i] = '\0';
12850Sstevel@tonic-gate return(buf);
12860Sstevel@tonic-gate }
12870Sstevel@tonic-gate
12880Sstevel@tonic-gate
12890Sstevel@tonic-gate /*
12900Sstevel@tonic-gate * find_type - find entries in _sactab for a particular port monitor type
12910Sstevel@tonic-gate *
12920Sstevel@tonic-gate * args: fp - file pointer for _sactab
12930Sstevel@tonic-gate * type - type of port monitor we're looking for (if type is
12940Sstevel@tonic-gate * null, it means find all PMs)
12950Sstevel@tonic-gate */
12960Sstevel@tonic-gate
12970Sstevel@tonic-gate struct taglist *
find_type(fp,type)12980Sstevel@tonic-gate find_type(fp, type)
12990Sstevel@tonic-gate FILE *fp;
13000Sstevel@tonic-gate char *type;
13010Sstevel@tonic-gate {
13020Sstevel@tonic-gate register char *p; /* working pointer */
13030Sstevel@tonic-gate struct sactab stab; /* place to hold parsed info */
13040Sstevel@tonic-gate register struct sactab *sp = &stab; /* and a pointer to it */
13050Sstevel@tonic-gate char buf[SIZE]; /* scratch buffer */
13060Sstevel@tonic-gate struct taglist *thead; /* linked list of tags */
13070Sstevel@tonic-gate register struct taglist *temp; /* scratch pointer */
13080Sstevel@tonic-gate
13090Sstevel@tonic-gate thead = NULL;
13100Sstevel@tonic-gate while (fgets(buf, SIZE, fp)) {
13110Sstevel@tonic-gate p = trim(buf);
13120Sstevel@tonic-gate if (*p == '\0')
13130Sstevel@tonic-gate continue;
13140Sstevel@tonic-gate parse(p, sp);
13150Sstevel@tonic-gate if ((type == NULL) || !(strcmp(sp->sc_type, type))) {
13160Sstevel@tonic-gate temp = (struct taglist *) malloc(sizeof(struct taglist));
13170Sstevel@tonic-gate if (temp == NULL) {
13180Sstevel@tonic-gate Saferrno = E_SYSERR;
13190Sstevel@tonic-gate error("malloc failed");
13200Sstevel@tonic-gate }
13210Sstevel@tonic-gate temp->t_next = thead;
13220Sstevel@tonic-gate (void) strcpy(temp->t_tag, sp->sc_tag);
13230Sstevel@tonic-gate (void) strcpy(temp->t_type, sp->sc_type);
13240Sstevel@tonic-gate thead = temp;
13250Sstevel@tonic-gate }
13260Sstevel@tonic-gate }
13270Sstevel@tonic-gate if (!feof(fp)) {
13280Sstevel@tonic-gate Saferrno = E_SYSERR;
13290Sstevel@tonic-gate error("error reading _sactab");
1330*334Sdp /* NOTREACHED */
1331*334Sdp return (0);
1332*334Sdp } else
1333*334Sdp return (thead ? thead : NULL);
13340Sstevel@tonic-gate }
1335