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

📄 dumper.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 4 页
字号:
{    (void)unused;	/* Quiet unused parameter warning */    assert(unused == NULL);    errstr = newstralloc(errstr, _("data timeout"));    dump_result = 2;    stop_dump();}/* * This is called when everything needs to shut down so event_loop() * will exit. */static voidstop_dump(void){    int i;    for (i = 0; i < NSTREAMS; i++) {	if (streams[i].fd != NULL) {	    security_stream_close(streams[i].fd);	    streams[i].fd = NULL;	}    }    timeout(0);}/* * Runs compress with the first arg as its stdout.  Returns * 0 on success or negative if error, and it's pid via the second * argument.  The outfd arg is dup2'd to the pipe to the compress * process. */static intruncompress(    int		outfd,    pid_t *	pid,    comp_t	comptype){    int outpipe[2], rval;    assert(outfd >= 0);    assert(pid != NULL);    /* outpipe[0] is pipe's stdin, outpipe[1] is stdout. */    if (pipe(outpipe) < 0) {	errstr = newvstrallocf(errstr, _("pipe: %s"), strerror(errno));	return (-1);    }    switch (*pid = fork()) {    case -1:	errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno));	aclose(outpipe[0]);	aclose(outpipe[1]);	return (-1);    default:	rval = dup2(outpipe[1], outfd);	if (rval < 0)	    errstr = newvstrallocf(errstr, _("couldn't dup2: %s"), strerror(errno));	aclose(outpipe[1]);	aclose(outpipe[0]);	return (rval);    case 0:	if (dup2(outpipe[0], 0) < 0) {	    error(_("err dup2 in: %s"), strerror(errno));	    /*NOTREACHED*/	}	if (dup2(outfd, 1) == -1) {	    error(_("err dup2 out: %s"), strerror(errno));	    /*NOTREACHED*/	}	safe_fd(-1, 0);	if (comptype != COMP_SERVER_CUST) {	    execlp(COMPRESS_PATH, COMPRESS_PATH, (  comptype == COMP_BEST ?		COMPRESS_BEST_OPT : COMPRESS_FAST_OPT), (char *)NULL);	    error(_("error: couldn't exec %s: %s"), COMPRESS_PATH, strerror(errno));	    /*NOTREACHED*/	} else if (*srvcompprog) {	    execlp(srvcompprog, srvcompprog, (char *)0);	    error(_("error: couldn't exec server custom filter%s.\n"), srvcompprog);	    /*NOTREACHED*/	}    }    /*NOTREACHED*/    return (-1);}/* * Runs encrypt with the first arg as its stdout.  Returns * 0 on success or negative if error, and it's pid via the second * argument.  The outfd arg is dup2'd to the pipe to the encrypt * process. */static intrunencrypt(    int		outfd,    pid_t *	pid,    encrypt_t	encrypttype){    int outpipe[2], rval;    assert(outfd >= 0);    assert(pid != NULL);    /* outpipe[0] is pipe's stdin, outpipe[1] is stdout. */    if (pipe(outpipe) < 0) {	errstr = newvstrallocf(errstr, _("pipe: %s"), strerror(errno));	return (-1);    }    switch (*pid = fork()) {    case -1:	errstr = newvstrallocf(errstr, _("couldn't fork: %s"), strerror(errno));	aclose(outpipe[0]);	aclose(outpipe[1]);	return (-1);    default:	rval = dup2(outpipe[1], outfd);	if (rval < 0)	    errstr = newvstrallocf(errstr, _("couldn't dup2: %s"), strerror(errno));	aclose(outpipe[1]);	aclose(outpipe[0]);	return (rval);    case 0:	if (dup2(outpipe[0], 0) < 0) {	    error(_("err dup2 in: %s"), strerror(errno));	    /*NOTREACHED*/	}	if (dup2(outfd, 1) < 0 ) {	    error(_("err dup2 out: %s"), strerror(errno));	    /*NOTREACHED*/	}	safe_fd(-1, 0);	if ((encrypttype == ENCRYPT_SERV_CUST) && *srv_encrypt) {	    execlp(srv_encrypt, srv_encrypt, (char *)0);	    error(_("error: couldn't exec server encryption%s.\n"), srv_encrypt);	    /*NOTREACHED*/	}    }    /*NOTREACHED*/    return (-1);}/* -------------------- */static voidsendbackup_response(    void *		datap,    pkt_t *		pkt,    security_handle_t *	sech){    int ports[NSTREAMS], *response_error = datap, i;    char *p;    char *tok;    char *extra;    assert(response_error != NULL);    assert(sech != NULL);    if (pkt == NULL) {	errstr = newvstrallocf(errstr, _("[request failed: %s]"),	    security_geterror(sech));	*response_error = 1;	return;    }    security_close_connection(sech, hostname);    extra = NULL;    memset(ports, 0, SIZEOF(ports));    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 = newvstrallocf(errstr, "NAK: %s", tok);	    *response_error = 1;	} else {bad_nak:	    errstr = newvstrallocf(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;    }    dbprintf(_("got response:\n----\n%s\n----\n\n"), pkt->body);    for(i = 0; i < NSTREAMS; i++) {	ports[i] = -1;	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 = newvstrallocf(errstr, "%s", 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, streams[i].name) != 0) {		    extra = vstrallocf(				_("CONNECT token is \"%s\": expected \"%s\""),				tok ? tok : "(null)",				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"),			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 = vstrallocf(_("OPTIONS token is missing"));		goto parse_error;	    }	    while((p = strchr(tok, ';')) != NULL) {		char ch;		*p++ = '\0';		if(strncmp_const_skip(tok, "features=", tok, ch) == 0) {		    am_release_feature_set(their_features);		    if((their_features = am_string_to_feature(tok)) == NULL) {			errstr = newvstrallocf(errstr,					      _("OPTIONS: bad features value: %s"),					      tok);			goto parse_error;		    }		}		tok = p;	    }	    continue;	}	extra = vstrallocf(_("next token is \"%s\": expected \"CONNECT\", \"ERROR\" or \"OPTIONS\""),			  tok ? tok : "(null)");	goto parse_error;    }    if (dumper_kencrypt == KENCRYPT_WILL_DO)	dumper_kencrypt = KENCRYPT_YES;    /*     * Connect the streams to their remote ports     */    for (i = 0; i < NSTREAMS; i++) {	if (ports[i] == -1)	    continue;	streams[i].fd = security_stream_client(sech, ports[i]);	if (streams[i].fd == NULL) {	    errstr = newvstrallocf(errstr,		_("[could not connect %s stream: %s]"),		streams[i].name,		security_geterror(sech));	    goto connect_error;	}    }    /*     * Authenticate the streams     */    for (i = 0; i < NSTREAMS; i++) {	if (streams[i].fd == NULL)	    continue;#ifdef KRB4_SECURITY	/*	 * XXX krb4 historically never authenticated the index stream!	 * We need to reproduce this lossage here to preserve compatibility	 * with old clients.	 * It is wrong to delve into sech, but we have no choice here.	 */	if (strcasecmp(sech->driver->name, "krb4") == 0 && i == INDEXFD)	    continue;#endif	if (security_stream_auth(streams[i].fd) < 0) {	    errstr = newvstrallocf(errstr,		_("[could not authenticate %s stream: %s]"),		streams[i].name, 		security_stream_geterror(streams[i].fd));	    goto connect_error;	}    }    /*     * The MESGFD and DATAFD streams are mandatory.  If we didn't get     * them, complain.     */    if (streams[MESGFD].fd == NULL || streams[DATAFD].fd == NULL) {	errstr = newvstrallocf(errstr, _("[couldn't open MESG or INDEX streams]"));	goto connect_error;    }    /* everything worked */    *response_error = 0;    return;parse_error:    errstr = newvstrallocf(errstr,			  _("[parse of reply message failed: %s]"),			  extra ? extra : _("(no additional information)"));    amfree(extra);    *response_error = 2;    return;connect_error:    stop_dump();    *response_error = 1;}static char *dumper_get_security_conf(    char *	string,    void *	arg){        (void)arg;	/* Quiet unused parameter warning */        if(!string || !*string)                return(NULL);        if(strcmp(string, "krb5principal")==0) {                return(getconf_str(CNF_KRB5PRINCIPAL));        } else if(strcmp(string, "krb5keytab")==0) {                return(getconf_str(CNF_KRB5KEYTAB));        } else if(strcmp(string, "amandad_path")==0) {                return (amandad_path);        } else if(strcmp(string, "client_username")==0) {                return (client_username);        } else if(strcmp(string, "ssh_keys")==0) {                return (ssh_keys);        } else if(strcmp(string, "kencrypt")==0) {		if (dumper_kencrypt == KENCRYPT_YES)                    return ("yes");		else		    return (NULL);        }        return(NULL);}static intstartup_dump(    const char *hostname,    const char *disk,    const char *device,    int		level,    const char *dumpdate,    const char *progname,    const char *amandad_path,    const char *client_username,    const char *ssh_keys,    const char *options){    char level_string[NUM_STR_SIZE];    char *req = NULL;    char *authopt, *endauthopt, authoptbuf[80];    int response_error;    const security_driver_t *secdrv;    char *backup_api;    int has_features;    int has_hostname;    int has_device;    int has_config;    (void)disk;			/* Quiet unused parameter warning */    (void)amandad_path;		/* Quiet unused parameter warning */    (void)client_username;	/* Quiet unused parameter warning */    (void)ssh_keys;		/* Quiet unused parameter warning */    has_features = am_has_feature(their_features, fe_req_options_features);    has_hostname = am_has_feature(their_features, fe_req_options_hostname);    has_config   = am_has_feature(their_features, fe_req_options_config);    has_device   = am_has_feature(their_features, fe_sendbackup_req_device);    /*     * Default to bsd authentication if none specified.  This is gross.     *     * Options really need to be pre-parsed into some sort of structure     * much earlier, and then flattened out again before transmission.     */    authopt = strstr(options, "auth=");    if (authopt == NULL) {	authopt = "BSD";    } else {	endauthopt = strchr(authopt, ';');	if ((endauthopt == NULL) ||	  ((sizeof(authoptbuf) - 1) < (size_t)(endauthopt - authopt))) {	    authopt = "BSD";	} else {	    authopt += strlen("auth=");	    strncpy(authoptbuf, authopt, (size_t)(endauthopt - authopt));	    authoptbuf[endauthopt - authopt] = '\0';	    authopt = authoptbuf;	}    }    g_snprintf(level_string, SIZEOF(level_string), "%d", level);    if(strcmp(progname, "DUMP") == 0       || strcmp(progname, "GNUTAR") == 0) {	backup_api = "";    } else {	backup_api = "BACKUP ";    }    req = vstralloc("SERVICE sendbackup\n",		    "OPTIONS ",		    has_features ? "features=" : "",		    has_features ? our_feature_string : "",		    has_features ? ";" : "",		    has_hostname ? "hostname=" : "",		    has_hostname ? hostname : "",		    has_hostname ? ";" : "",		    has_config   ? "config=" : "",		    has_config   ? config_name : "",		    has_config   ? ";" : "",		    "\n",		    backup_api, progname,		    " ", qdiskname,		    " ", device && has_device ? device : "",		    " ", level_string,		    " ", dumpdate,		    " OPTIONS ", options,		    /* compat: if auth=krb4, send krb4-auth */		    (strcasecmp(authopt, "krb4") ? "" : "krb4-auth"),		    "\n",		    NULL);    dbprintf(_("send request:\n----\n%s\n----\n\n"), req);    secdrv = security_getdriver(authopt);    if (secdrv == NULL) {	errstr = newvstrallocf(errstr,		_("[could not find security driver '%s']"), authopt);	amfree(req);	return 2;    }    protocol_sendreq(hostname, secdrv, dumper_get_security_conf, req,	STARTUP_TIMEOUT, sendbackup_response, &response_error);    amfree(req);    protocol_run();    return (response_error);}

⌨️ 快捷键说明

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