xref: /aosp_15_r20/external/e2fsprogs/e2fsck/logfile.c (revision 6a54128f25917bfc36a8a6e9d722c04a0b4641b6)
1*6a54128fSAndroid Build Coastguard Worker /*
2*6a54128fSAndroid Build Coastguard Worker  * logfile.c --- set up e2fsck log files
3*6a54128fSAndroid Build Coastguard Worker  *
4*6a54128fSAndroid Build Coastguard Worker  * Copyright 1996, 1997 by Theodore Ts'o
5*6a54128fSAndroid Build Coastguard Worker  *
6*6a54128fSAndroid Build Coastguard Worker  * %Begin-Header%
7*6a54128fSAndroid Build Coastguard Worker  * This file may be redistributed under the terms of the GNU Public
8*6a54128fSAndroid Build Coastguard Worker  * License.
9*6a54128fSAndroid Build Coastguard Worker  * %End-Header%
10*6a54128fSAndroid Build Coastguard Worker  */
11*6a54128fSAndroid Build Coastguard Worker 
12*6a54128fSAndroid Build Coastguard Worker #include "config.h"
13*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_ERRNO_H
14*6a54128fSAndroid Build Coastguard Worker #include <errno.h>
15*6a54128fSAndroid Build Coastguard Worker #endif
16*6a54128fSAndroid Build Coastguard Worker #include <sys/types.h>
17*6a54128fSAndroid Build Coastguard Worker #include <sys/stat.h>
18*6a54128fSAndroid Build Coastguard Worker #include <fcntl.h>
19*6a54128fSAndroid Build Coastguard Worker 
20*6a54128fSAndroid Build Coastguard Worker #include "e2fsck.h"
21*6a54128fSAndroid Build Coastguard Worker #include <pwd.h>
22*6a54128fSAndroid Build Coastguard Worker 
23*6a54128fSAndroid Build Coastguard Worker extern e2fsck_t e2fsck_global_ctx;   /* Try your very best not to use this! */
24*6a54128fSAndroid Build Coastguard Worker 
25*6a54128fSAndroid Build Coastguard Worker struct string {
26*6a54128fSAndroid Build Coastguard Worker 	char	*s;
27*6a54128fSAndroid Build Coastguard Worker 	int	len;
28*6a54128fSAndroid Build Coastguard Worker 	int	end;
29*6a54128fSAndroid Build Coastguard Worker };
30*6a54128fSAndroid Build Coastguard Worker 
alloc_string(struct string * s,int len)31*6a54128fSAndroid Build Coastguard Worker static void alloc_string(struct string *s, int len)
32*6a54128fSAndroid Build Coastguard Worker {
33*6a54128fSAndroid Build Coastguard Worker 	s->s = malloc(len);
34*6a54128fSAndroid Build Coastguard Worker /* e2fsck_allocate_memory(ctx, len, "logfile name"); */
35*6a54128fSAndroid Build Coastguard Worker 	s->len = s->s ? len : 0;
36*6a54128fSAndroid Build Coastguard Worker 	s->end = 0;
37*6a54128fSAndroid Build Coastguard Worker }
38*6a54128fSAndroid Build Coastguard Worker 
append_string(struct string * s,const char * a,int len)39*6a54128fSAndroid Build Coastguard Worker static void append_string(struct string *s, const char *a, int len)
40*6a54128fSAndroid Build Coastguard Worker {
41*6a54128fSAndroid Build Coastguard Worker 	int needlen;
42*6a54128fSAndroid Build Coastguard Worker 
43*6a54128fSAndroid Build Coastguard Worker 	if (!len)
44*6a54128fSAndroid Build Coastguard Worker 		len = strlen(a);
45*6a54128fSAndroid Build Coastguard Worker 
46*6a54128fSAndroid Build Coastguard Worker 	needlen = s->end + len + 1;
47*6a54128fSAndroid Build Coastguard Worker 	if (needlen > s->len) {
48*6a54128fSAndroid Build Coastguard Worker 		char *n;
49*6a54128fSAndroid Build Coastguard Worker 
50*6a54128fSAndroid Build Coastguard Worker 		if (s->len * 2 > needlen)
51*6a54128fSAndroid Build Coastguard Worker 			needlen = s->len * 2;
52*6a54128fSAndroid Build Coastguard Worker 	        n = realloc(s->s, needlen);
53*6a54128fSAndroid Build Coastguard Worker 
54*6a54128fSAndroid Build Coastguard Worker 		if (n) {
55*6a54128fSAndroid Build Coastguard Worker 			s->s = n;
56*6a54128fSAndroid Build Coastguard Worker 			s->len = needlen;
57*6a54128fSAndroid Build Coastguard Worker 		} else {
58*6a54128fSAndroid Build Coastguard Worker 			/* Don't append if we ran out of memory */
59*6a54128fSAndroid Build Coastguard Worker 			return;
60*6a54128fSAndroid Build Coastguard Worker 		}
61*6a54128fSAndroid Build Coastguard Worker 	}
62*6a54128fSAndroid Build Coastguard Worker 	memcpy(s->s + s->end, a, len);
63*6a54128fSAndroid Build Coastguard Worker 	s->end += len;
64*6a54128fSAndroid Build Coastguard Worker 	s->s[s->end] = 0;
65*6a54128fSAndroid Build Coastguard Worker }
66*6a54128fSAndroid Build Coastguard Worker 
67*6a54128fSAndroid Build Coastguard Worker #define FLAG_UTC	0x0001
68*6a54128fSAndroid Build Coastguard Worker 
expand_percent_expression(e2fsck_t ctx,char ch,struct string * s,int * flags)69*6a54128fSAndroid Build Coastguard Worker static void expand_percent_expression(e2fsck_t ctx, char ch,
70*6a54128fSAndroid Build Coastguard Worker 				      struct string *s, int *flags)
71*6a54128fSAndroid Build Coastguard Worker {
72*6a54128fSAndroid Build Coastguard Worker 	struct tm	*tm = NULL, tm_struct;
73*6a54128fSAndroid Build Coastguard Worker 	struct passwd	*pw = NULL, pw_struct;
74*6a54128fSAndroid Build Coastguard Worker 	char		*cp;
75*6a54128fSAndroid Build Coastguard Worker 	char		buf[256];
76*6a54128fSAndroid Build Coastguard Worker 
77*6a54128fSAndroid Build Coastguard Worker 	if ((ch == 'D') || (ch == 'd') || (ch == 'm') || (ch == 'y') ||
78*6a54128fSAndroid Build Coastguard Worker 	    (ch == 'Y') ||
79*6a54128fSAndroid Build Coastguard Worker 	    (ch == 'T') || (ch == 'H') || (ch == 'M') || (ch == 'S')) {
80*6a54128fSAndroid Build Coastguard Worker 		tzset();
81*6a54128fSAndroid Build Coastguard Worker 		tm = (*flags & FLAG_UTC) ? gmtime_r(&ctx->now, &tm_struct) :
82*6a54128fSAndroid Build Coastguard Worker 			localtime_r(&ctx->now, &tm_struct);
83*6a54128fSAndroid Build Coastguard Worker 	}
84*6a54128fSAndroid Build Coastguard Worker 
85*6a54128fSAndroid Build Coastguard Worker 	switch (ch) {
86*6a54128fSAndroid Build Coastguard Worker 	case '%':
87*6a54128fSAndroid Build Coastguard Worker 		append_string(s, "%", 1);
88*6a54128fSAndroid Build Coastguard Worker 		return;
89*6a54128fSAndroid Build Coastguard Worker 	case 'd':
90*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_mday);
91*6a54128fSAndroid Build Coastguard Worker 		break;
92*6a54128fSAndroid Build Coastguard Worker 	case 'D':
93*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%d%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1,
94*6a54128fSAndroid Build Coastguard Worker 			tm->tm_mday);
95*6a54128fSAndroid Build Coastguard Worker 		break;
96*6a54128fSAndroid Build Coastguard Worker 	case 'h':
97*6a54128fSAndroid Build Coastguard Worker #ifdef TEST_PROGRAM
98*6a54128fSAndroid Build Coastguard Worker 		strcpy(buf, "server");
99*6a54128fSAndroid Build Coastguard Worker #else
100*6a54128fSAndroid Build Coastguard Worker 		buf[0] = 0;
101*6a54128fSAndroid Build Coastguard Worker 		gethostname(buf, sizeof(buf));
102*6a54128fSAndroid Build Coastguard Worker 		buf[sizeof(buf)-1] = 0;
103*6a54128fSAndroid Build Coastguard Worker #endif
104*6a54128fSAndroid Build Coastguard Worker 		break;
105*6a54128fSAndroid Build Coastguard Worker 	case 'H':
106*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_hour);
107*6a54128fSAndroid Build Coastguard Worker 		break;
108*6a54128fSAndroid Build Coastguard Worker 	case 'm':
109*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_mon + 1);
110*6a54128fSAndroid Build Coastguard Worker 		break;
111*6a54128fSAndroid Build Coastguard Worker 	case 'M':
112*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_min);
113*6a54128fSAndroid Build Coastguard Worker 		break;
114*6a54128fSAndroid Build Coastguard Worker 	case 'N':		/* block device name */
115*6a54128fSAndroid Build Coastguard Worker 		cp = strrchr(ctx->filesystem_name, '/');
116*6a54128fSAndroid Build Coastguard Worker 		if (cp)
117*6a54128fSAndroid Build Coastguard Worker 			cp++;
118*6a54128fSAndroid Build Coastguard Worker 		else
119*6a54128fSAndroid Build Coastguard Worker 			cp = ctx->filesystem_name;
120*6a54128fSAndroid Build Coastguard Worker 		append_string(s, cp, 0);
121*6a54128fSAndroid Build Coastguard Worker 		return;
122*6a54128fSAndroid Build Coastguard Worker 	case 'p':
123*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%lu", (unsigned long) getpid());
124*6a54128fSAndroid Build Coastguard Worker 		break;
125*6a54128fSAndroid Build Coastguard Worker 	case 's':
126*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%lu", (unsigned long) ctx->now);
127*6a54128fSAndroid Build Coastguard Worker 		break;
128*6a54128fSAndroid Build Coastguard Worker 	case 'S':
129*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_sec);
130*6a54128fSAndroid Build Coastguard Worker 		break;
131*6a54128fSAndroid Build Coastguard Worker 	case 'T':
132*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d%02d%02d", tm->tm_hour, tm->tm_min,
133*6a54128fSAndroid Build Coastguard Worker 			tm->tm_sec);
134*6a54128fSAndroid Build Coastguard Worker 		break;
135*6a54128fSAndroid Build Coastguard Worker 	case 'u':
136*6a54128fSAndroid Build Coastguard Worker #ifdef TEST_PROGRAM
137*6a54128fSAndroid Build Coastguard Worker 		strcpy(buf, "tytso");
138*6a54128fSAndroid Build Coastguard Worker 		break;
139*6a54128fSAndroid Build Coastguard Worker #else
140*6a54128fSAndroid Build Coastguard Worker #ifdef HAVE_GETPWUID_R
141*6a54128fSAndroid Build Coastguard Worker 		getpwuid_r(getuid(), &pw_struct, buf, sizeof(buf), &pw);
142*6a54128fSAndroid Build Coastguard Worker #else
143*6a54128fSAndroid Build Coastguard Worker 		pw = getpwuid(getuid());
144*6a54128fSAndroid Build Coastguard Worker #endif
145*6a54128fSAndroid Build Coastguard Worker 		if (pw)
146*6a54128fSAndroid Build Coastguard Worker 			append_string(s, pw->pw_name, 0);
147*6a54128fSAndroid Build Coastguard Worker 		return;
148*6a54128fSAndroid Build Coastguard Worker #endif
149*6a54128fSAndroid Build Coastguard Worker 	case 'U':
150*6a54128fSAndroid Build Coastguard Worker 		*flags |= FLAG_UTC;
151*6a54128fSAndroid Build Coastguard Worker 		return;
152*6a54128fSAndroid Build Coastguard Worker 	case 'y':
153*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%02d", tm->tm_year % 100);
154*6a54128fSAndroid Build Coastguard Worker 		break;
155*6a54128fSAndroid Build Coastguard Worker 	case 'Y':
156*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%d", tm->tm_year + 1900);
157*6a54128fSAndroid Build Coastguard Worker 		break;
158*6a54128fSAndroid Build Coastguard Worker 	default:
159*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "%%%c", ch);
160*6a54128fSAndroid Build Coastguard Worker 		break;
161*6a54128fSAndroid Build Coastguard Worker 	}
162*6a54128fSAndroid Build Coastguard Worker 	append_string(s, buf, 0);
163*6a54128fSAndroid Build Coastguard Worker }
164*6a54128fSAndroid Build Coastguard Worker 
expand_logfn(e2fsck_t ctx,const char * log_fn,struct string * s)165*6a54128fSAndroid Build Coastguard Worker static void expand_logfn(e2fsck_t ctx, const char *log_fn, struct string *s)
166*6a54128fSAndroid Build Coastguard Worker {
167*6a54128fSAndroid Build Coastguard Worker 	const char	*cp;
168*6a54128fSAndroid Build Coastguard Worker 	int		i;
169*6a54128fSAndroid Build Coastguard Worker 	int		flags = 0;
170*6a54128fSAndroid Build Coastguard Worker 
171*6a54128fSAndroid Build Coastguard Worker 	alloc_string(s, 100);
172*6a54128fSAndroid Build Coastguard Worker 	for (cp = log_fn; *cp; cp++) {
173*6a54128fSAndroid Build Coastguard Worker 		if (cp[0] == '%') {
174*6a54128fSAndroid Build Coastguard Worker 			cp++;
175*6a54128fSAndroid Build Coastguard Worker 			expand_percent_expression(ctx, *cp, s, &flags);
176*6a54128fSAndroid Build Coastguard Worker 			continue;
177*6a54128fSAndroid Build Coastguard Worker 		}
178*6a54128fSAndroid Build Coastguard Worker 		for (i = 0; cp[i]; i++)
179*6a54128fSAndroid Build Coastguard Worker 			if (cp[i] == '%')
180*6a54128fSAndroid Build Coastguard Worker 				break;
181*6a54128fSAndroid Build Coastguard Worker 		append_string(s, cp, i);
182*6a54128fSAndroid Build Coastguard Worker 		cp += i-1;
183*6a54128fSAndroid Build Coastguard Worker 	}
184*6a54128fSAndroid Build Coastguard Worker }
185*6a54128fSAndroid Build Coastguard Worker 
186*6a54128fSAndroid Build Coastguard Worker static int	outbufsize;
187*6a54128fSAndroid Build Coastguard Worker static void	*outbuf;
188*6a54128fSAndroid Build Coastguard Worker 
do_read(int fd)189*6a54128fSAndroid Build Coastguard Worker static int do_read(int fd)
190*6a54128fSAndroid Build Coastguard Worker {
191*6a54128fSAndroid Build Coastguard Worker 	int	c;
192*6a54128fSAndroid Build Coastguard Worker 	char		*n;
193*6a54128fSAndroid Build Coastguard Worker 	char	buffer[4096];
194*6a54128fSAndroid Build Coastguard Worker 
195*6a54128fSAndroid Build Coastguard Worker 	c = read(fd, buffer, sizeof(buffer)-1);
196*6a54128fSAndroid Build Coastguard Worker 	if (c <= 0)
197*6a54128fSAndroid Build Coastguard Worker 		return c;
198*6a54128fSAndroid Build Coastguard Worker 
199*6a54128fSAndroid Build Coastguard Worker 	n = realloc(outbuf, outbufsize + c);
200*6a54128fSAndroid Build Coastguard Worker 	if (n) {
201*6a54128fSAndroid Build Coastguard Worker 		outbuf = n;
202*6a54128fSAndroid Build Coastguard Worker 		memcpy(((char *)outbuf)+outbufsize, buffer, c);
203*6a54128fSAndroid Build Coastguard Worker 		outbufsize += c;
204*6a54128fSAndroid Build Coastguard Worker 	}
205*6a54128fSAndroid Build Coastguard Worker 	return c;
206*6a54128fSAndroid Build Coastguard Worker }
207*6a54128fSAndroid Build Coastguard Worker 
208*6a54128fSAndroid Build Coastguard Worker /*
209*6a54128fSAndroid Build Coastguard Worker  * Fork a child process to save the output of the logfile until the
210*6a54128fSAndroid Build Coastguard Worker  * appropriate file system is mounted read/write.
211*6a54128fSAndroid Build Coastguard Worker  */
save_output(const char * s0,const char * s1,const char * s2)212*6a54128fSAndroid Build Coastguard Worker static FILE *save_output(const char *s0, const char *s1, const char *s2)
213*6a54128fSAndroid Build Coastguard Worker {
214*6a54128fSAndroid Build Coastguard Worker 	int c, fd, fds[2];
215*6a54128fSAndroid Build Coastguard Worker 	char *cp;
216*6a54128fSAndroid Build Coastguard Worker 	pid_t pid;
217*6a54128fSAndroid Build Coastguard Worker 	FILE *ret;
218*6a54128fSAndroid Build Coastguard Worker 
219*6a54128fSAndroid Build Coastguard Worker 	if (s0 && *s0 == 0)
220*6a54128fSAndroid Build Coastguard Worker 		s0 = 0;
221*6a54128fSAndroid Build Coastguard Worker 	if (s1 && *s1 == 0)
222*6a54128fSAndroid Build Coastguard Worker 		s1 = 0;
223*6a54128fSAndroid Build Coastguard Worker 	if (s2 && *s2 == 0)
224*6a54128fSAndroid Build Coastguard Worker 		s2 = 0;
225*6a54128fSAndroid Build Coastguard Worker 
226*6a54128fSAndroid Build Coastguard Worker 	/* At least one potential output file name is valid */
227*6a54128fSAndroid Build Coastguard Worker 	if (!s0 && !s1 && !s2)
228*6a54128fSAndroid Build Coastguard Worker 		return NULL;
229*6a54128fSAndroid Build Coastguard Worker 	if (pipe(fds) < 0) {
230*6a54128fSAndroid Build Coastguard Worker 		perror("pipe");
231*6a54128fSAndroid Build Coastguard Worker 		exit(1);
232*6a54128fSAndroid Build Coastguard Worker 	}
233*6a54128fSAndroid Build Coastguard Worker 
234*6a54128fSAndroid Build Coastguard Worker 	pid = fork();
235*6a54128fSAndroid Build Coastguard Worker 	if (pid < 0) {
236*6a54128fSAndroid Build Coastguard Worker 		perror("fork");
237*6a54128fSAndroid Build Coastguard Worker 		exit(1);
238*6a54128fSAndroid Build Coastguard Worker 	}
239*6a54128fSAndroid Build Coastguard Worker 
240*6a54128fSAndroid Build Coastguard Worker 	if (pid == 0) {
241*6a54128fSAndroid Build Coastguard Worker 		if (e2fsck_global_ctx && e2fsck_global_ctx->progress_fd)
242*6a54128fSAndroid Build Coastguard Worker 			close(e2fsck_global_ctx->progress_fd);
243*6a54128fSAndroid Build Coastguard Worker 		if (daemon(0, 0) < 0) {
244*6a54128fSAndroid Build Coastguard Worker 			perror("daemon");
245*6a54128fSAndroid Build Coastguard Worker 			exit(1);
246*6a54128fSAndroid Build Coastguard Worker 		}
247*6a54128fSAndroid Build Coastguard Worker 		/*
248*6a54128fSAndroid Build Coastguard Worker 		 * Grab the output from our parent
249*6a54128fSAndroid Build Coastguard Worker 		 */
250*6a54128fSAndroid Build Coastguard Worker 		close(fds[1]);
251*6a54128fSAndroid Build Coastguard Worker 		while (do_read(fds[0]) > 0)
252*6a54128fSAndroid Build Coastguard Worker 			;
253*6a54128fSAndroid Build Coastguard Worker 		close(fds[0]);
254*6a54128fSAndroid Build Coastguard Worker 
255*6a54128fSAndroid Build Coastguard Worker 		/* OK, now let's try to open the output file */
256*6a54128fSAndroid Build Coastguard Worker 		fd = -1;
257*6a54128fSAndroid Build Coastguard Worker 		while (1) {
258*6a54128fSAndroid Build Coastguard Worker 			if (fd < 0 && s0)
259*6a54128fSAndroid Build Coastguard Worker 				fd = open(s0, O_WRONLY|O_CREAT|O_TRUNC, 0644);
260*6a54128fSAndroid Build Coastguard Worker 			if (fd < 0 && s1)
261*6a54128fSAndroid Build Coastguard Worker 				fd = open(s1, O_WRONLY|O_CREAT|O_TRUNC, 0644);
262*6a54128fSAndroid Build Coastguard Worker 			if (fd < 0 && s2)
263*6a54128fSAndroid Build Coastguard Worker 				fd = open(s2, O_WRONLY|O_CREAT|O_TRUNC, 0644);
264*6a54128fSAndroid Build Coastguard Worker 			if (fd >= 0)
265*6a54128fSAndroid Build Coastguard Worker 				break;
266*6a54128fSAndroid Build Coastguard Worker 			sleep(1);
267*6a54128fSAndroid Build Coastguard Worker 		}
268*6a54128fSAndroid Build Coastguard Worker 
269*6a54128fSAndroid Build Coastguard Worker 		cp = outbuf;
270*6a54128fSAndroid Build Coastguard Worker 		while (outbufsize > 0) {
271*6a54128fSAndroid Build Coastguard Worker 			c = write(fd, cp, outbufsize);
272*6a54128fSAndroid Build Coastguard Worker 			if (c < 0) {
273*6a54128fSAndroid Build Coastguard Worker 				if ((errno == EAGAIN) || (errno == EINTR))
274*6a54128fSAndroid Build Coastguard Worker 					continue;
275*6a54128fSAndroid Build Coastguard Worker 				break;
276*6a54128fSAndroid Build Coastguard Worker 			}
277*6a54128fSAndroid Build Coastguard Worker 			outbufsize -= c;
278*6a54128fSAndroid Build Coastguard Worker 			cp += c;
279*6a54128fSAndroid Build Coastguard Worker 		}
280*6a54128fSAndroid Build Coastguard Worker 		exit(0);
281*6a54128fSAndroid Build Coastguard Worker 	}
282*6a54128fSAndroid Build Coastguard Worker 
283*6a54128fSAndroid Build Coastguard Worker 	close(fds[0]);
284*6a54128fSAndroid Build Coastguard Worker 	ret = fdopen(fds[1], "w");
285*6a54128fSAndroid Build Coastguard Worker 	if (!ret)
286*6a54128fSAndroid Build Coastguard Worker 		close(fds[1]);
287*6a54128fSAndroid Build Coastguard Worker 	return ret;
288*6a54128fSAndroid Build Coastguard Worker }
289*6a54128fSAndroid Build Coastguard Worker 
290*6a54128fSAndroid Build Coastguard Worker #ifndef TEST_PROGRAM
set_up_log_file(e2fsck_t ctx,const char * key,const char * fn)291*6a54128fSAndroid Build Coastguard Worker static FILE *set_up_log_file(e2fsck_t ctx, const char *key, const char *fn)
292*6a54128fSAndroid Build Coastguard Worker {
293*6a54128fSAndroid Build Coastguard Worker 	FILE *f = NULL;
294*6a54128fSAndroid Build Coastguard Worker 	struct string s, s1, s2;
295*6a54128fSAndroid Build Coastguard Worker 	char *s0 = 0, *log_dir = 0, *log_fn = 0;
296*6a54128fSAndroid Build Coastguard Worker 	int log_dir_wait = 0;
297*6a54128fSAndroid Build Coastguard Worker 
298*6a54128fSAndroid Build Coastguard Worker 	s.s = s1.s = s2.s = 0;
299*6a54128fSAndroid Build Coastguard Worker 
300*6a54128fSAndroid Build Coastguard Worker 	profile_get_boolean(ctx->profile, "options", "log_dir_wait", 0, 0,
301*6a54128fSAndroid Build Coastguard Worker 			    &log_dir_wait);
302*6a54128fSAndroid Build Coastguard Worker 	if (fn)
303*6a54128fSAndroid Build Coastguard Worker 		log_fn = string_copy(ctx, fn, 0);
304*6a54128fSAndroid Build Coastguard Worker 	else
305*6a54128fSAndroid Build Coastguard Worker 		profile_get_string(ctx->profile, "options", key,
306*6a54128fSAndroid Build Coastguard Worker 				   0, 0, &log_fn);
307*6a54128fSAndroid Build Coastguard Worker 	profile_get_string(ctx->profile, "options", "log_dir", 0, 0, &log_dir);
308*6a54128fSAndroid Build Coastguard Worker 
309*6a54128fSAndroid Build Coastguard Worker 	if (!log_fn || !log_fn[0])
310*6a54128fSAndroid Build Coastguard Worker 		goto out;
311*6a54128fSAndroid Build Coastguard Worker 
312*6a54128fSAndroid Build Coastguard Worker 	expand_logfn(ctx, log_fn, &s);
313*6a54128fSAndroid Build Coastguard Worker 	if ((log_fn[0] == '/') || !log_dir || !log_dir[0])
314*6a54128fSAndroid Build Coastguard Worker 		s0 = s.s;
315*6a54128fSAndroid Build Coastguard Worker 
316*6a54128fSAndroid Build Coastguard Worker 	if (log_dir && log_dir[0]) {
317*6a54128fSAndroid Build Coastguard Worker 		alloc_string(&s1, strlen(log_dir) + strlen(s.s) + 2);
318*6a54128fSAndroid Build Coastguard Worker 		append_string(&s1, log_dir, 0);
319*6a54128fSAndroid Build Coastguard Worker 		append_string(&s1, "/", 1);
320*6a54128fSAndroid Build Coastguard Worker 		append_string(&s1, s.s, 0);
321*6a54128fSAndroid Build Coastguard Worker 	}
322*6a54128fSAndroid Build Coastguard Worker 
323*6a54128fSAndroid Build Coastguard Worker 	free(log_dir);
324*6a54128fSAndroid Build Coastguard Worker 	profile_get_string(ctx->profile, "options", "log_dir_fallback", 0, 0,
325*6a54128fSAndroid Build Coastguard Worker 			   &log_dir);
326*6a54128fSAndroid Build Coastguard Worker 	if (log_dir && log_dir[0]) {
327*6a54128fSAndroid Build Coastguard Worker 		alloc_string(&s2, strlen(log_dir) + strlen(s.s) + 2);
328*6a54128fSAndroid Build Coastguard Worker 		append_string(&s2, log_dir, 0);
329*6a54128fSAndroid Build Coastguard Worker 		append_string(&s2, "/", 1);
330*6a54128fSAndroid Build Coastguard Worker 		append_string(&s2, s.s, 0);
331*6a54128fSAndroid Build Coastguard Worker 		printf("%s\n", s2.s);
332*6a54128fSAndroid Build Coastguard Worker 	}
333*6a54128fSAndroid Build Coastguard Worker 
334*6a54128fSAndroid Build Coastguard Worker 	if (s0)
335*6a54128fSAndroid Build Coastguard Worker 		f = fopen(s0, "w");
336*6a54128fSAndroid Build Coastguard Worker 	if (!f && s1.s)
337*6a54128fSAndroid Build Coastguard Worker 		f = fopen(s1.s, "w");
338*6a54128fSAndroid Build Coastguard Worker 	if (!f && s2.s)
339*6a54128fSAndroid Build Coastguard Worker 		f = fopen(s2.s, "w");
340*6a54128fSAndroid Build Coastguard Worker 	if (!f && log_dir_wait)
341*6a54128fSAndroid Build Coastguard Worker 		f = save_output(s0, s1.s, s2.s);
342*6a54128fSAndroid Build Coastguard Worker 
343*6a54128fSAndroid Build Coastguard Worker out:
344*6a54128fSAndroid Build Coastguard Worker 	free(s.s);
345*6a54128fSAndroid Build Coastguard Worker 	free(s1.s);
346*6a54128fSAndroid Build Coastguard Worker 	free(s2.s);
347*6a54128fSAndroid Build Coastguard Worker 	free(log_fn);
348*6a54128fSAndroid Build Coastguard Worker 	free(log_dir);
349*6a54128fSAndroid Build Coastguard Worker 	return f;
350*6a54128fSAndroid Build Coastguard Worker }
351*6a54128fSAndroid Build Coastguard Worker 
set_up_logging(e2fsck_t ctx)352*6a54128fSAndroid Build Coastguard Worker void set_up_logging(e2fsck_t ctx)
353*6a54128fSAndroid Build Coastguard Worker {
354*6a54128fSAndroid Build Coastguard Worker 	ctx->logf = set_up_log_file(ctx, "log_filename", ctx->log_fn);
355*6a54128fSAndroid Build Coastguard Worker 	ctx->problem_logf = set_up_log_file(ctx, "problem_log_filename",
356*6a54128fSAndroid Build Coastguard Worker 					    ctx->problem_log_fn);
357*6a54128fSAndroid Build Coastguard Worker }
358*6a54128fSAndroid Build Coastguard Worker #else
e2fsck_allocate_memory(e2fsck_t ctx,unsigned long size,const char * description)359*6a54128fSAndroid Build Coastguard Worker void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned long size,
360*6a54128fSAndroid Build Coastguard Worker 			     const char *description)
361*6a54128fSAndroid Build Coastguard Worker {
362*6a54128fSAndroid Build Coastguard Worker 	void *ret;
363*6a54128fSAndroid Build Coastguard Worker 	char buf[256];
364*6a54128fSAndroid Build Coastguard Worker 
365*6a54128fSAndroid Build Coastguard Worker 	ret = malloc(size);
366*6a54128fSAndroid Build Coastguard Worker 	if (!ret) {
367*6a54128fSAndroid Build Coastguard Worker 		sprintf(buf, "Can't allocate %s\n", description);
368*6a54128fSAndroid Build Coastguard Worker 		exit(1);
369*6a54128fSAndroid Build Coastguard Worker 	}
370*6a54128fSAndroid Build Coastguard Worker 	memset(ret, 0, size);
371*6a54128fSAndroid Build Coastguard Worker 	return ret;
372*6a54128fSAndroid Build Coastguard Worker }
373*6a54128fSAndroid Build Coastguard Worker 
e2fsck_allocate_context(e2fsck_t * ret)374*6a54128fSAndroid Build Coastguard Worker errcode_t e2fsck_allocate_context(e2fsck_t *ret)
375*6a54128fSAndroid Build Coastguard Worker {
376*6a54128fSAndroid Build Coastguard Worker 	e2fsck_t	context;
377*6a54128fSAndroid Build Coastguard Worker 	errcode_t	retval;
378*6a54128fSAndroid Build Coastguard Worker 	char		*time_env;
379*6a54128fSAndroid Build Coastguard Worker 
380*6a54128fSAndroid Build Coastguard Worker 	context = malloc(sizeof(struct e2fsck_struct));
381*6a54128fSAndroid Build Coastguard Worker 	if (!context)
382*6a54128fSAndroid Build Coastguard Worker 		return ENOMEM;
383*6a54128fSAndroid Build Coastguard Worker 
384*6a54128fSAndroid Build Coastguard Worker 	memset(context, 0, sizeof(struct e2fsck_struct));
385*6a54128fSAndroid Build Coastguard Worker 
386*6a54128fSAndroid Build Coastguard Worker 	context->now = 1332006474;
387*6a54128fSAndroid Build Coastguard Worker 
388*6a54128fSAndroid Build Coastguard Worker 	context->filesystem_name = "/dev/sda3";
389*6a54128fSAndroid Build Coastguard Worker 	context->device_name = "fslabel";
390*6a54128fSAndroid Build Coastguard Worker 
391*6a54128fSAndroid Build Coastguard Worker 	*ret = context;
392*6a54128fSAndroid Build Coastguard Worker 	return 0;
393*6a54128fSAndroid Build Coastguard Worker }
394*6a54128fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)395*6a54128fSAndroid Build Coastguard Worker int main(int argc, char **argv)
396*6a54128fSAndroid Build Coastguard Worker {
397*6a54128fSAndroid Build Coastguard Worker 	e2fsck_t	ctx;
398*6a54128fSAndroid Build Coastguard Worker 	struct string	s;
399*6a54128fSAndroid Build Coastguard Worker 
400*6a54128fSAndroid Build Coastguard Worker 	putenv("TZ=EST+5:00");
401*6a54128fSAndroid Build Coastguard Worker 	e2fsck_allocate_context(&ctx);
402*6a54128fSAndroid Build Coastguard Worker 	expand_logfn(ctx, "e2fsck-%N.%h.%u.%D-%T", &s);
403*6a54128fSAndroid Build Coastguard Worker 	printf("%s\n", s.s);
404*6a54128fSAndroid Build Coastguard Worker 	free(s.s);
405*6a54128fSAndroid Build Coastguard Worker 	expand_logfn(ctx, "e2fsck-%N.%h.%u.%Y%m%d-%H%M%S", &s);
406*6a54128fSAndroid Build Coastguard Worker 	printf("%s\n", s.s);
407*6a54128fSAndroid Build Coastguard Worker 	free(s.s);
408*6a54128fSAndroid Build Coastguard Worker 
409*6a54128fSAndroid Build Coastguard Worker 	return 0;
410*6a54128fSAndroid Build Coastguard Worker }
411*6a54128fSAndroid Build Coastguard Worker #endif
412