newsyslog.c (3c0f0ccce76efc877c8d68a1233878a202b05c5e) | newsyslog.c (2f8d7c56da1ce2c5069fab78876cc6a90b343cfa) |
---|---|
1/* 2 * This file contains changes from the Open Software Foundation. 3 */ 4 5/* 6 * Copyright 1988, 1989 by the Massachusetts Institute of Technology 7 * 8 * Permission to use, copy, modify, and distribute this software and its --- 41 unchanged lines hidden (view full) --- 50#include <signal.h> 51#include <stdio.h> 52#include <stdlib.h> 53#include <string.h> 54#include <time.h> 55#include <unistd.h> 56 57#include "pathnames.h" | 1/* 2 * This file contains changes from the Open Software Foundation. 3 */ 4 5/* 6 * Copyright 1988, 1989 by the Massachusetts Institute of Technology 7 * 8 * Permission to use, copy, modify, and distribute this software and its --- 41 unchanged lines hidden (view full) --- 50#include <signal.h> 51#include <stdio.h> 52#include <stdlib.h> 53#include <string.h> 54#include <time.h> 55#include <unistd.h> 56 57#include "pathnames.h" |
58#include "extern.h" |
|
58 59/* 60 * Bit-values for the 'flags' parsed from a config-file entry. 61 */ 62#define CE_COMPACT 0x0001 /* Compact the achived log files with gzip. */ 63#define CE_BZCOMPACT 0x0002 /* Compact the achived log files with bzip2. */ 64#define CE_COMPACTWAIT 0x0004 /* wait until compressing one file finishes */ 65 /* before starting the next step. */ --- 78 unchanged lines hidden (view full) --- 144static void bzcompress_log(char *logname, int dowait); 145static int sizefile(char *file); 146static int age_old_log(char *file); 147static int send_signal(const struct conf_entry *ent); 148static void movefile(char *from, char *to, int perm, uid_t owner_uid, 149 gid_t group_gid); 150static void createdir(const struct conf_entry *ent, char *dirpart); 151static void createlog(const struct conf_entry *ent); | 59 60/* 61 * Bit-values for the 'flags' parsed from a config-file entry. 62 */ 63#define CE_COMPACT 0x0001 /* Compact the achived log files with gzip. */ 64#define CE_BZCOMPACT 0x0002 /* Compact the achived log files with bzip2. */ 65#define CE_COMPACTWAIT 0x0004 /* wait until compressing one file finishes */ 66 /* before starting the next step. */ --- 78 unchanged lines hidden (view full) --- 145static void bzcompress_log(char *logname, int dowait); 146static int sizefile(char *file); 147static int age_old_log(char *file); 148static int send_signal(const struct conf_entry *ent); 149static void movefile(char *from, char *to, int perm, uid_t owner_uid, 150 gid_t group_gid); 151static void createdir(const struct conf_entry *ent, char *dirpart); 152static void createlog(const struct conf_entry *ent); |
152static time_t parse8601(const char *s); 153static time_t parseDWM(char *s); | |
154 155/* 156 * All the following are defined to work on an 'int', in the 157 * range 0 to 255, plus EOF. Define wrappers which can take 158 * values of type 'char', either signed or unsigned. 159 */ 160#define isdigitch(Anychar) isdigit(((int) Anychar) & 255) 161#define isprintch(Anychar) isprint(((int) Anychar) & 255) --- 430 unchanged lines hidden (view full) --- 592{ 593 const char TN[] = "TN="; 594 595 if (strncmp(doption, TN, sizeof(TN) - 1) == 0) { 596 /* 597 * The "TimeNow" debugging option. This probably will 598 * be off by an hour when crossing a timezone change. 599 */ | 153 154/* 155 * All the following are defined to work on an 'int', in the 156 * range 0 to 255, plus EOF. Define wrappers which can take 157 * values of type 'char', either signed or unsigned. 158 */ 159#define isdigitch(Anychar) isdigit(((int) Anychar) & 255) 160#define isprintch(Anychar) isprint(((int) Anychar) & 255) --- 430 unchanged lines hidden (view full) --- 591{ 592 const char TN[] = "TN="; 593 594 if (strncmp(doption, TN, sizeof(TN) - 1) == 0) { 595 /* 596 * The "TimeNow" debugging option. This probably will 597 * be off by an hour when crossing a timezone change. 598 */ |
600 dbg_timenow = parse8601(doption + sizeof(TN) - 1); | 599 dbg_timenow = parse8601(doption + sizeof(TN) - 1, NULL); |
601 if (dbg_timenow == (time_t)-1) { 602 warnx("Malformed time given on -D %s", doption); 603 return (0); /* failure */ 604 } 605 if (dbg_timenow == (time_t)-2) { 606 warnx("Non-existent time specified on -D %s", doption); 607 return (0); /* failure */ 608 } --- 423 unchanged lines hidden (view full) --- 1032 errx(1, "interval is too large:\n%s", errline); 1033 else 1034 working->hours = ul; 1035 1036 if (*ep != '\0' && *ep != '@' && *ep != '*' && 1037 *ep != '$') 1038 errx(1, "malformed interval/at:\n%s", errline); 1039 if (*ep == '@') { | 600 if (dbg_timenow == (time_t)-1) { 601 warnx("Malformed time given on -D %s", doption); 602 return (0); /* failure */ 603 } 604 if (dbg_timenow == (time_t)-2) { 605 warnx("Non-existent time specified on -D %s", doption); 606 return (0); /* failure */ 607 } --- 423 unchanged lines hidden (view full) --- 1031 errx(1, "interval is too large:\n%s", errline); 1032 else 1033 working->hours = ul; 1034 1035 if (*ep != '\0' && *ep != '@' && *ep != '*' && 1036 *ep != '$') 1037 errx(1, "malformed interval/at:\n%s", errline); 1038 if (*ep == '@') { |
1040 working->trim_at = parse8601(ep + 1); | 1039 working->trim_at = parse8601(ep + 1, NULL); |
1041 working->flags |= CE_TRIMAT; 1042 } else if (*ep == '$') { | 1040 working->flags |= CE_TRIMAT; 1041 } else if (*ep == '$') { |
1043 working->trim_at = parseDWM(ep + 1); | 1042 working->trim_at = parseDWM(ep + 1, NULL); |
1044 working->flags |= CE_TRIMAT; 1045 } 1046 if (working->flags & CE_TRIMAT) { 1047 if (working->trim_at == (time_t)-1) 1048 errx(1, "malformed at:\n%s", errline); 1049 if (working->trim_at == (time_t)-2) 1050 errx(1, "nonexistent time:\n%s", 1051 errline); --- 722 unchanged lines hidden (view full) --- 1774 failed = rename(tempfile, realfile); 1775 if (failed) 1776 err(1, "can't mv %s to %s", tempfile, realfile); 1777 } 1778 1779 if (fd >= 0) 1780 close(fd); 1781} | 1043 working->flags |= CE_TRIMAT; 1044 } 1045 if (working->flags & CE_TRIMAT) { 1046 if (working->trim_at == (time_t)-1) 1047 errx(1, "malformed at:\n%s", errline); 1048 if (working->trim_at == (time_t)-2) 1049 errx(1, "nonexistent time:\n%s", 1050 errline); --- 722 unchanged lines hidden (view full) --- 1773 failed = rename(tempfile, realfile); 1774 if (failed) 1775 err(1, "can't mv %s to %s", tempfile, realfile); 1776 } 1777 1778 if (fd >= 0) 1779 close(fd); 1780} |
1782 1783/*- 1784 * Parse a limited subset of ISO 8601. The specific format is as follows: 1785 * 1786 * [CC[YY[MM[DD]]]][THH[MM[SS]]] (where `T' is the literal letter) 1787 * 1788 * We don't accept a timezone specification; missing fields (including timezone) 1789 * are defaulted to the current date but time zero. 1790 */ 1791static time_t 1792parse8601(const char *s) 1793{ 1794 char *t; 1795 time_t tsecs; 1796 struct tm tm, *tmp; 1797 long l; 1798 1799 tmp = localtime(&timenow); 1800 tm = *tmp; 1801 1802 tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 1803 1804 l = strtol(s, &t, 10); 1805 if (l < 0 || l >= INT_MAX || (*t != '\0' && *t != 'T')) 1806 return (-1); 1807 1808 /* 1809 * Now t points either to the end of the string (if no time was 1810 * provided) or to the letter `T' which separates date and time in 1811 * ISO 8601. The pointer arithmetic is the same for either case. 1812 */ 1813 switch (t - s) { 1814 case 8: 1815 tm.tm_year = ((l / 1000000) - 19) * 100; 1816 l = l % 1000000; 1817 case 6: 1818 tm.tm_year -= tm.tm_year % 100; 1819 tm.tm_year += l / 10000; 1820 l = l % 10000; 1821 case 4: 1822 tm.tm_mon = (l / 100) - 1; 1823 l = l % 100; 1824 case 2: 1825 tm.tm_mday = l; 1826 case 0: 1827 break; 1828 default: 1829 return (-1); 1830 } 1831 1832 /* sanity check */ 1833 if (tm.tm_year < 70 || tm.tm_mon < 0 || tm.tm_mon > 12 1834 || tm.tm_mday < 1 || tm.tm_mday > 31) 1835 return (-1); 1836 1837 if (*t != '\0') { 1838 s = ++t; 1839 l = strtol(s, &t, 10); 1840 if (l < 0 || l >= INT_MAX || (*t != '\0' && !isspace(*t))) 1841 return (-1); 1842 1843 switch (t - s) { 1844 case 6: 1845 tm.tm_sec = l % 100; 1846 l /= 100; 1847 case 4: 1848 tm.tm_min = l % 100; 1849 l /= 100; 1850 case 2: 1851 tm.tm_hour = l; 1852 case 0: 1853 break; 1854 default: 1855 return (-1); 1856 } 1857 1858 /* sanity check */ 1859 if (tm.tm_sec < 0 || tm.tm_sec > 60 || tm.tm_min < 0 1860 || tm.tm_min > 59 || tm.tm_hour < 0 || tm.tm_hour > 23) 1861 return (-1); 1862 } 1863 1864 tsecs = mktime(&tm); 1865 /* 1866 * Check for invalid times, including things like the missing 1867 * hour when switching from "standard time" to "daylight saving". 1868 */ 1869 if (tsecs == (time_t)-1) 1870 tsecs = (time_t)-2; 1871 return (tsecs); 1872} 1873 1874/*- 1875 * Parse a cyclic time specification, the format is as follows: 1876 * 1877 * [Dhh] or [Wd[Dhh]] or [Mdd[Dhh]] 1878 * 1879 * to rotate a logfile cyclic at 1880 * 1881 * - every day (D) within a specific hour (hh) (hh = 0...23) 1882 * - once a week (W) at a specific day (d) OR (d = 0..6, 0 = Sunday) 1883 * - once a month (M) at a specific day (d) (d = 1..31,l|L) 1884 * 1885 * We don't accept a timezone specification; missing fields 1886 * are defaulted to the current date but time zero. 1887 */ 1888static time_t 1889parseDWM(char *s) 1890{ 1891 char *t; 1892 time_t tsecs; 1893 struct tm tm, *tmp; 1894 long l; 1895 int nd; 1896 static int mtab[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 1897 int WMseen = 0; 1898 int Dseen = 0; 1899 1900 tmp = localtime(&timenow); 1901 tm = *tmp; 1902 1903 /* set no. of days per month */ 1904 1905 nd = mtab[tm.tm_mon]; 1906 1907 if (tm.tm_mon == 1) { 1908 if (((tm.tm_year + 1900) % 4 == 0) && 1909 ((tm.tm_year + 1900) % 100 != 0) && 1910 ((tm.tm_year + 1900) % 400 == 0)) { 1911 nd++; /* leap year, 29 days in february */ 1912 } 1913 } 1914 tm.tm_hour = tm.tm_min = tm.tm_sec = 0; 1915 1916 for (;;) { 1917 switch (*s) { 1918 case 'D': 1919 if (Dseen) 1920 return (-1); 1921 Dseen++; 1922 s++; 1923 l = strtol(s, &t, 10); 1924 if (l < 0 || l > 23) 1925 return (-1); 1926 tm.tm_hour = l; 1927 break; 1928 1929 case 'W': 1930 if (WMseen) 1931 return (-1); 1932 WMseen++; 1933 s++; 1934 l = strtol(s, &t, 10); 1935 if (l < 0 || l > 6) 1936 return (-1); 1937 if (l != tm.tm_wday) { 1938 int save; 1939 1940 if (l < tm.tm_wday) { 1941 save = 6 - tm.tm_wday; 1942 save += (l + 1); 1943 } else { 1944 save = l - tm.tm_wday; 1945 } 1946 1947 tm.tm_mday += save; 1948 1949 if (tm.tm_mday > nd) { 1950 tm.tm_mon++; 1951 tm.tm_mday = tm.tm_mday - nd; 1952 } 1953 } 1954 break; 1955 1956 case 'M': 1957 if (WMseen) 1958 return (-1); 1959 WMseen++; 1960 s++; 1961 if (tolower(*s) == 'l') { 1962 tm.tm_mday = nd; 1963 s++; 1964 t = s; 1965 } else { 1966 l = strtol(s, &t, 10); 1967 if (l < 1 || l > 31) 1968 return (-1); 1969 1970 if (l > nd) 1971 return (-1); 1972 tm.tm_mday = l; 1973 } 1974 break; 1975 1976 default: 1977 return (-1); 1978 break; 1979 } 1980 1981 if (*t == '\0' || isspace(*t)) 1982 break; 1983 else 1984 s = t; 1985 } 1986 1987 tsecs = mktime(&tm); 1988 /* 1989 * Check for invalid times, including things like the missing 1990 * hour when switching from "standard time" to "daylight saving". 1991 */ 1992 if (tsecs == (time_t)-1) 1993 tsecs = (time_t)-2; 1994 return (tsecs); 1995} | |