119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * util.c --- miscellaneous utilities
33984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project *
619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %Begin-Header%
719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * This file may be redistributed under the terms of the GNU Public
819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * License.
919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * %End-Header%
1019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
1119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
1219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <stdlib.h>
133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <stdio.h>
1419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <unistd.h>
1519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <string.h>
1619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <ctype.h>
173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef __linux__
183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <sys/utsname.h>
193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
2019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_CONIO_H
2219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#undef HAVE_TERMIOS_H
2319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <conio.h>
2419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define read_a_char()	getch()
2519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
2619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_TERMIOS_H
2719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <termios.h>
2819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MALLOC_H
3219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <malloc.h>
3319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef HAVE_ERRNO_H
363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#include <errno.h>
373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include "e2fsck.h"
4019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern e2fsck_t e2fsck_global_ctx;   /* Try your very best not to use this! */
4219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/time.h>
4419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#include <sys/resource.h>
4519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
4619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid fatal_error(e2fsck_t ctx, const char *msg)
4719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (msg)
4919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf (stderr, "e2fsck: %s\n", msg);
5019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->fs && ctx->fs->io) {
5119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ctx->fs->io->magic == EXT2_ET_MAGIC_IO_CHANNEL)
5219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			io_channel_flush(ctx->fs->io);
5319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else
5419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			fprintf(stderr, "e2fsck: io manager magic bad!\n");
5519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
5619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ctx->flags |= E2F_FLAG_ABORT;
5719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->flags & E2F_FLAG_SETJMP_OK)
5819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		longjmp(ctx->abort_loc, 1);
5919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(FSCK_ERROR);
6019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
6119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size,
6319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			     const char *description)
6419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
6519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	void *ret;
6619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char buf[256];
6719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
6819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef DEBUG_ALLOCATE_MEMORY
693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	printf("Allocating %u bytes for %s...\n", size, description);
7019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
7119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ret = malloc(size);
7219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!ret) {
7319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		sprintf(buf, "Can't allocate %s\n", description);
7419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, buf);
7519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
7619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memset(ret, 0, size);
7719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ret;
7819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
7919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtchar *string_copy(e2fsck_t ctx EXT2FS_ATTR((unused)),
8119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		  const char *str, int len)
8219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
8319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	*ret;
843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
8519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!str)
8619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return NULL;
8719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!len)
8819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		len = strlen(str);
8919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ret = malloc(len+1);
9019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ret) {
9119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		strncpy(ret, str, len);
9219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ret[len] = 0;
9319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
9419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ret;
9519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
9619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
9719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef HAVE_STRNLEN
9819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
9919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Incredibly, libc5 doesn't appear to have strnlen.  So we have to
10019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * provide our own.
10119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
10219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint e2fsck_strnlen(const char * s, int count)
10319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
10419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char *cp = s;
10519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
10619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (count-- && *cp)
10719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		cp++;
10819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return cp - s;
10919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
11019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
11119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifndef HAVE_CONIO_H
11319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic int read_a_char(void)
11419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
11519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	char	c;
11619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	r;
11719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int	fail = 0;
11819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
11919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while(1) {
12019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (e2fsck_global_ctx &&
12119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) {
12219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 3;
12319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
12419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		r = read(0, &c, 1);
12519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (r == 1)
12619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return c;
12719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (fail++ > 100)
12819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
12919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
13019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return EOF;
13119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
13219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
13319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
13419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint ask_yn(const char * string, int def)
13519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
13619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int		c;
13719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*defstr;
13819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*short_yes = _("yY");
13919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*short_no = _("nN");
14019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_TERMIOS_H
14219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct termios	termios, tmp;
14319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
14419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tcgetattr (0, &termios);
14519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp = termios;
14619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp.c_lflag &= ~(ICANON | ECHO);
14719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp.c_cc[VMIN] = 1;
14819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tmp.c_cc[VTIME] = 0;
14919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tcsetattr (0, TCSANOW, &tmp);
15019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
15119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
15219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (def == 1)
15319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		defstr = _(_("<y>"));
15419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else if (def == 0)
15519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		defstr = _(_("<n>"));
15619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
15719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		defstr = _(" (y/n)");
15819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf("%s%s? ", string, defstr);
15919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	while (1) {
16019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fflush (stdout);
16119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((c = read_a_char()) == EOF)
16219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
16319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (c == 3) {
16419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_TERMIOS_H
16519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			tcsetattr (0, TCSANOW, &termios);
16619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
16719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (e2fsck_global_ctx &&
16819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			    e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) {
16919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				puts("\n");
17019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				longjmp(e2fsck_global_ctx->abort_loc, 1);
17119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
17219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			puts(_("cancelled!\n"));
17319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return 0;
17419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (strchr(short_yes, (char) c)) {
17619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			def = 1;
17719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
17819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
17919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if (strchr(short_no, (char) c)) {
18019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			def = 0;
18119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
18219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
18319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		else if ((c == ' ' || c == '\n') && (def != -1))
18419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
18519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
18619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (def)
18719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		puts(_("yes\n"));
18819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	else
18919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		puts (_("no\n"));
19019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_TERMIOS_H
19119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	tcsetattr (0, TCSANOW, &termios);
19219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
19319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return def;
19419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
19519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
19619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint ask (e2fsck_t ctx, const char * string, int def)
19719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
19819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->options & E2F_OPT_NO) {
19919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf (_("%s? no\n\n"), string);
20019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 0;
20119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
20219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->options & E2F_OPT_YES) {
20319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf (_("%s? yes\n\n"), string);
20419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return 1;
20519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
20619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->options & E2F_OPT_PREEN) {
20719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf ("%s? %s\n\n", string, def ? _("yes") : _("no"));
20819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return def;
20919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
21019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ask_yn(string, def);
21119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
21219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid e2fsck_read_bitmaps(e2fsck_t ctx)
21419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
21519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys fs = ctx->fs;
21619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	errcode_t	retval;
21719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*old_op;
21819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
21919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx->invalid_bitmaps) {
22019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, 0,
22119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    _("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"),
22219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->device_name);
22319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
22419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
22519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
22619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	old_op = ehandler_operation(_("reading inode and block bitmaps"));
22719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_read_bitmaps(fs);
22819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ehandler_operation(old_op);
22919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
23019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err(ctx->program_name, retval,
23119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			_("while retrying to read bitmaps for %s"),
23219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->device_name);
23319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
23419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
23519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
23619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
23719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid e2fsck_write_bitmaps(e2fsck_t ctx)
23819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
23919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys fs = ctx->fs;
24019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	errcode_t	retval;
24119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	const char	*old_op;
24219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
2433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	old_op = ehandler_operation(_("writing block and inode bitmaps"));
2443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	retval = ext2fs_write_bitmaps(fs);
2453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ehandler_operation(old_op);
2463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (retval) {
2473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err(ctx->program_name, retval,
2483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("while rewriting block and inode bitmaps for %s"),
2493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			ctx->device_name);
2503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fatal_error(ctx, 0);
25119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
25219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
25319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid preenhalt(e2fsck_t ctx)
25519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
25619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	ext2_filsys fs = ctx->fs;
25719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
25819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!(ctx->options & E2F_OPT_PREEN))
25919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return;
26019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; "
26119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		"RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"),
26219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       ctx->device_name);
2633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ctx->flags |= E2F_FLAG_EXITING;
26419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fs != NULL) {
26519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fs->super->s_state |= EXT2_ERROR_FS;
26619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_mark_super_dirty(fs);
26719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_close(fs);
26819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
26919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	exit(FSCK_UNCORRECTED);
27019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
27119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
27219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef RESOURCE_TRACK
2733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid init_resource_track(struct resource_track *track, io_channel channel)
27419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
27519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETRUSAGE
27619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct rusage r;
27719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	io_stats io_start = 0;
2793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
28019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	track->brk_start = sbrk(0);
28119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	gettimeofday(&track->time_start, 0);
28219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETRUSAGE
28319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef sun
28419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	memset(&r, 0, sizeof(struct rusage));
28519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
28619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	getrusage(RUSAGE_SELF, &r);
28719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	track->user_start = r.ru_utime;
28819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	track->system_start = r.ru_stime;
28919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
29019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	track->user_start.tv_sec = track->user_start.tv_usec = 0;
29119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	track->system_start.tv_sec = track->system_start.tv_usec = 0;
29219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
2933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	track->bytes_read = 0;
2943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	track->bytes_written = 0;
2953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (channel && channel->manager && channel->manager->get_stats)
2963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		channel->manager->get_stats(channel, &io_start);
2973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (io_start) {
2983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		track->bytes_read = io_start->bytes_read;
2993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		track->bytes_written = io_start->bytes_written;
3003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
30119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
30219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
30319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef __GNUC__
30419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _INLINE_ __inline__
30519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
30619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#define _INLINE_
30719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
30819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
30919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectstatic _INLINE_ float timeval_subtract(struct timeval *tv1,
31019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				       struct timeval *tv2)
31119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
31219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return ((tv1->tv_sec - tv2->tv_sec) +
31319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		((float) (tv1->tv_usec - tv2->tv_usec)) / 1000000);
31419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
31519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid print_resource_track(e2fsck_t ctx, const char *desc,
3173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			  struct resource_track *track, io_channel channel)
31819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
31919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETRUSAGE
32019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct rusage r;
32119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
32219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MALLINFO
32319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct mallinfo	malloc_info;
32419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
32519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct timeval time_end;
32619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
3273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if ((desc && !(ctx->options & E2F_OPT_TIME2)) ||
3283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	    (!desc && !(ctx->options & E2F_OPT_TIME)))
3293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return;
3303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	e2fsck_clear_progbar(ctx);
33219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	gettimeofday(&time_end, 0);
33319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
33419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (desc)
33519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		printf("%s: ", desc);
33619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
33719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_MALLINFO
3383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define kbytes(x)	(((unsigned long)(x) + 1023) / 1024)
3393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
34019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	malloc_info = mallinfo();
3413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	printf(_("Memory used: %luk/%luk (%luk/%luk), "),
34219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       kbytes(malloc_info.arena), kbytes(malloc_info.hblkhd),
34319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       kbytes(malloc_info.uordblks), kbytes(malloc_info.fordblks));
34419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
3453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	printf(_("Memory used: %lu, "),
3463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	       (unsigned long) (((char *) sbrk(0)) -
3473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				((char *) track->brk_start)));
3483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif
34919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef HAVE_GETRUSAGE
35019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	getrusage(RUSAGE_SELF, &r);
35119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
35219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(_("time: %5.2f/%5.2f/%5.2f\n"),
35319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       timeval_subtract(&time_end, &track->time_start),
35419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       timeval_subtract(&r.ru_utime, &track->user_start),
35519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       timeval_subtract(&r.ru_stime, &track->system_start));
35619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#else
35719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	printf(_("elapsed time: %6.3f\n"),
35819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	       timeval_subtract(&time_end, &track->time_start));
35919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
3603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define mbytes(x)	(((x) + 1048575) / 1048576)
3613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (channel && channel->manager && channel->manager->get_stats) {
3623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		io_stats delta = 0;
3633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		unsigned long long bytes_read = 0;
3643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		unsigned long long bytes_written = 0;
3653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (desc)
3673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			printf("%s: ", desc);
3683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		channel->manager->get_stats(channel, &delta);
3703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (delta) {
3713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			bytes_read = delta->bytes_read - track->bytes_read;
3723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			bytes_written = delta->bytes_written -
3733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				track->bytes_written;
3743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
3753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		printf("I/O read: %lluMB, write: %lluMB, rate: %.2fMB/s\n",
3763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       mbytes(bytes_read), mbytes(bytes_written),
3773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       (double)mbytes(bytes_read + bytes_written) /
3783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		       timeval_subtract(&time_end, &track->time_start));
3793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
38019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
38119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif /* RESOURCE_TRACK */
38219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid e2fsck_read_inode(e2fsck_t ctx, unsigned long ino,
38419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			      struct ext2_inode * inode, const char *proc)
38519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
38619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int retval;
38719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
38819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_read_inode(ctx->fs, ino, inode);
38919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
39019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err("ext2fs_read_inode", retval,
3913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("while reading inode %lu in %s"), ino, proc);
3923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		fatal_error(ctx, 0);
3933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
3943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
3953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
3963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtvoid e2fsck_read_inode_full(e2fsck_t ctx, unsigned long ino,
3973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			    struct ext2_inode *inode, int bufsize,
3983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			    const char *proc)
3993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
4003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int retval;
4013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
4023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	retval = ext2fs_read_inode_full(ctx->fs, ino, inode, bufsize);
4033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (retval) {
4043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		com_err("ext2fs_read_inode_full", retval,
4053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("while reading inode %lu in %s"), ino, proc);
40619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
40719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
40819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
40919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino,
41119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       struct ext2_inode * inode, int bufsize,
41219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       const char *proc)
41319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
41419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int retval;
41519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
41619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize);
41719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
41819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err("ext2fs_write_inode", retval,
4193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("while writing inode %lu in %s"), ino, proc);
42019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
42119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
42219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
42319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectextern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino,
42519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			       struct ext2_inode * inode, const char *proc)
42619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
42719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int retval;
42819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
42919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	retval = ext2fs_write_inode(ctx->fs, ino, inode);
43019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (retval) {
43119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		com_err("ext2fs_write_inode", retval,
4323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			_("while writing inode %lu in %s"), ino, proc);
43319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fatal_error(ctx, 0);
43419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
43519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
43619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
43719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#ifdef MTRACE
43819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectvoid mtrace_print(char *mesg)
43919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
44019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE	*malloc_get_mallstream();
44119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	FILE	*f = malloc_get_mallstream();
44219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (f)
44419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		fprintf(f, "============= %s\n", mesg);
44519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
44619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
44719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
44819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectblk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name,
44919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		   io_manager manager)
45019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
45119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	struct ext2_super_block *sb;
45219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	io_channel		io = NULL;
45319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	void			*buf = NULL;
45419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	int			blocksize;
45519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	blk_t			superblock, ret_sb = 8193;
4563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
45719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (fs && fs->super) {
45819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ret_sb = (fs->super->s_blocks_per_group +
45919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			  fs->super->s_first_data_block);
46019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ctx) {
46119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->superblock = ret_sb;
46219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->blocksize = fs->blocksize;
46319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
46419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return ret_sb;
46519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
4663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
46719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ctx) {
46819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (ctx->blocksize) {
46919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ret_sb = ctx->blocksize * 8;
47019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx->blocksize == 1024)
47119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ret_sb++;
47219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ctx->superblock = ret_sb;
47319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			return ret_sb;
47419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
47519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->superblock = ret_sb;
47619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ctx->blocksize = 1024;
47719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
47819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
47919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (!name || !manager)
48019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto cleanup;
48119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (manager->open(name, 0, &io) != 0)
48319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto cleanup;
48419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf))
48619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		goto cleanup;
48719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	sb = (struct ext2_super_block *) buf;
48819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
48919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	for (blocksize = EXT2_MIN_BLOCK_SIZE;
49019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	     blocksize <= EXT2_MAX_BLOCK_SIZE ; blocksize *= 2) {
49119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		superblock = blocksize*8;
49219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (blocksize == 1024)
49319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			superblock++;
49419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		io_channel_set_blksize(io, blocksize);
49519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (io_channel_read_blk(io, superblock,
49619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project					-SUPERBLOCK_SIZE, buf))
49719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			continue;
4983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef WORDS_BIGENDIAN
49919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC))
50019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ext2fs_swap_super(sb);
50119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project#endif
50219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		if ((sb->s_magic == EXT2_SUPER_MAGIC) &&
50319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		    (EXT2_BLOCK_SIZE(sb) == blocksize)) {
50419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			ret_sb = superblock;
50519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			if (ctx) {
50619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->superblock = superblock;
50719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project				ctx->blocksize = blocksize;
50819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			}
50919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project			break;
51019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		}
51119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	}
51219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
51319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectcleanup:
51419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (io)
51519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		io_channel_close(io);
51619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (buf)
51719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		ext2fs_free_mem(&buf);
51819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return (ret_sb);
51919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
52019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
52119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project/*
52219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project * Given a mode, return the ext2 file type
52319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project */
52419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Projectint ext2_file_type(unsigned int mode)
52519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project{
52619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISREG(mode))
52719dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_REG_FILE;
52819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
52919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISDIR(mode))
53019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_DIR;
5313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
53219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISCHR(mode))
53319dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_CHRDEV;
5343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
53519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISBLK(mode))
53619dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_BLKDEV;
5373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
53819dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISLNK(mode))
53919dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_SYMLINK;
54019dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project
54119dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISFIFO(mode))
54219dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_FIFO;
5433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
54419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	if (LINUX_S_ISSOCK(mode))
54519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project		return EXT2_FT_SOCK;
5463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
5473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return 0;
5483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
5493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
5503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#define STRIDE_LENGTH 8
5513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/*
5523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Helper function which zeros out _num_ blocks starting at _blk_.  In
5533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * case of an error, the details of the error is returned via _ret_blk_
5543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * and _ret_count_ if they are non-NULL pointers.  Returns 0 on
5553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * success, and an error code on an error.
5563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt *
5573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * As a special case, if the first argument is NULL, then it will
5583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * attempt to free the static zeroizing buffer.  (This is to keep
5593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * programs that check for memory leaks happy.)
5603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
5613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidterrcode_t e2fsck_zero_blocks(ext2_filsys fs, blk_t blk, int num,
5623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			     blk_t *ret_blk, int *ret_count)
5633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
5643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int		j, count, next_update, next_update_incr;
5653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	static char	*buf;
5663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	errcode_t	retval;
5673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
5683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* If fs is null, clean up the static buffer and return */
5693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!fs) {
5703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (buf) {
5713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			free(buf);
5723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			buf = 0;
5733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
5743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return 0;
5753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
5763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* Allocate the zeroizing buffer if necessary */
5773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!buf) {
5783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		buf = malloc(fs->blocksize * STRIDE_LENGTH);
5793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!buf) {
5803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			com_err("malloc", ENOMEM,
5813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				_("while allocating zeroizing buffer"));
5823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			exit(1);
5833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
5843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		memset(buf, 0, fs->blocksize * STRIDE_LENGTH);
5853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
5863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	/* OK, do the write loop */
5873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	next_update = 0;
5883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	next_update_incr = num / 100;
5893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (next_update_incr < 1)
5903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		next_update_incr = 1;
5913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	for (j = 0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) {
5923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		count = num - j;
5933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (count > STRIDE_LENGTH)
5943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			count = STRIDE_LENGTH;
5953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		retval = io_channel_write_blk(fs->io, blk, count, buf);
5963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (retval) {
5973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (ret_count)
5983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				*ret_count = count;
5993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (ret_blk)
6003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				*ret_blk = blk;
6013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return retval;
6023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
6033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
60419dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project	return 0;
60519dacda2b02bb08c0ffb649f84526b249c749279The Android Open Source Project}
6063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/*
6083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Check to see if a filesystem is in /proc/filesystems.
6093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Returns 1 if found, 0 if not
6103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
6113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint fs_proc_check(const char *fs_name)
6123984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
6133984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	FILE	*f;
6143984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char	buf[80], *cp, *t;
6153984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6163984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	f = fopen("/proc/filesystems", "r");
6173984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!f)
6183984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return (0);
6193984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (!feof(f)) {
6203984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!fgets(buf, sizeof(buf), f))
6213984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
6223984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		cp = buf;
6233984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!isspace(*cp)) {
6243984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			while (*cp && !isspace(*cp))
6253984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				cp++;
6263984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
6273984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		while (*cp && isspace(*cp))
6283984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			cp++;
6293984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((t = strchr(cp, '\n')) != NULL)
6303984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*t = 0;
6313984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((t = strchr(cp, '\t')) != NULL)
6323984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*t = 0;
6333984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((t = strchr(cp, ' ')) != NULL)
6343984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*t = 0;
6353984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcmp(fs_name, cp)) {
6363984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fclose(f);
6373984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return (1);
6383984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
6393984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
6403984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fclose(f);
6413984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return (0);
6423984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
6433984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6443984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/*
6453984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Check to see if a filesystem is available as a module
6463984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Returns 1 if found, 0 if not
6473984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
6483984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint check_for_modules(const char *fs_name)
6493984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
6503984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#ifdef __linux__
6513984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	struct utsname	uts;
6523984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	FILE		*f;
6533984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	char		buf[1024], *cp, *t;
6543984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int		i;
6553984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6563984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (uname(&uts))
6573984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return (0);
6583984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	snprintf(buf, sizeof(buf), "/lib/modules/%s/modules.dep", uts.release);
6593984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6603984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	f = fopen(buf, "r");
6613984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	if (!f)
6623984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		return (0);
6633984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (!feof(f)) {
6643984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!fgets(buf, sizeof(buf), f))
6653984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			break;
6663984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((cp = strchr(buf, ':')) != NULL)
6673984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			*cp = 0;
6683984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		else
6693984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			continue;
6703984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if ((cp = strrchr(buf, '/')) != NULL)
6713984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			cp++;
6723984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		else
6733984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			cp = buf;
6743984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		i = strlen(cp);
6753984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (i > 3) {
6763984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			t = cp + i - 3;
6773984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if (!strcmp(t, ".ko"))
6783984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				*t = 0;
6793984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
6803984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (!strcmp(cp, fs_name)) {
6813984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			fclose(f);
6823984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return (1);
6833984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
6843984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
6853984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	fclose(f);
6863984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt#endif /* __linux__ */
6873984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return (0);
6883984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
6893984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6903984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt/*
6913984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * Helper function that does the right thing if write returns a
6923984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt * partial write, or an EGAIN/EINTR error.
6933984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt */
6943984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidtint write_all(int fd, char *buf, size_t count)
6953984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt{
6963984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	ssize_t ret;
6973984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	int c = 0;
6983984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt
6993984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	while (count > 0) {
7003984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		ret = write(fd, buf, count);
7013984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		if (ret < 0) {
7023984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			if ((errno == EAGAIN) || (errno == EINTR))
7033984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt				continue;
7043984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt			return -1;
7053984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		}
7063984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		count -= ret;
7073984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		buf += ret;
7083984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt		c += ret;
7093984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	}
7103984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt	return c;
7113984b61df41c68966bdfbb2a5e5a45ef4b9a536cDmitry Shmidt}
712