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

📄 psftp.c

📁 putty
💻 C
📖 第 1 页 / 共 5 页
字号:
    unwcdir = snewn(1 + strlen(dir), char);
    if (wc_unescape(unwcdir, dir)) {
	dir = unwcdir;
	wildcard = NULL;
    } else {
	char *tmpdir;
	int len, check;

	wildcard = stripslashes(dir, 0);
	unwcdir = dupstr(dir);
	len = wildcard - dir;
	unwcdir[len] = '\0';
	if (len > 0 && unwcdir[len-1] == '/')
	    unwcdir[len-1] = '\0';
	tmpdir = snewn(1 + len, char);
	check = wc_unescape(tmpdir, unwcdir);
	sfree(tmpdir);
	if (!check) {
	    printf("Multiple-level wildcards are not supported\n");
	    sfree(unwcdir);
	    return 0;
	}
	dir = unwcdir;
    }

    cdir = canonify(dir);
    if (!cdir) {
	printf("%s: canonify: %s\n", dir, fxp_error());
	sfree(unwcdir);
	return 0;
    }

    printf("Listing directory %s\n", cdir);

    sftp_register(req = fxp_opendir_send(cdir));
    rreq = sftp_find_request(pktin = sftp_recv());
    assert(rreq == req);
    dirh = fxp_opendir_recv(pktin, rreq);

    if (dirh == NULL) {
	printf("Unable to open %s: %s\n", dir, fxp_error());
    } else {
	nnames = namesize = 0;
	ournames = NULL;

	while (1) {

	    sftp_register(req = fxp_readdir_send(dirh));
	    rreq = sftp_find_request(pktin = sftp_recv());
	    assert(rreq == req);
	    names = fxp_readdir_recv(pktin, rreq);

	    if (names == NULL) {
		if (fxp_error_type() == SSH_FX_EOF)
		    break;
		printf("Reading directory %s: %s\n", dir, fxp_error());
		break;
	    }
	    if (names->nnames == 0) {
		fxp_free_names(names);
		break;
	    }

	    if (nnames + names->nnames >= namesize) {
		namesize += names->nnames + 128;
		ournames = sresize(ournames, namesize, struct fxp_name *);
	    }

	    for (i = 0; i < names->nnames; i++)
		if (!wildcard || wc_match(wildcard, names->names[i].filename))
		    ournames[nnames++] = fxp_dup_name(&names->names[i]);

	    fxp_free_names(names);
	}
	sftp_register(req = fxp_close_send(dirh));
	rreq = sftp_find_request(pktin = sftp_recv());
	assert(rreq == req);
	fxp_close_recv(pktin, rreq);

	/*
	 * Now we have our filenames. Sort them by actual file
	 * name, and then output the longname parts.
	 */
	qsort(ournames, nnames, sizeof(*ournames), sftp_name_compare);

	/*
	 * And print them.
	 */
	for (i = 0; i < nnames; i++) {
	    printf("%s\n", ournames[i]->longname);
	    fxp_free_name(ournames[i]);
	}
	sfree(ournames);
    }

    sfree(cdir);
    sfree(unwcdir);

    return 1;
}

/*
 * Change directories. We do this by canonifying the new name, then
 * trying to OPENDIR it. Only if that succeeds do we set the new pwd.
 */
int sftp_cmd_cd(struct sftp_command *cmd)
{
    struct fxp_handle *dirh;
    struct sftp_packet *pktin;
    struct sftp_request *req, *rreq;
    char *dir;

    if (back == NULL) {
	not_connected();
	return 0;
    }

    if (cmd->nwords < 2)
	dir = dupstr(homedir);
    else
	dir = canonify(cmd->words[1]);

    if (!dir) {
	printf("%s: canonify: %s\n", dir, fxp_error());
	return 0;
    }

    sftp_register(req = fxp_opendir_send(dir));
    rreq = sftp_find_request(pktin = sftp_recv());
    assert(rreq == req);
    dirh = fxp_opendir_recv(pktin, rreq);

    if (!dirh) {
	printf("Directory %s: %s\n", dir, fxp_error());
	sfree(dir);
	return 0;
    }

    sftp_register(req = fxp_close_send(dirh));
    rreq = sftp_find_request(pktin = sftp_recv());
    assert(rreq == req);
    fxp_close_recv(pktin, rreq);

    sfree(pwd);
    pwd = dir;
    printf("Remote directory is now %s\n", pwd);

    return 1;
}

/*
 * Print current directory. Easy as pie.
 */
