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