#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include "extern.h"
#include "misc.h"
#include <sac.h>
#include "structs.h"
#define ADD 0x1
#define REMOVE 0x2
#define ENABLE 0x4
#define DISABLE 0x8
#define PLIST 0x10
#define LIST 0x20
#define CONFIG 0x40
# define U_FLAG 0x1
# define X_FLAG 0x2
char *pflags();
char *pspec();
struct taglist *find_type();
void usage();
void parseline();
void add_svc();
void rem_svc();
void ed_svc();
void list_svcs();
void doconf();
struct pmtab {
char *p_tag;
long p_flags;
char *p_id;
char *p_res1;
char *p_res2;
char *p_res3;
char *p_pmspec;
};
struct taglist {
struct taglist *t_next;
char t_tag[PMTAGSIZE + 1];
char t_type[PMTYPESIZE + 1];
};
# define NOTPRIV "User not privileged for operation"
# define BADINP "Embedded newlines not allowed"
int Saferrno;
int
main(int argc, char *argv[])
{
int c;
int ret;
uid_t uid;
int flag = 0;
int errflg = 0;
int badcnt = 0;
int version = -1;
int sawaflag = 0;
int conflag = 0;
long flags = 0;
char *pmtag = NULL;
char *type = NULL;
char *script = NULL;
char *comment = " ";
char *id = NULL;
char *svctag = NULL;
char *pmspec = NULL;
char badargs[SIZE];
char buf[SIZE];
register char *p;
if (argc == 1)
usage(argv[0]);
while ((c = getopt(argc, argv, "adef:gi:Llm:p:rs:t:v:y:z:")) != -1) {
switch (c) {
case 'a':
flag |= ADD;
sawaflag = 1;
break;
case 'd':
flag |= DISABLE;
break;
case 'e':
flag |= ENABLE;
break;
case 'f':
flag |= ADD;
while (*optarg) {
switch (*optarg++) {
case 'u':
flags |= U_FLAG;
break;
case 'x':
flags |= X_FLAG;
break;
default:
badargs[badcnt++] = *(optarg - 1);
break;
}
}
badargs[badcnt] = '\0';
break;
case 'g':
flag |= CONFIG;
break;
case 'i':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
flag |= ADD;
id = optarg;
break;
case 'L':
flag |= LIST;
break;
case 'l':
flag |= PLIST;
break;
case 'm':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
if (*optarg == '\0') {
errflg++;
break;
}
flag |= ADD;
pmspec = optarg;
break;
case 'p':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
pmtag = optarg;
if (strlen(pmtag) > PMTAGSIZE) {
pmtag[PMTAGSIZE] = '\0';
(void) fprintf(stderr, "tag too long, truncated to <%s>\n", pmtag);
}
for (p = pmtag; *p; p++) {
if (!isalnum(*p)) {
Saferrno = E_BADARGS;
error("port monitor tag must be alphanumeric");
}
}
break;
case 'r':
flag |= REMOVE;
break;
case 's':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
svctag = optarg;
if (strlen(svctag) > SVCTAGSIZE) {
svctag[SVCTAGSIZE] = '\0';
(void) fprintf(stderr, "svctag too long, truncated to <%s>\n", svctag);
}
for (p = svctag; *p; p++) {
if (!isalnum(*p)) {
Saferrno = E_BADARGS;
error("service tag must be alphanumeric");
}
}
break;
case 't':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
type = optarg;
if (strlen(type) > PMTYPESIZE) {
type[PMTYPESIZE] = '\0';
(void) fprintf(stderr, "type too long, truncated to <%s>\n", type);
}
for (p = type; *p; p++) {
if (!isalnum(*p)) {
Saferrno = E_BADARGS;
error("port monitor type must be alphanumeric");
}
}
break;
case 'v':
flag |= ADD;
version = atoi(optarg);
if (version < 0) {
Saferrno = E_BADARGS;
error("version number can not be negative");
}
break;
case 'y':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
flag |= ADD;
comment = optarg;
break;
case 'z':
if (strchr(optarg, '\n')) {
Saferrno = E_BADARGS;
error(BADINP);
}
script = optarg;
break;
case '?':
errflg++;
}
}
if (errflg || (optind < argc))
usage(argv[0]);
if (badcnt) {
(void) sprintf(buf, "Invalid request, %s are not valid arguments for \"-f\"", badargs);
Saferrno = E_BADARGS;
error(buf);
}
uid = getuid();
if ((ret = check_version(VERSION, SACTAB)) == 1) {
Saferrno = E_SAFERR;
error("_sactab version number is incorrect");
}
else if (ret == 2) {
(void) sprintf(buf, "could not open %s", SACTAB);
Saferrno = E_SYSERR;
error(buf);
}
else if (ret == 3) {
(void) sprintf(buf, "%s file is corrupt", SACTAB);
Saferrno = E_SAFERR;
error(buf);
}
switch (flag) {
case ADD:
if (uid) {
Saferrno = E_NOPRIV;
error(NOTPRIV);
}
if (!sawaflag || (pmtag && type) || (!pmtag && !type) || !svctag || !id || !pmspec || (version < 0))
usage(argv[0]);
add_svc(pmtag, type, svctag, id, pmspec, flags, version, comment, script);
break;
case REMOVE:
if (uid) {
Saferrno = E_NOPRIV;
error(NOTPRIV);
}
if (!pmtag || !svctag || type || script)
usage(argv[0]);
rem_svc(pmtag, svctag);
break;
case ENABLE:
if (uid) {
Saferrno = E_NOPRIV;
error(NOTPRIV);
}
if (!pmtag || !svctag || type || script)
usage(argv[0]);
ed_svc(pmtag, svctag, ENABLE);
break;
case DISABLE:
if (uid) {
Saferrno = E_NOPRIV;
error(NOTPRIV);
}
if (!pmtag || !svctag || type || script)
usage(argv[0]);
ed_svc(pmtag, svctag, DISABLE);
break;
case LIST:
conflag = 1;
case PLIST:
if ((pmtag && type) || script)
usage(argv[0]);
list_svcs(pmtag, type, svctag, conflag);
break;
case CONFIG:
if (script && uid) {
Saferrno = E_NOPRIV;
error(NOTPRIV);
}
if ((pmtag && type) || (!pmtag && !type) || !svctag || (type && !script))
usage(argv[0]);
doconf(script, pmtag, type, svctag);
break;
default:
usage(argv[0]);
}
quit();
}
void
usage(cmdname)
char *cmdname;
{
(void) fprintf(stderr, "Usage:\t%s -a [ -p pmtag | -t type ] -s svctag -i id -m \"pmspecific\"\n", cmdname);
(void) fprintf(stderr, "\t\t-v version [ -f xu ] [ -y comment ] [ -z script]\n");
(void) fprintf(stderr, "\t%s -r -p pmtag -s svctag\n", cmdname);
(void) fprintf(stderr, "\t%s -e -p pmtag -s svctag\n", cmdname);
(void) fprintf(stderr, "\t%s -d -p pmtag -s svctag\n", cmdname);
(void) fprintf(stderr, "\t%s -l [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
(void) fprintf(stderr, "\t%s -L [ -p pmtag | -t type ] [ -s svctag ]\n", cmdname);
(void) fprintf(stderr, "\t%s -g -p pmtag -s svctag [ -z script ]\n", cmdname);
(void) fprintf(stderr, "\t%s -g -s svctag -t type -z script\n", cmdname);
Saferrno = E_BADARGS;
quit();
}
void
add_svc(tag, type, svctag, id, pmspec, flags, version, comment, script)
char *tag;
char *type;
char *svctag;
char *id;
char *pmspec;
long flags;
int version;
char *comment;
char *script;
{
FILE *fp;
struct taglist tl;
register struct taglist *tp = NULL;
int ret;
char buf[SIZE];
char fname[SIZE];
int added;
fp = fopen(SACTAB, "r");
if (fp == NULL) {
Saferrno = E_SYSERR;
error("Could not open _sactab");
}
if (tag && !find_pm(fp, tag)) {
(void) sprintf(buf, "Invalid request, %s does not exist", tag);
Saferrno = E_NOEXIST;
error(buf);
}
if (type && !(tp = find_type(fp, type))) {
(void) sprintf(buf, "Invalid request, %s does not exist", type);
Saferrno = E_NOEXIST;
error(buf);
}
(void) fclose(fp);
if (tag) {
tp = &tl;
tp->t_next = NULL;
(void) strcpy(tp->t_tag, tag);
}
added = 0;
while (tp) {
(void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
if ((ret = check_version(version, fname)) == 1) {
(void) sprintf(buf, "%s version number is incorrect", fname);
Saferrno = E_SAFERR;
error(buf);
}
else if (ret == 2) {
(void) sprintf(buf, "could not open %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
else if (ret == 3) {
(void) sprintf(buf, "%s file is corrupt", fname);
Saferrno = E_SAFERR;
error(buf);
}
fp = fopen(fname, "r");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
if (find_svc(fp, tp->t_tag, svctag)) {
if (tag) {
(void) sprintf(buf, "Invalid request, %s already exists under %s", svctag, tag);
Saferrno = E_DUP;
error(buf);
}
else {
(void) fprintf(stderr, "warning - %s already exists under %s - ignoring\n", svctag, tp->t_tag);
tp = tp->t_next;
(void) fclose(fp);
continue;
}
}
(void) fclose(fp);
if (script) {
(void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
if (do_config(script, fname)) {
tp = tp->t_next;
continue;
}
}
(void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
fp = fopen(fname, "a");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
(void) fprintf(fp, "%s:%s:%s:reserved:reserved:reserved:%s#%s\n",
svctag, (flags ? pflags(flags, FALSE) : ""), id, pmspec,
(comment ? comment : ""));
(void) fclose(fp);
added++;
(void) tell_sac(tp->t_tag);
tp = tp->t_next;
}
if (added == 0) {
Saferrno = E_SAFERR;
error("No services added");
}
return;
}
void
rem_svc(pmtag, svctag)
char *pmtag;
char *svctag;
{
FILE *fp;
FILE *tfp;
int line;
char *tname;
char buf[SIZE];
char fname[SIZE];
fp = fopen(SACTAB, "r");
if (fp == NULL) {
Saferrno = E_SYSERR;
error("Could not open _sactab");
}
if (!find_pm(fp, pmtag)) {
(void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
Saferrno = E_NOEXIST;
error(buf);
}
(void) fclose(fp);
(void) sprintf(fname, "%s/_pmtab", pmtag);
(void) sprintf(buf, "%s/%s", HOME, fname);
fp = fopen(buf, "r");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s/%s", HOME, fname);
Saferrno = E_SYSERR;
error(buf);
}
if ((line = find_svc(fp, pmtag, svctag)) == 0) {
(void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
Saferrno = E_NOEXIST;
error(buf);
}
tname = make_tempname(fname);
tfp = open_temp(tname);
if (line != 1) {
if (copy_file(fp, tfp, 1, line - 1)) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error accessing temp file");
}
}
if (copy_file(fp, tfp, line + 1, -1)) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error accessing temp file");
}
(void) fclose(fp);
if (fclose(tfp) == EOF) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error closing tempfile");
}
replace(fname, tname);
if (tell_sac(pmtag)) {
(void) sprintf(buf, "%s/%s/%s", HOME, pmtag, svctag);
(void) unlink(buf);
return;
}
}
void
ed_svc(pmtag, svctag, flag)
char *pmtag;
char *svctag;
int flag;
{
FILE *fp;
FILE *tfp;
int line;
register char *from;
register char *to;
char *tname;
char *p;
char buf[SIZE];
char tbuf[SIZE];
char fname[SIZE];
fp = fopen(SACTAB, "r");
if (fp == NULL) {
Saferrno = E_SYSERR;
error("Could not open _sactab");
}
if (!find_pm(fp, pmtag)) {
(void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
Saferrno = E_NOEXIST;
error(buf);
}
(void) fclose(fp);
(void) sprintf(fname, "%s/_pmtab", pmtag);
(void) sprintf(buf, "%s/%s", HOME, fname);
fp = fopen(buf, "r");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s/%s", HOME, fname);
Saferrno = E_SYSERR;
error(buf);
}
if ((line = find_svc(fp, pmtag, svctag)) == 0) {
(void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, pmtag);
Saferrno = E_NOEXIST;
error(buf);
}
tname = make_tempname(fname);
tfp = open_temp(tname);
if (line != 1) {
if (copy_file(fp, tfp, 1, line - 1)) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error accessing temp file");
}
}
if (fgets(buf, SIZE, fp) == NULL) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error accessing temp file");
}
from = buf;
to = tbuf;
p = strchr(from, DELIMC);
for ( ; from <= p; )
*to++ = *from++;
p = strchr(from, DELIMC);
for ( ; from < p; ) {
if (*from == 'x') {
from++;
continue;
}
*to++ = *from++;
}
if (flag == DISABLE)
*to++ = 'x';
*to++ = *from++;
for ( ; from < &buf[SIZE - 1] ;)
*to++ = *from++;
(void) fprintf(tfp, "%s", tbuf);
if (copy_file(fp, tfp, line + 1, -1)) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error accessing temp file");
}
(void) fclose(fp);
if (fclose(tfp) == EOF) {
(void) unlink(tname);
Saferrno = E_SYSERR;
error("error closing tempfile");
}
replace(fname, tname);
(void) tell_sac(pmtag);
}
void
doconf(script, tag, type, svctag)
char *script;
char *tag;
char *type;
char *svctag;
{
FILE *fp;
int added;
struct taglist tl;
register struct taglist *tp = NULL;
char buf[SIZE];
char fname[SIZE];
fp = fopen(SACTAB, "r");
if (fp == NULL) {
Saferrno = E_SYSERR;
error("Could not open _sactab");
}
if (tag && !find_pm(fp, tag)) {
(void) sprintf(buf, "Invalid request, %s does not exist", tag);
Saferrno = E_NOEXIST;
error(buf);
}
if (type && !(tp = find_type(fp, type))) {
(void) sprintf(buf, "Invalid request, %s does not exist", type);
Saferrno = E_NOEXIST;
error(buf);
}
(void) fclose(fp);
if (tag) {
tp = &tl;
tp->t_next = NULL;
(void) strcpy(tp->t_tag, tag);
}
added = 0;
while (tp) {
(void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
fp = fopen(fname, "r");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
if (!find_svc(fp, tp->t_tag, svctag)) {
if (tag) {
(void) sprintf(buf, "Invalid request, %s does not exist under %s", svctag, tag);
Saferrno = E_NOEXIST;
error(buf);
}
else {
(void) fprintf(stderr, "warning - %s does not exist under %s - ignoring\n", svctag, tp->t_tag);
Saferrno = E_NOEXIST;
tp = tp->t_next;
(void) fclose(fp);
continue;
}
}
(void) fclose(fp);
(void) sprintf(fname, "%s/%s", tp->t_tag, svctag);
if (do_config(script, fname) == 0)
added++;
tp = tp->t_next;
}
if (added == 0) {
Saferrno = E_SAFERR;
error("No configuration scripts installed");
}
return;
}
int
tell_sac(char *tag)
{
pid_t pid;
int status;
if ((pid = fork()) < 0) {
(void) fprintf(stderr, "warning - fork failed - could not notify <%s> about modified table\n", tag);
(void) fprintf(stderr, "try executing the command \"sacadm -x -p %s\"\n", tag);
Saferrno = E_SYSERR;
return(FALSE);
}
else if (pid) {
(void) wait(&status);
if (status) {
if (((status >> 8) & 0xff) == E_PMNOTRUN) {
(void) fprintf(stderr, "warning - port monitor, %s is not running\n", tag);
return (FALSE);
}
if (((status >> 8) & 0xff) == E_SACNOTRUN) {
Saferrno = E_SACNOTRUN;
} else {
Saferrno = E_SYSERR;
}
(void) fprintf(stderr,
"warning - could not notify <%s> about modified"
" table\n", tag);
(void) fprintf(stderr, "try executing the command"
" \"sacadm -x -p %s\"\n", tag);
return(FALSE);
}
else {
return(TRUE);
}
}
else {
(void) putenv("IFS=\" \"");
(void) fclose(stderr);
(void) fopen("/dev/null", "w");
(void) execl("/usr/sbin/sacadm", "sacadm", "-x", "-p", tag, 0);
exit(1);
}
}
void
list_svcs(char *pmtag, char *type, char *svctag, int oflag)
{
FILE *fp;
register struct taglist *tp;
int nprint = 0;
struct pmtab pmtab;
register struct pmtab *pp = &pmtab;
register char *p;
char buf[SIZE];
char fname[SIZE];
fp = fopen(SACTAB, "r");
if (fp == NULL) {
Saferrno = E_SYSERR;
error("Could not open _sactab");
}
if (pmtag && !find_pm(fp, pmtag)) {
(void) sprintf(buf, "Invalid request, %s does not exist", pmtag);
Saferrno = E_NOEXIST;
error(buf);
}
rewind(fp);
if (type) {
tp = find_type(fp, type);
if (tp == NULL) {
(void) sprintf(buf, "Invalid request, %s does not exist", type);
Saferrno = E_NOEXIST;
error(buf);
}
}
else
tp = find_type(fp, NULL);
(void) fclose(fp);
while (tp) {
if (pmtag && strcmp(tp->t_tag, pmtag)) {
tp = tp->t_next;
continue;
}
(void) sprintf(fname, "%s/%s/_pmtab", HOME, tp->t_tag);
fp = fopen(fname, "r");
if (fp == NULL) {
(void) sprintf(buf, "Could not open %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
while (fgets(buf, SIZE, fp)) {
p = trim(buf);
if (*p == '\0')
continue;
parseline(p, pp, tp->t_tag);
if (!svctag || !strcmp(pp->p_tag, svctag)) {
if (oflag) {
(void) printf("%s:%s:%s:%s:%s:%s:%s:%s:%s#%s\n",
tp->t_tag, tp->t_type, pp->p_tag,
pflags(pp->p_flags, FALSE),
pp->p_id, pp->p_res1, pp->p_res2,
pp->p_res3,pp->p_pmspec, Comment);
}
else {
if (nprint == 0) {
(void) printf("PMTAG PMTYPE SVCTAG FLGS ID <PMSPECIFIC>\n");
}
(void) printf("%-14s %-14s %-14s %-4s %-8s %s #%s\n", tp->t_tag, tp->t_type, pp->p_tag,
pflags(pp->p_flags, TRUE), pp->p_id, pspec(pp->p_pmspec), Comment);
}
nprint++;
}
}
if (!feof(fp)) {
(void) sprintf(buf, "error reading %s", fname);
Saferrno = E_SYSERR;
error(buf);
}
else {
(void) fclose(fp);
tp = tp->t_next;
}
}
if (nprint == 0) {
if (svctag)
(void) fprintf(stderr, "Service <%s> does not exist\n", svctag);
else
(void) fprintf(stderr, "No services defined\n");
Saferrno = E_NOEXIST;
}
return;
}
int
find_svc(FILE *fp, char *tag, char *svctag)
{
register char *p;
int line = 0;
struct pmtab pmtab;
static char buf[SIZE];
while (fgets(buf, SIZE, fp)) {
line++;
p = trim(buf);
if (*p == '\0')
continue;
parseline(p, &pmtab, tag);
if (!(strcmp(pmtab.p_tag, svctag)))
return(line);
}
if (!feof(fp)) {
(void) sprintf(buf, "error reading %s/%s/_pmtab", HOME, tag);
Saferrno = E_SYSERR;
error(buf);
return (0);
} else
return (0);
}
void
parseline(p, pp, tag)
register char *p;
register struct pmtab *pp;
char *tag;
{
char buf[SIZE];
p = nexttok(p, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
if (strlen(p) > PMTAGSIZE) {
p[PMTAGSIZE] = '\0';
(void) fprintf(stderr, "tag too long, truncated to <%s>", p);
}
pp->p_tag = p;
p = nexttok(NULL, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_flags = 0;
while (*p) {
switch (*p++) {
case 'u':
pp->p_flags |= U_FLAG;
break;
case 'x':
pp->p_flags |= X_FLAG;
break;
default:
(void) sprintf(buf, "Unrecognized flag <%c>", *(p - 1));
Saferrno = E_SAFERR;
error(buf);
break;
}
}
p = nexttok(NULL, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_id = p;
p = nexttok(NULL, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_res1 = p;
p = nexttok(NULL, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_res2 = p;
p = nexttok(NULL, DELIM, FALSE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_res3 = p;
p = nexttok(NULL, DELIM, TRUE);
if (p == NULL) {
(void) sprintf(buf, "%s/%s/_pmtab is corrupt", HOME, tag);
Saferrno = E_SAFERR;
error(buf);
}
pp->p_pmspec = p;
return;
}
char *
pspec(spec)
char *spec;
{
static char buf[SIZE];
register char *from;
register char *to;
int newflag;
to = buf;
from = spec;
newflag = 1;
while (*from) {
switch (*from) {
case ':':
if (newflag) {
*to++ = '-';
}
*to++ = ' ';
from++;
newflag = 1;
break;
case '\\':
if (*(from + 1) == ':') {
*to++ = ':';
from += 2;
}
else
*to++ = *from++;
newflag = 0;
break;
default:
newflag = 0;
*to++ = *from++;
}
}
*to = '\0';
return(buf);
}
char *
pflags(flags, dflag)
long flags;
int dflag;
{
register int i;
static char buf[SIZE];
if (flags == 0) {
if (dflag)
return("-");
else
return("");
}
i = 0;
if (flags & U_FLAG) {
buf[i++] = 'u';
flags &= ~U_FLAG;
}
if (flags & X_FLAG) {
buf[i++] = 'x';
flags &= ~X_FLAG;
}
if (flags) {
Saferrno = E_SAFERR;
error("Internal error in pflags");
}
buf[i] = '\0';
return(buf);
}
struct taglist *
find_type(fp, type)
FILE *fp;
char *type;
{
register char *p;
struct sactab stab;
register struct sactab *sp = &stab;
char buf[SIZE];
struct taglist *thead;
register struct taglist *temp;
thead = NULL;
while (fgets(buf, SIZE, fp)) {
p = trim(buf);
if (*p == '\0')
continue;
parse(p, sp);
if ((type == NULL) || !(strcmp(sp->sc_type, type))) {
temp = (struct taglist *) malloc(sizeof(struct taglist));
if (temp == NULL) {
Saferrno = E_SYSERR;
error("malloc failed");
}
temp->t_next = thead;
(void) strcpy(temp->t_tag, sp->sc_tag);
(void) strcpy(temp->t_type, sp->sc_type);
thead = temp;
}
}
if (!feof(fp)) {
Saferrno = E_SYSERR;
error("error reading _sactab");
return (0);
} else
return (thead ? thead : NULL);
}