int sftp_cmd_pwd(struct sftp_command *cmd)
{
    if (back == NULL) {
	not_connected();
	return 0;
    }

    printf("Remote directory is %s\n", pwd);
    return 1;
}

/*
 * Get a file and save it at the local end. We have three very
 * similar commands here. The basic one is `get'; `reget' differs
 * in that it checks for the existence of the destination file and
 * starts from where a previous aborted transfer left off; `mget'
 * differs in that it interprets all its arguments as files to
 * transfer (never as a different local name for a remote file) and
 * can handle wildcards.
 */
int sftp_general_get(struct sftp_command *cmd, int restart, int multiple)
{
    char *fname, *unwcfname, *origfname, *origwfname, *outfname;
    int i, ret;
    int recurse = FALSE;

    if (back == NULL) {
	not_connected();
	return 0;
    }

    i = 1;
    while (i < cmd->nwords && cmd->words[i][0] == '-') {
	if (!strcmp(cmd->words[i], "--")) {
	    /* finish processing options */
	    i++;
	    break;
	} else if (!strcmp(cmd->words[i], "-r")) {
	    recurse = TRUE;
	} else {
	    printf("%s: unrecognised option '%s'\n", cmd->words[0], cmd->words[i]);
	    return 0;
	}
	i++;
    }

    if (i >= cmd->nwords) {
	printf("%s: expects a filename\n", cmd->words[0]);
	return 0;
    }

    ret = 1;
    do {
	SftpWildcardMatcher *swcm;

	origfname = cmd->words[i++];
	unwcfname = snewn(strlen(origfname)+1, char);

	if (multiple && !wc_unescape(unwcfname, origfname)) {
	    swcm = sftp_begin_wildcard_matching(origfname);
	    if (!swcm) {
		sfree(unwcfname);
		continue;
	    }
	    origwfname = sftp_wildcard_get_filename(swcm);
	    if (!origwfname) {
		/* Politely warn the user that nothing matched. */
		printf("%s: nothing matched\n", origfname);
		sftp_finish_wildcard_matching(swcm);
		sfree(unwcfname);
		continue;
	    }
	} else {
	    origwfname = origfname;
	    swcm = NULL;
	}

	while (origwfname) {
	    fname = canonify(origwfname);

	    if (!fname) {
		printf("%s: canonify: %s\n", origwfname, fxp_error());
		sfree(unwcfname);
		return 0;
	    }

	    if (!multiple && i < cmd->nwords)
		outfname = cmd->words[i++];
	    else
		outfname = stripslashes(origwfname, 0);

	    ret = sftp_get_file(fname, outfname, recurse, restart);

	    sfree(fname);

	    if (swcm) {
		sfree(origwfname);
		origwfname = sftp_wildcard_get_filename(swcm);
	    } else {
		origwfname = NULL;
	    }
	}
	sfree(unwcfname);
	if (swcm)
	    sftp_finish_wildcard_matching(swcm);
	if (!ret)
	    return ret;

    } while (multiple && i < cmd->nwords);

    return ret;
}
int sftp_cmd_get(struct sftp_command *cmd)
{
    return sftp_general_get(cmd, 0, 0);
}
int sftp_cmd_mget(struct sftp_command *cmd)
{
    return sftp_general_get(cmd, 0, 1);
}
int sftp_cmd_reget(struct sftp_command *cmd)
{
    return sftp_general_get(cmd, 1, 0);
}

/*
 * Send a file and store it at the remote end. We have three very
 * similar commands here. The basic one is `put'; `reput' differs
 * in that it checks for the existence of the destination file and
 * starts from where a previous aborted transfer left off; `mput'
 * differs in that it interprets all its arguments as files to
 * transfer (never as a different remote name for a local file) and
 * can handle wildcards.
 */
