Files
Arquivotheca.Solaris-2.5/cmd/backup/lib/config.c
seta75D 7c4988eac0 Init
2021-10-11 19:38:01 -03:00

1577 lines
32 KiB
C
Executable File

/*LINTLIBRARY*/
/*PROTOLIB1*/
#ident "@(#)config.c 1.0 90/12/07 SMI"
#ident "@(#)config.c 1.37 94/08/10"
/*
* Copyright (c) 1990,1991,1992 by Sun Microsystems, Inc.
*/
#include <config.h>
#include <metamucil.h>
#include <locale.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <malloc.h>
#include <errno.h>
#include <netdb.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#ifdef USG
#include <sys/utsname.h>
#include <sys/systeminfo.h>
#endif
/*
* This should be passed in from the Makefile.
* This is just CYA in case it isn't.
*/
#ifndef HSMROOT
#define HSMROOT "/opt/SUNWhsm"
#endif
struct fs_params {
char *fs_name; /* file system name */
char *fs_lock; /* file system lock type */
struct active {
int a_retries; /* number of retries */
u_long a_size; /* size threshhold */
int a_report; /* =1 if message should be produced */
struct active *a_next; /* next on list */
} *fs_active; /* activity commands */
int fs_online; /* =1 if online dumps should be done */
int fs_reset; /* =1 if hide user access changes */
struct fs_params *fs_next; /* next on list */
};
typedef struct fs_params fsparm_t;
struct logical_device {
char *ld_name; /* device name */
dtype_t ld_type; /* logical device type */
char **ld_drives; /* list of physical devices */
char **ld_current; /* current physical device name */
int ld_wrapped; /* number of times device used */
struct logical_device *ld_next; /* next on list */
};
typedef struct logical_device ldev_t;
struct cmd {
char *c_name; /* command name */
#ifdef __STDC__
int (*c_func)(char *); /* function */
#else
int (*c_func)() /* function */
#endif
};
#ifdef __STDC__
void createdefaultfs(int);
static int set_active(char *);
static int set_database(char *);
static int set_filesystem(char *);
static int set_lock(char *);
static int set_reset(char *);
static int set_mail(char *);
static int set_operd(char *);
static int set_sequence(char *);
static int set_tmpdir(char *);
static int set_online(char *);
#else
void createdefaultfs();
static int set_active();
static int set_database();
static int set_filesystem();
static int set_lock();
static int set_reset();
static int set_mail();
static int set_operd();
static int set_sequence();
static int set_tmpdir();
static int set_online();
#endif
static struct cmd cmdtab[] = {
{
"active",
set_active
},
{
"database",
set_database
},
{
"filesystem",
set_filesystem
},
{
"lock",
set_lock
},
{
"reset",
set_reset
},
{
"mail",
set_mail
},
{
"operd",
set_operd
},
{
"sequence",
set_sequence
},
{
"tmpdir",
set_tmpdir
},
{
"online",
set_online
}
};
static int ncmds = sizeof (cmdtab)/sizeof (struct cmd);
static struct active default_active[] = {
0, /* don't recopy */
0, /* regardless of size */
1, /* instead, notify */
NULL /* no other commands */
};
static fsparm_t default_fs = {
"default",
"scan",
default_active,
1,
1,
NULL
};
static fsparm_t *fslist; /* file system parameter list */
static char *default_dirs[] = { /* list of temporary directories */
TMPDIR,
0
};
static char **tmpdirlist = default_dirs;
static ldev_t *devlist; /* list of logical devices */
static ldev_t *current_dev; /* logical device currently in use */
static fsparm_t *current_fs; /* current file system */
static char **maillist; /* mail notification list */
static char opserver[BCHOSTNAMELEN] = "localhost"; /* operator daemon */
static char dbserver[BCHOSTNAMELEN] = "localhost"; /* database daemon */
static char hostname[BCHOSTNAMELEN]; /* our name */
static int lineno = 0; /* current line number in dump.config */
static char *errstr;
static int commentsok; /* interpret '#' as comment char */
/*
* For dgettext()
*/
static char *domainname = "hsm_libdump";
#ifdef __STDC__
static void printdevice(ldev_t *);
static int nstrings(char *);
static char *skip(char *);
static char **makelist(char *);
static void msg(const char *, ...);
/*
* XXX
*/
extern char *strdup(const char *);
extern int munmap(caddr_t, size_t);
extern caddr_t mmap(caddr_t, size_t, int, int, int, off_t);
extern int msync(caddr_t, size_t, int);
#else
static void printdevice();
static int nstrings();
static char *skip();
static char **makelist();
static void msg();
/*
* XXX
*/
extern char *strdup();
extern int munmap();
#endif
#ifdef __STDC__
readconfig(
char *filename, /* HSMROOT/etc/CONFIGFILE if 0 */
void (*func)(const char *, ...)) /* fprintf(stderr) if 0 */
#else
readconfig(filename, func)
char *filename; /* defaults to HSMROOT/etc/CONFIGFILE */
void (*func)(); /* defaults to fprintf(stderr) */
#endif
{
struct stat statb;
int fd;
caddr_t data;
char *cmd = NULL;
int errors = 0;
int cont = 0;
int comment = 0;
register int i;
register char *cp, *next;
#ifdef __STDC__
if (func == (void (*)(const char *, ...))0)
#else
if (func == (void (*)())0)
#endif
func = msg;
if (filename == (char *)0) {
char *etc = gethsmpath(etcdir);
filename = malloc(strlen(etc) + strlen(CONFIGFILE) + 2);
if (filename == (char *)0) {
func("out of memory");
return (0);
}
(void) sprintf(filename, "%s/%s", etc, CONFIGFILE);
}
#ifdef USG
if (sysinfo(SI_HOSTNAME, hostname, BCHOSTNAMELEN) < 0) {
#else
if (gethostname(hostname, BCHOSTNAMELEN) < 0) {
#endif
func(dgettext(domainname,
"cannot determine local host name\n"));
return (-1);
}
if ((fd = open(filename, O_RDONLY, 0)) < 0) {
if (errno != ENOENT)
return (-1);
else
return (0);
}
if (fstat(fd, &statb) < 0) {
(void) close(fd);
return (-1);
}
if (statb.st_size == 0) {
func(dgettext(domainname,
"Warning: zero-length configuration file %s ignored\n"),
filename);
(void) close(fd);
return (0);
}
data = mmap((caddr_t)0, (size_t)statb.st_size,
PROT_READ, MAP_SHARED, fd, 0L);
if (data == (caddr_t) -1) {
(void) close(fd);
return (-1);
}
commentsok++;
for (cp = next = (char *)data;
cp < &data[statb.st_size] && *cp; cp = next) {
if (cmd) {
free(cmd);
cmd = NULL;
}
while (*next) {
if (*next == '\n') {
comment = 0;
lineno++;
if (!cont) {
next++;
break;
}
cont = 0;
} else if (*next == '\\')
cont = 1;
else if (*next == '#')
comment = 1;
else if (cont && !isspace((u_char)*next) && !comment)
cont = 0;
next++;
}
cp = getstring(cp, &cmd);
if (cp == NULL)
goto error;
if (cmd == NULL)
continue;
for (i = 0; i < ncmds; i++)
if (strcmp(cmd, cmdtab[i].c_name) == 0) {
if ((*cmdtab[i].c_func)(cp) < 0)
goto error;
break;
}
if (i == ncmds)
errstr = dgettext(domainname, "unknown command");
else
continue;
error:
errors++;
func(dgettext(domainname, "error in %s, line %d: %s\n"),
filename, lineno,
errstr ? errstr : dgettext(domainname, "syntax error"));
}
commentsok = 0;
createdefaultfs(METAMUCIL);
(void) munmap(data, statb.st_size);
(void) close(fd);
return (errors);
}
void
#ifdef __STDC__
printconfig(void)
#else
printconfig()
#endif
{
register ldev_t *dev;
register fsparm_t *fsp;
register struct active *ap;
register char **cpp;
char mail[1024];
(void) fprintf(stderr, dgettext(domainname, "DATABASE SERVER: %s\n"),
dbserver);
(void) fprintf(stderr, dgettext(domainname, "OPERD SERVER: %s\n"),
opserver);
(void) fprintf(stderr, dgettext(domainname, "TEMPORARY DIRECTORIES:"));
if (tmpdirlist) {
(void) fprintf(stderr, "\n");
for (cpp = tmpdirlist; *cpp; cpp++)
(void) fprintf(stderr, " %s\n", *cpp);
} else
(void) fprintf(stderr, dgettext(domainname, " (none)\n"));
(void) getmail(mail, sizeof (mail));
(void) fprintf(stderr, dgettext(domainname, "MAIL: %s\n"),
mail[0] ? mail : dgettext(domainname, "none"));
for (dev = devlist; dev; dev = dev->ld_next)
printdevice(dev);
(void) fprintf(stderr, dgettext(domainname, "FILE SYSTEMS:\n"));
for (fsp = fslist; fsp; fsp = fsp->fs_next) {
(void) fprintf(stderr,
dgettext(domainname, " %s -- lock type %s\n"),
fsp->fs_name,
fsp->fs_lock ? fsp->fs_lock : default_fs.fs_lock);
(void) fprintf(stderr, dgettext(domainname,
" do online dumps? %s\n"),
fsp->fs_online ? "yes" : "no");
(void) fprintf(stderr, dgettext(domainname,
" hide user access time changes? %s\n"),
fsp->fs_reset ? "yes" : "no");
if (fsp->fs_active == NULL) {
(void) fprintf(stderr, dgettext(domainname,
" uses default active commands\n"));
continue;
}
(void) fprintf(stderr, dgettext(domainname,
" active commands:\n"));
for (ap = fsp->fs_active; ap; ap = ap->a_next)
(void) fprintf(stderr, dgettext(domainname,
"\ttries=%d, size=%d, report %s\n"),
ap->a_retries,
ap->a_size,
ap->a_report ? dgettext(domainname, "yes") :
dgettext(domainname, "no"));
}
}
char *
getstring(cp, bufp)
char *cp;
char **bufp;
{
char *p;
register char *op;
char *contp = (char *)0;
/*
* Find beginning of token or delimiter
*/
cp = skip(cp);
if (*cp == ',')
return (NULL);
if (*cp == '\0' || *cp == '\n') { /* end of string */
*bufp = NULL;
return (cp);
}
/*
* Find the end of the token
*/
for (p = cp; *p && !isspace((u_char)*p) && *p != ','; p++) {
if (*p == '\\')
contp = p;
else if (commentsok && *p == '#')
break;
else
contp = (char *)0;
}
if (contp)
p = contp;
*bufp = malloc((unsigned)(p + 1 - cp));
if (*bufp == NULL) {
errstr = dgettext(domainname, "out of memory");
return (NULL);
}
for (op = *bufp; cp < p; op++, cp++) {
if (*cp == '\\' && cp == contp) {
cp++;
while (cp < p && *cp != '\n')
cp++;
break;
}
*op = *cp;
}
*op = '\0';
/*
* Find end of white-space or delimiter
*/
p = skip(p);
if (*p == ',') {
p = skip(++p);
if (*p == ',' || *p == '\0' || *p == '\n')
return (NULL);
}
return (p); /* return current position */
}
char *
#ifdef __STDC__
gettmpdir(void)
#else
gettmpdir()
#endif
{
static char **tmpdir;
char *retval;
if (tmpdir == (char **)0)
tmpdir = tmpdirlist;
retval = *tmpdir;
if (*tmpdir != (char *)0)
tmpdir++;
return (retval);
}
#ifdef __STDC__
int
setdbserver(const char *host)
#else
int
setdbserver(host)
char *host;
#endif
{
struct hostent *h;
if (host == (char *)0) {
errno = EINVAL;
return (-1);
}
if (strcmp(host, "+default") == 0 && dbserver == (char *)0)
return (-1);
h = gethostbyname((char *)host);
if (h == (struct hostent *)0)
return (-1);
(void) strncpy(dbserver, host, sizeof (dbserver));
return (0);
}
int
getdbserver(buf, namelen)
char *buf;
int namelen;
{
if (buf == (char *)0 || namelen <= 0) {
errno = EINVAL;
return (-1);
}
(void) strncpy(buf, dbserver, namelen);
return (0);
}
#ifdef __STDC__
int
setopserver(const char *host)
#else
int
setopserver(host)
char *host;
#endif
{
struct hostent *h;
if (host == (char *)0) {
errno = EINVAL;
return (-1);
}
while (isspace(*host))
host++;
h = gethostbyname((char *)host);
if (h == (struct hostent *)0)
return (-1);
(void) strncpy(opserver, host, sizeof (opserver));
return (0);
}
int
getopserver(buf, namelen)
char *buf;
int namelen;
{
if (buf == (char *)0 || namelen <= 0) {
errno = EINVAL;
return (-1);
}
(void) strncpy(buf, opserver, namelen);
return (0);
}
makedevice(name, list, type)
char *name;
char *list;
dtype_t type;
{
ldev_t *dev;
errno = 0;
dev = (ldev_t *) malloc((unsigned)sizeof (ldev_t));
if (dev == NULL) {
errstr = dgettext(domainname, "out of memory");
return (-1);
}
dev->ld_name = malloc((unsigned)strlen(name)+1);
if (dev->ld_name == NULL) {
errstr = dgettext(domainname, "out of memory");
return (-1);
}
dev->ld_drives = makelist(list);
if (dev->ld_drives == NULL || dev->ld_drives[0] == NULL) {
errstr = dgettext(domainname,
"missing device list in `sequence' command");
if (errno != ENOMEM)
errno = EINVAL;
return (-1);
}
(void) strcpy(dev->ld_name, name);
dev->ld_wrapped = -1;
dev->ld_current = dev->ld_drives;
dev->ld_next = devlist;
dev->ld_type = type;
devlist = dev;
return (0);
}
static void
printdevice(dev)
ldev_t *dev;
{
register char **cpp;
if (dev == (ldev_t *)0)
return;
(void) fprintf(stderr, dgettext(domainname, "DEVICE NAME = %s\n"),
dev->ld_name);
(void) fprintf(stderr, dgettext(domainname, " COMPONENTS:\n"));
for (cpp = dev->ld_drives; *cpp; cpp++)
(void) fprintf(stderr, "\t%s\n", *cpp);
}
int
setdevice(name)
char *name;
{
ldev_t *dev;
for (dev = devlist; dev; dev = dev->ld_next)
if (strcmp(dev->ld_name, name) == 0)
break;
if (dev) {
current_dev = dev;
return (0);
}
current_dev = (ldev_t *)0;
return (-1);
}
char *
#ifdef __STDC__
getdevice(void)
#else
getdevice()
#endif
{
char *drive = *current_dev->ld_current;
if (current_dev->ld_current == current_dev->ld_drives)
current_dev->ld_wrapped++;
if (*++current_dev->ld_current == NULL)
current_dev->ld_current = current_dev->ld_drives;
return (drive);
}
/*
* Return information about the selected logical device.
* The arguments point to variables filled in with the
* device's type, number of constituent physical devices,
* and number of times the logical device has wrapped.
*/
void
getdevinfo(ptype, pdevices, pwrapped)
dtype_t *ptype;
int *pdevices;
int *pwrapped;
{
if (current_dev == (ldev_t *)0) {
if (ptype != (dtype_t *)0)
*ptype = none;
if (pdevices != (int *)0)
*pdevices = 0;
if (pwrapped != (int *)0)
*pwrapped = 0;
return;
}
if (ptype != (dtype_t *)0)
*ptype = current_dev->ld_type;
if (pdevices != (int *)0) {
register char **cpp;
int n = 0;
if (current_dev->ld_drives != (char **)0)
for (cpp = current_dev->ld_drives; *cpp; cpp++)
n++;
*pdevices = n;
}
if (pwrapped != (int *)0)
*pwrapped =
current_dev->ld_wrapped < 0 ? 0 : current_dev->ld_wrapped;
}
#ifdef __STDC__
void
setfsname(const char *name)
#else
void
setfsname(name)
char *name;
#endif
{
register struct active *ap, *last;
register fsparm_t *fsp = (fsparm_t *)0;
fsparm_t *dfs = (fsparm_t *)0;
createdefaultfs(METAMUCIL);
if (name != 0)
for (fsp = fslist; fsp; fsp = fsp->fs_next) {
if (strcmp(fsp->fs_name, name) == 0)
break;
if (dfs == (fsparm_t *)0 &&
strcmp(fsp->fs_name, "default") == 0)
dfs = fsp; /* defaults are specified */
}
if (dfs == (fsparm_t *)0)
dfs = &default_fs; /* defaults are internal */
if (fsp) {
/*
* We matched a file system by name.
* Merge in the defaults.
*/
if (fsp->fs_lock == (char *)0)
fsp->fs_lock = dfs->fs_lock;
if (fsp->fs_online == -1)
fsp->fs_online = dfs->fs_online;
if (fsp->fs_active == (struct active *)0)
fsp->fs_active = dfs->fs_active;
else {
/*
* If any active commands were specified,
* we have to determine whether we need
* to augment them with defaults. We'll
* need some defaults for file sizes between
* 0 and the lowest threshhold specified
* in the active commands.
*/
for (ap = fsp->fs_active; ap; ap = ap->a_next) {
last = ap;
if (ap->a_size <= default_active[0].a_size)
break;
}
if (ap == (struct active *)0)
last->a_next = default_active; /* augment */
}
current_fs = fsp;
} else
/*
* No match, use defaults
*/
current_fs = dfs;
}
char *
#ifdef __STDC__
getfslocktype(void)
#else
getfslocktype()
#endif
{
if (current_fs == (fsparm_t *)0) {
errno = ENOENT;
return ((char *)0);
}
return (current_fs->fs_lock);
}
int
#ifdef __STDC__
getfsreset(void)
#else
getfsreset()
#endif
{
if (current_fs == (fsparm_t *)0) {
errno = ENOENT;
return (-1);
}
return (current_fs->fs_reset);
}
/*
* For an active file of given size, return
* 1 if it should be recopied, 0 if it should
* be reported, -1 if no action is necessary.
*/
action_t
getfsaction(size, pass)
size_t size;
int pass;
{
register struct active *a, *thisa;
if (current_fs == (fsparm_t *)0) {
errno = ENOENT;
return (error);
}
/*
* Find the appropriate structure
* to determine what to do.
*/
for (a = current_fs->fs_active, thisa = NULL; a; a = a->a_next)
if (thisa == NULL ||
(size >= a->a_size && a->a_size > thisa->a_size))
thisa = a;
if (thisa == NULL)
return (error); /* this should never happen */
if (thisa->a_retries > pass)
if (thisa->a_report)
return (reportandretry);
else
return (retry);
else if (thisa->a_report)
return (report);
return (donothing);
}
void
#ifdef __STDC__
createdefaultfs(int mode)
#else
createdefaultfs(mode)
int mode;
#endif
{
static int done = 0;
register fsparm_t *fsp;
register struct active *ap, *dap;
if (done)
return;
else
done = 1;
if (mode == NOT_METAMUCIL) {
default_fs.fs_lock = "none";
default_fs.fs_online = 0;
}
if (fslist == (fsparm_t *)0) {
fslist = &default_fs;
return;
}
for (fsp = fslist; fsp; fsp = fsp->fs_next) {
if (strcmp("default", fsp->fs_name) == 0) {
if (fsp->fs_lock == NULL)
fsp->fs_lock = default_fs.fs_lock;
if (fsp->fs_online == -1)
fsp->fs_online = default_fs.fs_online;
if (fsp->fs_reset == -1)
fsp->fs_reset = default_fs.fs_reset;
if (fsp->fs_active == NULL) {
fsp->fs_active = default_fs.fs_active;
continue;
}
for (dap = default_fs.fs_active;
dap; dap = dap->a_next) {
for (ap = fsp->fs_active; ap; ap = ap->a_next) {
if (ap->a_size == dap->a_size)
break;
}
if (ap == NULL) {
dap->a_next = fsp->fs_active;
fsp->fs_active = dap;
break;
}
}
}
}
}
#define PTRINC 10 /* build pointer array in multiples of PTRINC */
/*
* Turn a white-space or comma-separated list of mail
* recipients into a canonicalized list with tokens
* separated by a single space.
*/
#ifdef __STDC__
int
setmail(const char *recipients)
#else
int
setmail(recipients)
char *recipients;
#endif
{
static unsigned nptr = 0;
static unsigned nrecip = 0;
register char **cpp;
#ifdef __STDC__
const char *cp, *token;
#else
char *cp, *token;
#endif
char *newstr;
unsigned rlen;
if (recipients == (char *)0) { /* null arg resets list */
if (maillist)
for (cpp = maillist; *cpp; cpp++) {
free(*cpp);
*cpp = (char *)0;
}
nrecip = 0;
return (0);
}
if (maillist == (char **)0) {
nptr += PTRINC;
maillist = (char **)malloc(nptr * sizeof (char *));
if (maillist == (char **)0)
return (-1);
(void) memset((char *)maillist, 0, nptr * sizeof (char *));
}
cp = recipients;
/*
* find beginning of first token
*/
while (*cp && (isspace((u_char)*cp) || *cp == ','))
cp++;
while (*cp) {
token = cp;
/*
* find end of token
*/
while (*cp && !isspace((u_char)*cp) && *cp != ',')
cp++;
rlen = cp - token;
if ((nrecip + 2) > nptr) {
nptr += PTRINC;
maillist =
(char **)realloc(maillist, nptr * sizeof (char *));
if (maillist == (char **)0)
return (-1);
}
newstr = malloc(rlen + 1);
if (newstr == (char *)0)
return (-1);
(void) strncpy(newstr, token, rlen);
/*
* check for potential duplication
*/
for (cpp = maillist; *cpp; cpp++) {
if (strcmp(*cpp, newstr) == 0) {
free(newstr);
return (0);
}
}
maillist[nrecip++] = newstr;
maillist[nrecip] = (char *)0;
/*
* find next token
*/
while (*cp && (isspace((u_char)*cp) || *cp == ','))
cp++;
}
return (0);
}
/*
* Return the contents of the mail recipient
* pointer array as a space-separated list of
* addresses, suitable for use as a mailer
* command-line argument.
*/
int
getmail(buf, buflen)
char *buf;
int buflen;
{
register char *bp = buf;
register char *cp, **cpp;
register int i;
if (buf == (char *)0 || buflen <= 0) {
errno = EINVAL;
return (-1);
}
if (maillist != (char **)0) {
i = 1; /* need one extra for trailing '\0' */
for (cpp = maillist; *cpp; cpp++) {
cp = *cpp;
while (*cp && i < buflen) {
*bp++ = *cp++;
i++;
}
*bp = ' '; /* separate tokens */
i++;
}
}
*bp = '\0';
return (0);
}
static int
set_active(cp)
register char *cp;
{
struct active *a, *ap;
char *cmd = NULL;
char *arg = NULL;
char units[256];
int ncmds = 0;
if (current_fs == NULL) {
if (set_filesystem("default") < 0) {
errstr = dgettext(domainname,
"missing default file system");
return (-1);
}
}
a = (struct active *) malloc((unsigned)sizeof (struct active));
if (a == NULL) {
errstr = dgettext(domainname, "out of memory");
return (-1);
}
(void) memset((void *)a, 0, sizeof (struct active));
for (cp = getstring(cp, &cmd); cp && cmd; cp = getstring(cp, &cmd)) {
cp = getstring(cp, &arg);
if (cp == NULL)
break;
if (arg == NULL) {
free(cmd);
errstr = dgettext(domainname,
"missing argument in `active' command");
return (-1);
}
if (strcmp(cmd, "retries") == 0) {
if (sscanf(arg, "%d", &a->a_retries) != 1 ||
a->a_retries < 0) {
errstr = dgettext(domainname,
"`retries' option requires non-negative integer");
return (-1);
}
} else if (strcmp(cmd, "size") == 0) {
units[0] = '\0';
if (sscanf(arg, "%lu%255s", &a->a_size, units) < 1) {
errstr = dgettext(domainname,
"`size' option requires non-negative integer");
return (-1);
}
if (units[0] != '\0' && units[1] != '\0') {
errstr = dgettext(domainname,
"bad unit specifier in `size' option");
return (-1);
}
switch (*units) {
case 'b':
case 'B':
a->a_size *= 512;
break;
case 'k':
case 'K':
a->a_size *= 1024;
break;
case 'm':
case 'M':
a->a_size *= 1024*1024;
break;
case 'g':
case 'G':
a->a_size *= 1024*1024*1024;
break;
case '\0':
break;
default:
errstr = dgettext(domainname,
"bad unit specifier in `size' option");
return (-1);
}
} else if (strcmp(cmd, "report") == 0) {
if (strcmp(arg, "yes") == 0)
a->a_report = 1;
else if (strcmp(arg, "no") == 0)
a->a_report = 0;
else {
errstr = dgettext(domainname,
"`report' option requires `yes' or `no'");
return (-1);
}
} else {
errstr = dgettext(domainname,
"unrecogned option to `active' command");
return (-1);
}
free(cmd);
cmd = NULL;
free(arg);
arg = NULL;
ncmds++;
}
if (cp == NULL) {
errstr = dgettext(domainname,
"syntax error in `active' command");
return (-1);
}
if (ncmds == 0) {
errstr = dgettext(domainname,
"missing options in `active' command");
return (-1);
}
for (ap = current_fs->fs_active; ap; ap = ap->a_next)
if (ap->a_size == a->a_size) {
errstr = dgettext(domainname,
"duplicate/conflicting `active' comands in file");
return (-1);
}
a->a_next = current_fs->fs_active;
current_fs->fs_active = a;
return (0);
}
static int
set_database(cp)
register char *cp;
{
static int set;
char *newserver, *garbage;
if (set++) {
errstr = dgettext(domainname,
"multiple `database' commands in file");
return (-1);
}
cp = getstring(cp, &newserver);
if (cp == NULL || newserver == NULL) {
errstr = dgettext(domainname,
"missing host in `database' command");
return (-1);
}
if (strcmp(newserver, "localhost") == 0)
(void) strcpy(dbserver, hostname);
else if ((size_t)strlen(newserver) > sizeof (dbserver)) {
static char buf[256];
(void) sprintf(buf, dgettext(domainname,
"hostname `%s' too large in `database' command"),
newserver);
errstr = buf;
return (-1);
} else if (gethostbyname(newserver) == NULL) {
static char buf[256];
(void) sprintf(buf, dgettext(domainname,
"unknown host `%s' in `database' command"), newserver);
errstr = buf;
return (-1);
}
cp = getstring(cp, &garbage); /* check for multiple hosts */
if (cp == NULL || garbage != NULL) {
errstr = dgettext(domainname,
"multiple hosts in `database' command");
return (-1);
}
(void) strncpy(dbserver, newserver, sizeof (dbserver));
return (0);
}
static int
set_filesystem(cp)
register char *cp;
{
char *fsname;
register fsparm_t *fsp;
for (cp = getstring(cp, &fsname);
cp && fsname;
cp = getstring(cp, &fsname)) {
for (fsp = fslist; fsp; fsp = fsp->fs_next) {
if (strcmp(fsname, fsp->fs_name) == 0) {
static char buf[256];
(void) sprintf(buf, dgettext(domainname,
"multiple entries for file system %s"),
fsname);
errstr = buf;
return (-1);
}
}
fsp = (fsparm_t *)
malloc((unsigned)sizeof (fsparm_t));
if (fsp == NULL)
return (-1);
fsp->fs_name = fsname;
fsp->fs_active = NULL; /* use defaults */
fsp->fs_lock = NULL;
fsp->fs_online = -1;
fsp->fs_reset = -1;
fsp->fs_lock = NULL;
fsp->fs_next = fslist;
fslist = current_fs = fsp;
}
return (cp == NULL ? -1 : 0);
}
static int
set_lock(cp)
register char *cp;
{
char *locktype;
if (current_fs == NULL) {
if (set_filesystem("default") < 0) {
errstr = dgettext(domainname,
"missing default file system");
return (-1);
}
}
cp = getstring(cp, &locktype);
if (cp == NULL || locktype == NULL) {
errstr = dgettext(domainname, "missing lock type");
return (-1);
}
if (strcmp(locktype, "delete") &&
strcmp(locktype, "rename") &&
strcmp(locktype, "name") &&
strcmp(locktype, "all") &&
strcmp(locktype, "write") &&
strcmp(locktype, "none") &&
strcmp(locktype, "scan")) {
errstr = dgettext(domainname, "unknown lock type");
return (-1);
}
current_fs->fs_lock = locktype;
cp = getstring(cp, &locktype);
if (cp && locktype) {
errstr = dgettext(domainname, "multiple lock types");
return (-1);
}
return (0);
}
static int
set_online(cp)
register char *cp;
{
char *yn;
#ifdef DEBUG
printf("SET_ONLINE: setting %s to online\n", (cp ? cp : "NULL"));
#endif
if (current_fs == NULL) {
if (set_filesystem("default") < 0) {
errstr = "missing default file system";
return (-1);
}
}
cp = getstring(cp, &yn);
if (cp == NULL || yn == NULL)
return (-1);
if (strcmp(yn, "yes") == 0)
current_fs->fs_online = 1;
else if (strcmp(yn, "no") == 0)
current_fs->fs_online = 0;
else
return (-1);
return (0);
}
int
#ifdef __STDC__
getfsonline(void)
#else
getfsonline()
#endif
{
if (current_fs == (fsparm_t *)0) {
errno = ENOENT;
return (-1);
}
return (current_fs->fs_online);
}
static int
set_reset(cp)
register char *cp;
{
char *yn;
if (current_fs == NULL) {
if (set_filesystem("default") < 0) {
errstr = dgettext(domainname,
"missing default file system");
return (-1);
}
}
cp = getstring(cp, &yn);
if (cp == NULL || yn == NULL)
return (-1);
if (strcmp(yn, "yes") == 0)
current_fs->fs_reset = 1;
else if (strcmp(yn, "no") == 0)
current_fs->fs_reset = 0;
else
return (-1);
return (0);
}
static int
set_mail(cp)
register char *cp;
{
char *recip;
int nadded = 0;
do {
cp = getstring(cp, &recip);
if (cp == NULL)
return (-1);
if (recip) {
if (setmail(recip) < 0)
return (-1);
nadded++;
}
} while (recip);
if (nadded == 0) {
errstr = dgettext(domainname,
"missing recipient list in `mail' command");
return (-1);
}
return (0);
}
static int
set_operd(cp)
register char *cp;
{
static int set;
char *newserver, *garbage;
if (set++) {
errstr = dgettext(domainname,
"multiple `operd' commands in file");
return (-1);
}
cp = getstring(cp, &newserver);
if (cp == NULL || newserver == NULL) {
errstr = dgettext(domainname,
"missing host in `operd' command");
return (-1);
}
if (gethostbyname(newserver) == NULL) {
static char buf[256];
(void) sprintf(buf, dgettext(domainname,
"unknown host `%s' in `operd' command"), newserver);
errstr = buf;
return (-1);
}
cp = getstring(cp, &garbage); /* check for multiple hosts */
if (cp == NULL || garbage != NULL) {
errstr = dgettext(domainname,
"multiple hosts in `operd' command");
return (-1);
}
(void) strncpy(opserver, newserver, sizeof (opserver));
return (0);
}
static int
set_sequence(cp)
register char *cp;
{
char *name;
cp = getstring(cp, &name);
if (cp == NULL || name == NULL) {
errstr = dgettext(domainname, "missing sequence name");
return (-1);
}
return (makedevice(name, cp, sequence));
}
static int
set_tmpdir(cp)
register char *cp;
{
tmpdirlist = makelist(cp);
if (tmpdirlist == NULL || tmpdirlist[0] == NULL) {
errstr = dgettext(domainname,
"missing directory list in `tmpdirs' command");
return (-1);
}
return (0);
}
static int
nstrings(cp)
char *cp;
{
int n; /* number of strings */
int delim = 1; /* in delimiter string */
int comment = 0; /* in a comment */
int cont = 0; /* continuation char on this line */
for (n = 0; *cp; cp++) {
if (*cp == '#' && commentsok) {
comment = 1;
delim = 1;
} else if (*cp == '\\')
cont = 1;
else if (*cp == '\n') {
comment = 0;
if (!delim) {
delim = 1;
n++;
}
if (!cont)
break;
cont = 0;
} else if (isspace((u_char)*cp) || *cp == ',') {
if (!comment && !delim) {
delim = 1;
n++;
}
} else if (!comment) {
delim = 0;
cont = 0;
}
}
if (!delim)
n++;
return (n);
}
/*
* Skip to next delimiter or token
*/
static char *
skip(cp)
char *cp;
{
int cont = 0;
int keepgoing = 1;
while (keepgoing && cp) {
switch (*cp) {
case '\n':
/*
* A newline terminates a command, unless
* preceeded by a continuation character.
*/
if (cont) {
cont = 0; /* reset flag */
cp++;
break;
}
/*FALLTHRU*/
case '\0':
keepgoing = 0;
break;
case '\\':
cont = 1; /* set continuation flag */
cp++;
break;
case '#':
if (commentsok) {
/*
* A comment extends to the end of the
* current line and thus terminates a
* command, unless we've previously seen
* a continuation character. Move forward
* to the end of the line.
*/
cp = strchr(cp, '\n');
} else
keepgoing = 0;
break;
default:
if (!isspace((u_char)*cp))
/*
* Found end of white-space
*/
keepgoing = 0;
else
cp++;
break;
}
}
return (cp);
}
/*
* [non-destructively] turn a comma-separated
* list of tokens into an array of pointers
*/
static char **
makelist(list)
char *list;
{
char *cp;
char **cpp;
char **lpp;
lpp = (char **)
malloc((unsigned)((nstrings(list)+1) * sizeof (char *)));
if (lpp == NULL)
return ((char **)0);
cp = list;
cpp = lpp;
do {
cp = getstring(cp, cpp);
if (cp == NULL)
return ((char **)0);
} while (*cpp++);
return (lpp);
}
/*
* Set up the paths used by this package. The root
* of the package is determined in the following order:
* 1) "root" argument
* 2) HSMROOT environment variable
* 3) HSMROOT pre-processor symbol
* 4) /opt/SUNWhsm
* The configured paths are available through the
* gethsmpath() routine that follows.
*/
static char rootpath[MAXPATHLEN]; /* root of package hierarchy */
static char binpath[MAXPATHLEN]; /* [user] command directory */
static char sbinpath[MAXPATHLEN]; /* [system] command directory */
static char libpath[MAXPATHLEN]; /* library directory */
static char localepath[MAXPATHLEN]; /* locale directory */
static char etcpath[MAXPATHLEN]; /* configuration directory */
static char admpath[MAXPATHLEN]; /* administrative database directory */
void
sethsmpath(root)
char *root;
{
if (root == (char *)0) {
root = getenv("HSMROOT");
if (root == (char *)0)
root = HSMROOT;
}
(void) sprintf(rootpath, "%.*s", MAXPATHLEN-1, root);
(void) sprintf(binpath, "%.*s/bin", MAXPATHLEN-5, root);
(void) sprintf(sbinpath, "%.*s/sbin", MAXPATHLEN-6, root);
(void) sprintf(libpath, "%.*s/lib", MAXPATHLEN-5, root);
(void) sprintf(localepath, "%.*s/locale", MAXPATHLEN-8, libpath);
(void) sprintf(etcpath, "%.*s/etc", MAXPATHLEN-5, root);
(void) sprintf(admpath, "%.*s/adm", MAXPATHLEN-5, root);
}
char *
gethsmpath(which)
dirpath_t which;
{
static int init;
if (init == 0) {
sethsmpath((char *)0);
++init;
}
switch ((int)(which)) {
case rootdir:
return (rootpath);
case bindir:
return (binpath);
case sbindir:
return (sbinpath);
case libdir:
return (libpath);
case localedir:
return (localepath);
case etcdir:
return (etcpath);
case admdir:
return (admpath);
default:
return ((char *)0);
}
}
#ifdef __STDC__
#include <stdarg.h>
/* VARARGS */
static void
msg(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
(void) vfprintf(stderr, fmt, args);
(void) fflush(stderr);
va_end(args);
}
#else
#include <varargs.h>
static void
msg(va_alist)
va_dcl
{
va_list args;
char *fmt;
va_start(args);
fmt = va_arg(args, char *);
(void) vfprintf(stderr, fmt, args);
(void) fflush(stderr);
va_end(args);
}
#endif