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