summaryrefslogtreecommitdiffstats
path: root/lib/libutil/login_times.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libutil/login_times.c')
-rw-r--r--lib/libutil/login_times.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/lib/libutil/login_times.c b/lib/libutil/login_times.c
new file mode 100644
index 0000000..e2c7bf2
--- /dev/null
+++ b/lib/libutil/login_times.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 1996 by
+ * David Nugent <davidn@blaze.net.au>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, is permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice immediately at the beginning of the file, without modification,
+ * this list of conditions, and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. This work was done expressly for inclusion into FreeBSD. Other use
+ * is permitted provided this notation is included.
+ * 4. Absolutely no warranty of function or purpose is made by the authors.
+ * 5. Modifications may be freely made to this file providing the above
+ * conditions are met.
+ *
+ * Login period parsing and comparison functions.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+#include <ctype.h>
+#include <login_cap.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+static struct
+{
+ const char *dw;
+ u_char cn;
+ u_char fl;
+} dws[] =
+{
+ { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE },
+ { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI },
+ { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY },
+ { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 }
+};
+
+static char *
+parse_time(char * ptr, u_short * t)
+{
+ u_short val;
+
+ for (val = 0; *ptr && isdigit(*ptr); ptr++)
+ val = (u_short)(val * 10 + (*ptr - '0'));
+
+ *t = (u_short)((val / 100) * 60 + (val % 100));
+
+ return (ptr);
+}
+
+
+login_time_t
+parse_lt(const char *str)
+{
+ login_time_t t;
+
+ memset(&t, 0, sizeof t);
+ t.lt_dow = LTM_NONE;
+ if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) {
+ int i;
+ login_time_t m = t;
+ char *p;
+ char buf[64];
+
+ /* Make local copy and force lowercase to simplify parsing */
+ strlcpy(buf, str, sizeof buf);
+ for (i = 0; buf[i]; i++)
+ buf[i] = (char)tolower(buf[i]);
+ p = buf;
+
+ while (isalpha(*p)) {
+
+ i = 0;
+ while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0)
+ i++;
+ if (dws[i].dw == NULL)
+ break;
+ m.lt_dow |= dws[i].fl;
+ p += dws[i].cn;
+ }
+
+ if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */
+ m.lt_dow |= LTM_ANY;
+
+ if (isdigit(*p))
+ p = parse_time(p, &m.lt_start);
+ else
+ m.lt_start = 0;
+ if (*p == '-')
+ p = parse_time(++p, &m.lt_end);
+ else
+ m.lt_end = 1440;
+
+ t = m;
+ }
+ return (t);
+}
+
+
+int
+in_ltm(const login_time_t *ltm, struct tm *tt, time_t *ends)
+{
+ int rc = 0;
+
+ if (tt != NULL) {
+ /* First, examine the day of the week */
+ if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) {
+ /* Convert `current' time to minute of the day */
+ u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min);
+
+ if (tt->tm_sec > 30)
+ ++now;
+ if (now >= ltm->lt_start && now < ltm->lt_end) {
+ rc = 2;
+ if (ends != NULL) {
+ /* If requested, return ending time for this period */
+ tt->tm_hour = (int)(ltm->lt_end / 60);
+ tt->tm_min = (int)(ltm->lt_end % 60);
+ *ends = mktime(tt);
+ }
+ }
+ }
+ }
+ return (rc);
+}
+
+
+int
+in_lt(const login_time_t *ltm, time_t *t)
+{
+
+ return (in_ltm(ltm, localtime(t), t));
+}
+
+int
+in_ltms(const login_time_t *ltm, struct tm *tm, time_t *t)
+{
+ int i = 0;
+
+ while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) {
+ if (in_ltm(ltm + i, tm, t))
+ return (i);
+ i++;
+ }
+ return (-1);
+}
+
+int
+in_lts(const login_time_t *ltm, time_t *t)
+{
+
+ return (in_ltms(ltm, localtime(t), t));
+}
OpenPOWER on IntegriCloud