login_times.c revision 184087
11638Srgrimes/*- 21638Srgrimes * Copyright (c) 1996 by 31638Srgrimes * David Nugent <davidn@blaze.net.au> 41638Srgrimes * All rights reserved. 51638Srgrimes * 61638Srgrimes * Redistribution and use in source and binary forms, with or without 71638Srgrimes * modification, is permitted provided that the following conditions 81638Srgrimes * are met: 91638Srgrimes * 1. Redistributions of source code must retain the above copyright 101638Srgrimes * notice immediately at the beginning of the file, without modification, 111638Srgrimes * this list of conditions, and the following disclaimer. 121638Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 131638Srgrimes * notice, this list of conditions and the following disclaimer in the 141638Srgrimes * documentation and/or other materials provided with the distribution. 151638Srgrimes * 3. This work was done expressly for inclusion into FreeBSD. Other use 161638Srgrimes * is permitted provided this notation is included. 171638Srgrimes * 4. Absolutely no warranty of function or purpose is made by the authors. 181638Srgrimes * 5. Modifications may be freely made to this file providing the above 191638Srgrimes * conditions are met. 201638Srgrimes * 211638Srgrimes * Login period parsing and comparison functions. 221638Srgrimes */ 231638Srgrimes 241638Srgrimes#include <sys/cdefs.h> 251638Srgrimes__FBSDID("$FreeBSD: head/lib/libutil/login_times.c 184087 2008-10-20 17:09:50Z des $"); 261638Srgrimes 271638Srgrimes#include <sys/types.h> 281638Srgrimes#include <ctype.h> 291638Srgrimes#include <login_cap.h> 301638Srgrimes#include <stdlib.h> 311638Srgrimes#include <string.h> 321638Srgrimes#include <time.h> 3350476Speter 341638Srgrimesstatic struct 351638Srgrimes{ 361638Srgrimes const char *dw; 371638Srgrimes u_char cn; 381638Srgrimes u_char fl; 391638Srgrimes} dws[] = 401638Srgrimes{ 411638Srgrimes { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 421638Srgrimes { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 431638Srgrimes { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 441638Srgrimes { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 451638Srgrimes}; 461638Srgrimes 471638Srgrimesstatic char * 48107631Sruparse_time(char * ptr, u_short * t) 49107631Sru{ 50107631Sru u_short val; 51107631Sru 52107631Sru for (val = 0; *ptr && isdigit(*ptr); ptr++) 5379727Sschweikh val = (u_short)(val * 10 + (*ptr - '0')); 5479727Sschweikh 5579727Sschweikh *t = (u_short)((val / 100) * 60 + (val % 100)); 5679727Sschweikh 5779727Sschweikh return (ptr); 5879727Sschweikh} 5979727Sschweikh 6079727Sschweikh 6179727Sschweikhlogin_time_t 6279727Sschweikhparse_lt(const char *str) 63107631Sru{ 641638Srgrimes login_time_t t; 651638Srgrimes 661638Srgrimes memset(&t, 0, sizeof t); 671638Srgrimes t.lt_dow = LTM_NONE; 681638Srgrimes if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { 691638Srgrimes int i; 70107631Sru login_time_t m = t; 71107631Sru char *p; 72107631Sru char buf[64]; 73107631Sru 74107631Sru /* Make local copy and force lowercase to simplify parsing */ 7579727Sschweikh strlcpy(buf, str, sizeof buf); 7679727Sschweikh for (i = 0; buf[i]; i++) 7779727Sschweikh buf[i] = (char)tolower(buf[i]); 7879727Sschweikh p = buf; 7979727Sschweikh 8079727Sschweikh while (isalpha(*p)) { 8179727Sschweikh 8279727Sschweikh i = 0; 8379727Sschweikh while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) 8479727Sschweikh i++; 85107631Sru if (dws[i].dw == NULL) 861638Srgrimes break; 871638Srgrimes m.lt_dow |= dws[i].fl; 881638Srgrimes p += dws[i].cn; 891638Srgrimes } 901638Srgrimes 911638Srgrimes if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 92107631Sru m.lt_dow |= LTM_ANY; 93107631Sru 94107631Sru if (isdigit(*p)) 95107631Sru p = parse_time(p, &m.lt_start); 96107631Sru else 9779727Sschweikh m.lt_start = 0; 9879727Sschweikh if (*p == '-') 9979727Sschweikh p = parse_time(++p, &m.lt_end); 10079727Sschweikh else 10179727Sschweikh m.lt_end = 1440; 10279727Sschweikh 10379727Sschweikh t = m; 10479727Sschweikh } 10579727Sschweikh return (t); 10679727Sschweikh} 107107631Sru 1081638Srgrimes 1091638Srgrimesint 1101638Srgrimesin_ltm(const login_time_t *ltm, struct tm *tt, time_t *ends) 1111638Srgrimes{ 1121638Srgrimes int rc = 0; 1131638Srgrimes 1141638Srgrimes if (tt != NULL) { 11568962Sru /* First, examine the day of the week */ 1161638Srgrimes if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { 1171638Srgrimes /* Convert `current' time to minute of the day */ 118 u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 119 120 if (tt->tm_sec > 30) 121 ++now; 122 if (now >= ltm->lt_start && now < ltm->lt_end) { 123 rc = 2; 124 if (ends != NULL) { 125 /* If requested, return ending time for this period */ 126 tt->tm_hour = (int)(ltm->lt_end / 60); 127 tt->tm_min = (int)(ltm->lt_end % 60); 128 *ends = mktime(tt); 129 } 130 } 131 } 132 } 133 return (rc); 134} 135 136 137int 138in_lt(const login_time_t *ltm, time_t *t) 139{ 140 141 return (in_ltm(ltm, localtime(t), t)); 142} 143 144int 145in_ltms(const login_time_t *ltm, struct tm *tm, time_t *t) 146{ 147 int i = 0; 148 149 while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) { 150 if (in_ltm(ltm + i, tm, t)) 151 return (i); 152 i++; 153 } 154 return (-1); 155} 156 157int 158in_lts(const login_time_t *ltm, time_t *t) 159{ 160 161 return (in_ltms(ltm, localtime(t), t)); 162} 163