eris

Very small inetd http server
git clone https://git.woozle.org/neale/eris.git

Neale Pickett  ·  2017-08-05

timerfc.c

  1/*
  2 *   Code in this file is from mathopd <http://www.mathopd.org/>
  3 *
  4 *   Copyright 1996, Michiel Boland.
  5 *   All rights reserved.
  6 *
  7 *   Redistribution and use in source and binary forms, with or
  8 *   without modification, are permitted provided that the following
  9 *   conditions are met:
 10 *
 11 *   1. Redistributions of source code must retain the above
 12 *      copyright notice, this list of conditions and the following
 13 *      disclaimer.
 14 *
 15 *   2. Redistributions in binary form must reproduce the above
 16 *      copyright notice, this list of conditions and the following
 17 *      disclaimer in the documentation and/or other materials
 18 *      provided with the distribution.
 19 *
 20 *   3. The name of the author may not be used to endorse or promote
 21 *      products derived from this software without specific prior
 22 *      written permission.
 23 *
 24 *   THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
 25 *   EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 26 *   THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 27 *   PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
 28 *   BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 29 *   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 30 *   TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 31 *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 32 *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 33 *   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 34 *   IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 35 *   THE POSSIBILITY OF SUCH DAMAGE.
 36 */
 37
 38#include <time.h>
 39#include <ctype.h>
 40#include <string.h>
 41#include "timerfc.h"
 42
 43time_t
 44timerfc(const char *s)
 45{
 46    static const int daytab[2][12] = {
 47        {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334},
 48        {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335}
 49    };
 50    unsigned        sec,
 51                    min,
 52                    hour,
 53                    day,
 54                    mon,
 55                    year;
 56    char            month[3];
 57    int             c;
 58    unsigned        n;
 59    char            flag;
 60    char            state;
 61    char            isctime;
 62    enum { D_START, D_END, D_MON, D_DAY, D_YEAR, D_HOUR, D_MIN, D_SEC };
 63
 64    sec = 60;
 65    min = 60;
 66    hour = 24;
 67    day = 32;
 68    year = 1969;
 69    isctime = 0;
 70    month[0] = 0;
 71    state = D_START;
 72    n = 0;
 73    flag = 1;
 74    do {
 75        c = *s++;
 76        switch (state) {
 77        case D_START:
 78            if (c == ' ') {
 79                state = D_MON;
 80                isctime = 1;
 81            } else if (c == ',')
 82                state = D_DAY;
 83            break;
 84        case D_MON:
 85            if (isalpha(c)) {
 86                if (n < 3)
 87                    month[n++] = c;
 88            } else {
 89                if (n < 3)
 90                    return -1;
 91                n = 0;
 92                state = isctime ? D_DAY : D_YEAR;
 93            }
 94            break;
 95        case D_DAY:
 96            if (c == ' ' && flag);
 97            else if (isdigit(c)) {
 98                flag = 0;
 99                n = 10 * n + (c - '0');
100            } else {
101                day = n;
102                n = 0;
103                state = isctime ? D_HOUR : D_MON;
104            }
105            break;
106        case D_YEAR:
107            if (isdigit(c))
108                n = 10 * n + (c - '0');
109            else {
110                year = n;
111                n = 0;
112                state = isctime ? D_END : D_HOUR;
113            }
114            break;
115        case D_HOUR:
116            if (isdigit(c))
117                n = 10 * n + (c - '0');
118            else {
119                hour = n;
120                n = 0;
121                state = D_MIN;
122            }
123            break;
124        case D_MIN:
125            if (isdigit(c))
126                n = 10 * n + (c - '0');
127            else {
128                min = n;
129                n = 0;
130                state = D_SEC;
131            }
132            break;
133        case D_SEC:
134            if (isdigit(c))
135                n = 10 * n + (c - '0');
136            else {
137                sec = n;
138                n = 0;
139                state = isctime ? D_YEAR : D_END;
140            }
141            break;
142        }
143    } while (state != D_END && c);
144    switch (month[0]) {
145    case 'A':
146        mon = (month[1] == 'p') ? 4 : 8;
147        break;
148    case 'D':
149        mon = 12;
150        break;
151    case 'F':
152        mon = 2;
153        break;
154    case 'J':
155        mon = (month[1] == 'a') ? 1 : ((month[2] == 'l') ? 7 : 6);
156        break;
157    case 'M':
158        mon = (month[2] == 'r') ? 3 : 5;
159        break;
160    case 'N':
161        mon = 11;
162        break;
163    case 'O':
164        mon = 10;
165        break;
166    case 'S':
167        mon = 9;
168        break;
169    default:
170        return -1;
171    }
172    if (year <= 100)
173        year += (year < 70) ? 2000 : 1900;
174    --mon;
175    --day;
176    if (sec >= 60 || min >= 60 || hour >= 60 || day >= 31)
177        return -1;
178    if (year < 1970)
179        return 0;
180    return sec + 60L * (min + 60L * (hour + 24L * (day +
181                                                   daytab[year % 4 == 0
182                                                          && (year % 100
183                                                              || year %
184                                                              400 ==
185                                                              0)][mon] +
186                                                   365L * (year - 1970L) +
187                                                   ((year -
188                                                     1969L) >> 2))));
189}
190
191char           *
192rfctime(time_t t, char *buf)
193{
194    struct tm      *tp;
195
196    /* ntp: in glibc, this triggers a bunch of needless I/O. */
197    tp = gmtime(&t);
198    if (tp == 0) {
199        strcpy(buf, "?");
200        return buf;
201    }
202    strftime(buf, 31, "%a, %d %b %Y %H:%M:%S GMT", tp);
203    return buf;
204}