1 // Copyright 2016 The Fuchsia Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include <errno.h>
6 #include <fcntl.h>
7 #include <stdarg.h>
8 #include <stdbool.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <unistd.h>
14 
15 #include <fs-management/mount.h>
16 #include <zircon/compiler.h>
17 #include <zircon/processargs.h>
18 #include <zircon/syscalls.h>
19 #include <lib/fdio/util.h>
20 
21 struct {
22     const char* name;
23     disk_format_t df;
24 } FILESYSTEMS[] = {
25     {"blobfs", DISK_FORMAT_BLOBFS},
26     {"minfs", DISK_FORMAT_MINFS},
27     {"fat", DISK_FORMAT_FAT},
28 };
29 
usage(void)30 int usage(void) {
31     fprintf(stderr, "usage: fsck [ <option>* ] devicepath filesystem\n");
32     fprintf(stderr, " -v  : Verbose mode\n");
33     fprintf(stderr, " values for 'filesystem' include:\n");
34     for (size_t i = 0; i < countof(FILESYSTEMS); i++) {
35         fprintf(stderr, "  '%s'\n", FILESYSTEMS[i].name);
36     }
37     return -1;
38 }
39 
parse_args(int argc,char ** argv,fsck_options_t * options,disk_format_t * df,char ** devicepath)40 int parse_args(int argc, char** argv, fsck_options_t* options, disk_format_t* df,
41                char** devicepath) {
42     *df = DISK_FORMAT_UNKNOWN;
43     while (argc > 1) {
44         if (!strcmp(argv[1], "-v")) {
45             options->verbose = true;
46         } else {
47             break;
48         }
49         argc--;
50         argv++;
51     }
52     if (argc < 3) {
53         return usage();
54     }
55 
56     *devicepath = argv[1];
57     for (size_t i = 0; i < countof(FILESYSTEMS); i++) {
58         if (!strcmp(FILESYSTEMS[i].name, argv[2])) {
59             *df = FILESYSTEMS[i].df;
60             break;
61         }
62     }
63     if (*df == DISK_FORMAT_UNKNOWN) {
64         fprintf(stderr, "fs_fsck: Cannot check a device with filesystem '%s'\n", argv[2]);
65         return -1;
66     }
67     return 0;
68 }
69 
main(int argc,char ** argv)70 int main(int argc, char** argv) {
71     char* devicepath;
72     disk_format_t df;
73     int r;
74     fsck_options_t options = default_fsck_options;
75     if ((r = parse_args(argc, argv, &options, &df, &devicepath))) {
76         return r;
77     }
78 
79     if (options.verbose) {
80         printf("fs_fsck: Checking device [%s]\n", devicepath);
81     }
82 
83     if ((r = fsck(devicepath, df, &options, launch_stdio_sync)) < 0) {
84         fprintf(stderr, "fs_fsck: Failed to check device: %d\n", r);
85     }
86     return r;
87 }
88