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

📄 psftp.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	    }        }	fclose(fp);    }}/* ---------------------------------------------------------------------- * Dirty bits: integration with PuTTY. */static int verbose = 0;/* *  Print an error message and perform a fatal exit. */void fatalbox(char *fmt, ...){    char *str, *str2;    va_list ap;    va_start(ap, fmt);    str = dupvprintf(fmt, ap);    str2 = dupcat("Fatal: ", str, "\n", NULL);    sfree(str);    va_end(ap);    fputs(str2, stderr);    sfree(str2);    cleanup_exit(1);}void modalfatalbox(char *fmt, ...){    char *str, *str2;    va_list ap;    va_start(ap, fmt);    str = dupvprintf(fmt, ap);    str2 = dupcat("Fatal: ", str, "\n", NULL);    sfree(str);    va_end(ap);    fputs(str2, stderr);    sfree(str2);    cleanup_exit(1);}void connection_fatal(void *frontend, char *fmt, ...){    char *str, *str2;    va_list ap;    va_start(ap, fmt);    str = dupvprintf(fmt, ap);    str2 = dupcat("Fatal: ", str, "\n", NULL);    sfree(str);    va_end(ap);    fputs(str2, stderr);    sfree(str2);    cleanup_exit(1);}void ldisc_send(void *handle, char *buf, int len, int interactive){    /*     * This is only here because of the calls to ldisc_send(NULL,     * 0) in ssh.c. Nothing in PSFTP actually needs to use the     * ldisc as an ldisc. So if we get called with any real data, I     * want to know about it.     */    assert(len == 0);}/* * In psftp, all agent requests should be synchronous, so this is a * never-called stub. */void agent_schedule_callback(void (*callback)(void *, void *, int),			     void *callback_ctx, void *data, int len){    assert(!"We shouldn't be here");}/* * Receive a block of data from the SSH link. Block until all data * is available. * * To do this, we repeatedly call the SSH protocol module, with our * own trap in from_backend() to catch the data that comes back. We * do this until we have enough data. */static unsigned char *outptr;	       /* where to put the data */static unsigned outlen;		       /* how much data required */static unsigned char *pending = NULL;  /* any spare data */static unsigned pendlen = 0, pendsize = 0;	/* length and phys. size of buffer */int from_backend(void *frontend, int is_stderr, const char *data, int datalen){    unsigned char *p = (unsigned char *) data;    unsigned len = (unsigned) datalen;    /*     * stderr data is just spouted to local stderr and otherwise     * ignored.     */    if (is_stderr) {	if (len > 0)	    fwrite(data, 1, len, stderr);	return 0;    }    /*     * If this is before the real session begins, just return.     */    if (!outptr)	return 0;    if ((outlen > 0) && (len > 0)) {	unsigned used = outlen;	if (used > len)	    used = len;	memcpy(outptr, p, used);	outptr += used;	outlen -= used;	p += used;	len -= used;    }    if (len > 0) {	if (pendsize < pendlen + len) {	    pendsize = pendlen + len + 4096;	    pending = sresize(pending, pendsize, unsigned char);	}	memcpy(pending + pendlen, p, len);	pendlen += len;    }    return 0;}int sftp_recvdata(char *buf, int len){    outptr = (unsigned char *) buf;    outlen = len;    /*     * See if the pending-input block contains some of what we     * need.     */    if (pendlen > 0) {	unsigned pendused = pendlen;	if (pendused > outlen)	    pendused = outlen;	memcpy(outptr, pending, pendused);	memmove(pending, pending + pendused, pendlen - pendused);	outptr += pendused;	outlen -= pendused;	pendlen -= pendused;	if (pendlen == 0) {	    pendsize = 0;	    sfree(pending);	    pending = NULL;	}	if (outlen == 0)	    return 1;    }    while (outlen > 0) {	if (ssh_sftp_loop_iteration() < 0)	    return 0;		       /* doom */    }    return 1;}int sftp_senddata(char *buf, int len){    back->send(backhandle, buf, len);    return 1;}/* *  Short description of parameters. */static void usage(void){    printf("PuTTY Secure File Transfer (SFTP) client\n");    printf("%s\n", ver);    printf("Usage: psftp [options] [user@]host\n");    printf("Options:\n");    printf("  -b file   use specified batchfile\n");    printf("  -bc       output batchfile commands\n");    printf("  -be       don't stop batchfile processing if errors\n");    printf("  -v        show verbose messages\n");    printf("  -load sessname  Load settings from saved session\n");    printf("  -l user   connect with specified username\n");    printf("  -P port   connect to specified port\n");    printf("  -pw passw login with specified password\n");    printf("  -1 -2     force use of particular SSH protocol version\n");    printf("  -C        enable compression\n");    printf("  -i key    private key file for authentication\n");    printf("  -batch    disable all interactive prompts\n");    printf("  -V        print version information\n");    cleanup_exit(1);}static void version(void){  printf("psftp: %s\n", ver);  cleanup_exit(1);}/* * Connect to a host. */static int psftp_connect(char *userhost, char *user, int portnumber){    char *host, *realhost;    const char *err;    void *logctx;    /* Separate host and username */    host = userhost;    host = strrchr(host, '@');    if (host == NULL) {	host = userhost;    } else {	*host++ = '\0';	if (user) {	    printf("psftp: multiple usernames specified; using \"%s\"\n",		   user);	} else	    user = userhost;    }    /*     * If we haven't loaded session details already (e.g., from -load),     * try looking for a session called "host".     */    if (!loaded_session) {	/* Try to load settings for `host' into a temporary config */	Config cfg2;	cfg2.host[0] = '\0';	do_defaults(host, &cfg2);	if (cfg2.host[0] != '\0') {	    /* Settings present and include hostname */	    /* Re-load data into the real config. */	    do_defaults(host, &cfg);	} else {	    /* Session doesn't exist or mention a hostname. */	    /* Use `host' as a bare hostname. */	    strncpy(cfg.host, host, sizeof(cfg.host) - 1);	    cfg.host[sizeof(cfg.host) - 1] = '\0';	}    } else {	/* Patch in hostname `host' to session details. */	strncpy(cfg.host, host, sizeof(cfg.host) - 1);	cfg.host[sizeof(cfg.host) - 1] = '\0';    }    /*     * Force use of SSH. (If they got the protocol wrong we assume the     * port is useless too.)     */    if (cfg.protocol != PROT_SSH) {        cfg.protocol = PROT_SSH;        cfg.port = 22;    }    /*     * If saved session / Default Settings says SSH-1 (`1 only' or `1'),     * then change it to SSH-2, on the grounds that that's more likely to     * work for SFTP. (Can be overridden with `-1' option.)     * But if it says `2 only' or `2', respect which.     */    if (cfg.sshprot != 2 && cfg.sshprot != 3)	cfg.sshprot = 2;    /*     * Enact command-line overrides.     */    cmdline_run_saved(&cfg);    /*     * Trim leading whitespace off the hostname if it's there.     */    {	int space = strspn(cfg.host, " \t");	memmove(cfg.host, cfg.host+space, 1+strlen(cfg.host)-space);    }    /* See if host is of the form user@host */    if (cfg.host[0] != '\0') {	char *atsign = strrchr(cfg.host, '@');	/* Make sure we're not overflowing the user field */	if (atsign) {	    if (atsign - cfg.host < sizeof cfg.username) {		strncpy(cfg.username, cfg.host, atsign - cfg.host);		cfg.username[atsign - cfg.host] = '\0';	    }	    memmove(cfg.host, atsign + 1, 1 + strlen(atsign + 1));	}    }    /*     * Trim a colon suffix off the hostname if it's there.     */    cfg.host[strcspn(cfg.host, ":")] = '\0';    /*     * Remove any remaining whitespace from the hostname.     */    {	int p1 = 0, p2 = 0;	while (cfg.host[p2] != '\0') {	    if (cfg.host[p2] != ' ' && cfg.host[p2] != '\t') {		cfg.host[p1] = cfg.host[p2];		p1++;	    }	    p2++;	}	cfg.host[p1] = '\0';    }    /* Set username */    if (user != NULL && user[0] != '\0') {	strncpy(cfg.username, user, sizeof(cfg.username) - 1);	cfg.username[sizeof(cfg.username) - 1] = '\0';    }    if (!cfg.username[0]) {	printf("login as: ");	fflush(stdout);	if (!fgets(cfg.username, sizeof(cfg.username), stdin)) {	    fprintf(stderr, "psftp: aborting\n");	    cleanup_exit(1);	} else {	    int len = strlen(cfg.username);	    if (cfg.username[len - 1] == '\n')		cfg.username[len - 1] = '\0';	}    }    if (portnumber)	cfg.port = portnumber;    /*     * Disable scary things which shouldn't be enabled for simple     * things like SCP and SFTP: agent forwarding, port forwarding,     * X forwarding.     */    cfg.x11_forward = 0;    cfg.agentfwd = 0;    cfg.portfwd[0] = cfg.portfwd[1] = '\0';    /* Set up subsystem name. */    strcpy(cfg.remote_cmd, "sftp");    cfg.ssh_subsys = TRUE;    cfg.nopty = TRUE;    /*     * Set up fallback option, for SSH1 servers or servers with the     * sftp subsystem not enabled but the server binary installed     * in the usual place. We only support fallback on Unix     * systems, and we use a kludgy piece of shellery which should     * try to find sftp-server in various places (the obvious     * systemwide spots /usr/lib and /usr/local/lib, and then the     * user's PATH) and finally give up.     *      *   test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server     *   test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server     *   exec sftp-server     *      * the idea being that this will attempt to use either of the     * obvious pathnames and then give up, and when it does give up     * it will print the preferred pathname in the error messages.     */    cfg.remote_cmd_ptr2 =	"test -x /usr/lib/sftp-server && exec /usr/lib/sftp-server\n"	"test -x /usr/local/lib/sftp-server && exec /usr/local/lib/sftp-server\n"	"exec sftp-server";    cfg.ssh_subsys2 = FALSE;    back = &ssh_backend;    err = back->init(NULL, &backhandle, &cfg, cfg.host, cfg.port, &realhost,		     0, cfg.tcp_keepalives);    if (err != NULL) {	fprintf(stderr, "ssh_init: %s\n", err);	return 1;    }    logctx = log_init(NULL, &cfg);    back->provide_logctx(backhandle, logctx);    console_provide_logctx(logctx);    while (!back->sendok(backhandle)) {	if (ssh_sftp_loop_iteration() < 0) {	    fprintf(stderr, "ssh_init: error during SSH connection setup\n");	    return 1;	}    }    if (verbose && realhost != NULL)	printf("Connected to %s\n", realhost);    if (realhost != NULL)	sfree(realhost);    return 0;}void cmdline_error(char *p, ...){    va_list ap;    fprintf(stderr, "psftp: ");    va_start(ap, p);    vfprintf(stderr, p, ap);    va_end(ap);    fprintf(stderr, "\n       try typing \"psftp -h\" for help\n");    exit(1);}/* * Main program. Parse arguments etc. */int psftp_main(int argc, char *argv[]){    int i;    int portnumber = 0;    char *userhost, *user;    int mode = 0;    int modeflags = 0;    char *batchfile = NULL;    int errors = 0;    statics()->flags = FLAG_STDERR | FLAG_INTERACTIVE#ifdef FLAG_SYNCAGENT	| FLAG_SYNCAGENT#endif	;    cmdline_tooltype = TOOLTYPE_FILETRANSFER;    statics()->ssh_get_line = &console_get_line;    sk_init();    userhost = user = NULL;    /* Load Default Settings before doing anything else. */    do_defaults(NULL, &cfg);    loaded_session = FALSE;    errors = 0;    for (i = 1; i < argc; i++) {	int ret;	if (argv[i][0] != '-') {            if (userhost)                usage();            else                userhost = dupstr(argv[i]);	    continue;	}	ret = cmdline_process_param(argv[i], i+1<argc?argv[i+1]:NULL, 1, &cfg);	if (ret == -2) {	    cmdline_error("option \"%s\" requires an argument", argv[i]);	} else if (ret == 2) {	    i++;	       /* skip next argument */	} else if (ret == 1) {	    /* We have our own verbosity in addition to `flags'. */	    if (statics()->flags & FLAG_VERBOSE)		verbose = 1;	} else if (strcmp(argv[i], "-h") == 0 ||		   strcmp(argv[i], "-?") == 0) {	    usage();	} else if (strcmp(argv[i], "-V") == 0) {	    version();	} else if (strcmp(argv[i], "-batch") == 0) {	    console_batch_mode = 1;	} else if (strcmp(argv[i], "-b") == 0 && i + 1 < argc) {	    mode = 1;	    batchfile = argv[++i];	} else if (strcmp(argv[i], "-bc") == 0) {	    modeflags = modeflags | 1;	} else if (strcmp(argv[i], "-be") == 0) {	    modeflags = modeflags | 2;	} else if (strcmp(argv[i], "--") == 0) {	    i++;	    break;	} else {	    cmdline_error("unknown option \"%s\"", argv[i]);	}    }    argc -= i;    argv += i;    back = NULL;    /*     * If the loaded session provides a hostname, and a hostname has not     * otherwise been specified, pop it in `userhost' so that     * `psftp -load sessname' is sufficient to start a session.     */    if (!userhost && cfg.host[0] != '\0') {	userhost = dupstr(cfg.host);    }    /*     * If a user@host string has already been provided, connect to     * it now.     */    if (userhost) {	int ret;	ret = psftp_connect(userhost, user, portnumber);	sfree(userhost);	if (ret)	    return 1;	if (do_sftp_init())	    return 1;    } else {	printf("psftp: no hostname specified; use \"open host.name\""	       " to connect\n");    }    do_sftp(mode, modeflags, batchfile);    if (back != NULL && back->socket(backhandle) != NULL) {	char ch;	back->special(backhandle, TS_EOF);	sftp_recvdata(&ch, 1);    }    random_save_seed();    cmdline_cleanup();    console_provide_logctx(NULL);    do_sftp_cleanup();    backhandle = NULL;    back = NULL;    sk_cleanup();    return 0;}

⌨️ 快捷键说明

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