#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/zone.h>
#include <errno.h>
#include <libintl.h>
#include <libscf.h>
#include <libscf_priv.h>
#include <libuutil.h>
#include <locale.h>
#include <signal.h>
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <zone.h>
#include "svccfg.h"
#ifndef TEXT_DOMAIN
#define TEXT_DOMAIN "SUNW_OST_OSCMD"
#endif
#define MAX_CMD_LINE_SZ 2048
static const char *myname;
int g_verbose = 0;
int g_do_zone = 0;
char g_zonename[ZONENAME_MAX];
const char *fmri;
static void
usage()
{
(void) fprintf(stderr, gettext(
"Usage:\tsvccfg [-v] [-z zone] [-s FMRI] [-f file]\n"
"\tsvccfg [-v] [-z zone] [-s FMRI] <command> [args]\n"));
exit(UU_EXIT_USAGE);
}
void *
safe_malloc(size_t sz)
{
void *p;
if ((p = calloc(1, sz)) == NULL)
uu_die(gettext("Out of memory.\n"));
return (p);
}
char *
safe_strdup(const char *cp)
{
char *result;
result = strdup(cp);
if (result == NULL)
uu_die(gettext("Out of memory.\n"));
return (result);
}
static void
vmessage(const char *fmt, va_list va)
{
int interactive = est->sc_cmd_flags & SC_CMD_IACTIVE;
FILE *strm = interactive ? stdout : stderr;
const char *ptr;
if (!interactive) {
if (est->sc_cmd_file == NULL)
(void) fprintf(stderr, "%s: ", myname);
else
(void) fprintf(stderr, "%s (%s, line %d): ", myname,
est->sc_cmd_filename, est->sc_cmd_lineno - 1);
}
if (vfprintf(strm, fmt, va) < 0 && interactive)
uu_die(gettext("printf() error"));
ptr = strchr(fmt, '\0');
if (*(ptr - 1) != '\n')
(void) fprintf(strm, ": %s.\n", strerror(errno));
}
void
warn(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vmessage(fmt, va);
va_end(va);
}
void
synerr(int com)
{
if (est->sc_cmd_flags & SC_CMD_IACTIVE) {
help(com);
return;
}
warn(gettext("Syntax error.\n"));
if ((est->sc_cmd_flags & SC_CMD_DONT_EXIT) == 0)
exit(1);
}
void
semerr(const char *fmt, ...)
{
va_list va;
va_start(va, fmt);
vmessage(fmt, va);
va_end(va);
if ((est->sc_cmd_flags & (SC_CMD_IACTIVE | SC_CMD_DONT_EXIT)) == 0)
exit(1);
}
static void
initialize(int argc, char *argv[])
{
myname = uu_setpname(argv[0]);
(void) atexit(lscf_cleanup);
(void) setlocale(LC_ALL, "");
(void) textdomain(TEXT_DOMAIN);
(void) lxml_init();
internal_init();
engine_init();
lscf_init();
tmpl_init();
}
int
main(int argc, char *argv[])
{
char *cmd, *command_file = NULL;
char *fmri = NULL;
int c;
while ((c = getopt(argc, argv, "vf:s:z:")) != EOF) {
switch (c) {
case 'v':
g_verbose = 1;
break;
case 's':
fmri = optarg;
break;
case 'f':
command_file = optarg;
break;
case 'z':
if (getzoneid() != GLOBAL_ZONEID) {
uu_die(gettext("svccfg -z may only be used "
"from the global zone\n"));
}
if (strlcpy(g_zonename, optarg, sizeof (g_zonename)) >=
sizeof (g_zonename)) {
uu_die(gettext(
"The provided zone name is too long, "
"max %zd\n"), sizeof (g_zonename) - 1);
}
g_do_zone = 1;
break;
default:
usage();
break;
}
}
initialize(argc, argv);
if (fmri != NULL)
lscf_select(fmri);
if (command_file != NULL)
return (engine_source(command_file, 0));
if (optind == argc) {
if (isatty(fileno(stdin)))
return (engine_interp());
else
return (engine_source("-", 0));
}
cmd = safe_malloc(MAX_CMD_LINE_SZ);
for (c = optind; c < argc; c++) {
(void) strlcat(cmd, argv[c], MAX_CMD_LINE_SZ);
(void) strlcat(cmd, " ", MAX_CMD_LINE_SZ);
}
return (engine_exec(cmd));
}