int delete_or_backup(const char *path, int keep) { int res; char *p, *confp; char *dest; /* get old path */ p = (keep == CONFLICT_KEEP_REMOTE) ? cache_path(path) : remote_path(path); /* get new path (or NULL if no bprefix/bsuffix set) */ dest = conflict_path(p); if (dest) { /* move to backup filename instead of deleting */ /* rename */ res = rename(p, dest); free(dest); /* schedule push/pull for new file */ if (!res) { confp = conflict_path(path); if (keep == CONFLICT_KEEP_REMOTE) job_schedule_push(confp); else job_schedule_pull(confp); free(confp); } } /* no backup prefix or suffix set -> just delete */ else { if (is_dir(path)) res = rmdir_rec(p); else res = unlink(p); } free(p); return res; }
/*! Main @param argc number of arguments @param argv arguments @return fuse_main()s return value */ int main(int argc, char **argv) { /* return value of fuse_main() */ int ret; /* for signal handling */ struct sigaction sig; /* argument handling */ struct fuse_args args = FUSE_ARGS_INIT(argc, argv); /* file name for database */ char *db_file; /*------------------------* * install signal handler * *------------------------*/ /* set handling function */ sig.sa_handler = sig_handler; /* set (no) flags */ sig.sa_flags = 0; /* don't ignore any signal */ sigemptyset(&sig.sa_mask); /* install signal handler for USR1 and USR2 */ sigaction(SIGUSR1, &sig, NULL); sigaction(SIGUSR2, &sig, NULL); /*------------------* * handle arguments * *------------------*/ if (fuse_opt_parse(&args, &discofs_options, discofs_opts, discofs_opt_proc) == -1) return EXIT_FAILURE; /* after option parsing, remote mount point must be set */ if (!REMOTE_ROOT) { fprintf(stderr, "no remote filesystem given\n"); return EXIT_FAILURE; } /* a mount point for discofs must also be set */ if (!discofs_options.discofs_mp) { fprintf(stderr, "no mount point given\n"); return EXIT_FAILURE; } /* add "use_ino" to display inodes in stat(1)*/ fuse_opt_add_arg(&args, "-ouse_ino"); /*---------------* * set UID / GID * *---------------*/ /* set GID first since permissions might not be sufficient if UID was set beforehand */ if (discofs_options.gid) { VERBOSE("setting gid to %d\n", discofs_options.gid); if (setgid(discofs_options.gid)) { perror("setting gid"); return EXIT_FAILURE; } } if (discofs_options.uid) { VERBOSE("setting uid to %d\n", discofs_options.uid); if (setuid(discofs_options.uid)) { perror("setting uid"); return EXIT_FAILURE; } } /*--------------------* * initialize logging * *--------------------*/ /* if -d is specified, override logging settings */ if (discofs_options.debug) log_init(LOG_DEBUG, NULL); else log_init(discofs_options.loglevel, discofs_options.logfile); /*=========================* * INITIALIZE CACHE AND DB * *=========================*/ /* compute data root if not passed as option */ if (!discofs_options.data_root) discofs_options.data_root = paths_data_root(REMOTE_ROOT); if (!is_dir(discofs_options.data_root)) { if (mkdir_rec(discofs_options.data_root)) FATAL("failed to create data directory %s\n", discofs_options.data_root); } /*----------------------* * initialize cache dir * *----------------------*/ /* set cache dir */ CACHE_ROOT = join_path(discofs_options.data_root, "cache"); /* store length of cache root (to save a few hundred strlen() calls) */ CACHE_ROOT_LEN = strlen(CACHE_ROOT); /* delete cache if "clear" specified */ if (discofs_options.clear) { VERBOSE("deleting cache\n"); rmdir_rec(CACHE_ROOT); } /* create cache root if needed */ if (!is_dir(CACHE_ROOT)) { if (mkdir(CACHE_ROOT, S_IRWXU) != 0) FATAL("failed to create cache directory %s\n", CACHE_ROOT); } /*---------------------* * initialize database * *---------------------*/ /* set db filename */ db_file = join_path(discofs_options.data_root, "db.sqlite"); /* create database file if it doesn't exist */ int fd = open(db_file, (O_RDONLY | O_CREAT), (S_IRUSR | S_IWUSR)); if (fd == -1) { perror(db_file); FATAL("couldn't open or create database file\n"); } close(fd); /* initialize tables etc */ db_init(db_file, discofs_options.clear); /* try to load filesystem features from DB */ if (db_cfg_get_int(CFG_FS_FEATURES, &discofs_options.fs_features)) { /* if loading failed, try to determine them */ if (is_mounted(REMOTE_ROOT) && is_reachable(discofs_options.host)) { if (test_fs_features(&discofs_options.fs_features)) { ERROR("failed to test remote fs features\n"); discofs_options.fs_features = 0; } /* test succeeded, store value for next time */ else db_cfg_set_int(CFG_FS_FEATURES, discofs_options.fs_features); } /* nag and assume that no features available (but don't save that) */ else { ERROR("could not determine remote fs features"); discofs_options.fs_features = 0; } } /*------------------* * initialize stuff * *------------------*/ #define INIT(name) \ if (name ## _init()) \ FATAL("error initializing " #name) INIT(lock); INIT(sync); INIT(job); #undef INIT /*----------------------* * print options to log * *----------------------*/ log_options(LOG_VERBOSE, discofs_options); /*-----------------* * run fuse_main() * *-----------------*/ ret = fuse_main(args.argc, args.argv, &discofs_oper, NULL); /*------* * exit * *------*/ lock_destroy(); sync_destroy(); job_destroy(); /* free arguments */ fuse_opt_free_args(&args); /* close database connection */ db_destroy(); /* end logging */ INFO("exiting\n"); log_destroy(); /* return fuse_main()s return value */ return ret; }