xref: /freebsd/lib/libutil/login_times.c (revision 0ddf9be1f0723916ebd4feb7313d64dffab0c2bb)
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