|
@@ -31,6 +31,7 @@
|
31
|
31
|
#include <stdlib.h>
|
32
|
32
|
#include <error.h>
|
33
|
33
|
#include <string.h>
|
|
34
|
+#include <getopt.h>
|
34
|
35
|
#include <errno.h>
|
35
|
36
|
#include <unistd.h>
|
36
|
37
|
#include <sys/types.h>
|
|
@@ -50,10 +51,19 @@ struct files {
|
50
|
51
|
struct fileinfo **data;
|
51
|
52
|
};
|
52
|
53
|
|
|
54
|
+enum fl_mode {
|
|
55
|
+ FL_FILE,
|
|
56
|
+ FL_GLOB,
|
|
57
|
+ FL_ARGS
|
|
58
|
+};
|
|
59
|
+
|
53
|
60
|
struct files *filelist;
|
54
|
61
|
char *filenames;
|
55
|
62
|
char *mountpoint;
|
|
63
|
+int debug = 0;
|
|
64
|
+int allow_other = 0;
|
56
|
65
|
int mountpoint_created = 0;
|
|
66
|
+enum fl_mode list_mode = FL_FILE;
|
57
|
67
|
|
58
|
68
|
static struct files *files_alloc(void) {
|
59
|
69
|
struct files *f = calloc(1, sizeof(struct files));
|
|
@@ -236,17 +246,96 @@ static struct fuse_operations concatfs_op = {
|
236
|
246
|
.destroy = fjfs_destroy,
|
237
|
247
|
};
|
238
|
248
|
|
|
249
|
+static const char *short_options = "fgaohd";
|
|
250
|
+
|
|
251
|
+static const struct option long_options[] = {
|
|
252
|
+ { "file", no_argument, NULL, 'f' },
|
|
253
|
+ { "glob", no_argument, NULL, 'g' },
|
|
254
|
+ { "args", no_argument, NULL, 'a' },
|
|
255
|
+ { "allow-other", no_argument, NULL, 'o' },
|
|
256
|
+ { "help", no_argument, NULL, 'h' },
|
|
257
|
+ { "debug", no_argument, NULL, 'd' },
|
|
258
|
+ { 0, 0, 0, 0 }
|
|
259
|
+};
|
|
260
|
+
|
|
261
|
+static void show_usage(void) {
|
|
262
|
+ printf("fjfs - FUSE module for virtual joining of multiple files into one.\n");
|
|
263
|
+ printf("\n");
|
|
264
|
+ printf("Usage: fjfs [file-list-options] [options] mount-point-file file-list\n");
|
|
265
|
+ printf("\n");
|
|
266
|
+ printf("Note: file-list depends on the options described bellow.\n");
|
|
267
|
+ printf("\n");
|
|
268
|
+ printf("File list options:\n");
|
|
269
|
+ printf(" -f --file | file-list is text file containing list of files (default).\n");
|
|
270
|
+ printf(" -g --glob | file-list is glob (*, ?, dir/file*).\n");
|
|
271
|
+ printf(" -a --args | file-list is N filenames (file1 file2 fileX).\n");
|
|
272
|
+ printf("\n");
|
|
273
|
+ printf("Examples:\n");
|
|
274
|
+ printf(" - Join files listed in filelist.txt as test-mount.txt\n");
|
|
275
|
+ printf(" fjfs test-mount.txt filelist.txt\n");
|
|
276
|
+ printf("\n");
|
|
277
|
+ printf(" - Join files named testfile*.txt as test-mount.txt\n");
|
|
278
|
+ printf(" fjfs --glob test-mount.txt 'testfile*.txt'\n");
|
|
279
|
+ printf("\n");
|
|
280
|
+ printf(" - Join files named testfileX.txt testfileY.txt testfileZ.txt as test-mount.txt\n");
|
|
281
|
+ printf(" fjfs --args test-mount.txt testfileX.txt testfileY.txt testfileZ.txt\n");
|
|
282
|
+ printf("\n");
|
|
283
|
+ printf("Other options:\n");
|
|
284
|
+ printf(" -o --allow-other | Mount FUSE with allow_other option. This allows other users\n");
|
|
285
|
+ printf(" . to access the mounted fjfs instance. /etc/fuse.conf must\n");
|
|
286
|
+ printf(" . contain \"user_allow_other\" in order for this option to work.\n");
|
|
287
|
+}
|
|
288
|
+
|
|
289
|
+static void parse_parameters(int argc, char *argv[]) {
|
|
290
|
+ int j;
|
|
291
|
+
|
|
292
|
+ while ( (j = getopt_long(argc, argv, short_options, long_options, NULL)) != -1 ) {
|
|
293
|
+ switch (j) {
|
|
294
|
+ case 'f': list_mode = FL_FILE; break;
|
|
295
|
+ case 'g': list_mode = FL_GLOB; break;
|
|
296
|
+ case 'a': list_mode = FL_ARGS; break;
|
|
297
|
+ case 'd': debug = 1; break;
|
|
298
|
+ case 'o': allow_other = 1; break;
|
|
299
|
+ case 'h':
|
|
300
|
+ show_usage();
|
|
301
|
+ exit(EXIT_SUCCESS);
|
|
302
|
+ break;
|
|
303
|
+ }
|
|
304
|
+ }
|
|
305
|
+
|
|
306
|
+ mountpoint = argv[optind];
|
|
307
|
+ filenames = argv[optind + 1];
|
|
308
|
+
|
|
309
|
+ if (!mountpoint || !filenames) {
|
|
310
|
+ show_usage();
|
|
311
|
+ exit(EXIT_FAILURE);
|
|
312
|
+ }
|
|
313
|
+
|
|
314
|
+ if (debug) {
|
|
315
|
+ fprintf(stderr, "mount point: %s\n", mountpoint);
|
|
316
|
+ switch (list_mode) {
|
|
317
|
+ case FL_FILE:
|
|
318
|
+ fprintf(stderr, "list (file) : %s\n", filenames);
|
|
319
|
+ break;
|
|
320
|
+ case FL_GLOB:
|
|
321
|
+ fprintf(stderr, "list (glob) : %s\n", filenames);
|
|
322
|
+ break;
|
|
323
|
+ case FL_ARGS:
|
|
324
|
+ fprintf(stderr, "list (args) :");
|
|
325
|
+ for (j = optind + 1; j < argc; j++) {
|
|
326
|
+ fprintf(stderr, " %s", argv[j]);
|
|
327
|
+ }
|
|
328
|
+ fprintf(stderr, "\n");
|
|
329
|
+ break;
|
|
330
|
+ }
|
|
331
|
+ }
|
|
332
|
+}
|
|
333
|
+
|
239
|
334
|
int main(int argc, char *argv[]) {
|
240
|
|
- int ret;
|
|
335
|
+ int ret = EXIT_FAILURE;
|
241
|
336
|
struct stat sb;
|
242
|
337
|
|
243
|
|
- if (argc < 3) {
|
244
|
|
- fprintf(stderr, "Usage: %s mount-point-file filelist.txt\n", argv[0]);
|
245
|
|
- exit(EXIT_FAILURE);
|
246
|
|
- }
|
247
|
|
-
|
248
|
|
- mountpoint = argv[1];
|
249
|
|
- filenames = argv[2];
|
|
338
|
+ parse_parameters(argc, argv);
|
250
|
339
|
|
251
|
340
|
if (stat(mountpoint, &sb) == -1) {
|
252
|
341
|
FILE *f = fopen(mountpoint, "wb");
|