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