int sftp_general_put(struct sftp_command *cmd, int restart, int multiple)
{
    char *fname, *wfname, *origoutfname, *outfname;
    int i, ret;
    int recurse = FALSE;

    if (back == NULL) {
	not_connected();
	return 0;
    }

    i = 1;
    while (i < cmd->nwords && cmd->words[i][0] == '-') {
	if (!strcmp(cmd->words[i], "--")) {
	    /* finish processing options */
	    i++;
	    break;
	} else if (!strcmp(cmd->words[i], "-r")) {
	    recurse = TRUE;
	} else {
	    printf("%s: unrecognised option '%s'\n", cmd->words[0], cmd->words[i]);
	    return 0;
	}
	i++;
    }

    if (i >= cmd->nwords) {
	printf("%s: expects a filename\n", cmd->words[0]);
	return 0;
    }

    ret = 1;
    do {
	WildcardMatcher *wcm;
	fname = cmd->words[i++];

	if (multiple && test_wildcard(fname, FALSE) == WCTYPE_WILDCARD) {
	    wcm = begin_wildcard_matching(fname);
	    wfname = wildcard_get_filename(wcm);
	    if (!wfname) {
		/* Politely warn the user that nothing matched. */
		printf("%s: nothing matched\n", fname);
		finish_wildcard_matching(wcm);
		continue;
	    }
	} else {
	    wfname = fname;
	    wcm = NULL;
	}

	while (wfname) {
	    if (!multiple && i < cmd->nwords)
		origoutfname = cmd->words[i++];
	    else
		origoutfname = stripslashes(wfname, 1);

	    outfname = canonify(origoutfname);
	    if (!outfname) {
		printf("%s: canonify: %s\n", origoutfname, fxp_error());
		if (wcm) {
		    sfree(wfname);
		    finish_wildcard_matching(wcm);
		}
		return 0;
	    }
	    ret = sftp_put_file(wfname, outfname, recurse, restart);
	    sfree(outfname);

	    if (wcm) {
		sfree(wfname);
		wfname = wildcard_get_filename(wcm);
	    } else {
		wfname = NULL;
	    }
	}

	if (wcm)
	    finish_wildcard_matching(wcm);

	if (!ret)
	    return ret;

    } while (multiple && i < cmd->nwords);

    return ret;
}
int sftp_cmd_put(struct sftp_command *cmd)
{
    return sftp_general_put(cmd, 0, 0);
}
int sftp_cmd_mput(struct sftp_command *cmd)
{
    return sftp_general_put(cmd, 0, 1);
}
int sftp_cmd_reput(struct sftp_command *cmd)
{
    return sftp_general_put(cmd, 1, 0);
}

int sftp_cmd_mkdir(struct sftp_command *cmd)
{
    char *dir;
    struct sftp_packet *pktin;
    struct sftp_request *req, *rreq;
    int result;
    int i, ret;

    if (back == NULL) {
	not_connected();
	return 0;
    }

    if (cmd->nwords < 2) {
	printf("mkdir: expects a directory\n");
	return 0;
    }

    ret = 1;
    for (i = 1; i < cmd->nwords; i++) {
	dir = canonify(cmd->words[i]);
	if (!dir) {
	    printf("%s: canonify: %s\n", dir, fxp_error());
	    return 0;
	}

	sftp_register(req = fxp_mkdir_send(dir));
	rreq = sftp_find_request(pktin = sftp_recv());
	assert(rreq == req);
	result = fxp_mkdir_recv(pktin, rreq);

	if (!result) {
	    printf("mkdir %s: %s\n", dir, fxp_error());
	    ret = 0;
	} else
	    printf("mkdir %s: OK\n", dir);

	sfree(dir);
    }

    return ret;
}

static int sftp_action_rmdir(void *vctx, char *dir)
{
    struct sftp_packet *pktin;
    struct sftp_request *req, *rreq;
    int result;

    sftp_register(req = fxp_rmdir_send(dir));
    rreq = sftp_find_request(pktin = sftp_recv());
    assert(rreq == req);
    result = fxp_rmdir_recv(pktin, rreq);

    if (!result) {
	printf("rmdir %s: %s\n", dir, fxp_error());
	return 0;
    }

    printf("rmdir %s: OK\n", dir);

    return 1;
}

int sftp_cmd_rmdir(struct sftp_command *cmd)
{
    int i, ret;

    if (back == NULL) {
	not_connected();
	return 0;
    }

    if (cmd->nwords < 2) {
	printf("rmdir: expects a directory\n");
	return 0;
    }

    ret = 1;
    for (i = 1; i < cmd->nwords; i++)
	ret &= wildcard_iterate(cmd->words[i], sftp_action_rmdir, NULL);

    return ret;
}

static int sftp_action_rm(void *vctx, char *fname)
{
    struct sftp_packet *pktin;
    struct sftp_request *req, *rreq;
    int result;

    sftp_register(req = fxp_remove_send(fname));
    rreq = sftp_find_request(pktin = sftp_recv());
    assert(rreq == req);
    result = fxp_remove_recv(pktin, rreq);

    if (!result) {
	printf("rm %s: %s\n", fname, fxp_error());
	return 0;
    }

    printf("rm %s: OK\n", fname);

    return 1;
}

int sftp_cmd_rm(struct sftp_command *cmd)
{
    int i, ret;

    if (back == NULL) {
	not_connected();
	return 0;

⌨️ 快捷键说明

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