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 * $Id$ 24 */ 25 26 #include <stdio.h> 27 #include <stdlib.h> 28 #include <string.h> 29 #include <time.h> 30 #include <ctype.h> 31 32 #include <sys/types.h> 33 #include <login_cap.h> 34 35 static struct 36 { 37 const char * dw; 38 u_char cn; 39 u_char fl; 40 } dws[] = 41 { 42 { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 43 { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 44 { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 45 { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 46 }; 47 48 static char * 49 parse_time(char * ptr, u_short * t) 50 { 51 u_short val; 52 53 for (val = 0; *ptr && isdigit(*ptr); ptr++) 54 val = (u_short)(val * 10 + (*ptr - '0')); 55 56 *t = (u_short)((val / 100) * 60 + (val % 100)); 57 return ptr; 58 } 59 60 login_time_t 61 parse_lt(const char * str) 62 { 63 login_time_t t; 64 65 memset(&t, 0, sizeof t); 66 t.lt_dow = LTM_NONE; 67 if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) 68 { 69 int i; 70 login_time_t m = t; 71 char * p; 72 char buf[64]; 73 74 /* Make local copy and force lowercase to simplify parsing 75 */ 76 p = strncpy(buf, str, sizeof buf); 77 buf[sizeof buf - 1] = '\0'; 78 for (i = 0; buf[i]; i++) 79 buf[i] = (char)tolower(buf[i]); 80 81 while (isalpha(*p)) 82 { 83 for (i = 0; dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0 ; i++) 84 ; 85 if (dws[i].dw == NULL) 86 break; 87 m.lt_dow |= dws[i].fl; 88 p += dws[i].cn; 89 } 90 91 if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 92 m.lt_dow |= LTM_ANY; 93 94 if (isdigit(*p)) 95 p = parse_time(p, &m.lt_start); 96 else 97 m.lt_start = 0; 98 if (*p == '-') 99 p = parse_time(++p, &m.lt_end); 100 else 101 m.lt_end = 1440; 102 103 t = m; 104 } 105 return t; 106 } 107 108 109 int 110 in_ltm(const login_time_t * ltm, struct tm * tt, time_t * ends) 111 { 112 int rc = 0; 113 114 if (tt != NULL) 115 { 116 /* First, examine the day of the week 117 */ 118 if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) 119 { 120 /* Convert `current' time to minute of the day 121 */ 122 u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 123 if (tt->tm_sec > 30) 124 ++now; 125 if (now >= ltm->lt_start && now < ltm->lt_end) 126 { 127 rc = 2; 128 if (ends != NULL) 129 { 130 /* If requested, return ending time for this period 131 */ 132 tt->tm_hour = (int)(ltm->lt_end / 60); 133 tt->tm_min = (int)(ltm->lt_end % 60); 134 *ends = mktime(tt); 135 } 136 } 137 } 138 } 139 return rc; 140 } 141 142 int 143 in_lt(const login_time_t * ltm, time_t * t) 144 { 145 return in_ltm(ltm, localtime(t), t); 146 } 147 148 int 149 in_ltms(const login_time_t * ltm, struct tm * tm, time_t * t) 150 { 151 int i = 0; 152 153 while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) 154 { 155 if (in_ltm(ltm + i, tm, t)) 156 return i; 157 i++; 158 } 159 return -1; 160 } 161 162 int 163 in_lts(const login_time_t * ltm, time_t * t) 164 { 165 return in_ltms(ltm, localtime(t), t); 166 } 167 168