4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
30 #pragma ident "%Z%%M% %I% %E% SMI"
35 #include <sys/types.h>
43 #define ADD 0x1 /* -a or other required options seen */
44 #define REMOVE 0x2 /* -r seen */
45 #define ENABLE 0x4 /* -e seen */
46 #define DISABLE 0x8 /* -d seen */
47 #define PLIST 0x10 /* -l seen */
48 #define LIST 0x20 /* -L seen */
49 #define CONFIG 0x40 /* -g seen */
51 # define U_FLAG 0x1 /* -fu seen */
52 # define X_FLAG 0x2 /* -fx seen */
60 struct taglist
*find_type();
70 * format of a _pmtab entry - used to hold parsed info
74 char *p_tag
; /* service tag */
75 long p_flags
; /* flags */
76 char *p_id
; /* logname to start service as */
77 char *p_res1
; /* reserved field */
78 char *p_res2
; /* reserved field */
79 char *p_res3
; /* reserved field */
80 char *p_pmspec
; /* port monitor specific info */
84 * format of a tag list, which is a list of port monitor tags of
89 struct taglist
*t_next
; /* next in list */
90 char t_tag
[PMTAGSIZE
+ 1]; /* PM tag */
91 char t_type
[PMTYPESIZE
+ 1]; /* PM type */
95 * common error messages
98 # define NOTPRIV "User not privileged for operation"
99 # define BADINP "Embedded newlines not allowed"
101 int Saferrno
; /* internal `errno' for exit */
105 * main - scan args for pmadm and call appropriate handling code
109 main(int argc
, char *argv
[])
111 int c
; /* option letter */
112 int ret
; /* return code from check_version */
113 uid_t uid
; /* invoker's real uid */
114 int flag
= 0; /* flag to record requested operations */
115 int errflg
= 0; /* error indicator */
116 int badcnt
= 0; /* count of bad args to -f */
117 int version
= -1; /* argument to -v */
118 int sawaflag
= 0; /* true if actually saw -a */
119 int conflag
= 0; /* true if output should be in condensed form */
120 long flags
= 0; /* arguments to -f */
121 char *pmtag
= NULL
; /* argument to -p */
122 char *type
= NULL
; /* argument to -t */
123 char *script
= NULL
; /* argument to -z */
124 char *comment
= " "; /* argument to -y */
125 char *id
= NULL
; /* argument to -i */
126 char *svctag
= NULL
; /* argument to -s */
127 char *pmspec
= NULL
; /* argument to -m */
128 char badargs
[SIZE
]; /* place to hold bad args to -f */
129 char buf
[SIZE
]; /* scratch buffer */
130 register char *p
; /* scratch pointer */
134 while ((c
= getopt(argc
, argv
, "adef:gi:Llm:p:rs:t:v:y:z:")) != -1) {
157 badargs
[badcnt
++] = *(optarg
- 1);
161 /* null terminate just in case anything is there */
162 badargs
[badcnt
] = '\0';
168 if (strchr(optarg
, '\n')) {
169 Saferrno
= E_BADARGS
;
182 if (strchr(optarg
, '\n')) {
183 Saferrno
= E_BADARGS
;
186 if (*optarg
== '\0') {
187 /* this will generate a usage message below */
195 if (strchr(optarg
, '\n')) {
196 Saferrno
= E_BADARGS
;
200 if (strlen(pmtag
) > PMTAGSIZE
) {
201 pmtag
[PMTAGSIZE
] = '\0';
202 (void) fprintf(stderr
, "tag too long, truncated to <%s>\n", pmtag
);
204 for (p
= pmtag
; *p
; p
++) {
206 Saferrno
= E_BADARGS
;
207 error("port monitor tag must be alphanumeric");
215 if (strchr(optarg
, '\n')) {
216 Saferrno
= E_BADARGS
;
220 if (strlen(svctag
) > SVCTAGSIZE
) {
221 svctag
[SVCTAGSIZE
] = '\0';
222 (void) fprintf(stderr
, "svctag too long, truncated to <%s>\n", svctag
);
224 for (p
= svctag
; *p
; p
++) {
226 Saferrno
= E_BADARGS
;
227 error("service tag must be alphanumeric");
232 if (strchr(optarg
, '\n')) {
233 Saferrno
= E_BADARGS
;
237 if (strlen(type
) > PMTYPESIZE
) {
238 type
[PMTYPESIZE
] = '\0';
239 (void) fprintf(stderr
, "type too long, truncated to <%s>\n", type
);
241 for (p
= type
; *p
; p
++) {
243 Saferrno
= E_BADARGS
;
244 error("port monitor type must be alphanumeric");
250 version
= atoi(optarg
);
252 Saferrno
= E_BADARGS
;
253 error("version number can not be negative");
257 if (strchr(optarg
, '\n')) {
258 Saferrno
= E_BADARGS
;
265 if (strchr(optarg
, '\n')) {
266 Saferrno
= E_BADARGS
;
275 if (errflg
|| (optind
< argc
))
279 /* bad flags were given to -f */
280 (void) sprintf(buf
, "Invalid request, %s are not valid arguments for \"-f\"", badargs
);
281 Saferrno
= E_BADARGS
;
288 * don't do anything if _sactab isn't the version we understand
291 if ((ret
= check_version(VERSION
, SACTAB
)) == 1) {
293 error("_sactab version number is incorrect");
296 (void) sprintf(buf
, "could not open %s", SACTAB
);
301 (void) sprintf(buf
, "%s file is corrupt", SACTAB
);
312 if (!sawaflag
|| (pmtag
&& type
) || (!pmtag
&& !type
) || !svctag
|| !id
|| !pmspec
|| (version
< 0))
314 add_svc(pmtag
, type
, svctag
, id
, pmspec
, flags
, version
, comment
, script
);
321 if (!pmtag
|| !svctag
|| type
|| script
)
323 rem_svc(pmtag
, svctag
);
330 if (!pmtag
|| !svctag
|| type
|| script
)
332 ed_svc(pmtag
, svctag
, ENABLE
);
339 if (!pmtag
|| !svctag
|| type
|| script
)
341 ed_svc(pmtag
, svctag
, DISABLE
);
347 if ((pmtag
&& type
) || script
)
349 list_svcs(pmtag
, type
, svctag
, conflag
);
356 if ((pmtag
&& type
) || (!pmtag
&& !type
) || !svctag
|| (type
&& !script
))
358 doconf(script
, pmtag
, type
, svctag
);
361 /* we only get here if more than one flag bit was set */
371 * usage - print out a usage message
373 * args: cmdname - the name command was invoked with
380 (void) fprintf(stderr
, "Usage:\t%s -a [ -p pmtag | -t type ] -s svctag -i id -m \"pmspecific\"\n", cmdname
);
381 (void) fprintf(stderr
, "\t\t-v version [ -f xu ] [ -y comment ] [ -z script]\n");
382 (void) fprintf(stderr
, "\t%s -r -p pmtag -s svctag\n", cmdname
);
383 (void) fprintf(stderr
, "\t%s -e -p pmtag -s svctag\n", cmdname
);
384 (void) fprintf(stderr
, "\t%s -d -p pmtag -s svctag\n", cmdname
);
385 (void) fprintf(stderr
, "\t%s -l [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname
);
386 (void) fprintf(stderr
, "\t%s -L [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname
);
387 (void) fprintf(stderr
, "\t%s -g -p pmtag -s svctag [ -z script ]\n", cmdname
);
388 (void) fprintf(stderr
, "\t%s -g -s svctag -t type -z script\n", cmdname
);
389 Saferrno
= E_BADARGS
;
395 * add_svc - add a service entry
397 * args: tag - port monitor's tag (may be null)
398 * type - port monitor's type (may be null)
399 * svctag - service's tag
400 * id - identity under which service should run
401 * pmspec - uninterpreted port monitor-specific info
402 * flags - service flags
403 * version - version number of port monitor's pmtab
404 * comment - comment describing service
405 * script - service's configuration script
409 add_svc(tag
, type
, svctag
, id
, pmspec
, flags
, version
, comment
, script
)
420 FILE *fp
; /* scratch file pointer */
421 struct taglist tl
; /* 'list' for degenerate case (1 PM) */
422 register struct taglist
*tp
= NULL
; /* working pointer */
423 int ret
; /* return code from check_version */
424 char buf
[SIZE
]; /* scratch buffer */
425 char fname
[SIZE
]; /* scratch buffer for building names */
426 int added
; /* count number added */
428 fp
= fopen(SACTAB
, "r");
431 error("Could not open _sactab");
433 if (tag
&& !find_pm(fp
, tag
)) {
434 (void) sprintf(buf
, "Invalid request, %s does not exist", tag
);
435 Saferrno
= E_NOEXIST
;
438 if (type
&& !(tp
= find_type(fp
, type
))) {
439 (void) sprintf(buf
, "Invalid request, %s does not exist", type
);
440 Saferrno
= E_NOEXIST
;
448 * treat the case of 1 PM as a degenerate case of a list of PMs from a
449 * type specification. Build the 'list' here.
454 (void) strcpy(tp
->t_tag
, tag
);
459 (void) sprintf(fname
, "%s/%s/_pmtab", HOME
, tp
->t_tag
);
460 if ((ret
= check_version(version
, fname
)) == 1) {
461 (void) sprintf(buf
, "%s version number is incorrect", fname
);
466 (void) sprintf(buf
, "could not open %s", fname
);
471 (void) sprintf(buf
, "%s file is corrupt", fname
);
475 fp
= fopen(fname
, "r");
477 (void) sprintf(buf
, "Could not open %s", fname
);
481 if (find_svc(fp
, tp
->t_tag
, svctag
)) {
483 /* special case of tag only */
484 (void) sprintf(buf
, "Invalid request, %s already exists under %s", svctag
, tag
);
489 (void) fprintf(stderr
, "warning - %s already exists under %s - ignoring\n", svctag
, tp
->t_tag
);
498 * put in the config script, if specified
502 (void) sprintf(fname
, "%s/%s", tp
->t_tag
, svctag
);
503 if (do_config(script
, fname
)) {
504 /* do_config put out any messages */
514 (void) sprintf(fname
, "%s/%s/_pmtab", HOME
, tp
->t_tag
);
515 fp
= fopen(fname
, "a");
517 (void) sprintf(buf
, "Could not open %s", fname
);
521 (void) fprintf(fp
, "%s:%s:%s:reserved:reserved:reserved:%s#%s\n",
522 svctag
, (flags
? pflags(flags
, FALSE
) : ""), id
, pmspec
,
523 (comment
? comment
: ""));
528 * tell the SAC to to tell PM to read _pmtab
531 (void) tell_sac(tp
->t_tag
);
536 error("No services added");
543 * rem_svc - remove a service
545 * args: pmtag - tag of port monitor responsible for the service
546 * svctag - tag of the service to be removed
550 rem_svc(pmtag
, svctag
)
554 FILE *fp
; /* scratch file pointer */
555 FILE *tfp
; /* file pointer for temp file */
556 int line
; /* line number entry is on */
557 char *tname
; /* temp file name */
558 char buf
[SIZE
]; /* scratch buffer */
559 char fname
[SIZE
]; /* path to correct _pmtab */
561 fp
= fopen(SACTAB
, "r");
564 error("Could not open _sactab");
566 if (!find_pm(fp
, pmtag
)) {
567 (void) sprintf(buf
, "Invalid request, %s does not exist", pmtag
);
568 Saferrno
= E_NOEXIST
;
573 (void) sprintf(fname
, "%s/_pmtab", pmtag
);
574 (void) sprintf(buf
, "%s/%s", HOME
, fname
);
575 fp
= fopen(buf
, "r");
577 (void) sprintf(buf
, "Could not open %s/%s", HOME
, fname
);
581 if ((line
= find_svc(fp
, pmtag
, svctag
)) == 0) {
582 (void) sprintf(buf
, "Invalid request, %s does not exist under %s", svctag
, pmtag
);
583 Saferrno
= E_NOEXIST
;
586 tname
= make_tempname(fname
);
587 tfp
= open_temp(tname
);
589 if (copy_file(fp
, tfp
, 1, line
- 1)) {
590 (void) unlink(tname
);
592 error("error accessing temp file");
595 if (copy_file(fp
, tfp
, line
+ 1, -1)) {
596 (void) unlink(tname
);
598 error("error accessing temp file");
601 if (fclose(tfp
) == EOF
) {
602 (void) unlink(tname
);
604 error("error closing tempfile");
606 /* note - replace only returns if successful */
607 replace(fname
, tname
);
610 * tell the SAC to to tell PM to read _pmtab
613 if (tell_sac(pmtag
)) {
616 * if we got rid of the service, try to remove the config script too.
617 * Don't check return status since it may not have existed anyhow.
620 (void) sprintf(buf
, "%s/%s/%s", HOME
, pmtag
, svctag
);
629 * ed_svc - enable or disable a particular service
631 * args: pmtag - tag of port monitor responsible for the service
632 * svctag - tag of service to be enabled or disabled
633 * flag - operation to perform (ENABLE or DISABLE)
637 ed_svc(pmtag
, svctag
, flag
)
642 FILE *fp
; /* scratch file pointer */
643 FILE *tfp
; /* file pointer for temp file */
644 int line
; /* line number entry is on */
645 register char *from
; /* working pointer */
646 register char *to
; /* working pointer */
647 char *tname
; /* temp file name */
648 char *p
; /* scratch pointer */
649 char buf
[SIZE
]; /* scratch buffer */
650 char tbuf
[SIZE
]; /* scratch buffer */
651 char fname
[SIZE
]; /* path to correct _pmtab */
653 fp
= fopen(SACTAB
, "r");
656 error("Could not open _sactab");
658 if (!find_pm(fp
, pmtag
)) {
659 (void) sprintf(buf
, "Invalid request, %s does not exist", pmtag
);
660 Saferrno
= E_NOEXIST
;
665 (void) sprintf(fname
, "%s/_pmtab", pmtag
);
666 (void) sprintf(buf
, "%s/%s", HOME
, fname
);
667 fp
= fopen(buf
, "r");
669 (void) sprintf(buf
, "Could not open %s/%s", HOME
, fname
);
673 if ((line
= find_svc(fp
, pmtag
, svctag
)) == 0) {
674 (void) sprintf(buf
, "Invalid request, %s does not exist under %s", svctag
, pmtag
);
675 Saferrno
= E_NOEXIST
;
678 tname
= make_tempname(fname
);
679 tfp
= open_temp(tname
);
681 if (copy_file(fp
, tfp
, 1, line
- 1)) {
682 (void) unlink(tname
);
684 error("error accessing temp file");
689 * Note: find_svc above has already read and parsed this entry, thus
690 * we know it to be well-formed, so just change the flags as appropriate
693 if (fgets(buf
, SIZE
, fp
) == NULL
) {
694 (void) unlink(tname
);
696 error("error accessing temp file");
702 * copy initial portion of entry
705 p
= strchr(from
, DELIMC
);
710 * isolate and fix the flags
713 p
= strchr(from
, DELIMC
);
714 for ( ; from
< p
; ) {
723 * above we removed x flag, if this was a disable operation, stick it in
724 * and also copy the field delimiter
732 * copy the rest of the line
735 for ( ; from
< &buf
[SIZE
- 1] ;)
737 /*** *to = '\0'; BUG: Don't uncomment it ****/
739 (void) fprintf(tfp
, "%s", tbuf
);
741 if (copy_file(fp
, tfp
, line
+ 1, -1)) {
742 (void) unlink(tname
);
744 error("error accessing temp file");
747 if (fclose(tfp
) == EOF
) {
748 (void) unlink(tname
);
750 error("error closing tempfile");
752 /* note - replace only returns if successful */
753 replace(fname
, tname
);
757 * tell the SAC to to tell PM to read _pmtab
760 (void) tell_sac(pmtag
);
765 * doconf - take a config script and have it put where it belongs or
766 * output an existing one
768 * args: script - name of file containing script (if NULL, means
769 * output existing one instead)
770 * tag - tag of port monitor that is responsible for the
771 * designated service (may be null)
772 * type - type of port monitor that is responsible for the
773 * designated service (may be null)
774 * svctag - tag of service whose config script we're operating on
778 doconf(script
, tag
, type
, svctag
)
784 FILE *fp
; /* scratch file pointer */
785 int added
; /* count of config scripts added */
786 struct taglist tl
; /* 'list' for degenerate case (1 PM) */
787 register struct taglist
*tp
= NULL
; /* working pointer */
788 char buf
[SIZE
]; /* scratch buffer */
789 char fname
[SIZE
]; /* scratch buffer for names */
791 fp
= fopen(SACTAB
, "r");
794 error("Could not open _sactab");
796 if (tag
&& !find_pm(fp
, tag
)) {
797 (void) sprintf(buf
, "Invalid request, %s does not exist", tag
);
798 Saferrno
= E_NOEXIST
;
801 if (type
&& !(tp
= find_type(fp
, type
))) {
802 (void) sprintf(buf
, "Invalid request, %s does not exist", type
);
803 Saferrno
= E_NOEXIST
;
811 * treat the case of 1 PM as a degenerate case of a list of PMs from a
812 * type specification. Build the 'list' here.
817 (void) strcpy(tp
->t_tag
, tag
);
822 (void) sprintf(fname
, "%s/%s/_pmtab", HOME
, tp
->t_tag
);
823 fp
= fopen(fname
, "r");
825 (void) sprintf(buf
, "Could not open %s", fname
);
829 if (!find_svc(fp
, tp
->t_tag
, svctag
)) {
831 /* special case of tag only */
832 (void) sprintf(buf
, "Invalid request, %s does not exist under %s", svctag
, tag
);
833 Saferrno
= E_NOEXIST
;
837 (void) fprintf(stderr
, "warning - %s does not exist under %s - ignoring\n", svctag
, tp
->t_tag
);
838 Saferrno
= E_NOEXIST
;
846 (void) sprintf(fname
, "%s/%s", tp
->t_tag
, svctag
);
849 * do_config does all the real work (keep track if any errors occurred)
852 if (do_config(script
, fname
) == 0)
858 error("No configuration scripts installed");
865 * tell_sac - use sacadm to tell the sac to tell a port monitor to read
866 * its _pmtab. Return TRUE on success, FALSE on failure.
868 * args: tag - tag of port monitor to be notified
875 pid_t pid
; /* returned pid from fork */
876 int status
; /* return status from sacadm child */
878 if ((pid
= fork()) < 0) {
879 (void) fprintf(stderr
, "warning - fork failed - could not notify <%s> about modified table\n", tag
);
880 (void) fprintf(stderr
, "try executing the command \"sacadm -x -p %s\"\n", tag
);
886 (void) wait(&status
);
888 if (((status
>> 8) & 0xff) == E_PMNOTRUN
) {
889 (void) fprintf(stderr
, "warning - port monitor, %s is not running\n", tag
);
892 if (((status
>> 8) & 0xff) == E_SACNOTRUN
) {
893 Saferrno
= E_SACNOTRUN
;
897 (void) fprintf(stderr
,
898 "warning - could not notify <%s> about modified"
900 (void) fprintf(stderr
, "try executing the command"
901 " \"sacadm -x -p %s\"\n", tag
);
909 /* set IFS for security */
910 (void) putenv("IFS=\" \"");
911 /* muffle sacadm warning messages */
912 (void) fclose(stderr
);
913 (void) fopen("/dev/null", "w");
914 (void) execl("/usr/sbin/sacadm", "sacadm", "-x", "-p", tag
, 0);
917 * if we got here, it didn't work, exit status will clue in parent to
918 * put out the warning
928 * list_svcs - list information about services
930 * args: pmtag - tag of port monitor responsible for the service
932 * type - type of port monitor responsible for the service
934 * svctag - tag of service to be listed (may be null)
935 * oflag - true if output should be easily parseable
939 list_svcs(pmtag
, type
, svctag
, oflag
)
944 FILE *fp
; /* scratch file pointer */
945 register struct taglist
*tp
; /* pointer to PM list */
946 int nprint
= 0; /* count # of svcs printed */
947 struct pmtab pmtab
; /* place to hold parsed info */
948 register struct pmtab
*pp
= &pmtab
; /* and a pointer to it */
949 register char *p
; /* working pointer */
950 char buf
[SIZE
]; /* scratch buffer */
951 char fname
[SIZE
]; /* scratch buffer for building names */
953 fp
= fopen(SACTAB
, "r");
956 error("Could not open _sactab");
958 if (pmtag
&& !find_pm(fp
, pmtag
)) {
959 (void) sprintf(buf
, "Invalid request, %s does not exist", pmtag
);
960 Saferrno
= E_NOEXIST
;
965 tp
= find_type(fp
, type
);
967 (void) sprintf(buf
, "Invalid request, %s does not exist", type
);
968 Saferrno
= E_NOEXIST
;
973 tp
= find_type(fp
, NULL
);
977 if (pmtag
&& strcmp(tp
->t_tag
, pmtag
)) {
978 /* not interested in this port monitor */
982 (void) sprintf(fname
, "%s/%s/_pmtab", HOME
, tp
->t_tag
);
983 fp
= fopen(fname
, "r");
985 (void) sprintf(buf
, "Could not open %s", fname
);
989 while (fgets(buf
, SIZE
, fp
)) {
993 parseline(p
, pp
, tp
->t_tag
);
994 if (!svctag
|| !strcmp(pp
->p_tag
, svctag
)) {
996 (void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s#%s\n",
997 tp
->t_tag
, tp
->t_type
, pp
->p_tag
,
998 pflags(pp
->p_flags
, FALSE
),
999 pp
->p_id
, pp
->p_res1
, pp
->p_res2
,
1000 pp
->p_res3
,pp
->p_pmspec
, Comment
);
1004 (void) printf("PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>\n");
1006 (void) printf("%-14s %-14s %-14s %-4s %-8s %s #%s\n", tp
->t_tag
, tp
->t_type
, pp
->p_tag
,
1007 pflags(pp
->p_flags
, TRUE
), pp
->p_id
, pspec(pp
->p_pmspec
), Comment
);
1013 (void) sprintf(buf
, "error reading %s", fname
);
1014 Saferrno
= E_SYSERR
;
1022 /* if we didn't find any valid ones, indicate an error */
1025 (void) fprintf(stderr
, "Service <%s> does not exist\n", svctag
);
1027 (void) fprintf(stderr
, "No services defined\n");
1028 Saferrno
= E_NOEXIST
;
1035 * find_svc - find an entry in _pmtab for a particular service tag
1037 * args: fp - file pointer for _pmtab
1038 * tag - port monitor tag (for error reporting)
1039 * svctag - tag of service we're looking for
1043 find_svc(FILE *fp
, char *tag
, char *svctag
)
1045 register char *p
; /* working pointer */
1046 int line
= 0; /* line number we found entry on */
1047 struct pmtab pmtab
; /* place to hold parsed info */
1048 static char buf
[SIZE
]; /* scratch buffer */
1050 while (fgets(buf
, SIZE
, fp
)) {
1055 parseline(p
, &pmtab
, tag
);
1056 if (!(strcmp(pmtab
.p_tag
, svctag
)))
1060 (void) sprintf(buf
, "error reading %s/%s/_pmtab", HOME
, tag
);
1061 Saferrno
= E_SYSERR
;
1071 * parseline - parse a line from _pmtab. This routine will return if the
1072 * parse wa successful, otherwise it will output an error and
1075 * args: p - pointer to the data read from the file (note - this is
1076 * a static data region, so we can point into it)
1077 * pp - pointer to a structure in which the separated fields
1079 * tag - port monitor tag (for error reporting)
1081 * A line in the file has the following format:
1083 * tag:flags:identity:reserved:reserved:reserved:PM_spec_info # comment
1088 parseline(p
, pp
, tag
)
1090 register struct pmtab
*pp
;
1093 char buf
[SIZE
]; /* scratch buffer */
1096 * get the service tag
1099 p
= nexttok(p
, DELIM
, FALSE
);
1101 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1102 Saferrno
= E_SAFERR
;
1105 if (strlen(p
) > PMTAGSIZE
) {
1106 p
[PMTAGSIZE
] = '\0';
1107 (void) fprintf(stderr
, "tag too long, truncated to <%s>", p
);
1115 p
= nexttok(NULL
, DELIM
, FALSE
);
1117 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1118 Saferrno
= E_SAFERR
;
1125 pp
->p_flags
|= U_FLAG
;
1128 pp
->p_flags
|= X_FLAG
;
1131 (void) sprintf(buf
, "Unrecognized flag <%c>", *(p
- 1));
1132 Saferrno
= E_SAFERR
;
1142 p
= nexttok(NULL
, DELIM
, FALSE
);
1144 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1145 Saferrno
= E_SAFERR
;
1151 * get the first reserved field
1154 p
= nexttok(NULL
, DELIM
, FALSE
);
1156 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1157 Saferrno
= E_SAFERR
;
1163 * get the second reserved field
1166 p
= nexttok(NULL
, DELIM
, FALSE
);
1168 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1169 Saferrno
= E_SAFERR
;
1175 * get the third reserved field
1178 p
= nexttok(NULL
, DELIM
, FALSE
);
1180 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1181 Saferrno
= E_SAFERR
;
1187 * the rest is the port monitor specific info
1190 p
= nexttok(NULL
, DELIM
, TRUE
);
1192 (void) sprintf(buf
, "%s/%s/_pmtab is corrupt", HOME
, tag
);
1193 Saferrno
= E_SAFERR
;
1202 * pspec - format port monitor specific information
1204 * args: spec - port monitor specific info, separated by
1205 * field separater character (may be escaped by \)
1212 static char buf
[SIZE
]; /* returned string */
1213 register char *from
; /* working pointer */
1214 register char *to
; /* working pointer */
1215 int newflag
; /* flag indicating new field */
1231 if (*(from
+ 1) == ':') {
1251 * pflags - put service flags into intelligible form for output
1253 * args: flags - binary representation of flags
1254 * dflag - true if a "-" should be returned if no flags
1258 pflags(flags
, dflag
)
1262 register int i
; /* scratch counter */
1263 static char buf
[SIZE
]; /* formatted flags */
1272 if (flags
& U_FLAG
) {
1276 if (flags
& X_FLAG
) {
1281 Saferrno
= E_SAFERR
;
1282 error("Internal error in pflags");
1290 * find_type - find entries in _sactab for a particular port monitor type
1292 * args: fp - file pointer for _sactab
1293 * type - type of port monitor we're looking for (if type is
1294 * null, it means find all PMs)
1302 register char *p
; /* working pointer */
1303 struct sactab stab
; /* place to hold parsed info */
1304 register struct sactab
*sp
= &stab
; /* and a pointer to it */
1305 char buf
[SIZE
]; /* scratch buffer */
1306 struct taglist
*thead
; /* linked list of tags */
1307 register struct taglist
*temp
; /* scratch pointer */
1310 while (fgets(buf
, SIZE
, fp
)) {
1315 if ((type
== NULL
) || !(strcmp(sp
->sc_type
, type
))) {
1316 temp
= (struct taglist
*) malloc(sizeof(struct taglist
));
1318 Saferrno
= E_SYSERR
;
1319 error("malloc failed");
1321 temp
->t_next
= thead
;
1322 (void) strcpy(temp
->t_tag
, sp
->sc_tag
);
1323 (void) strcpy(temp
->t_type
, sp
->sc_type
);
1328 Saferrno
= E_SYSERR
;
1329 error("error reading _sactab");
1333 return (thead
? thead
: NULL
);