121288Sdavidn/*- 221288Sdavidn * Copyright (c) 1996 by 321288Sdavidn * David Nugent <davidn@blaze.net.au> 421288Sdavidn * All rights reserved. 521288Sdavidn * 621288Sdavidn * Redistribution and use in source and binary forms, with or without 721288Sdavidn * modification, is permitted provided that the following conditions 821288Sdavidn * are met: 921288Sdavidn * 1. Redistributions of source code must retain the above copyright 1021288Sdavidn * notice immediately at the beginning of the file, without modification, 1121288Sdavidn * this list of conditions, and the following disclaimer. 1221288Sdavidn * 2. Redistributions in binary form must reproduce the above copyright 1321288Sdavidn * notice, this list of conditions and the following disclaimer in the 1421288Sdavidn * documentation and/or other materials provided with the distribution. 1521288Sdavidn * 3. This work was done expressly for inclusion into FreeBSD. Other use 1621288Sdavidn * is permitted provided this notation is included. 1721288Sdavidn * 4. Absolutely no warranty of function or purpose is made by the authors. 1821288Sdavidn * 5. Modifications may be freely made to this file providing the above 1921288Sdavidn * conditions are met. 2021288Sdavidn * 2121288Sdavidn * Login period parsing and comparison functions. 2221288Sdavidn */ 2321288Sdavidn 2484225Sdillon#include <sys/cdefs.h> 2584225Sdillon__FBSDID("$FreeBSD$"); 2684225Sdillon 27116344Smarkm#include <sys/types.h> 28116344Smarkm#include <ctype.h> 29116344Smarkm#include <login_cap.h> 3021288Sdavidn#include <stdlib.h> 3121288Sdavidn#include <string.h> 3221288Sdavidn#include <time.h> 3321288Sdavidn 3421288Sdavidnstatic struct 3521288Sdavidn{ 3625670Sdavidn const char *dw; 37184086Sdes u_char cn; 38184086Sdes u_char fl; 3921288Sdavidn} dws[] = 4021288Sdavidn{ 4125670Sdavidn { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 4225670Sdavidn { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 43184085Sdes { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 4425670Sdavidn { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 4521288Sdavidn}; 4621288Sdavidn 4721288Sdavidnstatic char * 4821288Sdavidnparse_time(char * ptr, u_short * t) 4921288Sdavidn{ 5025670Sdavidn u_short val; 5121288Sdavidn 5225670Sdavidn for (val = 0; *ptr && isdigit(*ptr); ptr++) 5325670Sdavidn val = (u_short)(val * 10 + (*ptr - '0')); 5421288Sdavidn 5525670Sdavidn *t = (u_short)((val / 100) * 60 + (val % 100)); 5625670Sdavidn 57184086Sdes return (ptr); 5821288Sdavidn} 5921288Sdavidn 6025670Sdavidn 6121288Sdavidnlogin_time_t 62184086Sdesparse_lt(const char *str) 6321288Sdavidn{ 6425670Sdavidn login_time_t t; 6521288Sdavidn 6625670Sdavidn memset(&t, 0, sizeof t); 6725670Sdavidn t.lt_dow = LTM_NONE; 6825670Sdavidn if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { 69184086Sdes int i; 70184086Sdes login_time_t m = t; 7125670Sdavidn char *p; 72184086Sdes char buf[64]; 7321288Sdavidn 7425670Sdavidn /* Make local copy and force lowercase to simplify parsing */ 75184085Sdes strlcpy(buf, str, sizeof buf); 7625670Sdavidn for (i = 0; buf[i]; i++) 7725670Sdavidn buf[i] = (char)tolower(buf[i]); 78184085Sdes p = buf; 7921288Sdavidn 8025670Sdavidn while (isalpha(*p)) { 8121288Sdavidn 8225670Sdavidn i = 0; 8325670Sdavidn while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) 8425670Sdavidn i++; 8525670Sdavidn if (dws[i].dw == NULL) 8625670Sdavidn break; 8725670Sdavidn m.lt_dow |= dws[i].fl; 8825670Sdavidn p += dws[i].cn; 8925670Sdavidn } 9021288Sdavidn 9125670Sdavidn if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 9225670Sdavidn m.lt_dow |= LTM_ANY; 9321288Sdavidn 9425670Sdavidn if (isdigit(*p)) 9525670Sdavidn p = parse_time(p, &m.lt_start); 9625670Sdavidn else 9725670Sdavidn m.lt_start = 0; 9825670Sdavidn if (*p == '-') 99252376Skientzle p = parse_time(p + 1, &m.lt_end); 10025670Sdavidn else 10125670Sdavidn m.lt_end = 1440; 10225670Sdavidn 10325670Sdavidn t = m; 10425670Sdavidn } 105184086Sdes return (t); 10621288Sdavidn} 10721288Sdavidn 10821288Sdavidn 10921288Sdavidnint 110184086Sdesin_ltm(const login_time_t *ltm, struct tm *tt, time_t *ends) 11121288Sdavidn{ 11225670Sdavidn int rc = 0; 11321288Sdavidn 11425670Sdavidn if (tt != NULL) { 11525670Sdavidn /* First, examine the day of the week */ 11625670Sdavidn if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { 11725670Sdavidn /* Convert `current' time to minute of the day */ 11825670Sdavidn u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 11925670Sdavidn 12025670Sdavidn if (tt->tm_sec > 30) 12125670Sdavidn ++now; 12225670Sdavidn if (now >= ltm->lt_start && now < ltm->lt_end) { 12325670Sdavidn rc = 2; 12425670Sdavidn if (ends != NULL) { 12525670Sdavidn /* If requested, return ending time for this period */ 12625670Sdavidn tt->tm_hour = (int)(ltm->lt_end / 60); 12725670Sdavidn tt->tm_min = (int)(ltm->lt_end % 60); 12825670Sdavidn *ends = mktime(tt); 12925670Sdavidn } 13025670Sdavidn } 13121288Sdavidn } 13221288Sdavidn } 133184086Sdes return (rc); 13421288Sdavidn} 13521288Sdavidn 13625670Sdavidn 13721288Sdavidnint 138184086Sdesin_lt(const login_time_t *ltm, time_t *t) 13921288Sdavidn{ 140184087Sdes 141184086Sdes return (in_ltm(ltm, localtime(t), t)); 14221288Sdavidn} 14321288Sdavidn 14421288Sdavidnint 145184087Sdesin_ltms(const login_time_t *ltm, struct tm *tm, time_t *t) 14621288Sdavidn{ 14725670Sdavidn int i = 0; 14821288Sdavidn 14925670Sdavidn while (i < LC_MAXTIMES && ltm[i].lt_dow != LTM_NONE) { 15025670Sdavidn if (in_ltm(ltm + i, tm, t)) 151184086Sdes return (i); 15225670Sdavidn i++; 15325670Sdavidn } 154184086Sdes return (-1); 15521288Sdavidn} 15621288Sdavidn 15721288Sdavidnint 158184086Sdesin_lts(const login_time_t *ltm, time_t *t) 15921288Sdavidn{ 160184087Sdes 161184086Sdes return (in_ltms(ltm, localtime(t), t)); 16221288Sdavidn} 163