⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 taper.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 3 页
字号:
        g_get_current_time(&start_time);        if (getconf_seen(CNF_DEVICE_OUTPUT_BUFFER_SIZE)) {            max_memory = getconf_size(CNF_DEVICE_OUTPUT_BUFFER_SIZE);            if (getconf_seen(CNF_TAPEBUFS)) {                g_fprintf(stderr,                        "Configuration directives 'device_output_buffer_size' "                        "and \n"                        "'tapebufs' are incompatible; using former.\n");            }        } else if (getconf_seen(CNF_TAPEBUFS)) {            max_memory = getconf_int(CNF_TAPEBUFS) *                device_write_max_size(taper_state->device);        } else {            /* Use default. */            max_memory = getconf_size(CNF_DEVICE_OUTPUT_BUFFER_SIZE);        }        queue_result = do_consumer_producer_queue_full            (taper_source_producer,             dump_info->source,             counting_consumer,             &consumer_data,             device_write_max_size(taper_state->device), max_memory,             streaming_mode);        g_get_current_time(&end_time);        run_time = timesub(end_time, start_time);        /* The device_write_consumer may have closed the file with a short         * write, so we only finish here if it needs it. */        if (taper_state->device->in_file &&            !device_finish_file(taper_state->device)) {            queue_result = queue_result | QUEUE_CONSUMER_ERROR;        }        if (!finish_part_attempt(taper_state, dump_info, queue_result,                                 run_time, consumer_data.bytes_written)) {            break;        }    }}/* Handle a PORT_WRITE command. */static void process_port_write(taper_state_t * state,                               struct cmdargs * cmdargs) {    dump_info_t dump_state;    guint64 splitsize;    guint64 fallback_splitsize;    char * split_diskbuffer;    char * argnames[] = {"command",               /* 1 */			 "handle",                /* 2 */                         "hostname",              /* 3 */                         "diskname",              /* 4 */                         "level",                 /* 5 */                         "datestamp",             /* 6 */                         "splitsize",             /* 7 */                         "split_diskbuffer",      /* 8 */                         "fallback_splitsize",    /* 9 */                          NULL };    validate_args(PORT_WRITE, cmdargs, argnames);    dump_state.handle = g_strdup(cmdargs->argv[2]);    dump_state.hostname = g_strdup(cmdargs->argv[3]);    dump_state.diskname = unquote_string(cmdargs->argv[4]);        errno = 0;    dump_state.level = strtol(cmdargs->argv[5], NULL, 10);    if (errno != 0) {        error("error [taper PORT-WRITE: Invalid dump level %s]",              cmdargs->argv[5]);        g_assert_not_reached();    }        dump_state.timestamp = strdup(cmdargs->argv[6]);    errno = 0;    splitsize = g_ascii_strtoull(cmdargs->argv[7], NULL, 10);    if (errno != 0) {        error("error [taper PORT-WRITE: Invalid splitsize %s]",              cmdargs->argv[7]);        g_assert_not_reached();    }        if (strcmp(cmdargs->argv[8], "NULL") == 0) {        split_diskbuffer = NULL;    } else {        split_diskbuffer = g_strdup(cmdargs->argv[8]);    }        errno = 0;    fallback_splitsize = g_ascii_strtoull(cmdargs->argv[9], NULL, 10);    if (errno != 0) {        error("error [taper PORT-WRITE: Invalid fallback_splitsize %s]",              cmdargs->argv[9]);        g_assert_not_reached();    }    dump_state.id_string = g_strdup_printf("%s:%s.%d", dump_state.hostname,                                           dump_state.diskname,					   dump_state.level);        if (!open_read_socket(&dump_state, split_diskbuffer, splitsize,                          fallback_splitsize)) {        free(split_diskbuffer);        return;    }    free(split_diskbuffer);    run_device_output(state, &dump_state);    free_dump_info(&dump_state);}/* Handle a FILE_WRITE command. */static void process_file_write(taper_state_t * state,                               struct cmdargs * cmdargs) {    dump_info_t dump_state;    char * holding_disk_file;    guint64 splitsize;    char * argnames[] = {"command",               /* 1 */			 "handle",                /* 2 */                         "filename",              /* 3 */                         "hostname",              /* 4 */                         "diskname",              /* 5 */                         "level",                 /* 6 */                         "datestamp",             /* 7 */                         "splitsize",             /* 8 */                          NULL };    validate_args(FILE_WRITE, cmdargs, argnames);    dump_state.handle = g_strdup(cmdargs->argv[2]);    holding_disk_file = unquote_string(cmdargs->argv[3]);    dump_state.hostname = g_strdup(cmdargs->argv[4]);    dump_state.diskname = unquote_string(cmdargs->argv[5]);        errno = 0;    dump_state.level = strtol(cmdargs->argv[6], NULL, 10);    if (errno != 0) {        error("error [taper FILE-WRITE: Invalid dump level %s]",              cmdargs->argv[5]);        g_assert_not_reached();    }        dump_state.timestamp = strdup(cmdargs->argv[7]);    errno = 0;    splitsize = g_ascii_strtoull(cmdargs->argv[8], NULL, 10);    if (errno != 0) {        error("error [taper FILE-WRITE: Invalid splitsize %s]",              cmdargs->argv[8]);        g_assert_not_reached();    }    dump_state.id_string = g_strdup_printf("%s:%s.%d", dump_state.hostname,                                           dump_state.diskname,					   dump_state.level);        dump_state.source = taper_source_new(dump_state.handle, FILE_WRITE,                                         holding_disk_file, -1,                                         NULL, splitsize, -1);    /* FIXME: This should be handled properly. */    g_assert(dump_state.source != NULL);    run_device_output(state, &dump_state);    free_dump_info(&dump_state);    amfree(holding_disk_file);}/* Send QUITTING message to driver and associated logging. Always   returns false. */static gboolean send_quitting(taper_state_t * state) {    putresult(QUITTING, "\n");    g_fprintf(stderr,"taper: DONE\n");    cleanup(state);    return FALSE;}/* This function recieves the START_TAPER command from driver, and   returns the attached timestamp. */static gboolean find_first_tape(taper_state_t * state) {    cmd_t cmd;    /* Note: cmdargs.argv is never freed. In the entire Amanda codebase. */    struct cmdargs cmdargs;    tape_search_request_t search_request;    GThread * tape_search = NULL;    gboolean use_threads;    /* We save the value here in case it changes while we're running. */    use_threads = g_thread_supported();    search_request.state = state;    search_request.prolong = TRUE;    search_request.errmsg = NULL;        if (use_threads) {        tape_search = g_thread_create(tape_search_thread,                                      &search_request, TRUE, NULL);    }    cmd = getcmd(&cmdargs);    switch (cmd) {    case START_TAPER: {        gboolean search_result;        state->driver_start_time = strdup(cmdargs.argv[2]);        if (use_threads) {            search_result = GPOINTER_TO_INT(g_thread_join(tape_search));        } else {            search_result =                GPOINTER_TO_INT(tape_search_thread(&search_request));        }        if (search_result) {            putresult(TAPER_OK, "\n");        } else {            putresult(TAPE_ERROR, "Could not find a tape to use.\n");	    log_add(L_ERROR, "no-tape [%s]", "Could not find a tape to use");	    if (search_request.errmsg != NULL) {		char *c, *c1;		c = c1 = search_request.errmsg;		while (*c != '\0') {		    if (*c == '\n') {			*c = '\0';			log_add(L_WARNING,"%s", c1);			c1 = c+1;		    }		    c++;		}		if (strlen(c1) > 1 )		    log_add(L_WARNING,"%s", c1);	    }        }	amfree(search_request.errmsg);        return TRUE;    }    case QUIT:        search_request.prolong = FALSE;        if (use_threads) {            g_thread_join(tape_search);        }        return send_quitting(state);    default:        error("error [file_reader_side cmd %d argc %d]", cmd, cmdargs.argc);    }    g_assert_not_reached();}/* In running mode (not startup mode), get a command from driver and   deal with it. */static gboolean process_driver_command(taper_state_t * state) {    cmd_t cmd;    struct cmdargs cmdargs;    char * q;    /* This will return QUIT if driver has died. */    cmd = getcmd(&cmdargs);    switch (cmd) {    case PORT_WRITE:        /*         * PORT-WRITE         *   handle         *   hostname         *   features         *   diskname         *   level         *   datestamp         *   splitsize         *   split_diskbuffer         */        process_port_write(state, &cmdargs);        break;            case FILE_WRITE:        /*         * FILE-WRITE         *   handle         *   filename         *   hostname         *   features         *   diskname         *   level         *   datestamp         *   splitsize         */        process_file_write(state, &cmdargs);        break;            case QUIT:        return send_quitting(state);    default:        if (cmdargs.argc >= 1) {            q = squote(cmdargs.argv[1]);        } else if (cmdargs.argc >= 0) {            q = squote(cmdargs.argv[0]);        } else {            q = stralloc("(no input?)");        }        putresult(BAD_COMMAND, "%s\n", q);        amfree(q);        break;    }    return TRUE;}int main(int argc, char ** argv) {    char * tapelist_name;    int have_changer;    taper_state_t state;    config_overwrites_t *cfg_ovr = NULL;    char *cfg_opt = NULL;    /*     * Configure program for internationalization:     *   1) Only set the message locale for now.     *   2) Set textdomain for all amanda related programs to "amanda"     *      We don't want to be forced to support dozens of message catalogs.     */    setlocale(LC_MESSAGES, "C");    textdomain("amanda");        safe_fd(-1, 0);    set_pname("taper");    dbopen("server");    device_api_init();    init_taper_state(&state);    /* Don't die when child closes pipe */    signal(SIGPIPE, SIG_IGN);    g_fprintf(stderr, _("%s: pid %ld executable %s version %s\n"),	    get_pname(), (long) getpid(), argv[0], version());    dbprintf(_("%s: pid %ld executable %s version %s\n"),              get_pname(), (long) getpid(), argv[0], version());    /* Process options */    cfg_ovr = extract_commandline_config_overwrites(&argc, &argv);    if(argc > 2) {        error("Too many arguments!\n");        g_assert_not_reached();    }    if (argc > 1)	cfg_opt = argv[1];    config_init(CONFIG_INIT_EXPLICIT_NAME | CONFIG_INIT_USE_CWD | CONFIG_INIT_FATAL,		cfg_opt);    apply_config_overwrites(cfg_ovr);    safe_cd();    set_logerror(logerror);    check_running_as(RUNNING_AS_DUMPUSER);    dbrename(config_name, DBG_SUBDIR_SERVER);    tapelist_name = config_dir_relative(getconf_str(CNF_TAPELIST));    if (read_tapelist(tapelist_name) != 0) {        error("could not load tapelist \"%s\"", tapelist_name);        g_assert_not_reached();    }    amfree(tapelist_name);    have_changer = changer_init();    if (have_changer < 0) {        error("changer initialization failed: %s", strerror(errno));        g_assert_not_reached();    }    state.next_tape_label = NULL;    state.next_tape_device = NULL;    state.cur_tape = 0;        if (!find_first_tape(&state)) {        return EXIT_SUCCESS;    }    while (process_driver_command(&state));    return EXIT_SUCCESS;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -