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