fsck: stop using strtok
This commit is contained in:
parent
1abf91aa25
commit
e18a293a52
157
e2fsprogs/fsck.c
157
e2fsprogs/fsck.c
@ -45,6 +45,7 @@
|
||||
*/
|
||||
|
||||
struct fs_info {
|
||||
struct fs_info *next;
|
||||
char *device;
|
||||
char *mountpt;
|
||||
char *type;
|
||||
@ -52,7 +53,6 @@ struct fs_info {
|
||||
int freq;
|
||||
int passno;
|
||||
int flags;
|
||||
struct fs_info *next;
|
||||
};
|
||||
|
||||
#define FLAG_DONE 1
|
||||
@ -61,6 +61,7 @@ struct fs_info {
|
||||
* Structure to allow exit codes to be stored
|
||||
*/
|
||||
struct fsck_instance {
|
||||
struct fsck_instance *next;
|
||||
int pid;
|
||||
int flags;
|
||||
int exit_status;
|
||||
@ -69,7 +70,6 @@ struct fsck_instance {
|
||||
char *type;
|
||||
char *device;
|
||||
char *base_device; /* /dev/hda for /dev/hdaN etc */
|
||||
struct fsck_instance *next;
|
||||
};
|
||||
|
||||
static const char *const ignored_types[] = {
|
||||
@ -104,6 +104,14 @@ static char **args;
|
||||
static int num_devices;
|
||||
static int num_args;
|
||||
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 smallint doall;
|
||||
static smallint noexecute;
|
||||
@ -122,13 +130,6 @@ static struct fs_info *filesys_info;
|
||||
static struct fs_info *filesys_last;
|
||||
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
|
||||
* 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
|
||||
* comma-delimited options list
|
||||
*/
|
||||
static int opt_in_list(char *opt, char *optlist)
|
||||
{
|
||||
char *list, *s;
|
||||
char *s;
|
||||
int len;
|
||||
|
||||
if (!optlist)
|
||||
return 0;
|
||||
list = xstrdup(optlist);
|
||||
|
||||
s = strtok(list, ",");
|
||||
while (s) {
|
||||
if (strcmp(s, opt) == 0) {
|
||||
free(list);
|
||||
return 1;
|
||||
}
|
||||
s = strtok(NULL, ",");
|
||||
len = strlen(opt);
|
||||
s = optlist - 1;
|
||||
while (1) {
|
||||
s = strstr(s + 1, opt);
|
||||
if (!s)
|
||||
return 0;
|
||||
/* 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 */
|
||||
static int fs_match(struct fs_info *fs)
|
||||
{
|
||||
int n, ret = 0, checked_type = 0;
|
||||
int n, ret, checked_type;
|
||||
char *cp;
|
||||
|
||||
if (!fs_type_list)
|
||||
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]) {
|
||||
case FS_TYPE_FLAG_NORMAL:
|
||||
checked_type++;
|
||||
@ -790,6 +842,7 @@ static int fs_match(struct fs_info *fs)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (checked_type == 0)
|
||||
return 1;
|
||||
@ -836,55 +889,14 @@ static int ignore(struct fs_info *fs)
|
||||
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. */
|
||||
static int check_all(void)
|
||||
{
|
||||
struct fs_info *fs = NULL;
|
||||
struct fs_info *fs;
|
||||
int status = EXIT_OK;
|
||||
int not_done_yet = 1;
|
||||
int passno = 1;
|
||||
int pass_done;
|
||||
smallint not_done_yet;
|
||||
smallint pass_done;
|
||||
int passno;
|
||||
|
||||
if (verbose)
|
||||
puts("Checking all filesystems");
|
||||
@ -926,6 +938,8 @@ static int check_all(void)
|
||||
if (LONE_CHAR(fs->mountpt, '/'))
|
||||
fs->flags |= FLAG_DONE;
|
||||
|
||||
not_done_yet = 1;
|
||||
passno = 1;
|
||||
while (not_done_yet) {
|
||||
not_done_yet = 0;
|
||||
pass_done = 1;
|
||||
@ -941,7 +955,7 @@ static int check_all(void)
|
||||
* do it yet.
|
||||
*/
|
||||
if (fs->passno > passno) {
|
||||
not_done_yet++;
|
||||
not_done_yet = 1;
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
@ -982,7 +996,7 @@ static int check_all(void)
|
||||
puts("----------------------------------");
|
||||
passno++;
|
||||
} else
|
||||
not_done_yet++;
|
||||
not_done_yet = 1;
|
||||
}
|
||||
kill_all_if_cancel_requested();
|
||||
status |= wait_many(FLAG_WAIT_ATLEAST_ONE);
|
||||
@ -1015,9 +1029,7 @@ static void compile_fs_type(char *fs_type)
|
||||
if (!fs_type)
|
||||
return;
|
||||
|
||||
// list = xstrdup(fs_type);
|
||||
num = 0;
|
||||
// s = strtok(list, ",");
|
||||
s = fs_type;
|
||||
while (1) {
|
||||
char *comma;
|
||||
@ -1030,6 +1042,7 @@ static void compile_fs_type(char *fs_type)
|
||||
s++;
|
||||
negate = 1;
|
||||
}
|
||||
|
||||
if (strcmp(s, "loop") == 0)
|
||||
/* loop is really short-hand for opts=loop */
|
||||
goto loop_special_case;
|
||||
@ -1050,9 +1063,7 @@ static void compile_fs_type(char *fs_type)
|
||||
if (!comma)
|
||||
break;
|
||||
s = comma + 1;
|
||||
// s = strtok(NULL, ",");
|
||||
}
|
||||
// free(list);
|
||||
}
|
||||
|
||||
static void parse_args(int argc, char *argv[])
|
||||
|
Loading…
Reference in New Issue
Block a user