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 <getopt.h>
8#include <stdarg.h>
9#include <stdbool.h>
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <sys/stat.h>
14#include <unistd.h>
15
16#include <fs-management/mount.h>
17#include <zircon/processargs.h>
18#include <zircon/syscalls.h>
19#include <lib/fdio/util.h>
20
21
22int usage(void) {
23    fprintf(stderr, "usage: mount [ <option>* ] devicepath mountpath\n"
24                    "options: \n"
25                    " -r|--readonly  : Open the filesystem as read-only\n"
26                    " -m|--metrics   : Collect filesystem metrics\n"
27                    " -v|--verbose   : Verbose mode\n"
28                    " -h|--help      : Display this message\n");
29    return -1;
30}
31
32int parse_args(int argc, char** argv, mount_options_t* options,
33               char** devicepath, char** mountpath) {
34    while (1) {
35        static struct option opts[] = {
36            {"readonly", no_argument, NULL, 'r'},
37            {"metrics", no_argument, NULL, 'm'},
38            {"verbose", no_argument, NULL, 'v'},
39            {"help", no_argument, NULL, 'h'},
40            {NULL, 0, NULL, 0},
41        };
42        int opt_index;
43        int c = getopt_long(argc, argv, "rmvh", opts, &opt_index);
44        if (c < 0) {
45            break;
46        }
47        switch (c) {
48        case 'r':
49            options->readonly = true;
50            break;
51        case 'm':
52            options->collect_metrics = true;
53            break;
54        case 'v':
55            options->verbose_mount = true;
56            break;
57        case 'h':
58        default:
59            return usage();
60        }
61    }
62
63    argc -= optind;
64    argv += optind;
65
66    if (argc < 2) {
67        return usage();
68    }
69    *devicepath = argv[0];
70    *mountpath = argv[1];
71    return 0;
72}
73
74int main(int argc, char** argv) {
75    char* devicepath;
76    char* mountpath;
77    mount_options_t options = default_mount_options;
78    int r;
79    if ((r = parse_args(argc, argv, &options, &devicepath, &mountpath))) {
80        return r;
81    }
82
83    if (options.verbose_mount) {
84        printf("fs_mount: Mounting device [%s] on path [%s]\n", devicepath, mountpath);
85    }
86
87    int fd;
88    if ((fd = open(devicepath, O_RDWR)) < 0) {
89        fprintf(stderr, "Error opening block device\n");
90        return -1;
91    }
92    disk_format_t df = detect_disk_format(fd);
93    zx_status_t status = mount(fd, mountpath, df, &options, launch_logs_async);
94    if (status != ZX_OK) {
95        fprintf(stderr, "fs_mount: Error while mounting: %d\n", status);
96    }
97    return status;
98}
99