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