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

📄 extract_list.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 5 页
字号:
                	/* if prompted for a tape, relay said prompt to the user */	if(sscanf(amidxtaped_line, "FEEDME %132s\n", desired_tape) == 1) {	    int done;	    g_printf(_("Load tape %s now\n"), desired_tape);	    dbprintf(_("Requesting tape %s from user\n"), desired_tape);	    done = okay_to_continue(am_has_feature(indexsrv_features,						   fe_amrecover_feedme_tape),				    0, 0);	    if (done == 1) {		if (am_has_feature(indexsrv_features,				   fe_amrecover_feedme_tape)) {		    char *reply = stralloc2("TAPE ", tape_device_name);		    send_to_tape_server(amidxtaped_streams[CTLFD].fd, reply);		    amfree(reply);		} else {		    send_to_tape_server(amidxtaped_streams[CTLFD].fd, "OK");		}	    } else {		send_to_tape_server(amidxtaped_streams[CTLFD].fd, "ERROR");		break;	    }	} else if(strncmp_const(amidxtaped_line, "MESSAGE ") == 0) {	    g_printf("%s\n",&amidxtaped_line[8]);	} else {	    g_fprintf(stderr, _("Strange message from tape server: %s"),		    amidxtaped_line);	    break;	}    }    /* CTL might be close before DATA */    event_loop(0);    aclose(child_pipe[1]);    waitpid(pid, &extractor_status, 0);    if(WEXITSTATUS(extractor_status) != 0){	int ret = WEXITSTATUS(extractor_status);        if(ret == 255) ret = -1;	g_printf(_("Extractor child exited with status %d\n"), ret);	return -1;    }    return(0);}/* exec restore to do the actual restoration *//* does the actual extraction of files *//* * The original design had the dump image being returned exactly as it * appears on the tape, and this routine getting from the index server * whether or not it is compressed, on the assumption that the tape * server may not know how to uncompress it. But * - Amrestore can't do that. It returns either compressed or uncompressed * (always). Amrestore assumes it can uncompress files. It is thus a good * idea to run the tape server on a machine with gzip. * - The information about compression in the disklist is really only * for future dumps. It is possible to change compression on a drive * so the information in the disklist may not necessarily relate to * the dump image on the tape. *   Consequently the design was changed to assuming that amrestore can * uncompress any dump image and have it return an uncompressed file * always. */voidextract_files(void){    EXTRACT_LIST *elist;    char * cwd;    char *l;    int first;    int otc;    tapelist_t *tlist = NULL, *a_tlist;    if (!is_extract_list_nonempty())    {	g_printf(_("Extract list empty - No files to extract!\n"));	return;    }    clean_extract_list();    /* get tape device name from index server if none specified */    if (tape_server_name == NULL) {	tape_server_name = newstralloc(tape_server_name, server_name);    }    if (tape_device_name == NULL) {	if (send_command("TAPE") == -1)	    exit(1);	if (get_reply_line() == -1)	    exit(1);	l = reply_line();	if (!server_happy())	{	    g_printf("%s\n", l);	    exit(1);	}	/* skip reply number */	tape_device_name = newstralloc(tape_device_name, l+4);    }    if (strcmp(tape_device_name, "/dev/null") == 0)    {	g_printf(_("amrecover: warning: using %s as the tape device will not work\n"),	       tape_device_name);    }    first=1;    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {	if(elist->tape[0]!='/') {	    if(first) {		g_printf(_("\nExtracting files using tape drive %s on host %s.\n"),			tape_device_name, tape_server_name);		g_printf(_("The following tapes are needed:"));		first=0;	    }	    else		g_printf("                               ");	    tlist = unmarshal_tapelist_str(elist->tape); 	    for(a_tlist = tlist ; a_tlist != NULL; a_tlist = a_tlist->next)		g_printf(" %s", a_tlist->label);	    g_printf("\n");	    free_tapelist(tlist);	}    }    first=1;    for (elist = first_tape_list(); elist != NULL; elist = next_tape_list(elist)) {	if(elist->tape[0]=='/') {	    if(first) {		g_printf(_("\nExtracting files from holding disk on host %s.\n"),			tape_server_name);		g_printf(_("The following files are needed:"));		first=0;	    }	    else		g_printf("                               ");	    tlist = unmarshal_tapelist_str(elist->tape); 	    for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)		g_printf(" %s", a_tlist->label);	    g_printf("\n");	    free_tapelist(tlist);	}    }    g_printf("\n");    cwd = g_get_current_dir();    if (cwd == NULL) {	perror(_("extract_list: Current working directory unavailable"));	exit(1);    }    g_printf(_("Restoring files into directory %s\n"), cwd);    check_file_overwrite(cwd);#ifdef SAMBA_CLIENT    if (samba_extract_method == SAMBA_SMBCLIENT)      g_printf(_("(unless it is a Samba backup, that will go through to the SMB server)\n"));#endif    dbprintf(_("Checking with user before restoring into directory %s\n"), cwd);    if (!okay_to_continue(0,0,0)) {        amfree(cwd);	return;    }    g_printf("\n");    if (!do_unlink_list()) {	g_fprintf(stderr, _("Can't recover because I can't cleanup the cwd (%s)\n"),		cwd);        amfree(cwd);	return;    }    free_unlink_list();    while ((elist = first_tape_list()) != NULL)    {	if(elist->tape[0]=='/') {	    dump_device_name = newstralloc(dump_device_name, elist->tape);	    g_printf(_("Extracting from file "));	    tlist = unmarshal_tapelist_str(dump_device_name); 	    for(a_tlist = tlist; a_tlist != NULL; a_tlist = a_tlist->next)		g_printf(" %s", a_tlist->label);	    g_printf("\n");	    free_tapelist(tlist);	}	else {	    g_printf(_("Extracting files using tape drive %s on host %s.\n"),		   tape_device_name, tape_server_name);	    tlist = unmarshal_tapelist_str(elist->tape); 	    g_printf(_("Load tape %s now\n"), tlist->label);	    dbprintf(_("Requesting tape %s from user\n"), tlist->label);	    free_tapelist(tlist);	    otc = okay_to_continue(1,1,0);	    if (otc == 0)	        return;	    else if (otc == SKIP_TAPE) {		delete_tape_list(elist); /* skip this tape */		continue;	    }	    dump_device_name = newstralloc(dump_device_name, tape_device_name);	}	dump_datestamp = newstralloc(dump_datestamp, elist->date);	/* connect to the tape handler daemon on the tape drive server */	if ((extract_files_setup(elist->tape, elist->fileno)) == -1)	{	    g_fprintf(stderr, _("amrecover - can't talk to tape server: %s\n"),		    errstr);	    return;	}	/* if the server have fe_amrecover_feedme_tape, it has asked for	 * the tape itself, even if the restore didn't succeed, we should	 * remove it.	 */	if(writer_intermediary(elist) == 0 ||	   am_has_feature(indexsrv_features, fe_amrecover_feedme_tape))	    delete_tape_list(elist);	/* tape done so delete from list */	stop_amidxtaped();    }}static voidamidxtaped_response(    void *		datap,    pkt_t *		pkt,    security_handle_t *	sech){    int ports[NSTREAMS], *response_error = datap, i;    char *p;    char *tok;    char *extra = NULL;    assert(response_error != NULL);    assert(sech != NULL);    memset(ports, -1, SIZEOF(ports));    if (pkt == NULL) {	errstr = newvstrallocf(errstr, _("[request failed: %s]"), security_geterror(sech));	*response_error = 1;	return;    }    security_close_connection(sech, dump_hostname);    if (pkt->type == P_NAK) {#if defined(PACKET_DEBUG)	g_fprintf(stderr, _("got nak response:\n----\n%s\n----\n\n"), pkt->body);#endif	tok = strtok(pkt->body, " ");	if (tok == NULL || strcmp(tok, "ERROR") != 0)	    goto bad_nak;	tok = strtok(NULL, "\n");	if (tok != NULL) {	    errstr = newvstralloc(errstr, "NAK: ", tok, NULL);	    *response_error = 1;	} else {bad_nak:	    errstr = newstralloc(errstr, "request NAK");	    *response_error = 2;	}	return;    }    if (pkt->type != P_REP) {	errstr = newvstrallocf(errstr, _("received strange packet type %s: %s"),			      pkt_type2str(pkt->type), pkt->body);	*response_error = 1;	return;    }#if defined(PACKET_DEBUG)    g_fprintf(stderr, _("got response:\n----\n%s\n----\n\n"), pkt->body);#endif    for(i = 0; i < NSTREAMS; i++) {        ports[i] = -1;        amidxtaped_streams[i].fd = NULL;    }    p = pkt->body;    while((tok = strtok(p, " \n")) != NULL) {	p = NULL;	/*	 * Error response packets have "ERROR" followed by the error message	 * followed by a newline.	 */	if (strcmp(tok, "ERROR") == 0) {	    tok = strtok(NULL, "\n");	    if (tok == NULL)		tok = _("[bogus error packet]");	    errstr = newstralloc(errstr, tok);	    *response_error = 2;	    return;	}        /*         * Regular packets have CONNECT followed by three streams         */        if (strcmp(tok, "CONNECT") == 0) {	    /*	     * Parse the three stream specifiers out of the packet.	     */	    for (i = 0; i < NSTREAMS; i++) {		tok = strtok(NULL, " ");		if (tok == NULL || strcmp(tok, amidxtaped_streams[i].name) != 0) {		    extra = vstrallocf(_("CONNECT token is \"%s\": expected \"%s\""),				      tok ? tok : "(null)",				      amidxtaped_streams[i].name);		    goto parse_error;		}		tok = strtok(NULL, " \n");		if (tok == NULL || sscanf(tok, "%d", &ports[i]) != 1) {		    extra = vstrallocf(_("CONNECT %s token is \"%s\": expected a port number"),				      amidxtaped_streams[i].name,				      tok ? tok : "(null)");		    goto parse_error;		}	    }	    continue;	}	/*	 * OPTIONS [options string] '\n'	 */	if (strcmp(tok, "OPTIONS") == 0) {	    tok = strtok(NULL, "\n");	    if (tok == NULL) {		extra = stralloc(_("OPTIONS token is missing"));		goto parse_error;	    }/*	    while((p = strchr(tok, ';')) != NULL) {		*p++ = '\0';		if(strncmp_const(tok, "features=") == 0) {		    tok += sizeof("features=") - 1;		    am_release_feature_set(their_features);		    if((their_features = am_string_to_feature(tok)) == NULL) {			errstr = newvstralloc(errstr,					      _("OPTIONS: bad features value: "),					      tok,					      NULL);			goto parse_error;		    }		}		tok = p;	    }*/	    continue;	}/*	extra = vstrallocf("next token is \"%s\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\""),			  tok ? tok : _("(null)"));	goto parse_error;*/    }    /*     * Connect the streams to their remote ports     */    for (i = 0; i < NSTREAMS; i++) {	if (ports[i] == -1)	    continue;	amidxtaped_streams[i].fd = security_stream_client(sech, ports[i]);	dbprintf(_("amidxtaped_streams[%d].fd = %p\n"),i, amidxtaped_streams[i].fd);	if (amidxtaped_streams[i].fd == NULL) {	    errstr = newvstrallocf(errstr,\			_("[could not connect %s stream: %s]"),			amidxtaped_streams[i].name,			security_geterror(sech));	    goto connect_error;	}    }    /*     * Authenticate the streams     */    for (i = 0; i < NSTREAMS; i++) {	if (amidxtaped_streams[i].fd == NULL)	    continue;	if (security_stream_auth(amidxtaped_streams[i].fd) < 0) {	    errstr = newvstrallocf(errstr,		_("[could not authenticate %s stream: %s]"),		amidxtaped_streams[i].name,		security_stream_geterror(amidxtaped_streams[i].fd));	    goto connect_error;	}    }    /*     * The CTLFD and DATAFD streams are mandatory.  If we didn't get     * them, complain.     */    if (amidxtaped_streams[CTLFD].fd == NULL) {        errstr = newvstrallocf(errstr, _("[couldn't open CTL streams]"));        goto connect_error;    }    if (amidxtaped_streams[DATAFD].fd == NULL) {        errstr = newvstrallocf(errstr, _("[couldn't open DATA streams]"));        goto connect_error;    }    /* everything worked */    *response_error = 0;    return;parse_error:    if (extra) {	errstr = newvstrallocf(errstr,			  _("[parse of reply message failed: %s]"), extra);    } else {	errstr = newvstrallocf(errstr,			  _("[parse of reply message failed: (no additional information)"));    }    amfree(extra);    *response_error = 2;    return;connect_error:    stop_amidxtaped();    *response_error = 1;}/* * This is called when everything needs to shut down so event_loop() * will exit. */static voidstop_amidxtaped(void){    int i;    for (i = 0; i < NSTREAMS; i++) {        if (amidxtaped_streams[i].fd != NULL) {            security_stream_close(amidxtaped_streams[i].fd);            amidxtaped_streams[i].fd = NULL;        }    }}static char* ctl_buffer = NULL;/* gets a "line" from server and put in server_line *//* server_line is terminated with \0, \r\n is striped *//* returns -1 if error */intget_amidxtaped_line(void){    ssize_t size;    char *newbuf, *s;    void *buf;    amfree(amidxtaped_line);    if (!ctl_buffer)	ctl_buffer = stralloc("");    while (!strstr(ctl_buffer,"\r\n")) {        size = security_stream_read_sync(amidxtaped_streams[CTLFD].fd, &buf);        if(size < 0) {            return -1;        }        else if(size == 0) {            return -1;        }        newbuf = alloc(strlen(ctl_buffer)+size+1);        strncpy(newbuf, ctl_buffer, (size_t)(strlen(ctl_buffer) + size + 1));        memcpy(newbuf+strlen(ctl_buffer), buf, (size_t)size);        newbuf[strlen(ctl_buffer)+size] = '\0';        amfree(ctl_buffer);        ctl_buffer = newbuf;    }    s = strstr(ctl_buffer,"\r\n");    *s = '\0';    newbuf = stralloc(s+2);    amidxtaped_line = stralloc(ctl_buffer);    amfree(ctl_buffer);    ctl_buffer = newbuf;    return 0;}static voidread_amidxtaped_data(    void *	cookie,    void *	buf,    ssize_t	size){    int fd;    assert(cookie != NULL);    fd = *(int *)cookie;    if (size < 0) {	errstr = newstralloc2(errstr, _("amidxtaped read: "),		 security_stream_geterror(amidxtaped_streams[DATAFD].fd));	return;    }    /*     * EOF.  Stop and return.     */    if (size == 0) {	security_stream_close(amidxtaped_streams[DATAFD].fd);	amidxtaped_streams[DATAFD].fd = NULL;	/*	 * If the mesg fd has also shut down, then 

⌨️ 快捷键说明

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