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 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 #include <stdio.h> 31 #include <string.h> 32 #include <signal.h> 33 #include <stdlib.h> 34 #include <locale.h> 35 #include <libintl.h> 36 #include <limits.h> 37 #include "usage.h" 38 #include "libadm.h" 39 40 #define BADPID (-2) 41 #define MAXREGEXP 128 42 43 static char *prog; 44 static char *deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL; 45 static int kpid = BADPID; 46 static int signo, length; 47 48 static const char vusage[] = "rl"; 49 static const char husage[] = "rlWh"; 50 static const char eusage[] = "rlWe"; 51 52 #define USAGE "[-l length] [[-r regexp] [...]]" 53 54 static void 55 usage(void) 56 { 57 switch (*prog) { 58 default: 59 (void) fprintf(stderr, 60 gettext("usage: %s [options] %s\n"), 61 prog, USAGE); 62 (void) fprintf(stderr, gettext(OPTMESG)); 63 (void) fprintf(stderr, gettext(STDOPTS)); 64 break; 65 66 case 'v': 67 (void) fprintf(stderr, 68 gettext("usage: %s %s input\n"), prog, USAGE); 69 break; 70 71 case 'h': 72 (void) fprintf(stderr, 73 gettext("usage: %s [options] %s\n"), 74 prog, USAGE); 75 (void) fprintf(stderr, gettext(OPTMESG)); 76 (void) fprintf(stderr, 77 gettext("\t-W width\n\t-h help\n")); 78 break; 79 80 case 'e': 81 (void) fprintf(stderr, 82 gettext("usage: %s [options] %s\n"), 83 prog, USAGE); 84 (void) fprintf(stderr, gettext(OPTMESG)); 85 (void) fprintf(stderr, 86 gettext("\t-W width\n\t-e error\n")); 87 break; 88 } 89 exit(1); 90 } 91 92 /* 93 * Given argv[0], return a pointer to the basename of the program. 94 */ 95 static char * 96 prog_name(char *arg0) 97 { 98 char *str; 99 100 /* first strip trailing '/' characters (exec() allows these!) */ 101 str = arg0 + strlen(arg0); 102 while (str > arg0 && *--str == '/') 103 *str = '\0'; 104 if ((str = strrchr(arg0, '/')) != NULL) 105 return (str + 1); 106 return (arg0); 107 } 108 109 int 110 main(int argc, char **argv) 111 { 112 int c, n; 113 char *strval; 114 char **regexp; 115 size_t len; 116 size_t maxregexp = MAXREGEXP; 117 size_t nregexp = 0; 118 119 (void) setlocale(LC_ALL, ""); 120 121 #if !defined(TEXT_DOMAIN) 122 #define TEXT_DOMAIN "SYS_TEST" 123 #endif 124 (void) textdomain(TEXT_DOMAIN); 125 126 prog = prog_name(argv[0]); 127 128 regexp = (char **)calloc(maxregexp, sizeof (char *)); 129 if (!regexp) { 130 (void) fprintf(stderr, 131 gettext("Not enough memory\n")); 132 exit(1); 133 } 134 while ((c = getopt(argc, argv, "r:l:d:p:e:h:k:s:QW:?")) != EOF) { 135 /* check for invalid option */ 136 if ((*prog == 'v') && !strchr(vusage, c)) 137 usage(); 138 if ((*prog == 'e') && !strchr(eusage, c)) 139 usage(); 140 if ((*prog == 'h') && !strchr(husage, c)) 141 usage(); 142 143 switch (c) { 144 case 'Q': 145 ckquit = 0; 146 break; 147 148 case 'W': 149 ckwidth = atoi(optarg); 150 if (ckwidth < 0) { 151 (void) fprintf(stderr, 152 gettext("%s: ERROR: negative display width specified\n"), 153 prog); 154 exit(1); 155 } 156 break; 157 158 case 'r': 159 regexp[nregexp++] = optarg; 160 if (nregexp == maxregexp) { 161 maxregexp += MAXREGEXP; 162 regexp = (char **)realloc(regexp, 163 maxregexp * sizeof (char *)); 164 if (!regexp) { 165 (void) fprintf(stderr, 166 gettext("Not enough memory\n")); 167 exit(1); 168 } 169 (void) memset(regexp + nregexp, 0, 170 (maxregexp - nregexp) * 171 sizeof (char *)); 172 } 173 break; 174 175 case 'l': 176 length = atoi(optarg); 177 if ((length <= 0) || (length > 128)) { 178 (void) fprintf(stderr, 179 gettext("%s: ERROR: length must be between 1 and 128\n"), 180 prog); 181 exit(1); 182 } 183 break; 184 185 case 'd': 186 deflt = optarg; 187 break; 188 189 case 'p': 190 prompt = optarg; 191 break; 192 193 case 'e': 194 error = optarg; 195 break; 196 197 case 'h': 198 help = optarg; 199 break; 200 201 case 'k': 202 kpid = atoi(optarg); 203 break; 204 205 case 's': 206 signo = atoi(optarg); 207 break; 208 209 default: 210 usage(); 211 } 212 } 213 214 if (signo) { 215 if (kpid == BADPID) 216 usage(); 217 } else 218 signo = SIGTERM; 219 220 if (*prog == 'v') { 221 if (argc != (optind+1)) 222 usage(); 223 if (ckstr_val(regexp, length, argv[optind])) 224 exit(1); 225 exit(0); 226 } 227 228 if (*prog == 'e') { 229 if (argc > (optind+1)) 230 usage(); /* too many args */ 231 ckindent = 0; 232 ckstr_err(regexp, length, error, argv[optind]); 233 exit(0); 234 } 235 236 if (optind != argc) 237 usage(); 238 239 if (*prog == 'h') { 240 ckindent = 0; 241 ckstr_hlp(regexp, length, help); 242 exit(0); 243 } 244 245 regexp[nregexp] = NULL; 246 247 if (deflt) { 248 len = strlen(deflt) + 1; 249 if (len < MAX_INPUT) 250 len = MAX_INPUT; 251 } else { 252 len = MAX_INPUT; 253 } 254 strval = (char *)malloc(len); 255 if (!strval) { 256 (void) fprintf(stderr, 257 gettext("Not enough memory\n")); 258 exit(1); 259 } 260 n = ckstr(strval, regexp, length, deflt, error, help, prompt); 261 if (n == 3) { 262 if (kpid > -2) 263 (void) kill(kpid, signo); 264 (void) puts("q"); 265 } else if (n == 0) 266 (void) fputs(strval, stdout); 267 return (n); 268 } 269