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

📄 sftp-int.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2001,2002 Damien Miller.  All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *//* XXX: globbed ls *//* XXX: recursive operations */#include "includes.h"RCSID("$OpenBSD: sftp-int.c,v 1.46 2002/03/30 18:51:15 markus Exp $");#include "buffer.h"#include "xmalloc.h"#include "log.h"#include "pathnames.h"#include "sftp.h"#include "sftp-common.h"#include "sftp-glob.h"#include "sftp-client.h"#include "sftp-int.h"/* File to read commands from */extern FILE *infile;/* Size of buffer used when copying files */extern size_t copy_buffer_len;/* Number of concurrent outstanding requests */extern int num_requests;/* Seperators for interactive commands */#define WHITESPACE " \t\r\n"/* Commands for interactive mode */#define I_CHDIR		1#define I_CHGRP		2#define I_CHMOD		3#define I_CHOWN		4#define I_GET		5#define I_HELP		6#define I_LCHDIR	7#define I_LLS		8#define I_LMKDIR	9#define I_LPWD		10#define I_LS		11#define I_LUMASK	12#define I_MKDIR		13#define I_PUT		14#define I_PWD		15#define I_QUIT		16#define I_RENAME	17#define I_RM		18#define I_RMDIR		19#define I_SHELL		20#define I_SYMLINK	21#define I_VERSION	22struct CMD {	const char *c;	const int n;};const struct CMD cmds[] = {	{ "bye",	I_QUIT },	{ "cd",		I_CHDIR },	{ "chdir",	I_CHDIR },	{ "chgrp",	I_CHGRP },	{ "chmod",	I_CHMOD },	{ "chown",	I_CHOWN },	{ "dir",	I_LS },	{ "exit",	I_QUIT },	{ "get",	I_GET },	{ "mget",	I_GET },	{ "help",	I_HELP },	{ "lcd",	I_LCHDIR },	{ "lchdir",	I_LCHDIR },	{ "lls",	I_LLS },	{ "lmkdir",	I_LMKDIR },	{ "ln",		I_SYMLINK },	{ "lpwd",	I_LPWD },	{ "ls",		I_LS },	{ "lumask",	I_LUMASK },	{ "mkdir",	I_MKDIR },	{ "put",	I_PUT },	{ "mput",	I_PUT },	{ "pwd",	I_PWD },	{ "quit",	I_QUIT },	{ "rename",	I_RENAME },	{ "rm",		I_RM },	{ "rmdir",	I_RMDIR },	{ "symlink",	I_SYMLINK },	{ "version",	I_VERSION },	{ "!",		I_SHELL },	{ "?",		I_HELP },	{ NULL,			-1}};static voidhelp(void){	printf("Available commands:\n");	printf("cd path                       Change remote directory to 'path'\n");	printf("lcd path                      Change local directory to 'path'\n");	printf("chgrp grp path                Change group of file 'path' to 'grp'\n");	printf("chmod mode path               Change permissions of file 'path' to 'mode'\n");	printf("chown own path                Change owner of file 'path' to 'own'\n");	printf("help                          Display this help text\n");	printf("get remote-path [local-path]  Download file\n");	printf("lls [ls-options [path]]       Display local directory listing\n");	printf("ln oldpath newpath            Symlink remote file\n");	printf("lmkdir path                   Create local directory\n");	printf("lpwd                          Print local working directory\n");	printf("ls [path]                     Display remote directory listing\n");	printf("lumask umask                  Set local umask to 'umask'\n");	printf("mkdir path                    Create remote directory\n");	printf("put local-path [remote-path]  Upload file\n");	printf("pwd                           Display remote working directory\n");	printf("exit                          Quit sftp\n");	printf("quit                          Quit sftp\n");	printf("rename oldpath newpath        Rename remote file\n");	printf("rmdir path                    Remove remote directory\n");	printf("rm path                       Delete remote file\n");	printf("symlink oldpath newpath       Symlink remote file\n");	printf("version                       Show SFTP version\n");	printf("!command                      Execute 'command' in local shell\n");	printf("!                             Escape to local shell\n");	printf("?                             Synonym for help\n");}static voidlocal_do_shell(const char *args){	int status;	char *shell;	pid_t pid;	if (!*args)		args = NULL;	if ((shell = getenv("SHELL")) == NULL)		shell = _PATH_BSHELL;	if ((pid = fork()) == -1)		fatal("Couldn't fork: %s", strerror(errno));	if (pid == 0) {		/* XXX: child has pipe fds to ssh subproc open - issue? */		if (args) {			debug3("Executing %s -c \"%s\"", shell, args);			execl(shell, shell, "-c", args, (char *)NULL);		} else {			debug3("Executing %s", shell);			execl(shell, shell, (char *)NULL);		}		fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,		    strerror(errno));		_exit(1);	}	while (waitpid(pid, &status, 0) == -1)		if (errno != EINTR)			fatal("Couldn't wait for child: %s", strerror(errno));	if (!WIFEXITED(status))		error("Shell exited abormally");	else if (WEXITSTATUS(status))		error("Shell exited with status %d", WEXITSTATUS(status));}static voidlocal_do_ls(const char *args){	if (!args || !*args)		local_do_shell(_PATH_LS);	else {		int len = strlen(_PATH_LS " ") + strlen(args) + 1;		char *buf = xmalloc(len);		/* XXX: quoting - rip quoting code from ftp? */		snprintf(buf, len, _PATH_LS " %s", args);		local_do_shell(buf);		xfree(buf);	}}static char *path_append(char *p1, char *p2){	char *ret;	int len = strlen(p1) + strlen(p2) + 2;	ret = xmalloc(len);	strlcpy(ret, p1, len);	if (strcmp(p1, "/") != 0)		strlcat(ret, "/", len);	strlcat(ret, p2, len);	return(ret);}static char *make_absolute(char *p, char *pwd){	char *abs;	/* Derelativise */	if (p && p[0] != '/') {		abs = path_append(pwd, p);		xfree(p);		return(abs);	} else		return(p);}static intinfer_path(const char *p, char **ifp){	char *cp;	cp = strrchr(p, '/');	if (cp == NULL) {		*ifp = xstrdup(p);		return(0);	}	if (!cp[1]) {		error("Invalid path");		return(-1);	}	*ifp = xstrdup(cp + 1);	return(0);}static intparse_getput_flags(const char **cpp, int *pflag){	const char *cp = *cpp;	/* Check for flags */	if (cp[0] == '-' && cp[1] && strchr(WHITESPACE, cp[2])) {		switch (cp[1]) {		case 'p':		case 'P':			*pflag = 1;			break;		default:			error("Invalid flag -%c", cp[1]);			return(-1);		}		cp += 2;		*cpp = cp + strspn(cp, WHITESPACE);	}	return(0);}static intget_pathname(const char **cpp, char **path){	const char *cp = *cpp, *end;	char quot;	int i;	cp += strspn(cp, WHITESPACE);	if (!*cp) {		*cpp = cp;		*path = NULL;		return (0);	}	/* Check for quoted filenames */	if (*cp == '\"' || *cp == '\'') {		quot = *cp++;		end = strchr(cp, quot);		if (end == NULL) {			error("Unterminated quote");			goto fail;		}		if (cp == end) {			error("Empty quotes");			goto fail;		}		*cpp = end + 1 + strspn(end + 1, WHITESPACE);	} else {		/* Read to end of filename */		end = strpbrk(cp, WHITESPACE);		if (end == NULL)			end = strchr(cp, '\0');		*cpp = end + strspn(end, WHITESPACE);	}	i = end - cp;	*path = xmalloc(i + 1);	memcpy(*path, cp, i);	(*path)[i] = '\0';	return(0); fail:	*path = NULL;	return (-1);}static intis_dir(char *path){	struct stat sb;	/* XXX: report errors? */	if (stat(path, &sb) == -1)		return(0);	return(sb.st_mode & S_IFDIR);}static intremote_is_dir(struct sftp_conn *conn, char *path){	Attrib *a;	/* XXX: report errors? */	if ((a = do_stat(conn, path, 1)) == NULL)		return(0);	if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))		return(0);	return(a->perm & S_IFDIR);}static intprocess_get(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag){	char *abs_src = NULL;	char *abs_dst = NULL;	char *tmp;	glob_t g;	int err = 0;	int i;	abs_src = xstrdup(src);	abs_src = make_absolute(abs_src, pwd);	memset(&g, 0, sizeof(g));	debug3("Looking up %s", abs_src);	if (remote_glob(conn, abs_src, 0, NULL, &g)) {		error("File \"%s\" not found.", abs_src);		err = -1;		goto out;	}	/* Only one match, dst may be file, directory or unspecified */	if (g.gl_pathv[0] && g.gl_matchc == 1) {		if (dst) {			/* If directory specified, append filename */			if (is_dir(dst)) {				if (infer_path(g.gl_pathv[0], &tmp)) {					err = 1;					goto out;				}				abs_dst = path_append(dst, tmp);				xfree(tmp);			} else				abs_dst = xstrdup(dst);		} else if (infer_path(g.gl_pathv[0], &abs_dst)) {			err = -1;			goto out;		}		printf("Fetching %s to %s\n", g.gl_pathv[0], abs_dst);		err = do_download(conn, g.gl_pathv[0], abs_dst, pflag);		goto out;	}	/* Multiple matches, dst may be directory or unspecified */	if (dst && !is_dir(dst)) {		error("Multiple files match, but \"%s\" is not a directory",		    dst);		err = -1;		goto out;	}	for (i = 0; g.gl_pathv[i]; i++) {		if (infer_path(g.gl_pathv[i], &tmp)) {			err = -1;			goto out;		}		if (dst) {			abs_dst = path_append(dst, tmp);			xfree(tmp);		} else			abs_dst = tmp;		printf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);		if (do_download(conn, g.gl_pathv[i], abs_dst, pflag) == -1)			err = -1;		xfree(abs_dst);		abs_dst = NULL;	}out:	xfree(abs_src);	if (abs_dst)		xfree(abs_dst);	globfree(&g);	return(err);}static intprocess_put(struct sftp_conn *conn, char *src, char *dst, char *pwd, int pflag){	char *tmp_dst = NULL;	char *abs_dst = NULL;	char *tmp;	glob_t g;	int err = 0;	int i;	if (dst) {		tmp_dst = xstrdup(dst);		tmp_dst = make_absolute(tmp_dst, pwd);	}	memset(&g, 0, sizeof(g));	debug3("Looking up %s", src);	if (glob(src, 0, NULL, &g)) {		error("File \"%s\" not found.", src);		err = -1;		goto out;	}	/* Only one match, dst may be file, directory or unspecified */	if (g.gl_pathv[0] && g.gl_matchc == 1) {		if (tmp_dst) {			/* If directory specified, append filename */			if (remote_is_dir(conn, tmp_dst)) {				if (infer_path(g.gl_pathv[0], &tmp)) {					err = 1;					goto out;				}				abs_dst = path_append(tmp_dst, tmp);				xfree(tmp);			} else				abs_dst = xstrdup(tmp_dst);		} else {

⌨️ 快捷键说明

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