login_times.c revision 25670
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 * 2325670Sdavidn * $Id: login_times.c,v 1.4 1997/02/22 15:08:27 peter Exp $ 2421288Sdavidn */ 2521288Sdavidn 2621288Sdavidn#include <stdio.h> 2721288Sdavidn#include <stdlib.h> 2821288Sdavidn#include <string.h> 2921288Sdavidn#include <time.h> 3021288Sdavidn#include <ctype.h> 3121288Sdavidn 3221329Sbde#include <sys/types.h> 3321288Sdavidn#include <login_cap.h> 3421288Sdavidn 3521288Sdavidnstatic struct 3621288Sdavidn{ 3725670Sdavidn const char *dw; 3825670Sdavidn u_char cn; 3925670Sdavidn u_char fl; 4021288Sdavidn} dws[] = 4121288Sdavidn{ 4225670Sdavidn { "su", 2, LTM_SUN }, { "mo", 2, LTM_MON }, { "tu", 2, LTM_TUE }, 4325670Sdavidn { "we", 2, LTM_WED }, { "th", 2, LTM_THU }, { "fr", 2, LTM_FRI }, 4425670Sdavidn { "sa", 2, LTM_SAT }, { "any",3, LTM_ANY }, { "all",3, LTM_ANY }, 4525670Sdavidn { "wk", 2, LTM_WK }, { "wd", 2, LTM_WD }, { NULL, 0, 0 } 4621288Sdavidn}; 4721288Sdavidn 4821288Sdavidnstatic char * 4921288Sdavidnparse_time(char * ptr, u_short * t) 5021288Sdavidn{ 5125670Sdavidn u_short val; 5221288Sdavidn 5325670Sdavidn for (val = 0; *ptr && isdigit(*ptr); ptr++) 5425670Sdavidn val = (u_short)(val * 10 + (*ptr - '0')); 5521288Sdavidn 5625670Sdavidn *t = (u_short)((val / 100) * 60 + (val % 100)); 5725670Sdavidn 5825670Sdavidn return ptr; 5921288Sdavidn} 6021288Sdavidn 6125670Sdavidn 6221288Sdavidnlogin_time_t 6321288Sdavidnparse_lt(const char * str) 6421288Sdavidn{ 6525670Sdavidn login_time_t t; 6621288Sdavidn 6725670Sdavidn memset(&t, 0, sizeof t); 6825670Sdavidn t.lt_dow = LTM_NONE; 6925670Sdavidn if (str && *str && strcmp(str, "Never") != 0 && strcmp(str, "None") != 0) { 7025670Sdavidn int i; 7125670Sdavidn login_time_t m = t; 7225670Sdavidn char *p; 7325670Sdavidn char buf[64]; 7421288Sdavidn 7525670Sdavidn /* Make local copy and force lowercase to simplify parsing */ 7625670Sdavidn p = strncpy(buf, str, sizeof buf); 7725670Sdavidn buf[sizeof buf - 1] = '\0'; 7825670Sdavidn for (i = 0; buf[i]; i++) 7925670Sdavidn buf[i] = (char)tolower(buf[i]); 8021288Sdavidn 8125670Sdavidn while (isalpha(*p)) { 8221288Sdavidn 8325670Sdavidn i = 0; 8425670Sdavidn while (dws[i].dw && strncmp(p, dws[i].dw, dws[i].cn) != 0) 8525670Sdavidn i++; 8625670Sdavidn if (dws[i].dw == NULL) 8725670Sdavidn break; 8825670Sdavidn m.lt_dow |= dws[i].fl; 8925670Sdavidn p += dws[i].cn; 9025670Sdavidn } 9121288Sdavidn 9225670Sdavidn if (m.lt_dow == LTM_NONE) /* No (valid) prefix, assume any */ 9325670Sdavidn m.lt_dow |= LTM_ANY; 9421288Sdavidn 9525670Sdavidn if (isdigit(*p)) 9625670Sdavidn p = parse_time(p, &m.lt_start); 9725670Sdavidn else 9825670Sdavidn m.lt_start = 0; 9925670Sdavidn if (*p == '-') 10025670Sdavidn p = parse_time(++p, &m.lt_end); 10125670Sdavidn else 10225670Sdavidn m.lt_end = 1440; 10325670Sdavidn 10425670Sdavidn t = m; 10525670Sdavidn } 10625670Sdavidn return t; 10721288Sdavidn} 10821288Sdavidn 10921288Sdavidn 11021288Sdavidnint 11121288Sdavidnin_ltm(const login_time_t * ltm, struct tm * tt, time_t * ends) 11221288Sdavidn{ 11325670Sdavidn int rc = 0; 11421288Sdavidn 11525670Sdavidn if (tt != NULL) { 11625670Sdavidn /* First, examine the day of the week */ 11725670Sdavidn if ((u_char)(0x01 << tt->tm_wday) & ltm->lt_dow) { 11825670Sdavidn /* Convert `current' time to minute of the day */ 11925670Sdavidn u_short now = (u_short)((tt->tm_hour * 60) + tt->tm_min); 12025670Sdavidn 12125670Sdavidn if (tt->tm_sec > 30) 12225670Sdavidn ++now; 12325670Sdavidn if (now >= ltm->lt_start && now < ltm->lt_end) { 12425670Sdavidn rc = 2; 12525670Sdavidn if (ends != NULL) { 12625670Sdavidn /* If requested, return ending time for this period */ 12725670Sdavidn tt->tm_hour = (int)(ltm->lt_end / 60); 12825670Sdavidn tt->tm_min = (int)(ltm->lt_end % 60); 12925670Sdavidn *ends = mktime(tt); 13025670Sdavidn } 13125670Sdavidn } 13221288Sdavidn } 13321288Sdavidn } 13425670Sdavidn return rc; 13521288Sdavidn} 13621288Sdavidn 13725670Sdavidn 13821288Sdavidnint 13921288Sdavidnin_lt(const login_time_t * ltm, time_t * t) 14021288Sdavidn{ 14125670Sdavidn return in_ltm(ltm, localtime(t), t); 14221288Sdavidn} 14321288Sdavidn 14421288Sdavidnint 14521288Sdavidnin_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)) 15125670Sdavidn return i; 15225670Sdavidn i++; 15325670Sdavidn } 15425670Sdavidn return -1; 15521288Sdavidn} 15621288Sdavidn 15721288Sdavidnint 15821288Sdavidnin_lts(const login_time_t * ltm, time_t * t) 15921288Sdavidn{ 16025670Sdavidn return in_ltms(ltm, localtime(t), t); 16121288Sdavidn} 16221288Sdavidn 163