static void print_msg(int len, const char *from, const char *fmt, ...) { va_list args; char path[PATH_BUF], date[128]; time_t t; FILE *f; if (!len) len = strlen(from); snprintf(path, sizeof(path), "%s/%.*s", rootdir, len, from); mkdir_rec(path); snprintf(path, sizeof(path), "%s/%.*s/out", rootdir, len, from); f = fopen(path, "a"); if (f) { t = time(0); strftime(date, sizeof(date), "%Y-%m-%d %H:%M", localtime(&t)); fprintf(f, "%s ", date); va_start(args, fmt); vfprintf(f, fmt, args); va_end(args); fclose(f); } }
static int open_pipe(const char *name) { char path[PATH_BUF]; snprintf(path, sizeof(path), "%s/%s", rootdir, name); if (access(path, F_OK) == -1) mkdir_rec(path); snprintf(path, sizeof(path), "%s/%s/in", rootdir, name); if (access(path, F_OK) == -1) mkfifo(path, S_IRWXU); return open(path, O_RDONLY | O_NONBLOCK, 0); }
/*! 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; }