]> andersk Git - openssh.git/blame - sftp.c
- deraadt@cvs.openbsd.org 2001/03/06 06:11:18
[openssh.git] / sftp.c
CommitLineData
61e96248 1/*
2 * Copyright (c) 2001 Damien Miller. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 */
24
25#include "includes.h"
26
c630ce76 27RCSID("$OpenBSD: sftp.c,v 1.9 2001/03/03 23:52:22 markus Exp $");
61e96248 28
29/* XXX: commandline mode */
30/* XXX: copy between two remote hosts (commandline) */
31/* XXX: short-form remote directory listings (like 'ls -C') */
32
33#include "buffer.h"
34#include "xmalloc.h"
35#include "log.h"
36#include "pathnames.h"
37
38#include "sftp.h"
39#include "sftp-common.h"
40#include "sftp-client.h"
41#include "sftp-int.h"
42
5152d46f 43#ifdef HAVE___PROGNAME
44extern char *__progname;
45#else
46char *__progname;
47#endif
48
0426a3b4 49int use_ssh1 = 0;
50char *ssh_program = _PATH_SSH_PROGRAM;
51char *sftp_server = NULL;
52
61e96248 53void
54connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
55{
56 int c_in, c_out;
57#ifdef USE_PIPES
58 int pin[2], pout[2];
59 if ((pipe(pin) == -1) || (pipe(pout) == -1))
60 fatal("pipe: %s", strerror(errno));
61 *in = pin[0];
62 *out = pout[1];
63 c_in = pout[0];
64 c_out = pin[1];
65#else /* USE_PIPES */
66 int inout[2];
67 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
68 fatal("socketpair: %s", strerror(errno));
69 *in = *out = inout[0];
70 c_in = c_out = inout[1];
71#endif /* USE_PIPES */
72
73 if ((*sshpid = fork()) == -1)
74 fatal("fork: %s", strerror(errno));
75 else if (*sshpid == 0) {
76 if ((dup2(c_in, STDIN_FILENO) == -1) ||
77 (dup2(c_out, STDOUT_FILENO) == -1)) {
78 fprintf(stderr, "dup2: %s\n", strerror(errno));
79 exit(1);
80 }
81 close(*in);
82 close(*out);
83 close(c_in);
84 close(c_out);
0426a3b4 85 execv(ssh_program, args);
86 fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
61e96248 87 exit(1);
88 }
89
90 close(c_in);
91 close(c_out);
92}
93
94char **
95make_ssh_args(char *add_arg)
96{
97 static char **args = NULL;
98 static int nargs = 0;
99 char debug_buf[4096];
c630ce76 100 int i;
61e96248 101
102 /* Init args array */
103 if (args == NULL) {
c630ce76 104 nargs = 2;
61e96248 105 i = 0;
106 args = xmalloc(sizeof(*args) * nargs);
107 args[i++] = "ssh";
61e96248 108 args[i++] = NULL;
109 }
110
111 /* If asked to add args, then do so and return */
112 if (add_arg) {
113 i = nargs++ - 1;
114 args = xrealloc(args, sizeof(*args) * nargs);
115 args[i++] = add_arg;
116 args[i++] = NULL;
117 return(NULL);
118 }
119
c630ce76 120 /* no subsystem if the server-spec contains a '/' */
121 if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
122 make_ssh_args("-s");
123 make_ssh_args("-oForwardX11=no");
124 make_ssh_args("-oForwardAgent=no");
125 make_ssh_args(use_ssh1 ? "-oProtocol=1" : "-oProtocol=2");
126
61e96248 127 /* Otherwise finish up and return the arg array */
0426a3b4 128 if (sftp_server != NULL)
129 make_ssh_args(sftp_server);
130 else
131 make_ssh_args("sftp");
61e96248 132
133 /* XXX: overflow - doesn't grow debug_buf */
134 debug_buf[0] = '\0';
135 for(i = 0; args[i]; i++) {
136 if (i)
137 strlcat(debug_buf, " ", sizeof(debug_buf));
138
139 strlcat(debug_buf, args[i], sizeof(debug_buf));
140 }
141 debug("SSH args \"%s\"", debug_buf);
142
143 return(args);
144}
145
2b87da3b 146void
61e96248 147usage(void)
148{
0426a3b4 149 fprintf(stderr, "usage: sftp [-1vC] [-osshopt=value] [user@]host\n");
61e96248 150 exit(1);
151}
152
2b87da3b 153int
61e96248 154main(int argc, char **argv)
155{
0426a3b4 156 int in, out, ch, debug_level, compress_flag;
61e96248 157 pid_t sshpid;
0426a3b4 158 char *host, *userhost;
61e96248 159 LogLevel ll;
0426a3b4 160 extern int optind;
161 extern char *optarg;
61e96248 162
5152d46f 163 __progname = get_progname(argv[0]);
61e96248 164 debug_level = compress_flag = 0;
0426a3b4 165
166 while ((ch = getopt(argc, argv, "1hvCo:s:S:")) != -1) {
167 switch (ch) {
168 case 'C':
61e96248 169 compress_flag = 1;
0426a3b4 170 break;
171 case 'v':
172 debug_level = MIN(3, debug_level + 1);
173 break;
174 case 'o':
175 make_ssh_args("-o");
176 make_ssh_args(optarg);
177 break;
178 case '1':
179 use_ssh1 = 1;
180 if (sftp_server == NULL)
181 sftp_server = _PATH_SFTP_SERVER;
182 break;
183 case 's':
184 sftp_server = optarg;
185 break;
186 case 'S':
187 ssh_program = optarg;
188 break;
189 case 'h':
190 default:
61e96248 191 usage();
192 }
193 }
194
0426a3b4 195 if (optind == argc || argc > (optind + 1))
61e96248 196 usage();
197
0426a3b4 198 userhost = argv[optind];
199
200 if ((host = strchr(userhost, '@')) == NULL)
201 host = userhost;
61e96248 202 else {
0426a3b4 203 *host = '\0';
204 if (!userhost[0]) {
61e96248 205 fprintf(stderr, "Missing username\n");
206 usage();
207 }
208 make_ssh_args("-l");
0426a3b4 209 make_ssh_args(userhost);
210 host++;
61e96248 211 }
212
0426a3b4 213 if (!*host) {
61e96248 214 fprintf(stderr, "Missing hostname\n");
215 usage();
216 }
217
218 /* Set up logging and debug '-d' arguments to ssh */
219 ll = SYSLOG_LEVEL_INFO;
220 switch (debug_level) {
221 case 1:
222 ll = SYSLOG_LEVEL_DEBUG1;
223 make_ssh_args("-v");
224 break;
225 case 2:
226 ll = SYSLOG_LEVEL_DEBUG2;
227 make_ssh_args("-v");
228 make_ssh_args("-v");
229 break;
230 case 3:
231 ll = SYSLOG_LEVEL_DEBUG3;
232 make_ssh_args("-v");
233 make_ssh_args("-v");
234 make_ssh_args("-v");
235 break;
236 }
237
238 if (compress_flag)
239 make_ssh_args("-C");
240
241 log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
242
0426a3b4 243 make_ssh_args(host);
61e96248 244
0426a3b4 245 fprintf(stderr, "Connecting to %s...\n", host);
61e96248 246
247 connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
248
249 do_init(in, out);
250
251 interactive_loop(in, out);
252
51fb577a 253#if !defined(USE_PIPES)
254 shutdown(in, SHUT_RDWR);
255 shutdown(out, SHUT_RDWR);
256#endif
257
61e96248 258 close(in);
259 close(out);
260
0426a3b4 261 if (waitpid(sshpid, NULL, 0) == -1)
262 fatal("Couldn't wait for ssh process: %s", strerror(errno));
61e96248 263
264 exit(0);
265}
This page took 0.0942499999999999 seconds and 5 git commands to generate.