]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/sftp.c
Try to support the Cirrus Logic PD6833 better in pci mode. This is
[FreeBSD/FreeBSD.git] / crypto / openssh / sftp.c
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
27 RCSID("$OpenBSD: sftp.c,v 1.15 2001/04/16 02:31:44 mouring Exp $");
28
29 /* XXX: commandline mode */
30 /* XXX: short-form remote directory listings (like 'ls -C') */
31
32 #include "buffer.h"
33 #include "xmalloc.h"
34 #include "log.h"
35 #include "pathnames.h"
36
37 #include "sftp.h"
38 #include "sftp-common.h"
39 #include "sftp-client.h"
40 #include "sftp-int.h"
41
42 #include "scp-common.h"
43
44 int use_ssh1 = 0;
45 char *ssh_program = _PATH_SSH_PROGRAM;
46 char *sftp_server = NULL;
47 FILE* infile;
48
49 void
50 connect_to_server(char **args, int *in, int *out, pid_t *sshpid)
51 {
52         int c_in, c_out;
53 #ifdef USE_PIPES
54         int pin[2], pout[2];
55         if ((pipe(pin) == -1) || (pipe(pout) == -1))
56                 fatal("pipe: %s", strerror(errno));
57         *in = pin[0];
58         *out = pout[1];
59         c_in = pout[0];
60         c_out = pin[1];
61 #else /* USE_PIPES */
62         int inout[2];
63         if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
64                 fatal("socketpair: %s", strerror(errno));
65         *in = *out = inout[0];
66         c_in = c_out = inout[1];
67 #endif /* USE_PIPES */
68
69         if ((*sshpid = fork()) == -1)
70                 fatal("fork: %s", strerror(errno));
71         else if (*sshpid == 0) {
72                 if ((dup2(c_in, STDIN_FILENO) == -1) ||
73                     (dup2(c_out, STDOUT_FILENO) == -1)) {
74                         fprintf(stderr, "dup2: %s\n", strerror(errno));
75                         exit(1);
76                 }
77                 close(*in);
78                 close(*out);
79                 close(c_in);
80                 close(c_out);
81                 execv(ssh_program, args);
82                 fprintf(stderr, "exec: %s: %s\n", ssh_program, strerror(errno));
83                 exit(1);
84         }
85
86         close(c_in);
87         close(c_out);
88 }
89
90 char **
91 make_ssh_args(char *add_arg)
92 {
93         static char **args = NULL;
94         static int nargs = 0;
95         char debug_buf[4096];
96         int i;
97
98         /* Init args array */
99         if (args == NULL) {
100                 nargs = 2;
101                 i = 0;
102                 args = xmalloc(sizeof(*args) * nargs);
103                 args[i++] = "ssh";
104                 args[i++] = NULL;
105         }
106
107         /* If asked to add args, then do so and return */
108         if (add_arg) {
109                 i = nargs++ - 1;
110                 args = xrealloc(args, sizeof(*args) * nargs);
111                 args[i++] = add_arg;
112                 args[i++] = NULL;
113                 return(NULL);
114         }
115
116         /* no subsystem if the server-spec contains a '/' */
117         if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
118                 make_ssh_args("-s");
119         make_ssh_args("-oForwardX11=no");
120         make_ssh_args("-oForwardAgent=no");
121         make_ssh_args(use_ssh1 ? "-oProtocol=1" : "-oProtocol=2");
122
123         /* Otherwise finish up and return the arg array */
124         if (sftp_server != NULL)
125                 make_ssh_args(sftp_server);
126         else
127                 make_ssh_args("sftp");
128
129         /* XXX: overflow - doesn't grow debug_buf */
130         debug_buf[0] = '\0';
131         for(i = 0; args[i]; i++) {
132                 if (i)
133                         strlcat(debug_buf, " ", sizeof(debug_buf));
134
135                 strlcat(debug_buf, args[i], sizeof(debug_buf));
136         }
137         debug("SSH args \"%s\"", debug_buf);
138
139         return(args);
140 }
141
142 void
143 usage(void)
144 {
145         fprintf(stderr, "usage: sftp [-1vC] [-b batchfile] [-osshopt=value] [user@]host[:file [file]]\n");
146         exit(1);
147 }
148
149 int
150 main(int argc, char **argv)
151 {
152         int in, out, ch, debug_level, compress_flag;
153         pid_t sshpid;
154         char *file1 = NULL;
155         char *host, *userhost, *cp, *file2;
156         LogLevel ll;
157         extern int optind;
158         extern char *optarg;
159
160         infile = stdin;         /* Read from STDIN unless changed by -b */
161         debug_level = compress_flag = 0;
162
163         while ((ch = getopt(argc, argv, "1hvCo:s:S:b:")) != -1) {
164                 switch (ch) {
165                 case 'C':
166                         compress_flag = 1;
167                         break;
168                 case 'v':
169                         debug_level = MIN(3, debug_level + 1);
170                         break;
171                 case 'o':
172                         make_ssh_args("-o");
173                         make_ssh_args(optarg);
174                         break;
175                 case '1':
176                         use_ssh1 = 1;
177                         if (sftp_server == NULL)
178                                 sftp_server = _PATH_SFTP_SERVER;
179                         break;
180                 case 's':
181                         sftp_server = optarg;
182                         break;
183                 case 'S':
184                         ssh_program = optarg;
185                         break;
186                 case 'b':
187                         if (infile == stdin) {
188                                 infile = fopen(optarg, "r");
189                                 if (infile == NULL)
190                                         fatal("%s (%s).", strerror(errno), optarg);
191                         } else
192                                 fatal("Filename already specified.");
193                         break;
194                 case 'h':
195                 default:
196                         usage();
197                 }
198         }
199
200         if (optind == argc || argc > (optind + 2))
201                 usage();
202
203         userhost = xstrdup(argv[optind]);
204         file2 = argv[optind+1];
205
206         if ((cp = colon(userhost)) != NULL) {
207                 *cp++ = '\0';
208                 file1 = cp;
209         }
210
211         if ((host = strchr(userhost, '@')) == NULL)
212                 host = userhost;
213         else {
214                 *host++ = '\0';
215                 if (!userhost[0]) {
216                         fprintf(stderr, "Missing username\n");
217                         usage();
218                 }
219                 make_ssh_args("-l");
220                 make_ssh_args(userhost);
221         }
222
223         host = cleanhostname(host);
224         if (!*host) {
225                 fprintf(stderr, "Missing hostname\n");
226                 usage();
227         }
228
229         /* Set up logging and debug '-d' arguments to ssh */
230         ll = SYSLOG_LEVEL_INFO;
231         switch (debug_level) {
232         case 1:
233                 ll = SYSLOG_LEVEL_DEBUG1;
234                 make_ssh_args("-v");
235                 break;
236         case 2:
237                 ll = SYSLOG_LEVEL_DEBUG2;
238                 make_ssh_args("-v");
239                 make_ssh_args("-v");
240                 break;
241         case 3:
242                 ll = SYSLOG_LEVEL_DEBUG3;
243                 make_ssh_args("-v");
244                 make_ssh_args("-v");
245                 make_ssh_args("-v");
246                 break;
247         }
248
249         if (compress_flag)
250                 make_ssh_args("-C");
251
252         log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);
253
254         make_ssh_args(host);
255
256         fprintf(stderr, "Connecting to %s...\n", host);
257
258         connect_to_server(make_ssh_args(NULL), &in, &out, &sshpid);
259
260         interactive_loop(in, out, file1, file2);
261
262         close(in);
263         close(out);
264         if (infile != stdin)
265                 fclose(infile);
266
267         if (waitpid(sshpid, NULL, 0) == -1)
268                 fatal("Couldn't wait for ssh process: %s", strerror(errno));
269
270         exit(0);
271 }