diff options
author | gad <gad@FreeBSD.org> | 2003-09-12 01:33:37 +0000 |
---|---|---|
committer | gad <gad@FreeBSD.org> | 2003-09-12 01:33:37 +0000 |
commit | 60909145e3ca1c6c165667bea0e781fb1526585d (patch) | |
tree | a3619aabe29cf1a57bbd4719ffeca4a8194fd85d /usr.sbin/newsyslog | |
parent | 671348b0ff54db3e2b5c4fbfea1b55a5a05e055f (diff) | |
download | FreeBSD-src-60909145e3ca1c6c165667bea0e781fb1526585d.zip FreeBSD-src-60909145e3ca1c6c165667bea0e781fb1526585d.tar.gz |
Move the parse8601 and parseDWM routines into a new ptime.c file. The
only code-change is to add a "next_time" parameter to both routines (and
that is not used yet). A later update will make "next_time" more useful.
MFC after: 20 days
Diffstat (limited to 'usr.sbin/newsyslog')
-rw-r--r-- | usr.sbin/newsyslog/Makefile | 1 | ||||
-rw-r--r-- | usr.sbin/newsyslog/extern.h | 48 | ||||
-rw-r--r-- | usr.sbin/newsyslog/newsyslog.c | 223 | ||||
-rw-r--r-- | usr.sbin/newsyslog/ptimes.c | 267 |
4 files changed, 320 insertions, 219 deletions
diff --git a/usr.sbin/newsyslog/Makefile b/usr.sbin/newsyslog/Makefile index ab06f3a..61c2b08 100644 --- a/usr.sbin/newsyslog/Makefile +++ b/usr.sbin/newsyslog/Makefile @@ -2,6 +2,7 @@ PROG= newsyslog MAN= newsyslog.8 +SRCS= newsyslog.c ptimes.c WARNS?= 2 diff --git a/usr.sbin/newsyslog/extern.h b/usr.sbin/newsyslog/extern.h new file mode 100644 index 0000000..05ef92c --- /dev/null +++ b/usr.sbin/newsyslog/extern.h @@ -0,0 +1,48 @@ +/*- + * ------+---------+---------+---------+---------+---------+---------+---------* + * Copyright (c) 2003 - Garance Alistair Drosehn <gad@FreeBSD.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the FreeBSD Project. + * + * ------+---------+---------+---------+---------+---------+---------+---------* + * $FreeBSD$ + * ------+---------+---------+---------+---------+---------+---------+---------* + */ + +#include <sys/cdefs.h> +#include <time.h> + +extern int noaction; /* command-line option */ +extern int verbose; /* command-line option */ + +extern time_t dbg_timenow; +extern time_t timenow; + +__BEGIN_DECLS +time_t parse8601(const char *_srcstr, time_t *_next_time); +time_t parseDWM(char *_srcstr, time_t *_next_time); +__END_DECLS diff --git a/usr.sbin/newsyslog/newsyslog.c b/usr.sbin/newsyslog/newsyslog.c index 3c6a42c..a9d1fd2 100644 --- a/usr.sbin/newsyslog/newsyslog.c +++ b/usr.sbin/newsyslog/newsyslog.c @@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$"); #include <unistd.h> #include "pathnames.h" +#include "extern.h" /* * Bit-values for the 'flags' parsed from a config-file entry. @@ -149,8 +150,6 @@ static void movefile(char *from, char *to, int perm, uid_t owner_uid, gid_t group_gid); static void createdir(const struct conf_entry *ent, char *dirpart); static void createlog(const struct conf_entry *ent); -static time_t parse8601(const char *s); -static time_t parseDWM(char *s); /* * All the following are defined to work on an 'int', in the @@ -597,7 +596,7 @@ parse_doption(const char *doption) * The "TimeNow" debugging option. This probably will * be off by an hour when crossing a timezone change. */ - dbg_timenow = parse8601(doption + sizeof(TN) - 1); + dbg_timenow = parse8601(doption + sizeof(TN) - 1, NULL); if (dbg_timenow == (time_t)-1) { warnx("Malformed time given on -D %s", doption); return (0); /* failure */ @@ -1037,10 +1036,10 @@ parse_file(FILE *cf, const char *cfname, struct conf_entry **work_p, *ep != '$') errx(1, "malformed interval/at:\n%s", errline); if (*ep == '@') { - working->trim_at = parse8601(ep + 1); + working->trim_at = parse8601(ep + 1, NULL); working->flags |= CE_TRIMAT; } else if (*ep == '$') { - working->trim_at = parseDWM(ep + 1); + working->trim_at = parseDWM(ep + 1, NULL); working->flags |= CE_TRIMAT; } if (working->flags & CE_TRIMAT) { @@ -1779,217 +1778,3 @@ createlog(const struct conf_entry *ent) if (fd >= 0) close(fd); } - -/*- - * Parse a limited subset of ISO 8601. The specific format is as follows: - * - * [CC[YY[MM[DD]]]][THH[MM[SS]]] (where `T' is the literal letter) - * - * We don't accept a timezone specification; missing fields (including timezone) - * are defaulted to the current date but time zero. - */ -static time_t -parse8601(const char *s) -{ - char *t; - time_t tsecs; - struct tm tm, *tmp; - long l; - - tmp = localtime(&timenow); - tm = *tmp; - - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - - l = strtol(s, &t, 10); - if (l < 0 || l >= INT_MAX || (*t != '\0' && *t != 'T')) - return (-1); - - /* - * Now t points either to the end of the string (if no time was - * provided) or to the letter `T' which separates date and time in - * ISO 8601. The pointer arithmetic is the same for either case. - */ - switch (t - s) { - case 8: - tm.tm_year = ((l / 1000000) - 19) * 100; - l = l % 1000000; - case 6: - tm.tm_year -= tm.tm_year % 100; - tm.tm_year += l / 10000; - l = l % 10000; - case 4: - tm.tm_mon = (l / 100) - 1; - l = l % 100; - case 2: - tm.tm_mday = l; - case 0: - break; - default: - return (-1); - } - - /* sanity check */ - if (tm.tm_year < 70 || tm.tm_mon < 0 || tm.tm_mon > 12 - || tm.tm_mday < 1 || tm.tm_mday > 31) - return (-1); - - if (*t != '\0') { - s = ++t; - l = strtol(s, &t, 10); - if (l < 0 || l >= INT_MAX || (*t != '\0' && !isspace(*t))) - return (-1); - - switch (t - s) { - case 6: - tm.tm_sec = l % 100; - l /= 100; - case 4: - tm.tm_min = l % 100; - l /= 100; - case 2: - tm.tm_hour = l; - case 0: - break; - default: - return (-1); - } - - /* sanity check */ - if (tm.tm_sec < 0 || tm.tm_sec > 60 || tm.tm_min < 0 - || tm.tm_min > 59 || tm.tm_hour < 0 || tm.tm_hour > 23) - return (-1); - } - - tsecs = mktime(&tm); - /* - * Check for invalid times, including things like the missing - * hour when switching from "standard time" to "daylight saving". - */ - if (tsecs == (time_t)-1) - tsecs = (time_t)-2; - return (tsecs); -} - -/*- - * Parse a cyclic time specification, the format is as follows: - * - * [Dhh] or [Wd[Dhh]] or [Mdd[Dhh]] - * - * to rotate a logfile cyclic at - * - * - every day (D) within a specific hour (hh) (hh = 0...23) - * - once a week (W) at a specific day (d) OR (d = 0..6, 0 = Sunday) - * - once a month (M) at a specific day (d) (d = 1..31,l|L) - * - * We don't accept a timezone specification; missing fields - * are defaulted to the current date but time zero. - */ -static time_t -parseDWM(char *s) -{ - char *t; - time_t tsecs; - struct tm tm, *tmp; - long l; - int nd; - static int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; - int WMseen = 0; - int Dseen = 0; - - tmp = localtime(&timenow); - tm = *tmp; - - /* set no. of days per month */ - - nd = mtab[tm.tm_mon]; - - if (tm.tm_mon == 1) { - if (((tm.tm_year + 1900) % 4 == 0) && - ((tm.tm_year + 1900) % 100 != 0) && - ((tm.tm_year + 1900) % 400 == 0)) { - nd++; /* leap year, 29 days in february */ - } - } - tm.tm_hour = tm.tm_min = tm.tm_sec = 0; - - for (;;) { - switch (*s) { - case 'D': - if (Dseen) - return (-1); - Dseen++; - s++; - l = strtol(s, &t, 10); - if (l < 0 || l > 23) - return (-1); - tm.tm_hour = l; - break; - - case 'W': - if (WMseen) - return (-1); - WMseen++; - s++; - l = strtol(s, &t, 10); - if (l < 0 || l > 6) - return (-1); - if (l != tm.tm_wday) { - int save; - - if (l < tm.tm_wday) { - save = 6 - tm.tm_wday; - save += (l + 1); - } else { - save = l - tm.tm_wday; - } - - tm.tm_mday += save; - - if (tm.tm_mday > nd) { - tm.tm_mon++; - tm.tm_mday = tm.tm_mday - nd; - } - } - break; - - case 'M': - if (WMseen) - return (-1); - WMseen++; - s++; - if (tolower(*s) == 'l') { - tm.tm_mday = nd; - s++; - t = s; - } else { - l = strtol(s, &t, 10); - if (l < 1 || l > 31) - return (-1); - - if (l > nd) - return (-1); - tm.tm_mday = l; - } - break; - - default: - return (-1); - break; - } - - if (*t == '\0' || isspace(*t)) - break; - else - s = t; - } - - tsecs = mktime(&tm); - /* - * Check for invalid times, including things like the missing - * hour when switching from "standard time" to "daylight saving". - */ - if (tsecs == (time_t)-1) - tsecs = (time_t)-2; - return (tsecs); -} diff --git a/usr.sbin/newsyslog/ptimes.c b/usr.sbin/newsyslog/ptimes.c new file mode 100644 index 0000000..c00b08c --- /dev/null +++ b/usr.sbin/newsyslog/ptimes.c @@ -0,0 +1,267 @@ +/*- + * ------+---------+---------+---------+---------+---------+---------+---------* + * Initial version of parse8601 was originally added to newsyslog.c in + * FreeBSD on Jan 22, 1999 by Garrett Wollman <wollman@FreeBSD.org>. + * Initial version of parseDWM was originally added to newsyslog.c in + * FreeBSD on Apr 4, 2000 by Hellmuth Michaelis <hm@FreeBSD.org>. + * + * Copyright (c) 2003 - Garance Alistair Drosehn <gad@FreeBSD.org>. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation + * are those of the authors and should not be interpreted as representing + * official policies, either expressed or implied, of the FreeBSD Project. + * + * ------+---------+---------+---------+---------+---------+---------+---------* + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <time.h> + +#include "extern.h" + +/*- + * Parse a limited subset of ISO 8601. The specific format is as follows: + * + * [CC[YY[MM[DD]]]][THH[MM[SS]]] (where `T' is the literal letter) + * + * We don't accept a timezone specification; missing fields (including timezone) + * are defaulted to the current date but time zero. + */ +time_t +parse8601(const char *s, time_t *next_time) +{ + char *t; + time_t tsecs; + struct tm tm, *tmp; + long l; + + tmp = localtime(&timenow); + tm = *tmp; + if (next_time != NULL) + *next_time = (time_t)-1; + + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + + l = strtol(s, &t, 10); + if (l < 0 || l >= INT_MAX || (*t != '\0' && *t != 'T')) + return (-1); + + /* + * Now t points either to the end of the string (if no time was + * provided) or to the letter `T' which separates date and time in + * ISO 8601. The pointer arithmetic is the same for either case. + */ + switch (t - s) { + case 8: + tm.tm_year = ((l / 1000000) - 19) * 100; + l = l % 1000000; + case 6: + tm.tm_year -= tm.tm_year % 100; + tm.tm_year += l / 10000; + l = l % 10000; + case 4: + tm.tm_mon = (l / 100) - 1; + l = l % 100; + case 2: + tm.tm_mday = l; + case 0: + break; + default: + return (-1); + } + + /* sanity check */ + if (tm.tm_year < 70 || tm.tm_mon < 0 || tm.tm_mon > 12 + || tm.tm_mday < 1 || tm.tm_mday > 31) + return (-1); + + if (*t != '\0') { + s = ++t; + l = strtol(s, &t, 10); + if (l < 0 || l >= INT_MAX || (*t != '\0' && !isspace(*t))) + return (-1); + + switch (t - s) { + case 6: + tm.tm_sec = l % 100; + l /= 100; + case 4: + tm.tm_min = l % 100; + l /= 100; + case 2: + tm.tm_hour = l; + case 0: + break; + default: + return (-1); + } + + /* sanity check */ + if (tm.tm_sec < 0 || tm.tm_sec > 60 || tm.tm_min < 0 + || tm.tm_min > 59 || tm.tm_hour < 0 || tm.tm_hour > 23) + return (-1); + } + + tsecs = mktime(&tm); + /* + * Check for invalid times, including things like the missing + * hour when switching from "standard time" to "daylight saving". + */ + if (tsecs == (time_t)-1) + tsecs = (time_t)-2; + return (tsecs); +} + +/*- + * Parse a cyclic time specification, the format is as follows: + * + * [Dhh] or [Wd[Dhh]] or [Mdd[Dhh]] + * + * to rotate a logfile cyclic at + * + * - every day (D) within a specific hour (hh) (hh = 0...23) + * - once a week (W) at a specific day (d) OR (d = 0..6, 0 = Sunday) + * - once a month (M) at a specific day (d) (d = 1..31,l|L) + * + * We don't accept a timezone specification; missing fields + * are defaulted to the current date but time zero. + */ +time_t +parseDWM(char *s, time_t *next_time) +{ + char *t; + time_t tsecs; + struct tm tm, *tmp; + long l; + int nd; + static int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + int WMseen = 0; + int Dseen = 0; + + tmp = localtime(&timenow); + tm = *tmp; + if (next_time != NULL) + *next_time = (time_t)-1; + + /* set no. of days per month */ + + nd = mtab[tm.tm_mon]; + + if (tm.tm_mon == 1) { + if (((tm.tm_year + 1900) % 4 == 0) && + ((tm.tm_year + 1900) % 100 != 0) && + ((tm.tm_year + 1900) % 400 == 0)) { + nd++; /* leap year, 29 days in february */ + } + } + tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + + for (;;) { + switch (*s) { + case 'D': + if (Dseen) + return (-1); + Dseen++; + s++; + l = strtol(s, &t, 10); + if (l < 0 || l > 23) + return (-1); + tm.tm_hour = l; + break; + + case 'W': + if (WMseen) + return (-1); + WMseen++; + s++; + l = strtol(s, &t, 10); + if (l < 0 || l > 6) + return (-1); + if (l != tm.tm_wday) { + int save; + + if (l < tm.tm_wday) { + save = 6 - tm.tm_wday; + save += (l + 1); + } else { + save = l - tm.tm_wday; + } + + tm.tm_mday += save; + + if (tm.tm_mday > nd) { + tm.tm_mon++; + tm.tm_mday = tm.tm_mday - nd; + } + } + break; + + case 'M': + if (WMseen) + return (-1); + WMseen++; + s++; + if (tolower(*s) == 'l') { + tm.tm_mday = nd; + s++; + t = s; + } else { + l = strtol(s, &t, 10); + if (l < 1 || l > 31) + return (-1); + + if (l > nd) + return (-1); + tm.tm_mday = l; + } + break; + + default: + return (-1); + break; + } + + if (*t == '\0' || isspace(*t)) + break; + else + s = t; + } + + tsecs = mktime(&tm); + /* + * Check for invalid times, including things like the missing + * hour when switching from "standard time" to "daylight saving". + */ + if (tsecs == (time_t)-1) + tsecs = (time_t)-2; + return (tsecs); +} |