1 /*- 2 * Copyright (c) 1996 by 3 * David Nugent <davidn@blaze.net.au> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, is permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice immediately at the beginning of the file, without modification, 11 * this list of conditions, and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. This work was done expressly for inclusion into FreeBSD. Other use 16 * is permitted provided this notation is included. 17 * 4. Absolutely no warranty of function or purpose is made by the authors. 18 * 5. Modifications may be freely made to this file providing the above 19 * conditions are met. 20 * 21 * Login period parsing and comparison functions. 22 */ 23 24 #include <sys/types.h> 25 #include <ctype.h> 26 #include <login_cap.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <time.h> 30 31 static struct 32 { 33 const char *dw; 34 u_char cn; 35 u_char fl; 36 } dws[] = 37 { 38 { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 39 { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 40 { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 41 { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 42 }; 43 44 static char * 45 parse_time(char * ptr, u_short * t) 46 { 47 u_short val; 48 49 for (val = 0; *ptr && isdigit(*ptr); ptr++) 50 val = (u_short)(val * 10 + (*ptr - '0')); 51 52 *t = (u_short)((val / 100) * 60 + (val % 100)); 53 54 return (ptr); 55 } 56 57 58 login_time_t 59 parse_lt(const char *str) 60 { 61 login_time_t t; 62 63 memset(&t, 0, sizeof t); 64 t.lt_dow = LTM_NONE; 65 if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { 66 int i; 67 login_time_t m = t; 68 char *p; 69 char buf[64]; 70 71 /* Make local copy and force lowercase to simplify parsing */ 72 strlcpy(buf, str, sizeof buf); 73 for (i = 0; buf[i]; i++) 74 buf[i] = (char)tolower(buf[i]); 75 p = buf; 76 77 while (isalpha(*p)) { 78 79 i = 0; 80 while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) 81 i++; 82 if (dws[i].dw == NULL) 83 break; 84 m.lt_dow |= dws[i].fl; 85 p += dws[i].cn; 86 } 87 88 if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 89 m.lt_dow |= LTM_ANY; 90 91 if (isdigit(*p)) 92 p = parse_time(p, &m.lt_start); 93 else 94 m.lt_start = 0; 95 if (*p == '-') 96 p = parse_time(p + 1, &m.lt_end); 97 else 98 m.lt_end = 1440; 99 100 t = m; 101 } 102 return (t); 103 } 104 105 106 int 107 in_ltm(const login_time_t *ltm, struct tm *tt, time_t *ends) 108 { 109 int rc = 0; 110 111 if (tt != NULL) { 112 /* First, examine the day of the week */ 113 if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { 114 /* Convert `current' time to minute of the day */ 115 u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 116 117 if (tt->tm_sec > 30) 118 ++now; 119 if (now >= ltm->lt_start && now < ltm->lt_end) { 120 rc = 2; 121 if (ends != NULL) { 122 /* If requested, return ending time for this period */ 123 tt->tm_hour = (int)(ltm->lt_end / 60); 124 tt->tm_min = (int)(ltm->lt_end % 60); 125 *ends = mktime(tt); 126 } 127 } 128 } 129 } 130 return (rc); 131 } 132 133 134 int 135 in_lt(const login_time_t *ltm, time_t *t) 136 { 137 138 return (in_ltm(ltm, localtime(t), t)); 139 } 140 141 int 142 in_ltms(const login_time_t *ltm, struct tm *tm, time_t *t) 143 { 144 int i = 0; 145 146 while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) { 147 if (in_ltm(ltm + i, tm, t)) 148 return (i); 149 i++; 150 } 151 return (-1); 152 } 153 154 int 155 in_lts(const login_time_t *ltm, time_t *t) 156 { 157 158 return (in_ltms(ltm, localtime(t), t)); 159 } 160