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 42 static char *prog; 43 static char *deflt = NULL, *prompt = NULL, *error = NULL, *help = NULL; 44 static int kpid = BADPID; 45 static int signo; 46 static char *fmt; 47 48 static const char vusage[] = "f"; 49 static const char husage[] = "fWh"; 50 static const char eusage[] = "fWe"; 51 52 #define MYFMT \ 53 "%s:ERROR:invalid format\n" \ 54 "valid format descriptors are:\n" \ 55 "\t%%H #hour (00-23)\n" \ 56 "\t%%I #hour (00-12)\n" \ 57 "\t%%M #minute (00-59)\n" \ 58 "\t%%p #AM, PM, am or pm\n" \ 59 "\t%%r #time as %%I:%%M:%%S %%p\n" \ 60 "\t%%R #time as %%H:%%M (default)\n" \ 61 "\t%%S #seconds (00-59)\n" \ 62 "\t%%T #time as %%H:%%M:%%S\n" 63 64 static void 65 usage(void) 66 { 67 switch (*prog) { 68 default: 69 (void) fprintf(stderr, 70 gettext("usage: %s [options] [-f format]\n"), 71 prog); 72 (void) fprintf(stderr, gettext(OPTMESG)); 73 (void) fprintf(stderr, gettext(STDOPTS)); 74 break; 75 76 case 'v': 77 (void) fprintf(stderr, 78 gettext("usage: %s [-f format] input\n"), prog); 79 break; 80 81 case 'h': 82 (void) fprintf(stderr, 83 gettext("usage: %s [options] [-f format]\n"), 84 prog); 85 (void) fprintf(stderr, gettext(OPTMESG)); 86 (void) fprintf(stderr, 87 gettext("\t-W width\n\t-h help\n")); 88 break; 89 90 case 'e': 91 (void) fprintf(stderr, 92 gettext("usage: %s [options] [-f format]\n"), 93 prog); 94 (void) fprintf(stderr, gettext(OPTMESG)); 95 (void) fprintf(stderr, 96 gettext("\t-W width\n\t-e error\n")); 97 break; 98 } 99 exit(1); 100 } 101 102 /* 103 * Given argv[0], return a pointer to the basename of the program. 104 */ 105 static char * 106 prog_name(char *arg0) 107 { 108 char *str; 109 110 /* first strip trailing '/' characters (exec() allows these!) */ 111 str = arg0 + strlen(arg0); 112 while (str > arg0 && *--str == '/') 113 *str = '\0'; 114 if ((str = strrchr(arg0, '/')) != NULL) 115 return (str + 1); 116 return (arg0); 117 } 118 119 int 120 main(int argc, char **argv) 121 { 122 int c, n; 123 char *tod; 124 size_t len; 125 126 (void) setlocale(LC_ALL, ""); 127 128 #if !defined(TEXT_DOMAIN) 129 #define TEXT_DOMAIN "SYS_TEST" 130 #endif 131 (void) textdomain(TEXT_DOMAIN); 132 133 prog = prog_name(argv[0]); 134 135 while ((c = getopt(argc, argv, "f:d:p:e:h:k:s:QW:?")) != EOF) { 136 /* check for invalid option */ 137 if ((*prog == 'v') && !strchr(vusage, c)) 138 usage(); 139 if ((*prog == 'e') && !strchr(eusage, c)) 140 usage(); 141 if ((*prog == 'h') && !strchr(husage, c)) 142 usage(); 143 144 switch (c) { 145 case 'Q': 146 ckquit = 0; 147 break; 148 149 case 'W': 150 ckwidth = atoi(optarg); 151 if (ckwidth < 0) { 152 (void) fprintf(stderr, 153 gettext("%s: ERROR: negative display width specified\n"), 154 prog); 155 exit(1); 156 } 157 break; 158 159 case 'f': 160 fmt = optarg; 161 break; 162 163 case 'd': 164 deflt = optarg; 165 break; 166 167 case 'p': 168 prompt = optarg; 169 break; 170 171 case 'e': 172 error = optarg; 173 break; 174 175 case 'h': 176 help = optarg; 177 break; 178 179 case 'k': 180 kpid = atoi(optarg); 181 break; 182 183 case 's': 184 signo = atoi(optarg); 185 break; 186 187 default: 188 usage(); 189 } 190 } 191 192 if (signo) { 193 if (kpid == BADPID) 194 usage(); 195 } else 196 signo = SIGTERM; 197 198 if (*prog == 'v') { 199 if (argc != (optind+1)) 200 usage(); 201 n = cktime_val(fmt, argv[optind]); 202 /* 203 * TRANSLATION_NOTE 204 * In the below, "AM", "PM", "am", and "pm" are 205 * keywords. So, do not translate them. 206 */ 207 if (n == 4) 208 (void) fprintf(stderr, gettext(MYFMT), prog); 209 exit(n); 210 } 211 212 if (optind != argc) 213 usage(); 214 215 if (*prog == 'e') { 216 ckindent = 0; 217 if (cktime_err(fmt, error)) { 218 (void) fprintf(stderr, gettext(MYFMT), prog); 219 exit(4); 220 } else 221 exit(0); 222 } else if (*prog == 'h') { 223 ckindent = 0; 224 if (cktime_hlp(fmt, help)) { 225 (void) fprintf(stderr, gettext(MYFMT), prog); 226 exit(4); 227 } else 228 exit(0); 229 } 230 231 if (deflt) { 232 len = strlen(deflt) + 1; 233 if (len < MAX_INPUT) 234 len = MAX_INPUT; 235 } else { 236 len = MAX_INPUT; 237 } 238 tod = (char *)malloc(len); 239 if (!tod) { 240 (void) fprintf(stderr, 241 gettext("Not enough memory\n")); 242 exit(1); 243 } 244 n = cktime(tod, fmt, deflt, error, help, prompt); 245 if (n == 3) { 246 if (kpid > -2) 247 (void) kill(kpid, signo); 248 (void) puts("q"); 249 } else if (n == 0) 250 (void) fputs(tod, stdout); 251 if (n == 4) 252 (void) fprintf(stderr, gettext(MYFMT), prog); 253 return (n); 254 } 255