aboutsummaryrefslogtreecommitdiffstats
path: root/main/logrotate/logrotate-3.7.9-shred.patch
blob: d9780007f35882b69d2573afbb0b1853fbf6908a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
Index: logrotate.c
===================================================================
--- logrotate.c	(revision 310)
+++ logrotate.c	(working copy)
@@ -71,7 +71,7 @@
 char *mailCommand = DEFAULT_MAIL_COMMAND;
 time_t nowSecs = 0;
 
-static int shred_file(char *filename, struct logInfo *log);
+static int shred_file(int fd, char *filename, struct logInfo *log);
 
 static int globerr(const char *pathname, int theerr)
 {
@@ -231,59 +231,79 @@
     return fd;
 }
 
-#define SHRED_CALL "shred -u "
-#define SHRED_COUNT_FLAG "-n "
 #define DIGITS 10
+
 /* unlink, but try to call shred from GNU fileutils */
-static int shred_file(char *filename, struct logInfo *log)
+static int shred_file(int fd, char *filename, struct logInfo *log)
 {
-	int len, ret;
-	char *cmd;
 	char count[DIGITS];    /*  that's a lot of shredding :)  */
+	const char **fullCommand;
+	int id = 0;
+	int status;
 
 	if (!(log->flags & LOG_FLAG_SHRED)) {
 		return unlink(filename);
 	}
 
-	len = strlen(filename) + strlen(SHRED_CALL);
-	len += strlen(SHRED_COUNT_FLAG) + DIGITS;
-	cmd = malloc(len);
+	message(MESS_DEBUG, "Using shred to remove the file %s\n", filename);
 
-	if (!cmd) {
-		message(MESS_ERROR, "malloc error while shredding");
-		return unlink(filename);
+	if (log->shred_cycles != 0) {
+		fullCommand = alloca(sizeof(*fullCommand) * 6);
 	}
-	strcpy(cmd, SHRED_CALL);
+	else {
+		fullCommand = alloca(sizeof(*fullCommand) * 4);
+	}
+	fullCommand[id++] = "shred";
+	fullCommand[id++] = "-u";
+
 	if (log->shred_cycles != 0) {
-		strcat(cmd, SHRED_COUNT_FLAG);
+		fullCommand[id++] = "-n";
 		snprintf(count, DIGITS - 1, "%d", log->shred_cycles);
-		strcat(count, " ");
-		strcat(cmd, count);
+		fullCommand[id++] = count;
 	}
-	strcat(cmd, filename);
-	ret = system(cmd);
-	free(cmd);
-	if (ret != 0) {
+	fullCommand[id++] = "-";
+	fullCommand[id++] = NULL;
+
+	if (!fork()) {
+		dup2(fd, 1);
+		close(fd);
+
+		execvp(fullCommand[0], (void *) fullCommand);
+		exit(1);
+	}
+	
+	wait(&status);
+
+	if (!WIFEXITED(status) || WEXITSTATUS(status)) {
 		message(MESS_ERROR, "Failed to shred %s\n, trying unlink", filename);
-		if (ret != -1) {
-			message(MESS_NORMAL, "Shred returned %d\n", ret);
-		}
 		return unlink(filename);
-	} else {
-		return ret;
 	}
+
+	/* We have to unlink it after shred anyway,
+	 * because it doesn't remove the file itself */
+	return unlink(filename);
 }
 
 static int removeLogFile(char *name, struct logInfo *log)
 {
-    message(MESS_DEBUG, "removing old log %s\n", name);
+	int fd;
+	message(MESS_DEBUG, "removing old log %s\n", name);
 
-    if (!debug && shred_file(name, log)) {
-	message(MESS_ERROR, "Failed to remove old log %s: %s\n",
-		name, strerror(errno));
-	return 1;
-    }
-    return 0;
+	if ((fd = open(name, O_RDWR)) < 0) {
+		message(MESS_ERROR, "error opening %s: %s\n",
+			name, strerror(errno));
+		return 1;
+	}
+
+	if (!debug && shred_file(fd, name, log)) {
+		message(MESS_ERROR, "Failed to remove old log %s: %s\n",
+			name, strerror(errno));
+		close(fd);
+		return 1;
+	}
+
+	close(fd);
+	return 0;
 }
 
 static int compressLogFile(char *name, struct logInfo *log, struct stat *sb)
@@ -310,7 +330,7 @@
     compressedName = alloca(strlen(name) + strlen(log->compress_ext) + 2);
     sprintf(compressedName, "%s%s", name, log->compress_ext);
 
-    if ((inFile = open(name, O_RDONLY)) < 0) {
+    if ((inFile = open(name, O_RDWR)) < 0) {
 	message(MESS_ERROR, "unable to open %s for compression\n", name);
 	return 1;
     }
@@ -357,7 +377,6 @@
 	exit(1);
     }
 
-    close(inFile);
     close(outFile);
 
     wait(&status);
@@ -373,7 +392,8 @@
     /* If we can't change atime/mtime, it's not a disaster.
        It might possibly fail under SELinux. */
 
-    shred_file(name, log);
+    shred_file(inFile, name, log);
+	close(inFile);
 
     return 0;
 }