diff options
Diffstat (limited to 'scp.c')
-rw-r--r-- | scp.c | 155 |
1 files changed, 68 insertions, 87 deletions
@@ -75,7 +75,7 @@ | |||
75 | */ | 75 | */ |
76 | 76 | ||
77 | #include "includes.h" | 77 | #include "includes.h" |
78 | RCSID("$OpenBSD: scp.c,v 1.40 2000/09/21 11:11:42 markus Exp $"); | 78 | RCSID("$OpenBSD: scp.c,v 1.41 2000/10/11 20:03:27 markus Exp $"); |
79 | 79 | ||
80 | #include "ssh.h" | 80 | #include "ssh.h" |
81 | #include "xmalloc.h" | 81 | #include "xmalloc.h" |
@@ -102,6 +102,9 @@ void progressmeter(int); | |||
102 | int getttywidth(void); | 102 | int getttywidth(void); |
103 | int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); | 103 | int do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc); |
104 | 104 | ||
105 | /* setup arguments for the call to ssh */ | ||
106 | void addargs(char *fmt, ...) __attribute__((format(printf, 1, 2))); | ||
107 | |||
105 | /* Time a transfer started. */ | 108 | /* Time a transfer started. */ |
106 | static struct timeval start; | 109 | static struct timeval start; |
107 | 110 | ||
@@ -114,12 +117,6 @@ off_t totalbytes = 0; | |||
114 | /* Name of current file being transferred. */ | 117 | /* Name of current file being transferred. */ |
115 | char *curfile; | 118 | char *curfile; |
116 | 119 | ||
117 | /* This is set to non-zero if IPv4 is desired. */ | ||
118 | int IPv4 = 0; | ||
119 | |||
120 | /* This is set to non-zero if IPv6 is desired. */ | ||
121 | int IPv6 = 0; | ||
122 | |||
123 | /* This is set to non-zero to enable verbose mode. */ | 120 | /* This is set to non-zero to enable verbose mode. */ |
124 | int verbose_mode = 0; | 121 | int verbose_mode = 0; |
125 | 122 | ||
@@ -129,23 +126,16 @@ int compress_flag = 0; | |||
129 | /* This is set to zero if the progressmeter is not desired. */ | 126 | /* This is set to zero if the progressmeter is not desired. */ |
130 | int showprogress = 1; | 127 | int showprogress = 1; |
131 | 128 | ||
132 | /* This is set to non-zero if running in batch mode (that is, password | ||
133 | and passphrase queries are not allowed). */ | ||
134 | int batchmode = 0; | ||
135 | |||
136 | /* This is set to the cipher type string if given on the command line. */ | ||
137 | char *cipher = NULL; | ||
138 | |||
139 | /* This is set to the RSA authentication identity file name if given on | ||
140 | the command line. */ | ||
141 | char *identity = NULL; | ||
142 | |||
143 | /* This is the port to use in contacting the remote site (is non-NULL). */ | ||
144 | char *port = NULL; | ||
145 | |||
146 | /* This is the program to execute for the secured connection. ("ssh" or -S) */ | 129 | /* This is the program to execute for the secured connection. ("ssh" or -S) */ |
147 | char *ssh_program = SSH_PROGRAM; | 130 | char *ssh_program = SSH_PROGRAM; |
148 | 131 | ||
132 | /* This is the list of arguments that scp passes to ssh */ | ||
133 | struct { | ||
134 | char **list; | ||
135 | int num; | ||
136 | int nalloc; | ||
137 | } args; | ||
138 | |||
149 | /* | 139 | /* |
150 | * This function executes the given command as the specified user on the | 140 | * This function executes the given command as the specified user on the |
151 | * given host. This returns < 0 if execution fails, and >= 0 otherwise. This | 141 | * given host. This returns < 0 if execution fails, and >= 0 otherwise. This |
@@ -158,8 +148,8 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) | |||
158 | int pin[2], pout[2], reserved[2]; | 148 | int pin[2], pout[2], reserved[2]; |
159 | 149 | ||
160 | if (verbose_mode) | 150 | if (verbose_mode) |
161 | fprintf(stderr, "Executing: host %s, user %s, command %s\n", | 151 | fprintf(stderr, "Executing: program %s host %s, user %s, command %s\n", |
162 | host, remuser ? remuser : "(unspecified)", cmd); | 152 | ssh_program, host, remuser ? remuser : "(unspecified)", cmd); |
163 | 153 | ||
164 | /* | 154 | /* |
165 | * Reserve two descriptors so that the real pipes won't get | 155 | * Reserve two descriptors so that the real pipes won't get |
@@ -178,10 +168,7 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) | |||
178 | close(reserved[1]); | 168 | close(reserved[1]); |
179 | 169 | ||
180 | /* For a child to execute the command on the remote host using ssh. */ | 170 | /* For a child to execute the command on the remote host using ssh. */ |
181 | if (fork() == 0) { | 171 | if (fork() == 0) { |
182 | char *args[100]; /* XXX careful */ | ||
183 | unsigned int i; | ||
184 | |||
185 | /* Child. */ | 172 | /* Child. */ |
186 | close(pin[1]); | 173 | close(pin[1]); |
187 | close(pout[0]); | 174 | close(pout[0]); |
@@ -190,41 +177,13 @@ do_cmd(char *host, char *remuser, char *cmd, int *fdin, int *fdout, int argc) | |||
190 | close(pin[0]); | 177 | close(pin[0]); |
191 | close(pout[1]); | 178 | close(pout[1]); |
192 | 179 | ||
193 | i = 0; | 180 | args.list[0] = ssh_program; |
194 | args[i++] = ssh_program; | 181 | if (remuser != NULL) |
195 | args[i++] = "-x"; | 182 | addargs("-l %s", remuser); |
196 | args[i++] = "-oFallBackToRsh no"; | 183 | addargs("%s", host); |
197 | if (IPv4) | 184 | addargs("%s", cmd); |
198 | args[i++] = "-4"; | ||
199 | if (IPv6) | ||
200 | args[i++] = "-6"; | ||
201 | if (verbose_mode) | ||
202 | args[i++] = "-v"; | ||
203 | if (compress_flag) | ||
204 | args[i++] = "-C"; | ||
205 | if (batchmode) | ||
206 | args[i++] = "-oBatchMode yes"; | ||
207 | if (cipher != NULL) { | ||
208 | args[i++] = "-c"; | ||
209 | args[i++] = cipher; | ||
210 | } | ||
211 | if (identity != NULL) { | ||
212 | args[i++] = "-i"; | ||
213 | args[i++] = identity; | ||
214 | } | ||
215 | if (port != NULL) { | ||
216 | args[i++] = "-p"; | ||
217 | args[i++] = port; | ||
218 | } | ||
219 | if (remuser != NULL) { | ||
220 | args[i++] = "-l"; | ||
221 | args[i++] = remuser; | ||
222 | } | ||
223 | args[i++] = host; | ||
224 | args[i++] = cmd; | ||
225 | args[i++] = NULL; | ||
226 | 185 | ||
227 | execvp(ssh_program, args); | 186 | execvp(ssh_program, args.list); |
228 | perror(ssh_program); | 187 | perror(ssh_program); |
229 | exit(1); | 188 | exit(1); |
230 | } | 189 | } |
@@ -290,27 +249,45 @@ main(argc, argv) | |||
290 | extern char *optarg; | 249 | extern char *optarg; |
291 | extern int optind; | 250 | extern int optind; |
292 | 251 | ||
252 | args.list = NULL; | ||
253 | addargs("ssh"); /* overwritten with ssh_program */ | ||
254 | addargs("-x"); | ||
255 | addargs("-oFallBackToRsh no"); | ||
256 | |||
293 | fflag = tflag = 0; | 257 | fflag = tflag = 0; |
294 | while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:")) != EOF) | 258 | while ((ch = getopt(argc, argv, "dfprtvBCc:i:P:q46S:o:")) != EOF) |
295 | switch (ch) { | 259 | switch (ch) { |
296 | /* User-visible flags. */ | 260 | /* User-visible flags. */ |
297 | case '4': | 261 | case '4': |
298 | IPv4 = 1; | ||
299 | break; | ||
300 | case '6': | 262 | case '6': |
301 | IPv6 = 1; | 263 | case 'C': |
264 | addargs("-%c", ch); | ||
302 | break; | 265 | break; |
303 | case 'p': | 266 | case 'o': |
304 | pflag = 1; | 267 | case 'c': |
268 | case 'i': | ||
269 | addargs("-%c %s", ch, optarg); | ||
305 | break; | 270 | break; |
306 | case 'P': | 271 | case 'P': |
307 | port = optarg; | 272 | addargs("-p %s", optarg); |
273 | break; | ||
274 | case 'B': | ||
275 | addargs("-o Batchmode yes"); | ||
276 | break; | ||
277 | case 'p': | ||
278 | pflag = 1; | ||
308 | break; | 279 | break; |
309 | case 'r': | 280 | case 'r': |
310 | iamrecursive = 1; | 281 | iamrecursive = 1; |
311 | break; | 282 | break; |
312 | case 'S': | 283 | case 'S': |
313 | ssh_program = optarg; | 284 | ssh_program = xstrdup(optarg); |
285 | break; | ||
286 | case 'v': | ||
287 | verbose_mode = 1; | ||
288 | break; | ||
289 | case 'q': | ||
290 | showprogress = 0; | ||
314 | break; | 291 | break; |
315 | 292 | ||
316 | /* Server options. */ | 293 | /* Server options. */ |
@@ -325,24 +302,6 @@ main(argc, argv) | |||
325 | iamremote = 1; | 302 | iamremote = 1; |
326 | tflag = 1; | 303 | tflag = 1; |
327 | break; | 304 | break; |
328 | case 'c': | ||
329 | cipher = optarg; | ||
330 | break; | ||
331 | case 'i': | ||
332 | identity = optarg; | ||
333 | break; | ||
334 | case 'v': | ||
335 | verbose_mode = 1; | ||
336 | break; | ||
337 | case 'B': | ||
338 | batchmode = 1; | ||
339 | break; | ||
340 | case 'C': | ||
341 | compress_flag = 1; | ||
342 | break; | ||
343 | case 'q': | ||
344 | showprogress = 0; | ||
345 | break; | ||
346 | case '?': | 305 | case '?': |
347 | default: | 306 | default: |
348 | usage(); | 307 | usage(); |
@@ -1287,3 +1246,25 @@ getttywidth(void) | |||
1287 | else | 1246 | else |
1288 | return (80); | 1247 | return (80); |
1289 | } | 1248 | } |
1249 | |||
1250 | void | ||
1251 | addargs(char *fmt, ...) | ||
1252 | { | ||
1253 | va_list ap; | ||
1254 | char buf[1024]; | ||
1255 | |||
1256 | va_start(ap, fmt); | ||
1257 | vsnprintf(buf, sizeof(buf), fmt, ap); | ||
1258 | va_end(ap); | ||
1259 | |||
1260 | if (args.list == NULL) { | ||
1261 | args.nalloc = 32; | ||
1262 | args.num = 0; | ||
1263 | args.list = xmalloc(args.nalloc * sizeof(char *)); | ||
1264 | } else if (args.num+2 >= args.nalloc) { | ||
1265 | args.nalloc *= 2; | ||
1266 | args.list = xrealloc(args.list, args.nalloc * sizeof(char *)); | ||
1267 | } | ||
1268 | args.list[args.num++] = xstrdup(buf); | ||
1269 | args.list[args.num] = NULL; | ||
1270 | } | ||