summaryrefslogtreecommitdiff
path: root/usr/src/lib/libadm/common/cktime.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libadm/common/cktime.c')
-rw-r--r--usr/src/lib/libadm/common/cktime.c388
1 files changed, 388 insertions, 0 deletions
diff --git a/usr/src/lib/libadm/common/cktime.c b/usr/src/lib/libadm/common/cktime.c
new file mode 100644
index 0000000000..71a5580600
--- /dev/null
+++ b/usr/src/lib/libadm/common/cktime.c
@@ -0,0 +1,388 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License"). You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
+/* All Rights Reserved */
+
+
+/*
+ * Copyright (c) 1997,1998 by Sun Microsystems, Inc.
+ * All rights reserved.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+/*LINTLIBRARY*/
+
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include "libadm.h"
+
+static int fmtcheck(char *);
+
+#define PROMPT "Enter the time of day"
+#define ERRMSG "Please enter the time of day. Format is"
+#define DEFAULT "%H:%M"
+
+#define TLEN 3
+#define LH 00
+#define UH 23
+#define USH 12
+#define LM 00
+#define UM 59
+#define LS 00
+#define US 59
+#define DELIM1 ':'
+#define BLANK ' '
+#define TAB ' '
+
+static void
+setmsg(char *msg, char *fmt)
+{
+ if (fmt == NULL)
+ fmt = DEFAULT;
+ (void) sprintf(msg, "%s <%s>.", ERRMSG, fmt);
+}
+
+static char *
+p_ndig(char *string, int *value)
+{
+ char *ptr;
+ int accum = 0;
+ int n = 2;
+
+ if (!string)
+ return (0);
+ for (ptr = string; *ptr && n > 0; n--, ptr++) {
+ if (! isdigit((unsigned char)*ptr))
+ return (NULL);
+ accum = (10 * accum) + (*ptr - '0');
+ }
+ if (n)
+ return (NULL);
+ *value = accum;
+ return (ptr);
+}
+
+static char *
+p_time(char *string, int llim, int ulim)
+{
+ char *ptr;
+ int begin = -1;
+ if (!(ptr = p_ndig(string, &begin)))
+ return (NULL);
+ if (begin >= llim && begin <= ulim)
+ return (ptr);
+ else return (NULL);
+}
+
+/* p_meridian will parse the string for the meridian - AM/PM or am/pm */
+
+static char *
+p_meridian(char *string)
+{
+ static char *middle[] = { "AM", "PM", "am", "pm" };
+ int legit, n;
+ char mid[TLEN];
+
+ legit = 0;
+ n = 0;
+ mid[2] = '\0';
+ (void) sscanf(string, "%2s", mid);
+ while (!(legit) && (n < 4)) {
+ if ((strncmp(mid, middle[n], 2)) == 0)
+ legit = 1; /* found legitimate string */
+ n++;
+ }
+ if (legit)
+ return (string+2);
+ return (NULL);
+}
+
+static char *
+p_delim(char *string, char dchoice)
+{
+ char dlm;
+
+ if (! string)
+ return (NULL);
+ (void) sscanf(string, "%1c", &dlm);
+ return ((dlm == dchoice) ? string + 1 : NULL);
+}
+
+int
+cktime_val(char *fmt, char *input)
+{
+ char ltrl, dfl;
+ int valid = 1; /* time of day string is valid for format */
+
+ if ((fmt != NULL) && (fmtcheck(fmt) == 1))
+ return (4);
+
+ if (fmt == NULL)
+ fmt = DEFAULT;
+ ltrl = '\0';
+ while (*fmt && valid) {
+ if ((*fmt) == '%') {
+ switch (*++fmt) {
+ case 'H':
+ input = p_time(input, LH, UH);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'M':
+ input = p_time(input, LM, UM);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'S':
+ input = p_time(input, LS, US);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'T':
+ input = p_time(input, LH, UH);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+
+ input = p_delim(input, DELIM1);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_time(input, LM, UM);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_delim(input, DELIM1);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_time(input, LS, US);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'R':
+ input = p_time(input, LH, UH);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_delim(input, DELIM1);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_time(input, LM, UM);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ break;
+
+ case 'r':
+ input = p_time(input, LH, USH);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_delim(input, DELIM1);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_time(input, LM, UM);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_delim(input, DELIM1);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_time(input, LS, US);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_delim(input, BLANK);
+ if (!input) {
+ valid = 0;
+ break;
+ }
+ input = p_meridian(input);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'I':
+ input = p_time(input, LH, USH);
+ if (!input)
+ valid = 0;
+ break;
+
+ case 'p':
+ input = p_meridian(input);
+ if (!input)
+ valid = 0;
+ break;
+
+ default:
+ (void) sscanf(input++, "%1c", &ltrl);
+ }
+ } else {
+ dfl = '\0';
+ (void) sscanf(input, "%1c", &dfl);
+ input++;
+ }
+ fmt++;
+ }
+
+ if (!(*fmt) && (input) && (*input))
+ valid = 0;
+
+ return ((valid == 0));
+}
+
+int
+cktime_err(char *fmt, char *error)
+{
+ char defmesg[128];
+
+ if ((fmt != NULL) && (fmtcheck(fmt) == 1))
+ return (4);
+ setmsg(defmesg, fmt);
+ puterror(stdout, defmesg, error);
+ return (0);
+}
+
+int
+cktime_hlp(char *fmt, char *help)
+{
+ char defmesg[128];
+
+ if ((fmt != NULL) && (fmtcheck(fmt) == 1))
+ return (4);
+ setmsg(defmesg, fmt);
+ puthelp(stdout, defmesg, help);
+ return (0);
+}
+
+/*
+ * A little state machine that checks out the format to
+ * make sure it is acceptable.
+ * return value 1: NG
+ * return value 0: OK
+ */
+int
+fmtcheck(char *fmt)
+{
+ int percent = 0;
+
+ while (*fmt) {
+ switch (*fmt++) {
+ case '%': /* previous state must be start or letter */
+ if (percent == 0)
+ percent = 1;
+ else
+ return (1);
+ break;
+ case 'H': /* previous state must be "%" */
+ case 'M':
+ case 'S':
+ case 'T':
+ case 'R':
+ case 'r':
+ case 'I':
+ case 'p':
+ if (percent == 1)
+ percent = 0;
+ else
+ return (1);
+ break;
+ case TAB: /* previous state must be start or letter */
+ case BLANK:
+ case DELIM1:
+ if (percent == 1)
+ return (1);
+ break;
+ default:
+ return (1);
+ }
+ }
+ return (percent);
+}
+
+int
+cktime(char *tod, char *fmt, char *defstr, char *error, char *help,
+ char *prompt)
+{
+ char input[MAX_INPUT],
+ defmesg[128];
+
+ if ((fmt != NULL) && (fmtcheck(fmt) == 1))
+ return (4);
+
+ if (fmt == NULL)
+ fmt = DEFAULT;
+ setmsg(defmesg, fmt);
+ if (!prompt)
+ prompt = "Enter a time of day";
+
+start:
+ putprmpt(stderr, prompt, NULL, defstr);
+ if (getinput(input))
+ return (1);
+
+ if (!strlen(input)) {
+ if (defstr) {
+ (void) strcpy(tod, defstr);
+ return (0);
+ }
+ puterror(stderr, defmesg, error);
+ goto start;
+ }
+ if (strcmp(input, "?") == 0) {
+ puthelp(stderr, defmesg, help);
+ goto start;
+ }
+ if (ckquit && (strcmp(input, "q") == 0))
+ return (3);
+
+ if (cktime_val(fmt, input)) {
+ puterror(stderr, defmesg, error);
+ goto start;
+ }
+ (void) strcpy(tod, input);
+ return (0);
+}