fsck: stop using strtok

This commit is contained in:
Denis Vlasenko 2007-01-19 02:03:14 +00:00
parent 1abf91aa25
commit e18a293a52

View File

@ -45,6 +45,7 @@
*/ */
struct fs_info { struct fs_info {
struct fs_info *next;
char *device; char *device;
char *mountpt; char *mountpt;
char *type; char *type;
@ -52,7 +53,6 @@ struct fs_info {
int freq; int freq;
int passno; int passno;
int flags; int flags;
struct fs_info *next;
}; };
#define FLAG_DONE 1 #define FLAG_DONE 1
@ -61,6 +61,7 @@ struct fs_info {
* Structure to allow exit codes to be stored * Structure to allow exit codes to be stored
*/ */
struct fsck_instance { struct fsck_instance {
struct fsck_instance *next;
int pid; int pid;
int flags; int flags;
int exit_status; int exit_status;
@ -69,7 +70,6 @@ struct fsck_instance {
char *type; char *type;
char *device; char *device;
char *base_device; /* /dev/hda for /dev/hdaN etc */ char *base_device; /* /dev/hda for /dev/hdaN etc */
struct fsck_instance *next;
}; };
static const char *const ignored_types[] = { static const char *const ignored_types[] = {
@ -104,6 +104,14 @@ static char **args;
static int num_devices; static int num_devices;
static int num_args; static int num_args;
static int verbose; static int verbose;
#define FS_TYPE_FLAG_NORMAL 0
#define FS_TYPE_FLAG_OPT 1
#define FS_TYPE_FLAG_NEGOPT 2
static char **fs_type_list;
static uint8_t *fs_type_flag;
static smallint fs_type_negated;
static volatile smallint cancel_requested; static volatile smallint cancel_requested;
static smallint doall; static smallint doall;
static smallint noexecute; static smallint noexecute;
@ -122,13 +130,6 @@ static struct fs_info *filesys_info;
static struct fs_info *filesys_last; static struct fs_info *filesys_last;
static struct fsck_instance *instance_list; static struct fsck_instance *instance_list;
#define FS_TYPE_FLAG_NORMAL 0
#define FS_TYPE_FLAG_OPT 1
#define FS_TYPE_FLAG_NEGOPT 2
static char **fs_type_list;
static uint8_t *fs_type_flag;
static int fs_type_negated;
/* /*
* Return the "base device" given a particular device; this is used to * Return the "base device" given a particular device; this is used to
* assure that we only fsck one partition on a particular drive at any * assure that we only fsck one partition on a particular drive at any
@ -741,40 +742,91 @@ static void fsck_device(struct fs_info *fs, int interactive)
} }
} }
/*
* Returns TRUE if a partition on the same disk is already being
* checked.
*/
static int device_already_active(char *device)
{
struct fsck_instance *inst;
char *base;
if (force_all_parallel)
return 0;
#ifdef BASE_MD
/* Don't check a soft raid disk with any other disk */
if (instance_list
&& (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1)
|| !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))
) {
return 1;
}
#endif
base = base_device(device);
/*
* If we don't know the base device, assume that the device is
* already active if there are any fsck instances running.
*/
if (!base)
return (instance_list != NULL);
for (inst = instance_list; inst; inst = inst->next) {
if (!inst->base_device || !strcmp(base, inst->base_device)) {
free(base);
return 1;
}
}
free(base);
return 0;
}
/* /*
* This function returns true if a particular option appears in a * This function returns true if a particular option appears in a
* comma-delimited options list * comma-delimited options list
*/ */
static int opt_in_list(char *opt, char *optlist) static int opt_in_list(char *opt, char *optlist)
{ {
char *list, *s; char *s;
int len;
if (!optlist) if (!optlist)
return 0; return 0;
list = xstrdup(optlist);
s = strtok(list, ","); len = strlen(opt);
while (s) { s = optlist - 1;
if (strcmp(s, opt) == 0) { while (1) {
free(list); s = strstr(s + 1, opt);
return 1; if (!s)
} return 0;
s = strtok(NULL, ","); /* neither "opt.." nor "xxx,opt.."? */
if (s != optlist && s[-1] != ',')
continue;
/* neither "..opt" nor "..opt,xxx"? */
if (s[len] != '\0' && s[len] != ',')
continue;
return 1;
} }
free(list);
return 0;
} }
/* See if the filesystem matches the criteria given by the -t option */ /* See if the filesystem matches the criteria given by the -t option */
static int fs_match(struct fs_info *fs) static int fs_match(struct fs_info *fs)
{ {
int n, ret = 0, checked_type = 0; int n, ret, checked_type;
char *cp; char *cp;
if (!fs_type_list) if (!fs_type_list)
return 1; return 1;
for (n = 0; (cp = fs_type_list[n]); n++) { ret = 0;
checked_type = 0;
n = 0;
while (1) {
cp = fs_type_list[n];
if (!cp)
break;
switch (fs_type_flag[n]) { switch (fs_type_flag[n]) {
case FS_TYPE_FLAG_NORMAL: case FS_TYPE_FLAG_NORMAL:
checked_type++; checked_type++;
@ -790,6 +842,7 @@ static int fs_match(struct fs_info *fs)
return 0; return 0;
break; break;
} }
n++;
} }
if (checked_type == 0) if (checked_type == 0)
return 1; return 1;
@ -836,55 +889,14 @@ static int ignore(struct fs_info *fs)
return 0; return 0;
} }
/*
* Returns TRUE if a partition on the same disk is already being
* checked.
*/
static int device_already_active(char *device)
{
struct fsck_instance *inst;
char *base;
if (force_all_parallel)
return 0;
#ifdef BASE_MD
/* Don't check a soft raid disk with any other disk */
if (instance_list
&& (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1)
|| !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))
) {
return 1;
}
#endif
base = base_device(device);
/*
* If we don't know the base device, assume that the device is
* already active if there are any fsck instances running.
*/
if (!base)
return (instance_list != NULL);
for (inst = instance_list; inst; inst = inst->next) {
if (!inst->base_device || !strcmp(base, inst->base_device)) {
free(base);
return 1;
}
}
free(base);
return 0;
}
/* Check all file systems, using the /etc/fstab table. */ /* Check all file systems, using the /etc/fstab table. */
static int check_all(void) static int check_all(void)
{ {
struct fs_info *fs = NULL; struct fs_info *fs;
int status = EXIT_OK; int status = EXIT_OK;
int not_done_yet = 1; smallint not_done_yet;
int passno = 1; smallint pass_done;
int pass_done; int passno;
if (verbose) if (verbose)
puts("Checking all filesystems"); puts("Checking all filesystems");
@ -926,6 +938,8 @@ static int check_all(void)
if (LONE_CHAR(fs->mountpt, '/')) if (LONE_CHAR(fs->mountpt, '/'))
fs->flags |= FLAG_DONE; fs->flags |= FLAG_DONE;
not_done_yet = 1;
passno = 1;
while (not_done_yet) { while (not_done_yet) {
not_done_yet = 0; not_done_yet = 0;
pass_done = 1; pass_done = 1;
@ -941,7 +955,7 @@ static int check_all(void)
* do it yet. * do it yet.
*/ */
if (fs->passno > passno) { if (fs->passno > passno) {
not_done_yet++; not_done_yet = 1;
continue; continue;
} }
/* /*
@ -982,7 +996,7 @@ static int check_all(void)
puts("----------------------------------"); puts("----------------------------------");
passno++; passno++;
} else } else
not_done_yet++; not_done_yet = 1;
} }
kill_all_if_cancel_requested(); kill_all_if_cancel_requested();
status |= wait_many(FLAG_WAIT_ATLEAST_ONE); status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
@ -1015,9 +1029,7 @@ static void compile_fs_type(char *fs_type)
if (!fs_type) if (!fs_type)
return; return;
// list = xstrdup(fs_type);
num = 0; num = 0;
// s = strtok(list, ",");
s = fs_type; s = fs_type;
while (1) { while (1) {
char *comma; char *comma;
@ -1030,6 +1042,7 @@ static void compile_fs_type(char *fs_type)
s++; s++;
negate = 1; negate = 1;
} }
if (strcmp(s, "loop") == 0) if (strcmp(s, "loop") == 0)
/* loop is really short-hand for opts=loop */ /* loop is really short-hand for opts=loop */
goto loop_special_case; goto loop_special_case;
@ -1050,9 +1063,7 @@ static void compile_fs_type(char *fs_type)
if (!comma) if (!comma)
break; break;
s = comma + 1; s = comma + 1;
// s = strtok(NULL, ",");
} }
// free(list);
} }
static void parse_args(int argc, char *argv[]) static void parse_args(int argc, char *argv[])