|
|
285127 |
diff --git a/logrotate.c b/logrotate.c
|
|
|
285127 |
index 174a26b..4ef044e 100644
|
|
|
285127 |
--- a/logrotate.c
|
|
|
285127 |
+++ b/logrotate.c
|
|
|
285127 |
@@ -77,6 +77,11 @@ struct logNames {
|
|
|
285127 |
char *baseName;
|
|
|
285127 |
};
|
|
|
285127 |
|
|
|
285127 |
+struct compData {
|
|
|
285127 |
+ int prefix_len;
|
|
|
285127 |
+ const char *dformat;
|
|
|
285127 |
+};
|
|
|
285127 |
+
|
|
|
285127 |
struct logStates {
|
|
|
285127 |
LIST_HEAD(stateSet, logState) head;
|
|
|
285127 |
} **states;
|
|
|
285127 |
@@ -142,6 +147,34 @@ int switch_user_permanently(const struct logInfo *log) {
|
|
|
285127 |
return 0;
|
|
|
285127 |
}
|
|
|
285127 |
|
|
|
285127 |
+static int compGlobResult(const void *result1, const void *result2, void *data) {
|
|
|
285127 |
+ struct tm time;
|
|
|
285127 |
+ time_t t1, t2;
|
|
|
285127 |
+ struct compData *d = (struct compData *) data;
|
|
|
285127 |
+ const char *r1 = *(const char **)(result1);
|
|
|
285127 |
+ const char *r2 = *(const char **)(result2);
|
|
|
285127 |
+
|
|
|
285127 |
+ memset(&time, 0, sizeof(struct tm));
|
|
|
285127 |
+ strptime(r1 + d->prefix_len, d->dformat, &time);
|
|
|
285127 |
+ t1 = mktime(&time);
|
|
|
285127 |
+
|
|
|
285127 |
+ memset(&time, 0, sizeof(struct tm));
|
|
|
285127 |
+ strptime(r2 + d->prefix_len, d->dformat, &time);
|
|
|
285127 |
+ t2 = mktime(&time);
|
|
|
285127 |
+
|
|
|
285127 |
+ if (t1 < t2) return -1;
|
|
|
285127 |
+ if (t1 > t2) return 1;
|
|
|
285127 |
+ return 0;
|
|
|
285127 |
+}
|
|
|
285127 |
+
|
|
|
285127 |
+static void sortGlobResult(glob_t *result, int prefix_len, const char *dformat) {
|
|
|
285127 |
+ struct compData d;
|
|
|
285127 |
+ if (!dformat || *dformat == '\0') return;
|
|
|
285127 |
+ d.prefix_len = prefix_len;
|
|
|
285127 |
+ d.dformat = dformat;
|
|
|
285127 |
+ qsort_r(result->gl_pathv, result->gl_pathc, sizeof(char *), compGlobResult, &d);
|
|
|
285127 |
+}
|
|
|
285127 |
+
|
|
|
285127 |
static void unescape(char *arg)
|
|
|
285127 |
{
|
|
|
285127 |
char *p = arg;
|
|
|
285127 |
@@ -923,7 +956,7 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
|
285127 |
#define DATEEXT_LEN 64
|
|
|
285127 |
#define PATTERN_LEN (DATEEXT_LEN * 2)
|
|
|
285127 |
char dext_str[DATEEXT_LEN];
|
|
|
285127 |
- char dformat[DATEEXT_LEN];
|
|
|
285127 |
+ char dformat[DATEEXT_LEN] = "";
|
|
|
285127 |
char dext_pattern[PATTERN_LEN];
|
|
|
285127 |
char *dext;
|
|
|
285127 |
|
|
|
285127 |
@@ -1112,6 +1145,7 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
|
285127 |
}
|
|
|
285127 |
rc = glob(glob_pattern, 0, globerr, &globResult);
|
|
|
285127 |
if (!rc && globResult.gl_pathc > 0) {
|
|
|
285127 |
+ sortGlobResult(&globResult, strlen(rotNames->dirName) + 1 + strlen(rotNames->baseName), dformat);
|
|
|
285127 |
for (i = 0; i < globResult.gl_pathc && !hasErrors; i++) {
|
|
|
285127 |
struct stat sbprev;
|
|
|
285127 |
|
|
|
285127 |
@@ -1176,6 +1210,7 @@ int prerotateSingleLog(struct logInfo *log, int logNum, struct logState *state,
|
|
|
285127 |
/* remove the first (n - rotateCount) matches
|
|
|
285127 |
* no real rotation needed, since the files have
|
|
|
285127 |
* the date in their name */
|
|
|
285127 |
+ sortGlobResult(&globResult, strlen(rotNames->dirName) + 1 + strlen(rotNames->baseName), dformat);
|
|
|
285127 |
for (i = 0; i < globResult.gl_pathc; i++) {
|
|
|
285127 |
if (!stat((globResult.gl_pathv)[i], &fst_buf)) {
|
|
|
285127 |
if ((i <= ((int) globResult.gl_pathc - rotateCount))
|
|
|
285127 |
diff --git a/test/test b/test/test
|
|
|
285127 |
index 793bf77..25b76a6 100755
|
|
|
285127 |
--- a/test/test
|
|
|
285127 |
+++ b/test/test
|
|
|
285127 |
@@ -1347,4 +1347,73 @@ test.log 0
|
|
|
285127 |
test.log.1 0 zero
|
|
|
285127 |
EOF
|
|
|
285127 |
|
|
|
285127 |
+cleanup 54
|
|
|
285127 |
+
|
|
|
285127 |
+# ------------------------------- Test 54 ------------------------------------
|
|
|
285127 |
+# removing last log file when using %Y-%m-%d
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+preptest test.log 54 1 0
|
|
|
285127 |
+
|
|
|
285127 |
+DATE=""
|
|
|
285127 |
+for i in {1..60}
|
|
|
285127 |
+do
|
|
|
285127 |
+ DATE=$(/bin/date "+%Y-%m-%d" --date "$i day ago" 2>/dev/null)
|
|
|
285127 |
+ echo "x" > test.log-$DATE
|
|
|
285127 |
+done
|
|
|
285127 |
+
|
|
|
285127 |
+$RLR test-config.54 --force
|
|
|
285127 |
+
|
|
|
285127 |
+if [ -e test.log-$DATE ]; then
|
|
|
285127 |
+ echo "File test.log-$DATE should not exist (it should be deleted)"
|
|
|
285127 |
+ exit 3
|
|
|
285127 |
+fi
|
|
|
285127 |
+
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+
|
|
|
285127 |
+cleanup 55
|
|
|
285127 |
+
|
|
|
285127 |
+# ------------------------------- Test 55 ------------------------------------
|
|
|
285127 |
+# removing last log file when using %s and hourly
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+preptest test.log 55 1 0
|
|
|
285127 |
+
|
|
|
285127 |
+DATE=""
|
|
|
285127 |
+for i in {1..60}
|
|
|
285127 |
+do
|
|
|
285127 |
+ DATE=$(/bin/date "+%s" --date "$i hour ago" 2>/dev/null)
|
|
|
285127 |
+ echo "x" > test.log-$DATE.gz
|
|
|
285127 |
+done
|
|
|
285127 |
+
|
|
|
285127 |
+$RLR test-config.55 --force
|
|
|
285127 |
+
|
|
|
285127 |
+if [ -e test.log-$DATE.gz ]; then
|
|
|
285127 |
+ echo "File test.log-$DATE.gz should not exist (it should be deleted)"
|
|
|
285127 |
+ exit 3
|
|
|
285127 |
+fi
|
|
|
285127 |
+
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+
|
|
|
285127 |
+cleanup 56
|
|
|
285127 |
+
|
|
|
285127 |
+# ------------------------------- Test 56 ------------------------------------
|
|
|
285127 |
+# removing last log file when using %d-%m-%Y
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+preptest test.log 56 1 0
|
|
|
285127 |
+
|
|
|
285127 |
+DATE=""
|
|
|
285127 |
+for i in {1..60}
|
|
|
285127 |
+do
|
|
|
285127 |
+ DATE=$(/bin/date "+%d-%m-%Y" --date "$i day ago" 2>/dev/null)
|
|
|
285127 |
+ echo "x" > test.log-$DATE
|
|
|
285127 |
+done
|
|
|
285127 |
+
|
|
|
285127 |
+$RLR test-config.56 --force
|
|
|
285127 |
+
|
|
|
285127 |
+if [ -e test.log-$DATE ]; then
|
|
|
285127 |
+ echo "File test.log-$DATE should not exist (it should be deleted)"
|
|
|
285127 |
+ exit 3
|
|
|
285127 |
+fi
|
|
|
285127 |
+
|
|
|
285127 |
+rm -f *test.log*
|
|
|
285127 |
+
|
|
|
285127 |
cleanup
|
|
|
285127 |
diff --git a/test/test-config.54.in b/test/test-config.54.in
|
|
|
285127 |
new file mode 100644
|
|
|
285127 |
index 0000000..c946af1
|
|
|
285127 |
--- /dev/null
|
|
|
285127 |
+++ b/test/test-config.54.in
|
|
|
285127 |
@@ -0,0 +1,8 @@
|
|
|
285127 |
+create
|
|
|
285127 |
+
|
|
|
285127 |
+&DIR&/test.log {
|
|
|
285127 |
+ daily
|
|
|
285127 |
+ dateext
|
|
|
285127 |
+ dateformat -%Y-%m-%d
|
|
|
285127 |
+ rotate 60
|
|
|
285127 |
+}
|
|
|
285127 |
diff --git a/test/test-config.55.in b/test/test-config.55.in
|
|
|
285127 |
new file mode 100644
|
|
|
285127 |
index 0000000..8b10ad1
|
|
|
285127 |
--- /dev/null
|
|
|
285127 |
+++ b/test/test-config.55.in
|
|
|
285127 |
@@ -0,0 +1,21 @@
|
|
|
285127 |
+create
|
|
|
285127 |
+
|
|
|
285127 |
+# continue and throw no error message when log file is not present
|
|
|
285127 |
+missingok
|
|
|
285127 |
+
|
|
|
285127 |
+# truncate the original log file in place after creating a copy
|
|
|
285127 |
+copytruncate
|
|
|
285127 |
+
|
|
|
285127 |
+# compress the file
|
|
|
285127 |
+compress
|
|
|
285127 |
+
|
|
|
285127 |
+# do only rotate when not empty
|
|
|
285127 |
+notifempty
|
|
|
285127 |
+
|
|
|
285127 |
+&DIR&/test.log {
|
|
|
285127 |
+ hourly
|
|
|
285127 |
+ dateext
|
|
|
285127 |
+ dateformat -%s
|
|
|
285127 |
+ rotate 60
|
|
|
285127 |
+ nosharedscripts
|
|
|
285127 |
+}
|
|
|
285127 |
diff --git a/test/test-config.56.in b/test/test-config.56.in
|
|
|
285127 |
new file mode 100644
|
|
|
285127 |
index 0000000..adaf2a5
|
|
|
285127 |
--- /dev/null
|
|
|
285127 |
+++ b/test/test-config.56.in
|
|
|
285127 |
@@ -0,0 +1,8 @@
|
|
|
285127 |
+create
|
|
|
285127 |
+
|
|
|
285127 |
+&DIR&/test.log {
|
|
|
285127 |
+ daily
|
|
|
285127 |
+ dateext
|
|
|
285127 |
+ dateformat -%d-%m-%Y
|
|
|
285127 |
+ rotate 60
|
|
|
285127 |
+}
|