168bbf3adSDavid Nugent /*- 268bbf3adSDavid Nugent * Copyright (c) 1996 by 368bbf3adSDavid Nugent * David Nugent <davidn@blaze.net.au> 468bbf3adSDavid Nugent * All rights reserved. 568bbf3adSDavid Nugent * 668bbf3adSDavid Nugent * Redistribution and use in source and binary forms, with or without 768bbf3adSDavid Nugent * modification, is permitted provided that the following conditions 868bbf3adSDavid Nugent * are met: 968bbf3adSDavid Nugent * 1. Redistributions of source code must retain the above copyright 1068bbf3adSDavid Nugent * notice immediately at the beginning of the file, without modification, 1168bbf3adSDavid Nugent * this list of conditions, and the following disclaimer. 1268bbf3adSDavid Nugent * 2. Redistributions in binary form must reproduce the above copyright 1368bbf3adSDavid Nugent * notice, this list of conditions and the following disclaimer in the 1468bbf3adSDavid Nugent * documentation and/or other materials provided with the distribution. 1568bbf3adSDavid Nugent * 3. This work was done expressly for inclusion into FreeBSD. Other use 1668bbf3adSDavid Nugent * is permitted provided this notation is included. 1768bbf3adSDavid Nugent * 4. Absolutely no warranty of function or purpose is made by the authors. 1868bbf3adSDavid Nugent * 5. Modifications may be freely made to this file providing the above 1968bbf3adSDavid Nugent * conditions are met. 2068bbf3adSDavid Nugent * 2168bbf3adSDavid Nugent * Login period parsing and comparison functions. 2268bbf3adSDavid Nugent */ 2368bbf3adSDavid Nugent 248719c58fSMatthew Dillon #include <sys/cdefs.h> 258719c58fSMatthew Dillon __FBSDID("$FreeBSD$"); 268719c58fSMatthew Dillon 270ebec5d3SMark Murray #include <sys/types.h> 280ebec5d3SMark Murray #include <ctype.h> 290ebec5d3SMark Murray #include <login_cap.h> 3068bbf3adSDavid Nugent #include <stdlib.h> 3168bbf3adSDavid Nugent #include <string.h> 3268bbf3adSDavid Nugent #include <time.h> 3368bbf3adSDavid Nugent 3468bbf3adSDavid Nugent static struct 3568bbf3adSDavid Nugent { 3668bbf3adSDavid Nugent const char *dw; 3768bbf3adSDavid Nugent u_char cn; 3868bbf3adSDavid Nugent u_char fl; 3968bbf3adSDavid Nugent } dws[] = 4068bbf3adSDavid Nugent { 4168bbf3adSDavid Nugent { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 4268bbf3adSDavid Nugent { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 4368bbf3adSDavid Nugent { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 4468bbf3adSDavid Nugent { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 4568bbf3adSDavid Nugent }; 4668bbf3adSDavid Nugent 4768bbf3adSDavid Nugent static char * 4868bbf3adSDavid Nugent parse_time(char * ptr, u_short * t) 4968bbf3adSDavid Nugent { 5068bbf3adSDavid Nugent u_short val; 5168bbf3adSDavid Nugent 5268bbf3adSDavid Nugent for (val = 0; *ptr && isdigit(*ptr); ptr++) 5368bbf3adSDavid Nugent val = (u_short)(val * 10 + (*ptr - '0')); 5468bbf3adSDavid Nugent 5568bbf3adSDavid Nugent *t = (u_short)((val / 100) * 60 + (val % 100)); 5656c04344SDavid Nugent 5768bbf3adSDavid Nugent return ptr; 5868bbf3adSDavid Nugent } 5968bbf3adSDavid Nugent 6056c04344SDavid Nugent 6168bbf3adSDavid Nugent login_time_t 6268bbf3adSDavid Nugent parse_lt(const char * str) 6368bbf3adSDavid Nugent { 6468bbf3adSDavid Nugent login_time_t t; 6568bbf3adSDavid Nugent 6668bbf3adSDavid Nugent memset(&t, 0, sizeof t); 6768bbf3adSDavid Nugent t.lt_dow = LTM_NONE; 6856c04344SDavid Nugent if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { 6968bbf3adSDavid Nugent int i; 7068bbf3adSDavid Nugent login_time_t m = t; 7168bbf3adSDavid Nugent char *p; 7268bbf3adSDavid Nugent char buf[64]; 7368bbf3adSDavid Nugent 7456c04344SDavid Nugent /* Make local copy and force lowercase to simplify parsing */ 7568bbf3adSDavid Nugent p = strncpy(buf, str, sizeof buf); 7668bbf3adSDavid Nugent buf[sizeof buf - 1] = '\0'; 7768bbf3adSDavid Nugent for (i = 0; buf[i]; i++) 7868bbf3adSDavid Nugent buf[i] = (char)tolower(buf[i]); 7968bbf3adSDavid Nugent 8056c04344SDavid Nugent while (isalpha(*p)) { 8156c04344SDavid Nugent 8256c04344SDavid Nugent i = 0; 8356c04344SDavid Nugent while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) 8456c04344SDavid Nugent i++; 8568bbf3adSDavid Nugent if (dws[i].dw == NULL) 8668bbf3adSDavid Nugent break; 8768bbf3adSDavid Nugent m.lt_dow |= dws[i].fl; 8868bbf3adSDavid Nugent p += dws[i].cn; 8968bbf3adSDavid Nugent } 9068bbf3adSDavid Nugent 9168bbf3adSDavid Nugent if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 9268bbf3adSDavid Nugent m.lt_dow |= LTM_ANY; 9368bbf3adSDavid Nugent 9468bbf3adSDavid Nugent if (isdigit(*p)) 9568bbf3adSDavid Nugent p = parse_time(p, &m.lt_start); 9668bbf3adSDavid Nugent else 9768bbf3adSDavid Nugent m.lt_start = 0; 9868bbf3adSDavid Nugent if (*p == '-') 9968bbf3adSDavid Nugent p = parse_time(++p, &m.lt_end); 10068bbf3adSDavid Nugent else 10168bbf3adSDavid Nugent m.lt_end = 1440; 10268bbf3adSDavid Nugent 10368bbf3adSDavid Nugent t = m; 10468bbf3adSDavid Nugent } 10568bbf3adSDavid Nugent return t; 10668bbf3adSDavid Nugent } 10768bbf3adSDavid Nugent 10868bbf3adSDavid Nugent 10968bbf3adSDavid Nugent int 11068bbf3adSDavid Nugent in_ltm(const login_time_t * ltm, struct tm * tt, time_t * ends) 11168bbf3adSDavid Nugent { 11268bbf3adSDavid Nugent int rc = 0; 11368bbf3adSDavid Nugent 11456c04344SDavid Nugent if (tt != NULL) { 11556c04344SDavid Nugent /* First, examine the day of the week */ 11656c04344SDavid Nugent if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { 11756c04344SDavid Nugent /* Convert `current' time to minute of the day */ 11868bbf3adSDavid Nugent u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 11956c04344SDavid Nugent 12068bbf3adSDavid Nugent if (tt->tm_sec > 30) 12168bbf3adSDavid Nugent ++now; 12256c04344SDavid Nugent if (now >= ltm->lt_start && now < ltm->lt_end) { 12368bbf3adSDavid Nugent rc = 2; 12456c04344SDavid Nugent if (ends != NULL) { 12556c04344SDavid Nugent /* If requested, return ending time for this period */ 12668bbf3adSDavid Nugent tt->tm_hour = (int)(ltm->lt_end / 60); 12768bbf3adSDavid Nugent tt->tm_min = (int)(ltm->lt_end % 60); 12868bbf3adSDavid Nugent *ends = mktime(tt); 12968bbf3adSDavid Nugent } 13068bbf3adSDavid Nugent } 13168bbf3adSDavid Nugent } 13268bbf3adSDavid Nugent } 13368bbf3adSDavid Nugent return rc; 13468bbf3adSDavid Nugent } 13568bbf3adSDavid Nugent 13656c04344SDavid Nugent 13768bbf3adSDavid Nugent int 13868bbf3adSDavid Nugent in_lt(const login_time_t * ltm, time_t * t) 13968bbf3adSDavid Nugent { 14068bbf3adSDavid Nugent return in_ltm(ltm, localtime(t), t); 14168bbf3adSDavid Nugent } 14268bbf3adSDavid Nugent 14368bbf3adSDavid Nugent int 14468bbf3adSDavid Nugent in_ltms(const login_time_t * ltm, struct tm * tm, time_t * t) 14568bbf3adSDavid Nugent { 14668bbf3adSDavid Nugent int i = 0; 14768bbf3adSDavid Nugent 14856c04344SDavid Nugent while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) { 14968bbf3adSDavid Nugent if (in_ltm(ltm + i, tm, t)) 15068bbf3adSDavid Nugent return i; 15168bbf3adSDavid Nugent i++; 15268bbf3adSDavid Nugent } 15368bbf3adSDavid Nugent return -1; 15468bbf3adSDavid Nugent } 15568bbf3adSDavid Nugent 15668bbf3adSDavid Nugent int 15768bbf3adSDavid Nugent in_lts(const login_time_t * ltm, time_t * t) 15868bbf3adSDavid Nugent { 15968bbf3adSDavid Nugent return in_ltms(ltm, localtime(t), t); 16068bbf3adSDavid Nugent } 16168bbf3adSDavid Nugent 162