fsck: stop using strtok
No binary (build failed)
—
(log yok)
| @@ -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[]) | |