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

📄 psftp.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 4 页
字号:
    fname = cmd->words[1];    origoutfname = (cmd->nwords == 2 ?		    stripslashes(cmd->words[1], 1) : cmd->words[2]);    outfname = canonify(origoutfname);    if (!outfname) {	printf("%s: %s\n", origoutfname, fxp_error());	return 0;    }    fp = fopen(fname, "rb");    if (!fp) {	printf("local: unable to open %s\n", fname);	sfree(outfname);	return 0;    }    if (restart) {	sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE));    } else {	sftp_register(req = fxp_open_send(outfname, SSH_FXF_WRITE |					  SSH_FXF_CREAT | SSH_FXF_TRUNC));    }    rreq = sftp_find_request(pktin = sftp_recv());    assert(rreq == req);    fh = fxp_open_recv(pktin, rreq);    if (!fh) {	printf("%s: %s\n", outfname, fxp_error());	sfree(outfname);	return 0;    }    if (restart) {	char decbuf[30];	struct fxp_attrs attrs;	int ret;	sftp_register(req = fxp_fstat_send(fh));	rreq = sftp_find_request(pktin = sftp_recv());	assert(rreq == req);	ret = fxp_fstat_recv(pktin, rreq, &attrs);	if (!ret) {	    printf("read size of %s: %s\n", outfname, fxp_error());	    sfree(outfname);	    return 0;	}	if (!(attrs.flags & SSH_FILEXFER_ATTR_SIZE)) {	    printf("read size of %s: size was not given\n", outfname);	    sfree(outfname);	    return 0;	}	offset = attrs.size;	uint64_decimal(offset, decbuf);	printf("reput: restarting at file position %s\n", decbuf);	if (uint64_compare(offset, uint64_make(0, LONG_MAX)) > 0) {	    printf("reput: remote file is larger than we can deal with\n");	    sfree(outfname);	    return 0;	}	if (fseek(fp, offset.lo, SEEK_SET) != 0)	    fseek(fp, 0, SEEK_END);    /* *shrug* */    } else {	offset = uint64_make(0, 0);    }    printf("local:%s => remote:%s\n", fname, outfname);    /*     * FIXME: we can use FXP_FSTAT here to get the file size, and     * thus put up a progress bar.     */    ret = 1;    xfer = xfer_upload_init(fh, offset);    err = eof = 0;    while ((!err && !eof) || !xfer_done(xfer)) {	char buffer[4096];	int len, ret;	while (xfer_upload_ready(xfer) && !err && !eof) {	    len = fread(buffer, 1, sizeof(buffer), fp);	    if (len == -1) {		printf("error while reading local file\n");		err = 1;	    } else if (len == 0) {		eof = 1;	    } else {		xfer_upload_data(xfer, buffer, len);	    }	}	if (!xfer_done(xfer)) {	    pktin = sftp_recv();	    ret = xfer_upload_gotpkt(xfer, pktin);	    if (!ret) {		printf("error while writing: %s\n", fxp_error());		err = 1;	    }	}    }    xfer_cleanup(xfer);    sftp_register(req = fxp_close_send(fh));    rreq = sftp_find_request(pktin = sftp_recv());    assert(rreq == req);    fxp_close_recv(pktin, rreq);    fclose(fp);    sfree(outfname);    return ret;}int sftp_cmd_put(struct sftp_command *cmd){    return sftp_general_put(cmd, 0);}int sftp_cmd_reput(struct sftp_command *cmd){    return sftp_general_put(cmd, 1);}int sftp_cmd_mkdir(struct sftp_command *cmd){    char *dir;    struct sftp_packet *pktin;    struct sftp_request *req, *rreq;    int result;    if (back == NULL) {	printf("psftp: not connected to a host; use \"open host.name\"\n");	return 0;    }    if (cmd->nwords < 2) {	printf("mkdir: expects a directory\n");	return 0;    }    dir = canonify(cmd->words[1]);    if (!dir) {	printf("%s: %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());	sfree(dir);	return 0;    }    sfree(dir);    return 1;}int sftp_cmd_rmdir(struct sftp_command *cmd){    char *dir;    struct sftp_packet *pktin;    struct sftp_request *req, *rreq;    int result;    if (back == NULL) {	printf("psftp: not connected to a host; use \"open host.name\"\n");	return 0;    }    if (cmd->nwords < 2) {	printf("rmdir: expects a directory\n");	return 0;    }    dir = canonify(cmd->words[1]);    if (!dir) {	printf("%s: %s\n", dir, fxp_error());	return 0;    }    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());	sfree(dir);	return 0;    }    sfree(dir);    return 1;}int sftp_cmd_rm(struct sftp_command *cmd){    char *fname;    struct sftp_packet *pktin;    struct sftp_request *req, *rreq;    int result;    if (back == NULL) {	printf("psftp: not connected to a host; use \"open host.name\"\n");	return 0;    }    if (cmd->nwords < 2) {	printf("rm: expects a filename\n");	return 0;    }    fname = canonify(cmd->words[1]);    if (!fname) {	printf("%s: %s\n", fname, fxp_error());	return 0;    }    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());	sfree(fname);	return 0;    }    sfree(fname);    return 1;}int sftp_cmd_mv(struct sftp_command *cmd){    char *srcfname, *dstfname;    struct sftp_packet *pktin;    struct sftp_request *req, *rreq;    int result;    if (back == NULL) {	printf("psftp: not connected to a host; use \"open host.name\"\n");	return 0;    }    if (cmd->nwords < 3) {	printf("mv: expects two filenames\n");	return 0;    }    srcfname = canonify(cmd->words[1]);    if (!srcfname) {	printf("%s: %s\n", srcfname, fxp_error());	return 0;    }    dstfname = canonify(cmd->words[2]);    if (!dstfname) {	printf("%s: %s\n", dstfname, fxp_error());	return 0;    }    sftp_register(req = fxp_rename_send(srcfname, dstfname));    rreq = sftp_find_request(pktin = sftp_recv());    assert(rreq == req);    result = fxp_rename_recv(pktin, rreq);    if (!result) {	char const *error = fxp_error();	struct fxp_attrs attrs;	/*	 * The move might have failed because dstfname pointed at a	 * directory. We check this possibility now: if dstfname	 * _is_ a directory, we re-attempt the move by appending	 * the basename of srcfname to dstfname.	 */	sftp_register(req = fxp_stat_send(dstfname));	rreq = sftp_find_request(pktin = sftp_recv());	assert(rreq == req);	result = fxp_stat_recv(pktin, rreq, &attrs);	if (result &&	    (attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS) &&	    (attrs.permissions & 0040000)) {	    char *p;	    char *newname, *newcanon;	    printf("(destination %s is a directory)\n", dstfname);	    p = srcfname + strlen(srcfname);	    while (p > srcfname && p[-1] != '/') p--;	    newname = dupcat(dstfname, "/", p, NULL);	    newcanon = canonify(newname);	    sfree(newname);	    if (newcanon) {		sfree(dstfname);		dstfname = newcanon;		sftp_register(req = fxp_rename_send(srcfname, dstfname));		rreq = sftp_find_request(pktin = sftp_recv());		assert(rreq == req);		result = fxp_rename_recv(pktin, rreq);		error = result ? NULL : fxp_error();	    }	}	if (error) {	    printf("mv %s %s: %s\n", srcfname, dstfname, error);	    sfree(srcfname);	    sfree(dstfname);	    return 0;	}    }    printf("%s -> %s\n", srcfname, dstfname);    sfree(srcfname);    sfree(dstfname);    return 1;}int sftp_cmd_chmod(struct sftp_command *cmd){    char *fname, *mode;    int result;    struct fxp_attrs attrs;    unsigned attrs_clr, attrs_xor, oldperms, newperms;    struct sftp_packet *pktin;    struct sftp_request *req, *rreq;    if (back == NULL) {	printf("psftp: not connected to a host; use \"open host.name\"\n");	return 0;    }    if (cmd->nwords < 3) {	printf("chmod: expects a mode specifier and a filename\n");	return 0;    }    /*     * Attempt to parse the mode specifier in cmd->words[1]. We     * don't support the full horror of Unix chmod; instead we     * support a much simpler syntax in which the user can either     * specify an octal number, or a comma-separated sequence of     * [ugoa]*[-+=][rwxst]+. (The initial [ugoa] sequence may     * _only_ be omitted if the only attribute mentioned is t,     * since all others require a user/group/other specification.     * Additionally, the s attribute may not be specified for any     * [ugoa] specifications other than exactly u or exactly g.     */    attrs_clr = attrs_xor = 0;    mode = cmd->words[1];    if (mode[0] >= '0' && mode[0] <= '9') {	if (mode[strspn(mode, "01234567")]) {	    printf("chmod: numeric file modes should"		   " contain digits 0-7 only\n");	    return 0;	}	attrs_clr = 07777;	sscanf(mode, "%o", &attrs_xor);	attrs_xor &= attrs_clr;    } else {	while (*mode) {	    char *modebegin = mode;	    unsigned subset, perms;	    int action;	    subset = 0;	    while (*mode && *mode != ',' &&		   *mode != '+' && *mode != '-' && *mode != '=') {		switch (*mode) {		  case 'u': subset |= 04700; break; /* setuid, user perms */		  case 'g': subset |= 02070; break; /* setgid, group perms */		  case 'o': subset |= 00007; break; /* just other perms */		  case 'a': subset |= 06777; break; /* all of the above */		  default:		    printf("chmod: file mode '%.*s' contains unrecognised"			   " user/group/other specifier '%c'\n",			   (int)strcspn(modebegin, ","), modebegin, *mode);		    return 0;		}		mode++;	    }	    if (!*mode || *mode == ',') {		printf("chmod: file mode '%.*s' is incomplete\n",		       (int)strcspn(modebegin, ","), modebegin);		return 0;	    }	    action = *mode++;	    if (!*mode || *mode == ',') {		printf("chmod: file mode '%.*s' is incomplete\n",		       (int)strcspn(modebegin, ","), modebegin);		return 0;	    }	    perms = 0;	    while (*mode && *mode != ',') {		switch (*mode) {		  case 'r': perms |= 00444; break;		  case 'w': perms |= 00222; break;		  case 'x': perms |= 00111; break;		  case 't': perms |= 01000; subset |= 01000; break;		  case 's':		    if ((subset & 06777) != 04700 &&			(subset & 06777) != 02070) {			printf("chmod: file mode '%.*s': set[ug]id bit should"			       " be used with exactly one of u or g only\n",			       (int)strcspn(modebegin, ","), modebegin);			return 0;		    }		    perms |= 06000;		    break;		  default:		    printf("chmod: file mode '%.*s' contains unrecognised"			   " permission specifier '%c'\n",			   (int)strcspn(modebegin, ","), modebegin, *mode);		    return 0;		}		mode++;	    }	    if (!(subset & 06777) && (perms &~ subset)) {		printf("chmod: file mode '%.*s' contains no user/group/other"		       " specifier and permissions other than 't' \n",		       (int)strcspn(modebegin, ","), modebegin);		return 0;	    }	    perms &= subset;	    switch (action) {	      case '+':		attrs_clr |= perms;		attrs_xor |= perms;		break;	      case '-':		attrs_clr |= perms;		attrs_xor &= ~perms;		break;	      case '=':		attrs_clr |= subset;		attrs_xor |= perms;		break;	    }	    if (*mode) mode++;	       /* eat comma */	}    }    fname = canonify(cmd->words[2]);    if (!fname) {	printf("%s: %s\n", fname, fxp_error());	return 0;    }    sftp_register(req = fxp_stat_send(fname));    rreq = sftp_find_request(pktin = sftp_recv());    assert(rreq == req);    result = fxp_stat_recv(pktin, rreq, &attrs);    if (!result || !(attrs.flags & SSH_FILEXFER_ATTR_PERMISSIONS)) {	printf("get attrs for %s: %s\n", fname,	       result ? "file permissions not provided" : fxp_error());	sfree(fname);	return 0;    }    attrs.flags = SSH_FILEXFER_ATTR_PERMISSIONS;   /* perms _only_ */    oldperms = attrs.permissions & 07777;    attrs.permissions &= ~attrs_clr;    attrs.permissions ^= attrs_xor;    newperms = attrs.permissions & 07777;    sftp_register(req = fxp_setstat_send(fname, attrs));    rreq = sftp_find_request(pktin = sftp_recv());    assert(rreq == req);    result = fxp_setstat_recv(pktin, rreq);    if (!result) {	printf("set attrs for %s: %s\n", fname, fxp_error());	sfree(fname);	return 0;    }    printf("%s: %04o -> %04o\n", fname, oldperms, newperms);    sfree(fname);    return 1;}static int sftp_cmd_open(struct sftp_command *cmd){    int portnumber;    if (back != NULL) {	printf("psftp: already connected\n");	return 0;    }    if (cmd->nwords < 2) {	printf("open: expects a host name\n");	return 0;    }    if (cmd->nwords > 2) {	portnumber = atoi(cmd->words[2]);	if (portnumber == 0) {	    printf("open: invalid port number\n");	    return 0;	}    } else	portnumber = 0;    if (psftp_connect(cmd->words[1], NULL, portnumber)) {	back = NULL;		       /* connection is already closed */	return -1;		       /* this is fatal */    }    do_sftp_init();    return 1;}static int sftp_cmd_lcd(struct sftp_command *cmd){    char *currdir, *errmsg;    if (cmd->nwords < 2) {	printf("lcd: expects a local directory name\n");	return 0;    }    errmsg = psftp_lcd(cmd->words[1]);    if (errmsg) {

⌨️ 快捷键说明

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