1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * svccfg - modify service configuration repository 30 */ 31 32 #include <sys/stat.h> 33 #include <sys/types.h> 34 #include <sys/wait.h> 35 36 #include <errno.h> 37 #include <libintl.h> 38 #include <libscf.h> 39 #include <libscf_priv.h> 40 #include <libuutil.h> 41 #include <locale.h> 42 #include <signal.h> 43 #include <stdarg.h> 44 #include <stddef.h> 45 #include <stdio.h> 46 #include <stdlib.h> 47 #include <string.h> 48 #include <unistd.h> 49 50 #include "svccfg.h" 51 52 #ifndef TEXT_DOMAIN 53 #define TEXT_DOMAIN "SUNW_OST_OSCMD" 54 #endif /* TEXT_DOMAIN */ 55 56 #define MAX_CMD_LINE_SZ 2048 57 58 static const char *myname; 59 int g_verbose = 0; 60 const char *fmri; 61 62 static void 63 usage() 64 { 65 (void) fprintf(stderr, gettext( 66 "Usage:\tsvccfg [-v] [-s FMRI] [-f file]\n" 67 "\tsvccfg [-v] [-s FMRI] <command> [args]\n")); 68 exit(UU_EXIT_USAGE); 69 } 70 71 void * 72 safe_malloc(size_t sz) 73 { 74 void *p; 75 76 if ((p = calloc(1, sz)) == NULL) 77 uu_die(gettext("Out of memory.\n")); 78 79 return (p); 80 } 81 82 char * 83 safe_strdup(const char *cp) 84 { 85 char *result; 86 87 result = strdup(cp); 88 if (result == NULL) 89 uu_die(gettext("Out of memory.\n")); 90 91 return (result); 92 } 93 94 /* 95 * Send a message to the user. If we're interactive, send it to stdout. 96 * Otherwise send it to stderr. 97 */ 98 static void 99 vmessage(const char *fmt, va_list va) 100 { 101 int interactive = est->sc_cmd_flags & SC_CMD_IACTIVE; 102 FILE *strm = interactive ? stdout : stderr; 103 const char *ptr; 104 105 if (!interactive) { 106 if (est->sc_cmd_file == NULL) 107 (void) fprintf(stderr, "%s: ", myname); 108 else 109 (void) fprintf(stderr, "%s (%s, line %d): ", myname, 110 est->sc_cmd_filename, est->sc_cmd_lineno - 1); 111 } 112 113 if (vfprintf(strm, fmt, va) < 0 && interactive) 114 uu_die(gettext("printf() error")); 115 116 ptr = strchr(fmt, '\0'); 117 if (*(ptr - 1) != '\n') 118 (void) fprintf(strm, ": %s.\n", strerror(errno)); 119 } 120 121 /* 122 * Display a warning. Should usually be predicated by g_verbose. 123 */ 124 /* PRINTFLIKE1 */ 125 void 126 warn(const char *fmt, ...) 127 { 128 va_list va; 129 130 va_start(va, fmt); 131 vmessage(fmt, va); 132 va_end(va); 133 } 134 135 /* 136 * Syntax error. 137 */ 138 void 139 synerr(int com) 140 { 141 if (est->sc_cmd_flags & SC_CMD_IACTIVE) { 142 help(com); 143 return; 144 } 145 146 warn(gettext("Syntax error.\n")); 147 148 if ((est->sc_cmd_flags & SC_CMD_DONT_EXIT) == 0) 149 exit(1); 150 } 151 152 /* 153 * Semantic error. Display the warning and exit if we're not interactive. 154 */ 155 /* PRINTFLIKE1 */ 156 void 157 semerr(const char *fmt, ...) 158 { 159 va_list va; 160 161 va_start(va, fmt); 162 vmessage(fmt, va); 163 va_end(va); 164 165 if ((est->sc_cmd_flags & (SC_CMD_IACTIVE | SC_CMD_DONT_EXIT)) == 0) 166 exit(1); 167 } 168 169 /*ARGSUSED*/ 170 static void 171 initialize(int argc, char *argv[]) 172 { 173 myname = uu_setpname(argv[0]); 174 (void) atexit(lscf_cleanup); 175 176 (void) setlocale(LC_ALL, ""); 177 (void) textdomain(TEXT_DOMAIN); 178 179 (void) lxml_init(); 180 internal_init(); 181 engine_init(); 182 lscf_init(); /* must follow engine_init() */ 183 } 184 185 int 186 main(int argc, char *argv[]) 187 { 188 char *cmd, *command_file = NULL; 189 char *fmri = NULL; 190 int c; 191 192 while ((c = getopt(argc, argv, "vf:s:")) != EOF) 193 switch (c) { 194 case 'v': 195 g_verbose = 1; 196 break; 197 198 case 's': 199 fmri = optarg; 200 break; 201 202 case 'f': 203 command_file = optarg; 204 break; 205 206 default: 207 usage(); 208 break; 209 } 210 211 initialize(argc, argv); 212 213 if (fmri != NULL) 214 lscf_select(fmri); 215 216 if (command_file != NULL) 217 return (engine_source(command_file, 0)); 218 219 if (optind == argc) { 220 if (isatty(fileno(stdin))) 221 return (engine_interp()); 222 else 223 return (engine_source("-", 0)); 224 } 225 226 /* 227 * Knit together remaining arguments into a single statement. 228 */ 229 cmd = safe_malloc(MAX_CMD_LINE_SZ); 230 for (c = optind; c < argc; c++) { 231 (void) strlcat(cmd, argv[c], MAX_CMD_LINE_SZ); 232 (void) strlcat(cmd, " ", MAX_CMD_LINE_SZ); 233 } 234 235 return (engine_exec(cmd)); 236 } 237