int os_main(int argc, char* argv[]) { adv_conf* context; char* section_map[1]; context = conf_init(); if (os_init(context) != 0) goto err_conf; inputb_reg(context, 1); inputb_reg_driver_all(context); if (conf_input_args_load(context, 0, "", &argc, argv, error_callback, 0) != 0) goto err_os; if (argc > 1) { fprintf(stderr, "Unknown argument '%s'\n", argv[1]); goto err_os; } section_map[0] = ""; conf_section_set(context, section_map, 1); if (inputb_load(context) != 0) goto err_os; if (os_inner_init("AdvanceINPUT") != 0) goto err_os; if (inputb_init() != 0) goto err_os_inner; if (inputb_enable(0) != 0) goto err_input; run(); inputb_disable(); inputb_done(); os_inner_done(); os_done(); conf_done(context); return EXIT_SUCCESS; err_input: inputb_done(); err_os_inner: os_inner_done(); err_os: os_done(); err_conf: conf_done(context); return EXIT_FAILURE; }
int os_main(int argc, char* argv[]) { int keyboard_id; adv_conf* context; const char* s; char* section_map[1]; const char** file_map; unsigned file_mac; int i; double latency_time; double buffer_time; double volume; unsigned rate; int attenuation; adv_bool opt_log; adv_bool opt_logsync; opt_log = 0; opt_logsync = 0; file_map = 0; file_mac = 0; context = conf_init(); if (os_init(context) != 0) goto err_conf; mixer_reg(context); conf_int_register_limit_default(context, "sound_volume", -32, 0, 0); conf_int_register_limit_default(context, "sound_samplerate", 5000, 96000, 44100); conf_float_register_limit_default(context, "sound_latency", 0.01, 2.0, 0.1); conf_float_register_limit_default(context, "sound_buffer", 0.05, 2.0, 0.1); if (conf_input_args_load(context, 0, "", &argc, argv, error_callback, 0) != 0) goto err_os; file_map = malloc(argc * sizeof(const char*)); for(i=1;i<argc;++i) { if (target_option_compare(argv[i], "log")) { opt_log = 1; } else if (target_option_compare(argv[i], "logsync")) { opt_logsync = 1; } else if (target_option_extract(argv[i]) == 0) { file_map[file_mac++] = argv[i]; } else { target_err("Unknown command line option '%s'.\n", argv[i]); goto err_os; } } if (argc <= 1 || file_mac == 0) { target_err("Syntax: advs FILES...\n"); goto err_os; } if (opt_log || opt_logsync) { const char* log = "advs.log"; remove(log); log_init(log, opt_logsync); } section_map[0] = ""; conf_section_set(context, section_map, 1); if (mixer_load(context) != 0) { goto err_os; } attenuation = conf_int_get_default(context, "sound_volume"); latency_time = conf_float_get_default(context, "sound_latency"); buffer_time = conf_float_get_default(context, "sound_buffer"); rate = conf_int_get_default(context, "sound_samplerate"); volume = 1.0; while (attenuation++ < 0) volume /= 1.122018454; /* = (10 ^ (1/20)) = 1dB */ if (os_inner_init("AdvanceSOUND") != 0) goto err_os; if (file_mac > MIXER_CHANNEL_MAX) { target_err("Too many files\n"); goto err_os_inner; } if (mixer_init(rate, file_mac, 1, buffer_time + latency_time, latency_time) != 0) { target_err("%s\n", error_get()); goto err_os_inner; } mixer_volume(volume); for(i=0;i<file_mac;++i) run(i, file_map[i]); free(file_map); signal(SIGINT, sigint); while (!done) { for(i=0;i<file_mac;++i) if (mixer_is_playing(i)) break; if (i==file_mac) break; mixer_poll(); target_idle(); } log_std(("s: shutdown\n")); mixer_done(); os_inner_done(); log_std(("s: the end\n")); if (opt_log || opt_logsync) { log_done(); } os_done(); conf_done(context); return EXIT_SUCCESS; err_os_inner: os_inner_done(); log_done(); err_os: os_done(); err_conf: conf_done(context); err: return EXIT_FAILURE; }
int main(int argc, char* argv[]) { int c; struct snapraid_option opt; char conf[PATH_MAX]; struct snapraid_state state; int operation; block_off_t blockstart; block_off_t blockcount; int ret; tommy_list filterlist_file; tommy_list filterlist_disk; int filter_missing; int filter_error; int plan; int olderthan; char* e; const char* command; const char* import_timestamp; const char* import_content; const char* log_file; int lock; const char* gen_conf; const char* run; int speedtest; int period; time_t t; struct tm* tm; int i; /* defaults */ config(conf, sizeof(conf), argv[0]); memset(&opt, 0, sizeof(opt)); opt.io_error_limit = 100; blockstart = 0; blockcount = 0; tommy_list_init(&filterlist_file); tommy_list_init(&filterlist_disk); period = 1000; filter_missing = 0; filter_error = 0; plan = SCRUB_AUTO; olderthan = SCRUB_AUTO; import_timestamp = 0; import_content = 0; log_file = 0; lock = 0; gen_conf = 0; speedtest = 0; run = 0; opterr = 0; while ((c = #if HAVE_GETOPT_LONG getopt_long(argc, argv, OPTIONS, long_options, 0)) #else getopt(argc, argv, OPTIONS)) #endif != EOF) { switch (c) { case 'c' : pathimport(conf, sizeof(conf), optarg); break; case 'f' : { struct snapraid_filter* filter = filter_alloc_file(1, optarg); if (!filter) { /* LCOV_EXCL_START */ log_fatal("Invalid filter specification '%s'\n", optarg); log_fatal("Filters using relative paths are not supported. Ensure to add an initial slash\n"); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } tommy_list_insert_tail(&filterlist_file, &filter->node, filter); } break; case 'd' : { struct snapraid_filter* filter = filter_alloc_disk(1, optarg); if (!filter) { /* LCOV_EXCL_START */ log_fatal("Invalid filter specification '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } tommy_list_insert_tail(&filterlist_disk, &filter->node, filter); } break; case 'm' : filter_missing = 1; opt.expected_missing = 1; break; case 'e' : /* when processing only error, we filter both files and blocks */ /* and we apply fixes only to synced ones */ filter_error = 1; opt.badonly = 1; opt.syncedonly = 1; break; case 'p' : if (strcmp(optarg, "bad") == 0) { plan = SCRUB_BAD; } else if (strcmp(optarg, "new") == 0) { plan = SCRUB_NEW; } else if (strcmp(optarg, "full") == 0) { plan = SCRUB_FULL; } else { plan = strtoul(optarg, &e, 10); if (!e || *e || plan > 100) { /* LCOV_EXCL_START */ log_fatal("Invalid plan/percentage '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } break; case 'o' : olderthan = strtoul(optarg, &e, 10); if (!e || *e || olderthan > 1000) { /* LCOV_EXCL_START */ log_fatal("Invalid number of days '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } break; case 'S' : blockstart = strtoul(optarg, &e, 0); if (!e || *e) { /* LCOV_EXCL_START */ log_fatal("Invalid start position '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } break; case 'B' : blockcount = strtoul(optarg, &e, 0); if (!e || *e) { /* LCOV_EXCL_START */ log_fatal("Invalid count number '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } break; case 'L' : opt.io_error_limit = strtoul(optarg, &e, 0); if (!e || *e) { /* LCOV_EXCL_START */ log_fatal("Invalid error limit number '%s'\n", optarg); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } break; case 'i' : if (import_timestamp) { /* LCOV_EXCL_START */ log_fatal("Import directory '%s' already specified as '%s'\n", optarg, import_timestamp); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } import_timestamp = optarg; break; case OPT_TEST_IMPORT_CONTENT : if (import_content) { /* LCOV_EXCL_START */ log_fatal("Import directory '%s' already specified as '%s'\n", optarg, import_content); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } import_content = optarg; break; case 'l' : if (log_file) { /* LCOV_EXCL_START */ log_fatal("Log file '%s' already specified as '%s'\n", optarg, log_file); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } log_file = optarg; break; case 'Z' : opt.force_zero = 1; break; case 'E' : opt.force_empty = 1; break; case 'U' : opt.force_uuid = 1; break; case 'D' : opt.force_device = 1; break; case 'N' : opt.force_nocopy = 1; break; case 'F' : opt.force_full = 1; break; case 'a' : opt.auditonly = 1; break; case 'h' : opt.prehash = 1; break; case 'v' : ++msg_level; break; case 'q' : --msg_level; break; case 'G' : opt.gui = 1; break; case 'H' : usage(); exit(EXIT_SUCCESS); case 'V' : version(); exit(EXIT_SUCCESS); case 'T' : speedtest = 1; break; case 'C' : gen_conf = optarg; break; case OPT_TEST_KILL_AFTER_SYNC : opt.kill_after_sync = 1; break; case OPT_TEST_EXPECT_UNRECOVERABLE : opt.expect_unrecoverable = 1; break; case OPT_TEST_EXPECT_RECOVERABLE : opt.expect_recoverable = 1; break; case OPT_TEST_SKIP_SELF : opt.skip_self = 1; break; case OPT_TEST_SKIP_SIGN : opt.skip_sign = 1; break; case OPT_TEST_SKIP_FALLOCATE : opt.skip_fallocate = 1; break; case OPT_TEST_SKIP_SEQUENTIAL : opt.skip_sequential = 1; break; case OPT_TEST_SKIP_DEVICE : opt.skip_device = 1; period = 50; /* reduce period of the speed test */ break; case OPT_TEST_SKIP_CONTENT_CHECK : opt.skip_content_check = 1; break; case OPT_TEST_SKIP_PARITY_ACCESS : opt.skip_parity_access = 1; break; case OPT_TEST_SKIP_DISK_ACCESS : opt.skip_disk_access = 1; break; case OPT_TEST_FORCE_MURMUR3 : opt.force_murmur3 = 1; break; case OPT_TEST_FORCE_SPOOKY2 : opt.force_spooky2 = 1; break; case OPT_TEST_SKIP_LOCK : opt.skip_lock = 1; break; case OPT_TEST_FORCE_ORDER_PHYSICAL : opt.force_order = SORT_PHYSICAL; break; case OPT_TEST_FORCE_ORDER_INODE : opt.force_order = SORT_INODE; break; case OPT_TEST_FORCE_ORDER_ALPHA : opt.force_order = SORT_ALPHA; break; case OPT_TEST_FORCE_ORDER_DIR : opt.force_order = SORT_DIR; break; case OPT_TEST_FORCE_SCRUB_AT : opt.force_scrub_at = atoi(optarg); break; case OPT_TEST_FORCE_SCRUB_EVEN : opt.force_scrub_even = 1; break; case OPT_TEST_FORCE_CONTENT_WRITE : opt.force_content_write = 1; break; case OPT_TEST_EXPECT_FAILURE : /* invert the exit codes */ exit_success = 1; exit_failure = 0; break; case OPT_TEST_EXPECT_NEED_SYNC : /* invert the exit codes */ exit_success = 1; exit_sync_needed = 0; break; case OPT_TEST_RUN : run = optarg; break; case OPT_TEST_FORCE_SCAN_WINFIND : opt.force_scan_winfind = 1; break; case OPT_TEST_FORCE_PROGRESS : opt.force_progress = 1; break; case OPT_TEST_FORCE_AUTOSAVE_AT : opt.force_autosave_at = atoi(optarg); break; case OPT_TEST_FAKE_DEVICE : opt.fake_device = 1; break; case OPT_NO_WARNINGS : opt.no_warnings = 1; break; default : /* LCOV_EXCL_START */ log_fatal("Unknown option '%c'\n", (char)c); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } os_init(opt.force_scan_winfind); raid_init(); crc32c_init(); if (speedtest != 0) { speed(period); os_done(); exit(EXIT_SUCCESS); } if (gen_conf != 0) { generate_configuration(gen_conf); os_done(); exit(EXIT_SUCCESS); } if (optind + 1 != argc) { /* LCOV_EXCL_START */ usage(); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } command = argv[optind]; if (strcmp(command, "diff") == 0) { operation = OPERATION_DIFF; } else if (strcmp(argv[optind], "sync") == 0) { operation = OPERATION_SYNC; } else if (strcmp(argv[optind], "check") == 0) { operation = OPERATION_CHECK; } else if (strcmp(argv[optind], "fix") == 0) { operation = OPERATION_FIX; } else if (strcmp(argv[optind], "test-dry") == 0) { operation = OPERATION_DRY; } else if (strcmp(argv[optind], "dup") == 0) { operation = OPERATION_DUP; } else if (strcmp(argv[optind], "list") == 0) { operation = OPERATION_LIST; } else if (strcmp(argv[optind], "pool") == 0) { operation = OPERATION_POOL; } else if (strcmp(argv[optind], "rehash") == 0) { operation = OPERATION_REHASH; } else if (strcmp(argv[optind], "scrub") == 0) { operation = OPERATION_SCRUB; } else if (strcmp(argv[optind], "status") == 0) { operation = OPERATION_STATUS; } else if (strcmp(argv[optind], "test-rewrite") == 0) { operation = OPERATION_REWRITE; } else if (strcmp(argv[optind], "test-read") == 0) { operation = OPERATION_READ; } else if (strcmp(argv[optind], "test-nano") == 0) { operation = OPERATION_NANO; } else if (strcmp(argv[optind], "up") == 0) { operation = OPERATION_SPINUP; } else if (strcmp(argv[optind], "down") == 0) { operation = OPERATION_SPINDOWN; } else if (strcmp(argv[optind], "devices") == 0) { operation = OPERATION_DEVICES; } else if (strcmp(argv[optind], "smart") == 0) { operation = OPERATION_SMART; } else { /* LCOV_EXCL_START */ log_fatal("Unknown command '%s'\n", argv[optind]); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } /* check options compatibility */ switch (operation) { case OPERATION_CHECK : break; default : if (opt.auditonly) { /* LCOV_EXCL_START */ log_fatal("You cannot use -a, --audit-only with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } switch (operation) { case OPERATION_FIX : break; default : if (opt.force_device) { /* LCOV_EXCL_START */ log_fatal("You cannot use -D, --force-device with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } switch (operation) { case OPERATION_SYNC : case OPERATION_CHECK : case OPERATION_FIX : break; default : if (opt.force_nocopy) { /* LCOV_EXCL_START */ log_fatal("You cannot use -N, --force-nocopy with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } switch (operation) { case OPERATION_SYNC : break; default : if (opt.prehash) { /* LCOV_EXCL_START */ log_fatal("You cannot use -h, --pre-hash with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (opt.force_full) { /* LCOV_EXCL_START */ log_fatal("You cannot use -F, --force-full with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } if (opt.force_full && opt.force_nocopy) { /* LCOV_EXCL_START */ log_fatal("You cannot use the -F, --force-full and -N, --force-nocopy options at the same time\n"); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (opt.prehash && opt.force_nocopy) { /* LCOV_EXCL_START */ log_fatal("You cannot use the -h, --pre-hash and -N, --force-nocopy options at the same time\n"); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } switch (operation) { case OPERATION_CHECK : case OPERATION_FIX : case OPERATION_DRY : break; default : if (!tommy_list_empty(&filterlist_file)) { /* LCOV_EXCL_START */ log_fatal("You cannot use -f, --filter with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (!tommy_list_empty(&filterlist_disk)) { /* LCOV_EXCL_START */ log_fatal("You cannot use -d, --filter-disk with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (filter_missing != 0) { /* LCOV_EXCL_START */ log_fatal("You cannot use -m, --filter-missing with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } if (filter_error != 0) { /* LCOV_EXCL_START */ log_fatal("You cannot use -e, --filter-error with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } /* errors must be always fixed on all disks */ /* becasue we don't keep the information on what disk is the error */ if (filter_error != 0 && !tommy_list_empty(&filterlist_disk)) { /* LCOV_EXCL_START */ log_fatal("You cannot use -e, --filter-error and -d, --filter-disk at the same time\n"); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } switch (operation) { case OPERATION_CHECK : case OPERATION_FIX : break; default : if (import_timestamp != 0 || import_content != 0) { /* LCOV_EXCL_START */ log_fatal("You cannot import with the '%s' command\n", command); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } switch (operation) { case OPERATION_LIST : case OPERATION_DUP : case OPERATION_STATUS : case OPERATION_REWRITE : case OPERATION_READ : case OPERATION_REHASH : case OPERATION_SPINUP : /* we want to do it in different threads to avoid blocking */ /* avoid to check and access data disks if not needed */ opt.skip_disk_access = 1; break; } switch (operation) { case OPERATION_DIFF : case OPERATION_LIST : case OPERATION_DUP : case OPERATION_POOL : case OPERATION_STATUS : case OPERATION_REWRITE : case OPERATION_READ : case OPERATION_REHASH : case OPERATION_NANO : case OPERATION_SPINUP : /* we want to do it in different threads to avoid blocking */ /* avoid to check and access parity disks if not needed */ opt.skip_parity_access = 1; break; } switch (operation) { case OPERATION_FIX : case OPERATION_CHECK : /* avoid to stop processing if a content file is not accessible */ opt.skip_content_access = 1; break; } switch (operation) { case OPERATION_DIFF : case OPERATION_LIST : case OPERATION_DUP : case OPERATION_POOL : case OPERATION_NANO : case OPERATION_SPINUP : case OPERATION_SPINDOWN : case OPERATION_DEVICES : case OPERATION_SMART : opt.skip_self = 1; break; } switch (operation) { case OPERATION_DEVICES : case OPERATION_SMART : /* we may need to use these commands during operations */ opt.skip_lock = 1; break; } /* open the log file */ log_open(log_file); /* print generic info into the log */ t = time(0); tm = localtime(&t); log_tag("version:%s\n", PACKAGE_VERSION); log_tag("unixtime:%" PRIi64 "\n", (int64_t)t); if (tm) { char datetime[64]; strftime(datetime, sizeof(datetime), "%Y-%m-%d %H:%M:%S", tm); log_tag("time:%s\n", datetime); } log_tag("command:%s\n", command); for (i = 0; i < argc; ++i) log_tag("argv:%u:%s\n", i, argv[i]); log_flush(); if (!opt.skip_self) selftest(); state_init(&state); /* read the configuration file */ state_config(&state, conf, command, &opt, &filterlist_disk); /* set the raid mode */ raid_mode(state.raid_mode); #if HAVE_LOCKFILE /* create the lock file */ if (!opt.skip_lock && state.lockfile[0]) { lock = lock_lock(state.lockfile); if (lock == -1) { /* LCOV_EXCL_START */ if (errno != EWOULDBLOCK) { log_fatal("Error creating the lock file '%s'. %s.\n", state.lockfile, strerror(errno)); } else { log_fatal("The lock file '%s' is already locked!\n", state.lockfile); log_fatal("SnapRAID is already in use!\n"); } exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } #else (void)lock; #endif if (operation == OPERATION_DIFF) { state_read(&state); ret = state_diff(&state); /* abort if sync needed */ if (ret > 0) exit(EXIT_SYNC_NEEDED); } else if (operation == OPERATION_SYNC) { /* in the next state read ensures to clear all the past hashes in case */ /* we are reading from an incomplete sync */ /* The undeterminated hash are only for CHG/DELETED blocks for which we don't */ /* know if the previous interrupted sync was able to update or not the parity. */ /* The sync process instead needs to trust this information because it's used */ /* to avoid to recompute the parity if all the input are equals as before. */ /* In these cases we don't know if the old state is still the one */ /* stored inside the parity, because after an aborted sync, the parity */ /* may be or may be not have been updated with the data that may be now */ /* deleted. Then we reset the hash to a bogus value. */ /* An example for CHG blocks is: */ /* - One file is added creating a CHG block with ZERO state */ /* - Sync aborted after updating the parity to the new state, */ /* but without saving the content file representing this new BLK state. */ /* - File is now deleted after the aborted sync */ /* - Sync again, deleting the blocks overt the CHG ones */ /* with the hash of CHG blocks not represeting the real parity state */ /* An example for DELETED blocks is: */ /* - One file is deleted creating DELETED blocks */ /* - Sync aborted after, updating the parity to the new state, */ /* but without saving the content file representing this new EMPTY state. */ /* - Another file is added again over the DELETE ones */ /* with the hash of DELETED blocks not represeting the real parity state */ state.clear_past_hash = 1; state_read(&state); state_scan(&state); /* refresh the size info before the content write */ state_refresh(&state); memory(); /* intercept signals while operating */ signal_init(); /* save the new state before the sync */ /* this allow to recover the case of the changes in the array after an aborted sync. */ /* for example, think at this case: */ /* - add some files at the array */ /* - run a sync command, it will recompute the parity adding the new files */ /* - abort the sync command before it stores the new content file */ /* - delete the not yet synced files from the array */ /* - run a new sync command */ /* the new sync command has now way to know that the parity file was modified */ /* because the files triggering these changes are now deleted */ /* and they aren't listed in the content file */ if (state.need_write) state_write(&state); /* run a test command if required */ if (run != 0) { ret = system(run); /* ignore error */ if (ret != 0) { /* LCOV_EXCL_START */ log_fatal("Error in running command '%s'.\n", run); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } /* waits some time to ensure that any concurrent modification done at the files, */ /* using the same mtime read by the scan process, will be read by sync. */ /* Note that any later modification done, potentially not read by sync, will have */ /* a different mtime, and it will be syncronized at the next sync. */ /* The worst case is the FAT filesystem with a two seconds resolution for mtime. */ /* If you don't use FAT, the wait is not needed, because most filesystems have now */ /* at least microseconds resolution, but better to be safe. */ if (!opt.skip_self) sleep(2); ret = state_sync(&state, blockstart, blockcount); /* save the new state if required */ if (!opt.kill_after_sync && (state.need_write || state.opt.force_content_write)) state_write(&state); /* abort if required */ if (ret != 0) { /* LCOV_EXCL_START */ exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } else if (operation == OPERATION_DRY) { state_read(&state); /* filter */ state_skip(&state); state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing, filter_error); memory(); /* intercept signals while operating */ signal_init(); state_dry(&state, blockstart, blockcount); } else if (operation == OPERATION_REHASH) { state_read(&state); /* intercept signals while operating */ signal_init(); state_rehash(&state); /* save the new state if required */ if (state.need_write) state_write(&state); } else if (operation == OPERATION_SCRUB) { state_read(&state); memory(); /* intercept signals while operating */ signal_init(); ret = state_scrub(&state, plan, olderthan); /* save the new state if required */ if (state.need_write || state.opt.force_content_write) state_write(&state); /* abort if required */ if (ret != 0) { /* LCOV_EXCL_START */ exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } else if (operation == OPERATION_REWRITE) { state_read(&state); /* intercept signals while operating */ signal_init(); state_write(&state); memory(); } else if (operation == OPERATION_READ) { state_read(&state); memory(); } else if (operation == OPERATION_NANO) { state_read(&state); state_nano(&state); /* intercept signals while operating */ signal_init(); state_write(&state); memory(); } else if (operation == OPERATION_SPINUP) { state_device(&state, DEVICE_UP); } else if (operation == OPERATION_SPINDOWN) { state_device(&state, DEVICE_DOWN); } else if (operation == OPERATION_DEVICES) { state_device(&state, DEVICE_LIST); } else if (operation == OPERATION_SMART) { state_device(&state, DEVICE_SMART); } else if (operation == OPERATION_STATUS) { state_read(&state); memory(); state_status(&state); } else if (operation == OPERATION_DUP) { state_read(&state); state_dup(&state); } else if (operation == OPERATION_LIST) { state_read(&state); state_list(&state); } else if (operation == OPERATION_POOL) { state_read(&state); state_pool(&state); } else { state_read(&state); /* if we are also trying to recover */ if (!state.opt.auditonly) { /* import the user specified dirs */ if (import_timestamp != 0) state_search(&state, import_timestamp); if (import_content != 0) state_import(&state, import_content); /* import from all the array */ if (!state.opt.force_nocopy) state_search_array(&state); } /* filter */ state_skip(&state); state_filter(&state, &filterlist_file, &filterlist_disk, filter_missing, filter_error); memory(); /* intercept signals while operating */ signal_init(); if (operation == OPERATION_CHECK) { ret = state_check(&state, 0, blockstart, blockcount); } else { /* it's fix */ ret = state_check(&state, 1, blockstart, blockcount); } /* abort if required */ if (ret != 0) { /* LCOV_EXCL_START */ exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } /* close log file */ log_close(log_file); #if HAVE_LOCKFILE if (!opt.skip_lock && state.lockfile[0]) { if (lock_unlock(lock) == -1) { /* LCOV_EXCL_START */ log_fatal("Error closing the lock file '%s'. %s.\n", state.lockfile, strerror(errno)); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ } } #endif state_done(&state); tommy_list_foreach(&filterlist_file, (tommy_foreach_func*)filter_free); tommy_list_foreach(&filterlist_disk, (tommy_foreach_func*)filter_free); os_done(); return EXIT_SUCCESS; }
int os_main(int argc, char* argv[]) { adv_crtc_container selected; adv_crtc_container_iterator i; const char* opt_rc; adv_bool opt_log; adv_bool opt_logsync; int j; adv_error res; char* section_map[1]; char buffer[1024]; opt_rc = 0; opt_log = 0; opt_logsync = 0; the_advance = advance_mame; the_sound_flag = 1; the_config = conf_init(); if (os_init(the_config)!=0) { target_err("Error initializing the OS support.\n"); goto err_conf; } video_reg(the_config, 1); monitor_register(the_config); crtc_container_register(the_config); generate_interpolate_register(the_config); gtf_register(the_config); inputb_reg(the_config, 1); inputb_reg_driver_all(the_config); /* MSDOS requires a special driver sub set */ #ifndef __MSDOS__ video_reg_driver_all(the_config); #endif if (conf_input_args_load(the_config, 1, "", &argc, argv, error_callback, 0) != 0) goto err_os; for(j=1;j<argc;++j) { if (target_option_compare(argv[j], "rc") && j+1<argc) { opt_rc = argv[++j]; } else if (target_option_compare(argv[j], "log")) { opt_log = 1; } else if (target_option_compare(argv[j], "logsync")) { opt_logsync = 1; } else if (target_option_compare(argv[j], "nosound")) { the_sound_flag = 0; } else if (target_option_compare(argv[j], "advmamev")) { the_advance = advance_mame; } else if (target_option_compare(argv[j], "advmessv")) { the_advance = advance_mess; } else if (target_option_compare(argv[j], "advpacv")) { the_advance = advance_pac; } else if (target_option_compare(argv[j], "advmenuv")) { the_advance = advance_menu; #ifdef __MSDOS__ } else if (target_option_compare(argv[j], "vgav")) { the_advance = advance_vga; } else if (target_option_compare(argv[j], "vbev")) { the_advance = advance_vbe; #endif #ifdef __WIN32__ } else if (target_option_compare(argv[j], "videowv")) { the_advance = advance_videow; #endif } else { target_err("Unknown option %s\n", argv[j]); goto err; } } #ifdef __MSDOS__ /* WARNING the MSDOS drivers are registered after the command line management. */ /* It implyes that you cannot specify any driver options on the command line */ msdos_rut(); if (the_advance == advance_vga) { if (the_advance_vga_active) { target_err("The AdvanceVGA utility is active. Disable it before running vgav.\n"); goto err; } video_reg_driver(the_config, &video_vgaline_driver); } else if (the_advance == advance_vbe) { if (the_advance_vbe_active) { target_err("The AdvanceVBE utility is active. Disable it before running vbev.\n"); goto err; } video_reg_driver(the_config, &video_vbeline_driver); video_reg_driver(the_config, &video_vgaline_driver); /* for the text modes */ } else { video_reg_driver_all(the_config); } #endif if (!opt_rc) { switch (the_advance) { case advance_vbe : opt_rc = "vbe.rc"; break; case advance_vga : opt_rc = "vga.rc"; break; case advance_menu : opt_rc = file_config_file_home("advmenu.rc"); break; case advance_mame : opt_rc = file_config_file_home("advmame.rc"); break; case advance_mess : opt_rc = file_config_file_home("advmess.rc"); break; case advance_pac : opt_rc = file_config_file_home("advpac.rc"); break; case advance_videow : opt_rc = file_config_file_home("videow.rc"); break; default : opt_rc = "advv.rc"; break; } } if (access(opt_rc, R_OK)!=0) { target_err("Configuration file %s not found.\n", opt_rc); goto err_os; } if (conf_input_file_load_adv(the_config, 0, opt_rc, opt_rc, 1, 1, STANDARD, sizeof(STANDARD)/sizeof(STANDARD[0]), error_callback, 0) != 0) goto err_os; if (opt_log || opt_logsync) { const char* log = "advv.log"; remove(log); log_init(log, opt_logsync); } log_std(("v: %s %s\n", __DATE__, __TIME__)); section_map[0] = ""; conf_section_set(the_config, section_map, 1); if (video_load(the_config, "") != 0) { target_err("Error loading the video options from the configuration file %s.\n", opt_rc); target_err("%s\n", error_get()); goto err_os; } if (inputb_load(the_config) != 0) { target_err("%s\n", error_get()); goto err_os; } /* NOTE: After this command all the target_err() string must */ /* have \n\r at the end to ensure correct newline in graphics mode. */ if (os_inner_init("AdvanceVIDEO") != 0) { goto err_os; } if (adv_video_init() != 0) { target_err("%s\n\r", error_get()); troubleshotting(); goto err_os_inner; } if (video_blit_init() != 0) { target_err("%s\n\r", error_get()); goto err_video; } if (the_advance != advance_vbe && the_advance != advance_vga) { if ((video_mode_generate_driver_flags(VIDEO_DRIVER_FLAGS_MODE_GRAPH_MASK, 0) & VIDEO_DRIVER_FLAGS_PROGRAMMABLE_CLOCK) == 0) { target_err("No active video driver is able to program your video board.\n\r"); troubleshotting(); goto err_blit; } } if (inputb_init() != 0) { target_err("%s\n\r", error_get()); goto err_blit; } if (monitor_load(the_config, &the_monitor) != 0) { target_err("Error loading the clock options from the configuration file %s.\n\r", opt_rc); target_err("%s\n\r", error_get()); goto err_input; } monitor_print(buffer, sizeof(buffer), &the_monitor); log_std(("v: clock %s\n", buffer)); /* load generate_linear config */ res = generate_interpolate_load(the_config, &the_interpolate); if (res<0) { target_err("Error loading the format options from the configuration file %s.\n\r", opt_rc); target_err("%s\n\r", error_get()); goto err_input; } if (res>0) { generate_default_vga(&the_interpolate.map[0].gen); the_interpolate.map[0].hclock = 31500; the_interpolate.mac = 1; } /* load generate_linear config */ res = gtf_load(the_config, &the_gtf); if (res<0) { target_err("Error loading the gtf options from the configuration file %s.\n\r", opt_rc); target_err("%s\n\r", error_get()); goto err_input; } if (res>0) { gtf_default_vga(&the_gtf); } /* all mode */ crtc_container_init(&selected); /* insert modes */ crtc_container_insert_default_all(&selected); /* sort */ crtc_container_init(&the_modes); for(crtc_container_iterator_begin(&i, &selected);!crtc_container_iterator_is_end(&i);crtc_container_iterator_next(&i)) { adv_crtc* crtc = crtc_container_iterator_get(&i); crtc_container_insert_sort(&the_modes, crtc, crtc_compare); } crtc_container_done(&selected); /* load selected */ crtc_container_init(&selected); if (crtc_container_load(the_config, &selected) != 0) { target_err("%s\n\r", error_get()); goto err_input; } /* union set */ for(crtc_container_iterator_begin(&i, &selected);!crtc_container_iterator_is_end(&i);crtc_container_iterator_next(&i)) { adv_crtc* crtc = crtc_container_iterator_get(&i); adv_bool has = crtc_container_has(&the_modes, crtc, crtc_compare) != 0; if (has) crtc_container_remove(&the_modes, crtc_select_by_compare, crtc); crtc->user_flags |= MODE_FLAGS_USER_BIT0; crtc_container_insert_sort(&the_modes, crtc, crtc_compare); } crtc_container_done(&selected); the_modes_modified = 0; if (text_init(&the_modes, &the_monitor) != 0) { goto err_input; } if (inputb_enable(0) != 0) { goto err_text; } sound_signal(); menu_run(); log_std(("v: shutdown\n")); inputb_disable(); text_done(); crtc_container_done(&the_modes); inputb_done(); video_blit_done(); adv_video_done(); os_inner_done(); log_std(("v: the end\n")); if (opt_log || opt_logsync) { log_done(); } os_done(); conf_save(the_config, 0, 0, error_callback, 0); conf_done(the_config); return EXIT_SUCCESS; err_text: text_done(); err_input: inputb_done(); err_blit: video_blit_done(); err_video: adv_video_done(); err_os_inner: os_inner_done(); err_os: if (opt_log || opt_logsync) { log_done(); } os_done(); err_conf: conf_done(the_config); err: return EXIT_FAILURE; }
int os_main(int argc, char* argv[]) { int i; adv_conf* context; const char* section_map[1]; adv_bool opt_log; adv_bool opt_logsync; opt_log = 0; opt_logsync = 0; context = conf_init(); if (os_init(context) != 0) goto err_conf; joystickb_reg(context, 1); joystickb_reg_driver_all(context); if (conf_input_args_load(context, 0, "", &argc, argv, error_callback, 0) != 0) goto err_os; for (i = 1; i < argc; ++i) { if (target_option_compare(argv[i], "log")) { opt_log = 1; } else if (target_option_compare(argv[i], "logsync")) { opt_logsync = 1; } else { fprintf(stderr, "Unknown argument '%s'\n", argv[1]); goto err_os; } } if (opt_log || opt_logsync) { const char* log = "advj.log"; remove(log); log_init(log, opt_logsync); } log_std(("j: %s %s %s %s\n", "AdvanceJOYSTICK", ADV_VERSION, __DATE__, __TIME__)); section_map[0] = ""; conf_section_set(context, section_map, 1); if (joystickb_load(context) != 0) goto err_os; if (os_inner_init("AdvanceJOYSTICK") != 0) goto err_os; if (joystickb_init() != 0) { target_err("%s\n", error_get()); goto err_os_inner; } probe(); calibrate(); run(); joystickb_done(); os_inner_done(); log_std(("j: the end\n")); if (opt_log || opt_logsync) { log_done(); } os_done(); conf_done(context); return EXIT_SUCCESS; err_os_inner: os_inner_done(); log_done(); err_os: os_done(); err_conf: conf_done(context); return EXIT_FAILURE; }