1 /** 2 * Copyright (c) 2008-2015 Alper Akcan <alper.akcan@gmail.com> 3 * Copyright (c) 2009 Renzo Davoli <renzo@cs.unibo.it> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program (in the main directory of the fuse-ext2 17 * distribution in the file COPYING); if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #include "fuse-ext2.h" 22 23 static const char *HOME = "http://sourceforge.net/projects/fuse-ext2/"; 24 25 static const char *usage_msg = 26 "\n" 27 "%s %s %d - Probe EXT2FS volume mountability\n" 28 "\n" 29 "Copyright (C) 2008-2015 Alper Akcan <alper.akcan@gmail.com>\n" 30 "\n" 31 "Usage: %s <--readonly|--readwrite> <device|image_file>\n" 32 "\n" 33 "Example: fuse-ext2.probe --readwrite /dev/sda1\n" 34 "\n" 35 "%s\n" 36 "\n"; 37 38 static void usage (void) 39 { 40 printf(usage_msg, PACKAGE, VERSION, fuse_version(), PACKAGE, HOME); 41 } 42 43 static int parse_options (int argc, char *argv[], struct extfs_data *opts) 44 { 45 int c; 46 47 static const char *sopt = "-rwd"; 48 static const struct option lopt[] = { 49 { "readonly", no_argument, NULL, 'r' }, 50 { "readwrite", no_argument, NULL, 'w' }, 51 { "debug", no_argument, NULL, 'd' }, 52 { NULL, 0, NULL, 0 } 53 }; 54 55 opterr = 0; /* We'll handle the errors, thank you. */ 56 57 while ((c = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) { 58 switch (c) { 59 case 1: /* A non-option argument */ 60 if (!opts->device) { 61 opts->device = malloc(PATH_MAX + 1); 62 if (!opts->device) 63 return -1; 64 65 /* We don't want relative path in /etc/mtab. */ 66 if (optarg[0] != '/') { 67 if (!realpath(optarg, opts->device)) { 68 debugf_main("Cannot mount %s", optarg); 69 free(opts->device); 70 opts->device = NULL; 71 return -1; 72 } 73 } else 74 strcpy(opts->device, optarg); 75 } else { 76 debugf_main("You must specify exactly one device"); 77 return -1; 78 } 79 break; 80 case 'r': 81 opts->readonly = 1; 82 break; 83 case 'w': 84 opts->readonly = 0; 85 break; 86 case 'd': 87 opts->debug = 1; 88 break; 89 default: 90 debugf_main("Unknown option '%s'", argv[optind - 1]); 91 return -1; 92 } 93 } 94 95 if (!opts->device) { 96 debugf_main("No device is specified"); 97 return -1; 98 } 99 100 return 0; 101 } 102 103 int main (int argc, char *argv[]) 104 { 105 int err = 0; 106 struct stat sbuf; 107 struct extfs_data opts; 108 109 memset(&opts, 0, sizeof(opts)); 110 111 if (parse_options(argc, argv, &opts)) { 112 usage(); 113 return -1; 114 } 115 116 if (stat(opts.device, &sbuf)) { 117 debugf_main("Failed to access '%s'", opts.device); 118 err = -3; 119 goto err_out; 120 } 121 122 debugf_main("opts.device: %s", opts.device); 123 124 if (do_probe(&opts) != 0) { 125 debugf_main("Probe failed"); 126 err = -4; 127 goto err_out; 128 } 129 130 err_out: 131 free(opts.device); 132 free(opts.volname); 133 free(opts.options); 134 return err; 135 } 136