OpenCoverage

sftp.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/openssh/src/sftp.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* $OpenBSD: sftp.c,v 1.186 2018/09/07 04:26:56 dtucker Exp $ */-
2/*-
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>-
4 *-
5 * Permission to use, copy, modify, and distribute this software for any-
6 * purpose with or without fee is hereby granted, provided that the above-
7 * copyright notice and this permission notice appear in all copies.-
8 *-
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES-
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF-
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR-
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES-
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN-
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF-
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.-
16 */-
17-
18#include "includes.h"-
19-
20#include <sys/types.h>-
21#include <sys/ioctl.h>-
22#ifdef HAVE_SYS_STAT_H-
23# include <sys/stat.h>-
24#endif-
25#include <sys/param.h>-
26#include <sys/socket.h>-
27#include <sys/wait.h>-
28#ifdef HAVE_SYS_STATVFS_H-
29#include <sys/statvfs.h>-
30#endif-
31-
32#include <ctype.h>-
33#include <errno.h>-
34-
35#ifdef HAVE_PATHS_H-
36# include <paths.h>-
37#endif-
38#ifdef HAVE_LIBGEN_H-
39#include <libgen.h>-
40#endif-
41#ifdef HAVE_LOCALE_H-
42# include <locale.h>-
43#endif-
44#ifdef USE_LIBEDIT-
45#include <histedit.h>-
46#else-
47typedef void EditLine;-
48#endif-
49#include <limits.h>-
50#include <signal.h>-
51#include <stdarg.h>-
52#include <stdlib.h>-
53#include <stdio.h>-
54#include <string.h>-
55#include <unistd.h>-
56#include <stdarg.h>-
57-
58#ifdef HAVE_UTIL_H-
59# include <util.h>-
60#endif-
61-
62#include "xmalloc.h"-
63#include "log.h"-
64#include "pathnames.h"-
65#include "misc.h"-
66#include "utf8.h"-
67-
68#include "sftp.h"-
69#include "ssherr.h"-
70#include "sshbuf.h"-
71#include "sftp-common.h"-
72#include "sftp-client.h"-
73-
74#define DEFAULT_COPY_BUFLEN 32768 /* Size of buffer for up/download */-
75#define DEFAULT_NUM_REQUESTS 64 /* # concurrent outstanding requests */-
76-
77/* File to read commands from */-
78FILE* infile;-
79-
80/* Are we in batchfile mode? */-
81int batchmode = 0;-
82-
83/* PID of ssh transport process */-
84static volatile pid_t sshpid = -1;-
85-
86/* Suppress diagnositic messages */-
87int quiet = 0;-
88-
89/* This is set to 0 if the progressmeter is not desired. */-
90int showprogress = 1;-
91-
92/* When this option is set, we always recursively download/upload directories */-
93int global_rflag = 0;-
94-
95/* When this option is set, we resume download or upload if possible */-
96int global_aflag = 0;-
97-
98/* When this option is set, the file transfers will always preserve times */-
99int global_pflag = 0;-
100-
101/* When this option is set, transfers will have fsync() called on each file */-
102int global_fflag = 0;-
103-
104/* SIGINT received during command processing */-
105volatile sig_atomic_t interrupted = 0;-
106-
107/* I wish qsort() took a separate ctx for the comparison function...*/-
108int sort_flag;-
109glob_t *sort_glob;-
110-
111/* Context used for commandline completion */-
112struct complete_ctx {-
113 struct sftp_conn *conn;-
114 char **remote_pathp;-
115};-
116-
117int remote_glob(struct sftp_conn *, const char *, int,-
118 int (*)(const char *, int), glob_t *); /* proto for sftp-glob.c */-
119-
120extern char *__progname;-
121-
122/* Separators for interactive commands */-
123#define WHITESPACE " \t\r\n"-
124-
125/* ls flags */-
126#define LS_LONG_VIEW 0x0001 /* Full view ala ls -l */-
127#define LS_SHORT_VIEW 0x0002 /* Single row view ala ls -1 */-
128#define LS_NUMERIC_VIEW 0x0004 /* Long view with numeric uid/gid */-
129#define LS_NAME_SORT 0x0008 /* Sort by name (default) */-
130#define LS_TIME_SORT 0x0010 /* Sort by mtime */-
131#define LS_SIZE_SORT 0x0020 /* Sort by file size */-
132#define LS_REVERSE_SORT 0x0040 /* Reverse sort order */-
133#define LS_SHOW_ALL 0x0080 /* Don't skip filenames starting with '.' */-
134#define LS_SI_UNITS 0x0100 /* Display sizes as K, M, G, etc. */-
135-
136#define VIEW_FLAGS (LS_LONG_VIEW|LS_SHORT_VIEW|LS_NUMERIC_VIEW|LS_SI_UNITS)-
137#define SORT_FLAGS (LS_NAME_SORT|LS_TIME_SORT|LS_SIZE_SORT)-
138-
139/* Commands for interactive mode */-
140enum sftp_command {-
141 I_CHDIR = 1,-
142 I_CHGRP,-
143 I_CHMOD,-
144 I_CHOWN,-
145 I_DF,-
146 I_GET,-
147 I_HELP,-
148 I_LCHDIR,-
149 I_LINK,-
150 I_LLS,-
151 I_LMKDIR,-
152 I_LPWD,-
153 I_LS,-
154 I_LUMASK,-
155 I_MKDIR,-
156 I_PUT,-
157 I_PWD,-
158 I_QUIT,-
159 I_REGET,-
160 I_RENAME,-
161 I_REPUT,-
162 I_RM,-
163 I_RMDIR,-
164 I_SHELL,-
165 I_SYMLINK,-
166 I_VERSION,-
167 I_PROGRESS,-
168};-
169-
170struct CMD {-
171 const char *c;-
172 const int n;-
173 const int t;-
174};-
175-
176/* Type of completion */-
177#define NOARGS 0-
178#define REMOTE 1-
179#define LOCAL 2-
180-
181static const struct CMD cmds[] = {-
182 { "bye", I_QUIT, NOARGS },-
183 { "cd", I_CHDIR, REMOTE },-
184 { "chdir", I_CHDIR, REMOTE },-
185 { "chgrp", I_CHGRP, REMOTE },-
186 { "chmod", I_CHMOD, REMOTE },-
187 { "chown", I_CHOWN, REMOTE },-
188 { "df", I_DF, REMOTE },-
189 { "dir", I_LS, REMOTE },-
190 { "exit", I_QUIT, NOARGS },-
191 { "get", I_GET, REMOTE },-
192 { "help", I_HELP, NOARGS },-
193 { "lcd", I_LCHDIR, LOCAL },-
194 { "lchdir", I_LCHDIR, LOCAL },-
195 { "lls", I_LLS, LOCAL },-
196 { "lmkdir", I_LMKDIR, LOCAL },-
197 { "ln", I_LINK, REMOTE },-
198 { "lpwd", I_LPWD, LOCAL },-
199 { "ls", I_LS, REMOTE },-
200 { "lumask", I_LUMASK, NOARGS },-
201 { "mkdir", I_MKDIR, REMOTE },-
202 { "mget", I_GET, REMOTE },-
203 { "mput", I_PUT, LOCAL },-
204 { "progress", I_PROGRESS, NOARGS },-
205 { "put", I_PUT, LOCAL },-
206 { "pwd", I_PWD, REMOTE },-
207 { "quit", I_QUIT, NOARGS },-
208 { "reget", I_REGET, REMOTE },-
209 { "rename", I_RENAME, REMOTE },-
210 { "reput", I_REPUT, LOCAL },-
211 { "rm", I_RM, REMOTE },-
212 { "rmdir", I_RMDIR, REMOTE },-
213 { "symlink", I_SYMLINK, REMOTE },-
214 { "version", I_VERSION, NOARGS },-
215 { "!", I_SHELL, NOARGS },-
216 { "?", I_HELP, NOARGS },-
217 { NULL, -1, -1 }-
218};-
219-
220/* ARGSUSED */-
221static void-
222killchild(int signo)-
223{-
224 if (sshpid > 1) {
sshpid > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
225 kill(sshpid, SIGTERM);-
226 waitpid(sshpid, NULL, 0);-
227 }
never executed: end of block
0
228-
229 _exit(1);-
230}
never executed: end of block
0
231-
232/* ARGSUSED */-
233static void-
234suspchild(int signo)-
235{-
236 if (sshpid > 1) {
sshpid > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
237 kill(sshpid, signo);-
238 while (waitpid(sshpid, NULL, WUNTRACED) == -1 && errno == EINTR)
waitpid(sshpid...0) , 2 ) == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
239 continue;
never executed: continue;
0
240 }
never executed: end of block
0
241 kill(getpid(), SIGSTOP);-
242}
never executed: end of block
0
243-
244/* ARGSUSED */-
245static void-
246cmd_interrupt(int signo)-
247{-
248 const char msg[] = "\rInterrupt \n";-
249 int olderrno = errno;-
250-
251 (void)write(STDERR_FILENO, msg, sizeof(msg) - 1);-
252 interrupted = 1;-
253 errno = olderrno;-
254}
never executed: end of block
0
255-
256/*ARGSUSED*/-
257static void-
258sigchld_handler(int sig)-
259{-
260 int save_errno = errno;-
261 pid_t pid;-
262 const char msg[] = "\rConnection closed. \n";-
263-
264 /* Report if ssh transport process dies. */-
265 while ((pid = waitpid(sshpid, NULL, WNOHANG)) == -1 && errno == EINTR)
(pid = waitpid...) , 1 )) == -1Description
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 4Description
TRUEnever evaluated
FALSEnever evaluated
0
266 continue;
never executed: continue;
0
267 if (pid == sshpid) {
pid == sshpidDescription
TRUEnever evaluated
FALSEnever evaluated
0
268 (void)write(STDERR_FILENO, msg, sizeof(msg) - 1);-
269 sshpid = -1;-
270 }
never executed: end of block
0
271-
272 errno = save_errno;-
273}
never executed: end of block
0
274-
275static void-
276help(void)-
277{-
278 printf("Available commands:\n"-
279 "bye Quit sftp\n"-
280 "cd path Change remote directory to 'path'\n"-
281 "chgrp grp path Change group of file 'path' to 'grp'\n"-
282 "chmod mode path Change permissions of file 'path' to 'mode'\n"-
283 "chown own path Change owner of file 'path' to 'own'\n"-
284 "df [-hi] [path] Display statistics for current directory or\n"-
285 " filesystem containing 'path'\n"-
286 "exit Quit sftp\n"-
287 "get [-afPpRr] remote [local] Download file\n"-
288 "reget [-fPpRr] remote [local] Resume download file\n"-
289 "reput [-fPpRr] [local] remote Resume upload file\n"-
290 "help Display this help text\n"-
291 "lcd path Change local directory to 'path'\n"-
292 "lls [ls-options [path]] Display local directory listing\n"-
293 "lmkdir path Create local directory\n"-
294 "ln [-s] oldpath newpath Link remote file (-s for symlink)\n"-
295 "lpwd Print local working directory\n"-
296 "ls [-1afhlnrSt] [path] Display remote directory listing\n"-
297 "lumask umask Set local umask to 'umask'\n"-
298 "mkdir path Create remote directory\n"-
299 "progress Toggle display of progress meter\n"-
300 "put [-afPpRr] local [remote] Upload file\n"-
301 "pwd Display remote working directory\n"-
302 "quit Quit sftp\n"-
303 "rename oldpath newpath Rename remote file\n"-
304 "rm path Delete remote file\n"-
305 "rmdir path Remove remote directory\n"-
306 "symlink oldpath newpath Symlink remote file\n"-
307 "version Show SFTP version\n"-
308 "!command Execute 'command' in local shell\n"-
309 "! Escape to local shell\n"-
310 "? Synonym for help\n");-
311}
never executed: end of block
0
312-
313static void-
314local_do_shell(const char *args)-
315{-
316 int status;-
317 char *shell;-
318 pid_t pid;-
319-
320 if (!*args)
!*argsDescription
TRUEnever evaluated
FALSEnever evaluated
0
321 args = NULL;
never executed: args = ((void *)0) ;
0
322-
323 if ((shell = getenv("SHELL")) == NULL || *shell == '\0')
(shell = geten...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*shell == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
324 shell = _PATH_BSHELL;
never executed: shell = "/bin/sh" ;
0
325-
326 if ((pid = fork()) == -1)
(pid = fork()) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
327 fatal("Couldn't fork: %s", strerror(errno));
never executed: fatal("Couldn't fork: %s", strerror( (*__errno_location ()) ));
0
328-
329 if (pid == 0) {
pid == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
330 /* XXX: child has pipe fds to ssh subproc open - issue? */-
331 if (args) {
argsDescription
TRUEnever evaluated
FALSEnever evaluated
0
332 debug3("Executing %s -c \"%s\"", shell, args);-
333 execl(shell, shell, "-c", args, (char *)NULL);-
334 } else {
never executed: end of block
0
335 debug3("Executing %s", shell);-
336 execl(shell, shell, (char *)NULL);-
337 }
never executed: end of block
0
338 fprintf(stderr, "Couldn't execute \"%s\": %s\n", shell,-
339 strerror(errno));-
340 _exit(1);-
341 }
never executed: end of block
0
342 while (waitpid(pid, &status, 0) == -1)
waitpid(pid, &status, 0) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
343 if (errno != EINTR)
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
344 fatal("Couldn't wait for child: %s", strerror(errno));
never executed: fatal("Couldn't wait for child: %s", strerror( (*__errno_location ()) ));
0
345 if (!WIFEXITED(status))
! ((( status ) & 0x7f) == 0)Description
TRUEnever evaluated
FALSEnever evaluated
0
346 error("Shell exited abnormally");
never executed: error("Shell exited abnormally");
0
347 else if (WEXITSTATUS(status))
((( status ) & 0xff00) >> 8)Description
TRUEnever evaluated
FALSEnever evaluated
0
348 error("Shell exited with status %d", WEXITSTATUS(status));
never executed: error("Shell exited with status %d", ((( status ) & 0xff00) >> 8) );
0
349}
never executed: end of block
0
350-
351static void-
352local_do_ls(const char *args)-
353{-
354 if (!args || !*args)
!argsDescription
TRUEnever evaluated
FALSEnever evaluated
!*argsDescription
TRUEnever evaluated
FALSEnever evaluated
0
355 local_do_shell(_PATH_LS);
never executed: local_do_shell("ls");
0
356 else {-
357 int len = strlen(_PATH_LS " ") + strlen(args) + 1;-
358 char *buf = xmalloc(len);-
359-
360 /* XXX: quoting - rip quoting code from ftp? */-
361 snprintf(buf, len, _PATH_LS " %s", args);-
362 local_do_shell(buf);-
363 free(buf);-
364 }
never executed: end of block
0
365}-
366-
367/* Strip one path (usually the pwd) from the start of another */-
368static char *-
369path_strip(const char *path, const char *strip)-
370{-
371 size_t len;-
372-
373 if (strip == NULL)
strip == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
374 return (xstrdup(path));
never executed: return (xstrdup(path));
0
375-
376 len = strlen(strip);-
377 if (strncmp(path, strip, len) == 0) {
never executed: __result = (((const unsigned char *) (const char *) ( path ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( strip ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
(__extension__..., len ))) == 0Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( len )Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( path )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( path ...ze_t) ( len ))Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( strip )Description
TRUEnever evaluated
FALSEnever evaluated
strlen ( strip...ze_t) ( len ))Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
378 if (strip[len - 1] != '/' && path[len] == '/')
strip[len - 1] != '/'Description
TRUEnever evaluated
FALSEnever evaluated
path[len] == '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
379 len++;
never executed: len++;
0
380 return (xstrdup(path + len));
never executed: return (xstrdup(path + len));
0
381 }-
382-
383 return (xstrdup(path));
never executed: return (xstrdup(path));
0
384}-
385-
386static char *-
387make_absolute(char *p, const char *pwd)-
388{-
389 char *abs_str;-
390-
391 /* Derelativise */-
392 if (p && p[0] != '/') {
pDescription
TRUEnever evaluated
FALSEnever evaluated
p[0] != '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
393 abs_str = path_append(pwd, p);-
394 free(p);-
395 return(abs_str);
never executed: return(abs_str);
0
396 } else-
397 return(p);
never executed: return(p);
0
398}-
399-
400static int-
401parse_getput_flags(const char *cmd, char **argv, int argc,-
402 int *aflag, int *fflag, int *pflag, int *rflag)-
403{-
404 extern int opterr, optind, optopt, optreset;-
405 int ch;-
406-
407 optind = optreset = 1;-
408 opterr = 0;-
409-
410 *aflag = *fflag = *rflag = *pflag = 0;-
411 while ((ch = getopt(argc, argv, "afPpRr")) != -1) {
(ch = BSDgetop...fPpRr")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
412 switch (ch) {-
413 case 'a':
never executed: case 'a':
0
414 *aflag = 1;-
415 break;
never executed: break;
0
416 case 'f':
never executed: case 'f':
0
417 *fflag = 1;-
418 break;
never executed: break;
0
419 case 'p':
never executed: case 'p':
0
420 case 'P':
never executed: case 'P':
0
421 *pflag = 1;-
422 break;
never executed: break;
0
423 case 'r':
never executed: case 'r':
0
424 case 'R':
never executed: case 'R':
0
425 *rflag = 1;-
426 break;
never executed: break;
0
427 default:
never executed: default:
0
428 error("%s: Invalid flag -%c", cmd, optopt);-
429 return -1;
never executed: return -1;
0
430 }-
431 }-
432-
433 return optind;
never executed: return BSDoptind;
0
434}-
435-
436static int-
437parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)-
438{-
439 extern int opterr, optind, optopt, optreset;-
440 int ch;-
441-
442 optind = optreset = 1;-
443 opterr = 0;-
444-
445 *sflag = 0;-
446 while ((ch = getopt(argc, argv, "s")) != -1) {
(ch = BSDgetop...v, "s")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
447 switch (ch) {-
448 case 's':
never executed: case 's':
0
449 *sflag = 1;-
450 break;
never executed: break;
0
451 default:
never executed: default:
0
452 error("%s: Invalid flag -%c", cmd, optopt);-
453 return -1;
never executed: return -1;
0
454 }-
455 }-
456-
457 return optind;
never executed: return BSDoptind;
0
458}-
459-
460static int-
461parse_rename_flags(const char *cmd, char **argv, int argc, int *lflag)-
462{-
463 extern int opterr, optind, optopt, optreset;-
464 int ch;-
465-
466 optind = optreset = 1;-
467 opterr = 0;-
468-
469 *lflag = 0;-
470 while ((ch = getopt(argc, argv, "l")) != -1) {
(ch = BSDgetop...v, "l")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
471 switch (ch) {-
472 case 'l':
never executed: case 'l':
0
473 *lflag = 1;-
474 break;
never executed: break;
0
475 default:
never executed: default:
0
476 error("%s: Invalid flag -%c", cmd, optopt);-
477 return -1;
never executed: return -1;
0
478 }-
479 }-
480-
481 return optind;
never executed: return BSDoptind;
0
482}-
483-
484static int-
485parse_ls_flags(char **argv, int argc, int *lflag)-
486{-
487 extern int opterr, optind, optopt, optreset;-
488 int ch;-
489-
490 optind = optreset = 1;-
491 opterr = 0;-
492-
493 *lflag = LS_NAME_SORT;-
494 while ((ch = getopt(argc, argv, "1Safhlnrt")) != -1) {
(ch = BSDgetop...hlnrt")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
495 switch (ch) {-
496 case '1':
never executed: case '1':
0
497 *lflag &= ~VIEW_FLAGS;-
498 *lflag |= LS_SHORT_VIEW;-
499 break;
never executed: break;
0
500 case 'S':
never executed: case 'S':
0
501 *lflag &= ~SORT_FLAGS;-
502 *lflag |= LS_SIZE_SORT;-
503 break;
never executed: break;
0
504 case 'a':
never executed: case 'a':
0
505 *lflag |= LS_SHOW_ALL;-
506 break;
never executed: break;
0
507 case 'f':
never executed: case 'f':
0
508 *lflag &= ~SORT_FLAGS;-
509 break;
never executed: break;
0
510 case 'h':
never executed: case 'h':
0
511 *lflag |= LS_SI_UNITS;-
512 break;
never executed: break;
0
513 case 'l':
never executed: case 'l':
0
514 *lflag &= ~LS_SHORT_VIEW;-
515 *lflag |= LS_LONG_VIEW;-
516 break;
never executed: break;
0
517 case 'n':
never executed: case 'n':
0
518 *lflag &= ~LS_SHORT_VIEW;-
519 *lflag |= LS_NUMERIC_VIEW|LS_LONG_VIEW;-
520 break;
never executed: break;
0
521 case 'r':
never executed: case 'r':
0
522 *lflag |= LS_REVERSE_SORT;-
523 break;
never executed: break;
0
524 case 't':
never executed: case 't':
0
525 *lflag &= ~SORT_FLAGS;-
526 *lflag |= LS_TIME_SORT;-
527 break;
never executed: break;
0
528 default:
never executed: default:
0
529 error("ls: Invalid flag -%c", optopt);-
530 return -1;
never executed: return -1;
0
531 }-
532 }-
533-
534 return optind;
never executed: return BSDoptind;
0
535}-
536-
537static int-
538parse_df_flags(const char *cmd, char **argv, int argc, int *hflag, int *iflag)-
539{-
540 extern int opterr, optind, optopt, optreset;-
541 int ch;-
542-
543 optind = optreset = 1;-
544 opterr = 0;-
545-
546 *hflag = *iflag = 0;-
547 while ((ch = getopt(argc, argv, "hi")) != -1) {
(ch = BSDgetop..., "hi")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
548 switch (ch) {-
549 case 'h':
never executed: case 'h':
0
550 *hflag = 1;-
551 break;
never executed: break;
0
552 case 'i':
never executed: case 'i':
0
553 *iflag = 1;-
554 break;
never executed: break;
0
555 default:
never executed: default:
0
556 error("%s: Invalid flag -%c", cmd, optopt);-
557 return -1;
never executed: return -1;
0
558 }-
559 }-
560-
561 return optind;
never executed: return BSDoptind;
0
562}-
563-
564static int-
565parse_no_flags(const char *cmd, char **argv, int argc)-
566{-
567 extern int opterr, optind, optopt, optreset;-
568 int ch;-
569-
570 optind = optreset = 1;-
571 opterr = 0;-
572-
573 while ((ch = getopt(argc, argv, "")) != -1) {
(ch = BSDgetop...gv, "")) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
574 switch (ch) {-
575 default:
never executed: default:
0
576 error("%s: Invalid flag -%c", cmd, optopt);-
577 return -1;
never executed: return -1;
0
578 }-
579 }-
580-
581 return optind;
never executed: return BSDoptind;
0
582}-
583-
584static int-
585is_dir(const char *path)-
586{-
587 struct stat sb;-
588-
589 /* XXX: report errors? */-
590 if (stat(path, &sb) == -1)
stat(path, &sb) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
591 return(0);
never executed: return(0);
0
592-
593 return(S_ISDIR(sb.st_mode));
never executed: return( (((( sb.st_mode )) & 0170000) == (0040000)) );
0
594}-
595-
596static int-
597remote_is_dir(struct sftp_conn *conn, const char *path)-
598{-
599 Attrib *a;-
600-
601 /* XXX: report errors? */-
602 if ((a = do_stat(conn, path, 1)) == NULL)
(a = do_stat(c...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
603 return(0);
never executed: return(0);
0
604 if (!(a->flags & SSH2_FILEXFER_ATTR_PERMISSIONS))
!(a->flags & 0x00000004)Description
TRUEnever evaluated
FALSEnever evaluated
0
605 return(0);
never executed: return(0);
0
606 return(S_ISDIR(a->perm));
never executed: return( (((( a->perm )) & 0170000) == (0040000)) );
0
607}-
608-
609/* Check whether path returned from glob(..., GLOB_MARK, ...) is a directory */-
610static int-
611pathname_is_dir(const char *pathname)-
612{-
613 size_t l = strlen(pathname);-
614-
615 return l > 0 && pathname[l - 1] == '/';
never executed: return l > 0 && pathname[l - 1] == '/';
l > 0Description
TRUEnever evaluated
FALSEnever evaluated
pathname[l - 1] == '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
616}-
617-
618static int-
619process_get(struct sftp_conn *conn, const char *src, const char *dst,-
620 const char *pwd, int pflag, int rflag, int resume, int fflag)-
621{-
622 char *abs_src = NULL;-
623 char *abs_dst = NULL;-
624 glob_t g;-
625 char *filename, *tmp=NULL;-
626 int i, r, err = 0;-
627-
628 abs_src = xstrdup(src);-
629 abs_src = make_absolute(abs_src, pwd);-
630 memset(&g, 0, sizeof(g));-
631-
632 debug3("Looking up %s", abs_src);-
633 if ((r = remote_glob(conn, abs_src, GLOB_MARK, NULL, &g)) != 0) {
(r = remote_gl...0) , &g)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
634 if (r == GLOB_NOSPACE) {
r == (-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
635 error("Too many matches for \"%s\".", abs_src);-
636 } else {
never executed: end of block
0
637 error("File \"%s\" not found.", abs_src);-
638 }
never executed: end of block
0
639 err = -1;-
640 goto out;
never executed: goto out;
0
641 }-
642-
643 /*-
644 * If multiple matches then dst must be a directory or-
645 * unspecified.-
646 */-
647 if (g.gl_matchc > 1 && dst != NULL && !is_dir(dst)) {
g.gl_matchc > 1Description
TRUEnever evaluated
FALSEnever evaluated
dst != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
!is_dir(dst)Description
TRUEnever evaluated
FALSEnever evaluated
0
648 error("Multiple source paths, but destination "-
649 "\"%s\" is not a directory", dst);-
650 err = -1;-
651 goto out;
never executed: goto out;
0
652 }-
653-
654 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
655 tmp = xstrdup(g.gl_pathv[i]);-
656 if ((filename = basename(tmp)) == NULL) {
(filename = __...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
657 error("basename %s: %s", tmp, strerror(errno));-
658 free(tmp);-
659 err = -1;-
660 goto out;
never executed: goto out;
0
661 }-
662-
663 if (g.gl_matchc == 1 && dst) {
g.gl_matchc == 1Description
TRUEnever evaluated
FALSEnever evaluated
dstDescription
TRUEnever evaluated
FALSEnever evaluated
0
664 if (is_dir(dst)) {
is_dir(dst)Description
TRUEnever evaluated
FALSEnever evaluated
0
665 abs_dst = path_append(dst, filename);-
666 } else {
never executed: end of block
0
667 abs_dst = xstrdup(dst);-
668 }
never executed: end of block
0
669 } else if (dst) {
dstDescription
TRUEnever evaluated
FALSEnever evaluated
0
670 abs_dst = path_append(dst, filename);-
671 } else {
never executed: end of block
0
672 abs_dst = xstrdup(filename);-
673 }
never executed: end of block
0
674 free(tmp);-
675-
676 resume |= global_aflag;-
677 if (!quiet && resume)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
resumeDescription
TRUEnever evaluated
FALSEnever evaluated
0
678 mprintf("Resuming %s to %s\n",
never executed: mprintf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
0
679 g.gl_pathv[i], abs_dst);
never executed: mprintf("Resuming %s to %s\n", g.gl_pathv[i], abs_dst);
0
680 else if (!quiet && !resume)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
!resumeDescription
TRUEnever evaluated
FALSEnever evaluated
0
681 mprintf("Fetching %s to %s\n",
never executed: mprintf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
0
682 g.gl_pathv[i], abs_dst);
never executed: mprintf("Fetching %s to %s\n", g.gl_pathv[i], abs_dst);
0
683 if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
pathname_is_dir(g.gl_pathv[i])Description
TRUEnever evaluated
FALSEnever evaluated
rflagDescription
TRUEnever evaluated
FALSEnever evaluated
global_rflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
684 if (download_dir(conn, g.gl_pathv[i], abs_dst, NULL,
download_dir(c...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
685 pflag || global_pflag, 1, resume,
download_dir(c...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
686 fflag || global_fflag) == -1)
download_dir(c...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
687 err = -1;
never executed: err = -1;
0
688 } else {
never executed: end of block
0
689 if (do_download(conn, g.gl_pathv[i], abs_dst, NULL,
do_download(co...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
690 pflag || global_pflag, resume,
do_download(co...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
691 fflag || global_fflag) == -1)
do_download(co...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
692 err = -1;
never executed: err = -1;
0
693 }
never executed: end of block
0
694 free(abs_dst);-
695 abs_dst = NULL;-
696 }
never executed: end of block
0
697-
698out:
code before this statement never executed: out:
0
699 free(abs_src);-
700 globfree(&g);-
701 return(err);
never executed: return(err);
0
702}-
703-
704static int-
705process_put(struct sftp_conn *conn, const char *src, const char *dst,-
706 const char *pwd, int pflag, int rflag, int resume, int fflag)-
707{-
708 char *tmp_dst = NULL;-
709 char *abs_dst = NULL;-
710 char *tmp = NULL, *filename = NULL;-
711 glob_t g;-
712 int err = 0;-
713 int i, dst_is_dir = 1;-
714 struct stat sb;-
715-
716 if (dst) {
dstDescription
TRUEnever evaluated
FALSEnever evaluated
0
717 tmp_dst = xstrdup(dst);-
718 tmp_dst = make_absolute(tmp_dst, pwd);-
719 }
never executed: end of block
0
720-
721 memset(&g, 0, sizeof(g));-
722 debug3("Looking up %s", src);-
723 if (glob(src, GLOB_NOCHECK | GLOB_MARK, NULL, &g)) {
_ssh__compat_g...oid *)0) , &g)Description
TRUEnever evaluated
FALSEnever evaluated
0
724 error("File \"%s\" not found.", src);-
725 err = -1;-
726 goto out;
never executed: goto out;
0
727 }-
728-
729 /* If we aren't fetching to pwd then stash this status for later */-
730 if (tmp_dst != NULL)
tmp_dst != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
731 dst_is_dir = remote_is_dir(conn, tmp_dst);
never executed: dst_is_dir = remote_is_dir(conn, tmp_dst);
0
732-
733 /* If multiple matches, dst may be directory or unspecified */-
734 if (g.gl_matchc > 1 && tmp_dst && !dst_is_dir) {
g.gl_matchc > 1Description
TRUEnever evaluated
FALSEnever evaluated
tmp_dstDescription
TRUEnever evaluated
FALSEnever evaluated
!dst_is_dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
735 error("Multiple paths match, but destination "-
736 "\"%s\" is not a directory", tmp_dst);-
737 err = -1;-
738 goto out;
never executed: goto out;
0
739 }-
740-
741 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
742 if (stat(g.gl_pathv[i], &sb) == -1) {
stat(g.gl_pathv[i], &sb) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
743 err = -1;-
744 error("stat %s: %s", g.gl_pathv[i], strerror(errno));-
745 continue;
never executed: continue;
0
746 }-
747-
748 tmp = xstrdup(g.gl_pathv[i]);-
749 if ((filename = basename(tmp)) == NULL) {
(filename = __...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
750 error("basename %s: %s", tmp, strerror(errno));-
751 free(tmp);-
752 err = -1;-
753 goto out;
never executed: goto out;
0
754 }-
755-
756 if (g.gl_matchc == 1 && tmp_dst) {
g.gl_matchc == 1Description
TRUEnever evaluated
FALSEnever evaluated
tmp_dstDescription
TRUEnever evaluated
FALSEnever evaluated
0
757 /* If directory specified, append filename */-
758 if (dst_is_dir)
dst_is_dirDescription
TRUEnever evaluated
FALSEnever evaluated
0
759 abs_dst = path_append(tmp_dst, filename);
never executed: abs_dst = path_append(tmp_dst, filename);
0
760 else-
761 abs_dst = xstrdup(tmp_dst);
never executed: abs_dst = xstrdup(tmp_dst);
0
762 } else if (tmp_dst) {
tmp_dstDescription
TRUEnever evaluated
FALSEnever evaluated
0
763 abs_dst = path_append(tmp_dst, filename);-
764 } else {
never executed: end of block
0
765 abs_dst = make_absolute(xstrdup(filename), pwd);-
766 }
never executed: end of block
0
767 free(tmp);-
768-
769 resume |= global_aflag;-
770 if (!quiet && resume)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
resumeDescription
TRUEnever evaluated
FALSEnever evaluated
0
771 mprintf("Resuming upload of %s to %s\n",
never executed: mprintf("Resuming upload of %s to %s\n", g.gl_pathv[i], abs_dst);
0
772 g.gl_pathv[i], abs_dst);
never executed: mprintf("Resuming upload of %s to %s\n", g.gl_pathv[i], abs_dst);
0
773 else if (!quiet && !resume)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
!resumeDescription
TRUEnever evaluated
FALSEnever evaluated
0
774 mprintf("Uploading %s to %s\n",
never executed: mprintf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
0
775 g.gl_pathv[i], abs_dst);
never executed: mprintf("Uploading %s to %s\n", g.gl_pathv[i], abs_dst);
0
776 if (pathname_is_dir(g.gl_pathv[i]) && (rflag || global_rflag)) {
pathname_is_dir(g.gl_pathv[i])Description
TRUEnever evaluated
FALSEnever evaluated
rflagDescription
TRUEnever evaluated
FALSEnever evaluated
global_rflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
777 if (upload_dir(conn, g.gl_pathv[i], abs_dst,
upload_dir(con...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
778 pflag || global_pflag, 1, resume,
upload_dir(con...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
779 fflag || global_fflag) == -1)
upload_dir(con...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
780 err = -1;
never executed: err = -1;
0
781 } else {
never executed: end of block
0
782 if (do_upload(conn, g.gl_pathv[i], abs_dst,
do_upload(conn...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
783 pflag || global_pflag, resume,
do_upload(conn...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
784 fflag || global_fflag) == -1)
do_upload(conn...l_fflag) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
785 err = -1;
never executed: err = -1;
0
786 }
never executed: end of block
0
787 }-
788-
789out:
code before this statement never executed: out:
0
790 free(abs_dst);-
791 free(tmp_dst);-
792 globfree(&g);-
793 return(err);
never executed: return(err);
0
794}-
795-
796static int-
797sdirent_comp(const void *aa, const void *bb)-
798{-
799 SFTP_DIRENT *a = *(SFTP_DIRENT **)aa;-
800 SFTP_DIRENT *b = *(SFTP_DIRENT **)bb;-
801 int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
sort_flag & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
802-
803#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))-
804 if (sort_flag & LS_NAME_SORT)
sort_flag & 0x0008Description
TRUEnever evaluated
FALSEnever evaluated
0
805 return (rmul * strcmp(a->filename, b->filename));
never executed: return (rmul * __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( a->filename ) && __builtin_constant_p ( b->filename ) && (__s1_len = __builtin_strlen ( a->filename ), __s2_len = __builtin_strlen ( b->filename ), (!((size_t)(const void *...ned char *) (const char *) ( b->filename ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( b->filename ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( a->filename , b->filename )))); }) );
never executed: __result = (((const unsigned char *) (const char *) ( a->filename ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( b->filename ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
806 else if (sort_flag & LS_TIME_SORT)
sort_flag & 0x0010Description
TRUEnever evaluated
FALSEnever evaluated
0
807 return (rmul * NCMP(a->a.mtime, b->a.mtime));
never executed: return (rmul * (a->a.mtime == b->a.mtime ? 0 : (a->a.mtime < b->a.mtime ? 1 : -1)));
0
808 else if (sort_flag & LS_SIZE_SORT)
sort_flag & 0x0020Description
TRUEnever evaluated
FALSEnever evaluated
0
809 return (rmul * NCMP(a->a.size, b->a.size));
never executed: return (rmul * (a->a.size == b->a.size ? 0 : (a->a.size < b->a.size ? 1 : -1)));
0
810-
811 fatal("Unknown ls sort type");-
812}
never executed: end of block
0
813-
814/* sftp ls.1 replacement for directories */-
815static int-
816do_ls_dir(struct sftp_conn *conn, const char *path,-
817 const char *strip_path, int lflag)-
818{-
819 int n;-
820 u_int c = 1, colspace = 0, columns = 1;-
821 SFTP_DIRENT **d;-
822-
823 if ((n = do_readdir(conn, path, &d)) != 0)
(n = do_readdi...ath, &d)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
824 return (n);
never executed: return (n);
0
825-
826 if (!(lflag & LS_SHORT_VIEW)) {
!(lflag & 0x0002)Description
TRUEnever evaluated
FALSEnever evaluated
0
827 u_int m = 0, width = 80;-
828 struct winsize ws;-
829 char *tmp;-
830-
831 /* Count entries for sort and find longest filename */-
832 for (n = 0; d[n] != NULL; n++) {
d[n] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
833 if (d[n]->filename[0] != '.' || (lflag & LS_SHOW_ALL))
d[n]->filename[0] != '.'Description
TRUEnever evaluated
FALSEnever evaluated
(lflag & 0x0080)Description
TRUEnever evaluated
FALSEnever evaluated
0
834 m = MAXIMUM(m, strlen(d[n]->filename));
never executed: m = (((m) > (strlen(d[n]->filename))) ? (m) : (strlen(d[n]->filename)));
((m) > (strlen...]->filename)))Description
TRUEnever evaluated
FALSEnever evaluated
0
835 }
never executed: end of block
0
836-
837 /* Add any subpath that also needs to be counted */-
838 tmp = path_strip(path, strip_path);-
839 m += strlen(tmp);-
840 free(tmp);-
841-
842 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
ioctl(fileno( ...3 , &ws) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
843 width = ws.ws_col;
never executed: width = ws.ws_col;
0
844-
845 columns = width / (m + 2);-
846 columns = MAXIMUM(columns, 1);
((columns) > (1))Description
TRUEnever evaluated
FALSEnever evaluated
0
847 colspace = width / columns;-
848 colspace = MINIMUM(colspace, width);
((colspace) < (width))Description
TRUEnever evaluated
FALSEnever evaluated
0
849 }
never executed: end of block
0
850-
851 if (lflag & SORT_FLAGS) {
lflag & (0x0008|0x0010|0x0020)Description
TRUEnever evaluated
FALSEnever evaluated
0
852 for (n = 0; d[n] != NULL; n++)
d[n] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
853 ; /* count entries */
never executed: ;
0
854 sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);-
855 qsort(d, n, sizeof(*d), sdirent_comp);-
856 }
never executed: end of block
0
857-
858 for (n = 0; d[n] != NULL && !interrupted; n++) {
d[n] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
859 char *tmp, *fname;-
860-
861 if (d[n]->filename[0] == '.' && !(lflag & LS_SHOW_ALL))
d[n]->filename[0] == '.'Description
TRUEnever evaluated
FALSEnever evaluated
!(lflag & 0x0080)Description
TRUEnever evaluated
FALSEnever evaluated
0
862 continue;
never executed: continue;
0
863-
864 tmp = path_append(path, d[n]->filename);-
865 fname = path_strip(tmp, strip_path);-
866 free(tmp);-
867-
868 if (lflag & LS_LONG_VIEW) {
lflag & 0x0001Description
TRUEnever evaluated
FALSEnever evaluated
0
869 if (lflag & (LS_NUMERIC_VIEW|LS_SI_UNITS)) {
lflag & (0x0004|0x0100)Description
TRUEnever evaluated
FALSEnever evaluated
0
870 char *lname;-
871 struct stat sb;-
872-
873 memset(&sb, 0, sizeof(sb));-
874 attrib_to_stat(&d[n]->a, &sb);-
875 lname = ls_file(fname, &sb, 1,-
876 (lflag & LS_SI_UNITS));-
877 mprintf("%s\n", lname);-
878 free(lname);-
879 } else
never executed: end of block
0
880 mprintf("%s\n", d[n]->longname);
never executed: mprintf("%s\n", d[n]->longname);
0
881 } else {-
882 mprintf("%-*s", colspace, fname);-
883 if (c >= columns) {
c >= columnsDescription
TRUEnever evaluated
FALSEnever evaluated
0
884 printf("\n");-
885 c = 1;-
886 } else
never executed: end of block
0
887 c++;
never executed: c++;
0
888 }-
889-
890 free(fname);-
891 }
never executed: end of block
0
892-
893 if (!(lflag & LS_LONG_VIEW) && (c != 1))
!(lflag & 0x0001)Description
TRUEnever evaluated
FALSEnever evaluated
(c != 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
894 printf("\n");
never executed: printf("\n");
0
895-
896 free_sftp_dirents(d);-
897 return (0);
never executed: return (0);
0
898}-
899-
900static int-
901sglob_comp(const void *aa, const void *bb)-
902{-
903 u_int a = *(const u_int *)aa;-
904 u_int b = *(const u_int *)bb;-
905 const char *ap = sort_glob->gl_pathv[a];-
906 const char *bp = sort_glob->gl_pathv[b];-
907 const struct stat *as = sort_glob->gl_statv[a];-
908 const struct stat *bs = sort_glob->gl_statv[b];-
909 int rmul = sort_flag & LS_REVERSE_SORT ? -1 : 1;
sort_flag & 0x0040Description
TRUEnever evaluated
FALSEnever evaluated
0
910-
911#define NCMP(a,b) (a == b ? 0 : (a < b ? 1 : -1))-
912 if (sort_flag & LS_NAME_SORT)
sort_flag & 0x0008Description
TRUEnever evaluated
FALSEnever evaluated
0
913 return (rmul * strcmp(ap, bp));
never executed: return (rmul * __extension__ ({ size_t __s1_len, __s2_len; (__builtin_constant_p ( ap ) && __builtin_constant_p ( bp ) && (__s1_len = __builtin_strlen ( ap ), __s2_len = __builtin_strlen ( bp ), (!((size_t)(const void *)(( ap ) + 1) - (size_t)(const void ...lt == 0) { __result = (((const unsigned char *) (const char *) ( bp ))[2] - __s2[2]); if (__s2_len > 2 && __result == 0) __result = (((const unsigned char *) (const char *) ( bp ))[3] - __s2[3]); } } __result; }))) : __builtin_strcmp ( ap , bp )))); }) );
never executed: __result = (((const unsigned char *) (const char *) ( ap ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( bp ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
914 else if (sort_flag & LS_TIME_SORT) {
sort_flag & 0x0010Description
TRUEnever evaluated
FALSEnever evaluated
0
915#if defined(HAVE_STRUCT_STAT_ST_MTIM)-
916 return (rmul * timespeccmp(&as->st_mtim, &bs->st_mtim, <));
never executed: return (rmul * (((&as->st_mtim)->tv_sec == (&bs->st_mtim)->tv_sec) ? ((&as->st_mtim)->tv_nsec < (&bs->st_mtim)->tv_nsec) : ((&as->st_mtim)->tv_sec < (&bs->st_mtim)->tv_sec)));
0
917#elif defined(HAVE_STRUCT_STAT_ST_MTIME)-
918 return (rmul * NCMP(as->st_mtime, bs->st_mtime));-
919#else-
920 return rmul * 1;-
921#endif-
922 } else if (sort_flag & LS_SIZE_SORT)
sort_flag & 0x0020Description
TRUEnever evaluated
FALSEnever evaluated
0
923 return (rmul * NCMP(as->st_size, bs->st_size));
never executed: return (rmul * (as->st_size == bs->st_size ? 0 : (as->st_size < bs->st_size ? 1 : -1)));
0
924-
925 fatal("Unknown ls sort type");-
926}
never executed: end of block
0
927-
928/* sftp ls.1 replacement which handles path globs */-
929static int-
930do_globbed_ls(struct sftp_conn *conn, const char *path,-
931 const char *strip_path, int lflag)-
932{-
933 char *fname, *lname;-
934 glob_t g;-
935 int err, r;-
936 struct winsize ws;-
937 u_int i, j, nentries, *indices = NULL, c = 1;-
938 u_int colspace = 0, columns = 1, m = 0, width = 80;-
939-
940 memset(&g, 0, sizeof(g));-
941-
942 if ((r = remote_glob(conn, path,
(r = remote_gl...0) , &g)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
943 GLOB_MARK|GLOB_NOCHECK|GLOB_BRACE|GLOB_KEEPSTAT|GLOB_NOSORT,
(r = remote_gl...0) , &g)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
944 NULL, &g)) != 0 ||
(r = remote_gl...0) , &g)) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
945 (g.gl_pathc && !g.gl_matchc)) {
g.gl_pathcDescription
TRUEnever evaluated
FALSEnever evaluated
!g.gl_matchcDescription
TRUEnever evaluated
FALSEnever evaluated
0
946 if (g.gl_pathc)
g.gl_pathcDescription
TRUEnever evaluated
FALSEnever evaluated
0
947 globfree(&g);
never executed: _ssh__compat_globfree(&g);
0
948 if (r == GLOB_NOSPACE) {
r == (-1)Description
TRUEnever evaluated
FALSEnever evaluated
0
949 error("Can't ls: Too many matches for \"%s\"", path);-
950 } else {
never executed: end of block
0
951 error("Can't ls: \"%s\" not found", path);-
952 }
never executed: end of block
0
953 return -1;
never executed: return -1;
0
954 }-
955-
956 if (interrupted)
interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
957 goto out;
never executed: goto out;
0
958-
959 /*-
960 * If the glob returns a single match and it is a directory,-
961 * then just list its contents.-
962 */-
963 if (g.gl_matchc == 1 && g.gl_statv[0] != NULL &&
g.gl_matchc == 1Description
TRUEnever evaluated
FALSEnever evaluated
g.gl_statv[0] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
964 S_ISDIR(g.gl_statv[0]->st_mode)) {
(((( g.gl_stat... == (0040000))Description
TRUEnever evaluated
FALSEnever evaluated
0
965 err = do_ls_dir(conn, g.gl_pathv[0], strip_path, lflag);-
966 globfree(&g);-
967 return err;
never executed: return err;
0
968 }-
969-
970 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)
ioctl(fileno( ...3 , &ws) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
971 width = ws.ws_col;
never executed: width = ws.ws_col;
0
972-
973 if (!(lflag & LS_SHORT_VIEW)) {
!(lflag & 0x0002)Description
TRUEnever evaluated
FALSEnever evaluated
0
974 /* Count entries for sort and find longest filename */-
975 for (i = 0; g.gl_pathv[i]; i++)
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
0
976 m = MAXIMUM(m, strlen(g.gl_pathv[i]));
never executed: m = (((m) > (strlen(g.gl_pathv[i]))) ? (m) : (strlen(g.gl_pathv[i])));
((m) > (strlen...gl_pathv[i])))Description
TRUEnever evaluated
FALSEnever evaluated
0
977-
978 columns = width / (m + 2);-
979 columns = MAXIMUM(columns, 1);
((columns) > (1))Description
TRUEnever evaluated
FALSEnever evaluated
0
980 colspace = width / columns;-
981 }
never executed: end of block
0
982-
983 /*-
984 * Sorting: rather than mess with the contents of glob_t, prepare-
985 * an array of indices into it and sort that. For the usual-
986 * unsorted case, the indices are just the identity 1=1, 2=2, etc.-
987 */-
988 for (nentries = 0; g.gl_pathv[nentries] != NULL; nentries++)
g.gl_pathv[nen...!= ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
989 ; /* count entries */
never executed: ;
0
990 indices = calloc(nentries, sizeof(*indices));-
991 for (i = 0; i < nentries; i++)
i < nentriesDescription
TRUEnever evaluated
FALSEnever evaluated
0
992 indices[i] = i;
never executed: indices[i] = i;
0
993-
994 if (lflag & SORT_FLAGS) {
lflag & (0x0008|0x0010|0x0020)Description
TRUEnever evaluated
FALSEnever evaluated
0
995 sort_glob = &g;-
996 sort_flag = lflag & (SORT_FLAGS|LS_REVERSE_SORT);-
997 qsort(indices, nentries, sizeof(*indices), sglob_comp);-
998 sort_glob = NULL;-
999 }
never executed: end of block
0
1000-
1001 for (j = 0; j < nentries && !interrupted; j++) {
j < nentriesDescription
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1002 i = indices[j];-
1003 fname = path_strip(g.gl_pathv[i], strip_path);-
1004 if (lflag & LS_LONG_VIEW) {
lflag & 0x0001Description
TRUEnever evaluated
FALSEnever evaluated
0
1005 if (g.gl_statv[i] == NULL) {
g.gl_statv[i] == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1006 error("no stat information for %s", fname);-
1007 continue;
never executed: continue;
0
1008 }-
1009 lname = ls_file(fname, g.gl_statv[i], 1,-
1010 (lflag & LS_SI_UNITS));-
1011 mprintf("%s\n", lname);-
1012 free(lname);-
1013 } else {
never executed: end of block
0
1014 mprintf("%-*s", colspace, fname);-
1015 if (c >= columns) {
c >= columnsDescription
TRUEnever evaluated
FALSEnever evaluated
0
1016 printf("\n");-
1017 c = 1;-
1018 } else
never executed: end of block
0
1019 c++;
never executed: c++;
0
1020 }-
1021 free(fname);-
1022 }
never executed: end of block
0
1023-
1024 if (!(lflag & LS_LONG_VIEW) && (c != 1))
!(lflag & 0x0001)Description
TRUEnever evaluated
FALSEnever evaluated
(c != 1)Description
TRUEnever evaluated
FALSEnever evaluated
0
1025 printf("\n");
never executed: printf("\n");
0
1026-
1027 out:
code before this statement never executed: out:
0
1028 if (g.gl_pathc)
g.gl_pathcDescription
TRUEnever evaluated
FALSEnever evaluated
0
1029 globfree(&g);
never executed: _ssh__compat_globfree(&g);
0
1030 free(indices);-
1031-
1032 return 0;
never executed: return 0;
0
1033}-
1034-
1035static int-
1036do_df(struct sftp_conn *conn, const char *path, int hflag, int iflag)-
1037{-
1038 struct sftp_statvfs st;-
1039 char s_used[FMT_SCALED_STRSIZE], s_avail[FMT_SCALED_STRSIZE];-
1040 char s_root[FMT_SCALED_STRSIZE], s_total[FMT_SCALED_STRSIZE];-
1041 char s_icapacity[16], s_dcapacity[16];-
1042-
1043 if (do_statvfs(conn, path, &st, 1) == -1)
do_statvfs(con... &st, 1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1044 return -1;
never executed: return -1;
0
1045 if (st.f_files == 0)
st.f_files == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1046 strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
never executed: strlcpy(s_icapacity, "ERR", sizeof(s_icapacity));
0
1047 else {-
1048 snprintf(s_icapacity, sizeof(s_icapacity), "%3llu%%",-
1049 (unsigned long long)(100 * (st.f_files - st.f_ffree) /-
1050 st.f_files));-
1051 }
never executed: end of block
0
1052 if (st.f_blocks == 0)
st.f_blocks == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1053 strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity));
never executed: strlcpy(s_dcapacity, "ERR", sizeof(s_dcapacity));
0
1054 else {-
1055 snprintf(s_dcapacity, sizeof(s_dcapacity), "%3llu%%",-
1056 (unsigned long long)(100 * (st.f_blocks - st.f_bfree) /-
1057 st.f_blocks));-
1058 }
never executed: end of block
0
1059 if (iflag) {
iflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1060 printf(" Inodes Used Avail "-
1061 "(root) %%Capacity\n");-
1062 printf("%11llu %11llu %11llu %11llu %s\n",-
1063 (unsigned long long)st.f_files,-
1064 (unsigned long long)(st.f_files - st.f_ffree),-
1065 (unsigned long long)st.f_favail,-
1066 (unsigned long long)st.f_ffree, s_icapacity);-
1067 } else if (hflag) {
never executed: end of block
hflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1068 strlcpy(s_used, "error", sizeof(s_used));-
1069 strlcpy(s_avail, "error", sizeof(s_avail));-
1070 strlcpy(s_root, "error", sizeof(s_root));-
1071 strlcpy(s_total, "error", sizeof(s_total));-
1072 fmt_scaled((st.f_blocks - st.f_bfree) * st.f_frsize, s_used);-
1073 fmt_scaled(st.f_bavail * st.f_frsize, s_avail);-
1074 fmt_scaled(st.f_bfree * st.f_frsize, s_root);-
1075 fmt_scaled(st.f_blocks * st.f_frsize, s_total);-
1076 printf(" Size Used Avail (root) %%Capacity\n");-
1077 printf("%7sB %7sB %7sB %7sB %s\n",-
1078 s_total, s_used, s_avail, s_root, s_dcapacity);-
1079 } else {
never executed: end of block
0
1080 printf(" Size Used Avail "-
1081 "(root) %%Capacity\n");-
1082 printf("%12llu %12llu %12llu %12llu %s\n",-
1083 (unsigned long long)(st.f_frsize * st.f_blocks / 1024),-
1084 (unsigned long long)(st.f_frsize *-
1085 (st.f_blocks - st.f_bfree) / 1024),-
1086 (unsigned long long)(st.f_frsize * st.f_bavail / 1024),-
1087 (unsigned long long)(st.f_frsize * st.f_bfree / 1024),-
1088 s_dcapacity);-
1089 }
never executed: end of block
0
1090 return 0;
never executed: return 0;
0
1091}-
1092-
1093/*-
1094 * Undo escaping of glob sequences in place. Used to undo extra escaping-
1095 * applied in makeargv() when the string is destined for a function that-
1096 * does not glob it.-
1097 */-
1098static void-
1099undo_glob_escape(char *s)-
1100{-
1101 size_t i, j;-
1102-
1103 for (i = j = 0;;) {-
1104 if (s[i] == '\0') {
s[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1105 s[j] = '\0';-
1106 return;
never executed: return;
0
1107 }-
1108 if (s[i] != '\\') {
s[i] != '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1109 s[j++] = s[i++];-
1110 continue;
never executed: continue;
0
1111 }-
1112 /* s[i] == '\\' */-
1113 ++i;-
1114 switch (s[i]) {-
1115 case '?':
never executed: case '?':
0
1116 case '[':
never executed: case '[':
0
1117 case '*':
never executed: case '*':
0
1118 case '\\':
never executed: case '\\':
0
1119 s[j++] = s[i++];-
1120 break;
never executed: break;
0
1121 case '\0':
never executed: case '\0':
0
1122 s[j++] = '\\';-
1123 s[j] = '\0';-
1124 return;
never executed: return;
0
1125 default:
never executed: default:
0
1126 s[j++] = '\\';-
1127 s[j++] = s[i++];-
1128 break;
never executed: break;
0
1129 }-
1130 }-
1131}
never executed: end of block
0
1132-
1133/*-
1134 * Split a string into an argument vector using sh(1)-style quoting,-
1135 * comment and escaping rules, but with some tweaks to handle glob(3)-
1136 * wildcards.-
1137 * The "sloppy" flag allows for recovery from missing terminating quote, for-
1138 * use in parsing incomplete commandlines during tab autocompletion.-
1139 *-
1140 * Returns NULL on error or a NULL-terminated array of arguments.-
1141 *-
1142 * If "lastquote" is not NULL, the quoting character used for the last-
1143 * argument is placed in *lastquote ("\0", "'" or "\"").-
1144 *-
1145 * If "terminated" is not NULL, *terminated will be set to 1 when the-
1146 * last argument's quote has been properly terminated or 0 otherwise.-
1147 * This parameter is only of use if "sloppy" is set.-
1148 */-
1149#define MAXARGS 128-
1150#define MAXARGLEN 8192-
1151static char **-
1152makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,-
1153 u_int *terminated)-
1154{-
1155 int argc, quot;-
1156 size_t i, j;-
1157 static char argvs[MAXARGLEN];-
1158 static char *argv[MAXARGS + 1];-
1159 enum { MA_START, MA_SQUOTE, MA_DQUOTE, MA_UNQUOTED } state, q;-
1160-
1161 *argcp = argc = 0;-
1162 if (strlen(arg) > sizeof(argvs) - 1) {
strlen(arg) > ...eof(argvs) - 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1163 args_too_longs:-
1164 error("string too long");-
1165 return NULL;
never executed: return ((void *)0) ;
0
1166 }-
1167 if (terminated != NULL)
terminated != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1168 *terminated = 1;
never executed: *terminated = 1;
0
1169 if (lastquote != NULL)
lastquote != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1170 *lastquote = '\0';
never executed: *lastquote = '\0';
0
1171 state = MA_START;-
1172 i = j = 0;-
1173 for (;;) {-
1174 if ((size_t)argc >= sizeof(argv) / sizeof(*argv)){
(size_t)argc >... sizeof(*argv)Description
TRUEnever evaluated
FALSEnever evaluated
0
1175 error("Too many arguments.");-
1176 return NULL;
never executed: return ((void *)0) ;
0
1177 }-
1178 if (isspace((unsigned char)arg[i])) {
((*__ctype_b_l...int) _ISspace)Description
TRUEnever evaluated
FALSEnever evaluated
0
1179 if (state == MA_UNQUOTED) {
state == MA_UNQUOTEDDescription
TRUEnever evaluated
FALSEnever evaluated
0
1180 /* Terminate current argument */-
1181 argvs[j++] = '\0';-
1182 argc++;-
1183 state = MA_START;-
1184 } else if (state != MA_START)
never executed: end of block
state != MA_STARTDescription
TRUEnever evaluated
FALSEnever evaluated
0
1185 argvs[j++] = arg[i];
never executed: argvs[j++] = arg[i];
0
1186 } else if (arg[i] == '"' || arg[i] == '\'') {
never executed: end of block
arg[i] == '"'Description
TRUEnever evaluated
FALSEnever evaluated
arg[i] == '\''Description
TRUEnever evaluated
FALSEnever evaluated
0
1187 q = arg[i] == '"' ? MA_DQUOTE : MA_SQUOTE;
arg[i] == '"'Description
TRUEnever evaluated
FALSEnever evaluated
0
1188 if (state == MA_START) {
state == MA_STARTDescription
TRUEnever evaluated
FALSEnever evaluated
0
1189 argv[argc] = argvs + j;-
1190 state = q;-
1191 if (lastquote != NULL)
lastquote != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1192 *lastquote = arg[i];
never executed: *lastquote = arg[i];
0
1193 } else if (state == MA_UNQUOTED)
never executed: end of block
state == MA_UNQUOTEDDescription
TRUEnever evaluated
FALSEnever evaluated
0
1194 state = q;
never executed: state = q;
0
1195 else if (state == q)
state == qDescription
TRUEnever evaluated
FALSEnever evaluated
0
1196 state = MA_UNQUOTED;
never executed: state = MA_UNQUOTED;
0
1197 else-
1198 argvs[j++] = arg[i];
never executed: argvs[j++] = arg[i];
0
1199 } else if (arg[i] == '\\') {
arg[i] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1200 if (state == MA_SQUOTE || state == MA_DQUOTE) {
state == MA_SQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
state == MA_DQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
0
1201 quot = state == MA_SQUOTE ? '\'' : '"';
state == MA_SQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
0
1202 /* Unescape quote we are in */-
1203 /* XXX support \n and friends? */-
1204 if (arg[i + 1] == quot) {
arg[i + 1] == quotDescription
TRUEnever evaluated
FALSEnever evaluated
0
1205 i++;-
1206 argvs[j++] = arg[i];-
1207 } else if (arg[i + 1] == '?' ||
never executed: end of block
arg[i + 1] == '?'Description
TRUEnever evaluated
FALSEnever evaluated
0
1208 arg[i + 1] == '[' || arg[i + 1] == '*') {
arg[i + 1] == '['Description
TRUEnever evaluated
FALSEnever evaluated
arg[i + 1] == '*'Description
TRUEnever evaluated
FALSEnever evaluated
0
1209 /*-
1210 * Special case for sftp: append-
1211 * double-escaped glob sequence --
1212 * glob will undo one level of-
1213 * escaping. NB. string can grow here.-
1214 */-
1215 if (j >= sizeof(argvs) - 5)
j >= sizeof(argvs) - 5Description
TRUEnever evaluated
FALSEnever evaluated
0
1216 goto args_too_longs;
never executed: goto args_too_longs;
0
1217 argvs[j++] = '\\';-
1218 argvs[j++] = arg[i++];-
1219 argvs[j++] = '\\';-
1220 argvs[j++] = arg[i];-
1221 } else {
never executed: end of block
0
1222 argvs[j++] = arg[i++];-
1223 argvs[j++] = arg[i];-
1224 }
never executed: end of block
0
1225 } else {-
1226 if (state == MA_START) {
state == MA_STARTDescription
TRUEnever evaluated
FALSEnever evaluated
0
1227 argv[argc] = argvs + j;-
1228 state = MA_UNQUOTED;-
1229 if (lastquote != NULL)
lastquote != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1230 *lastquote = '\0';
never executed: *lastquote = '\0';
0
1231 }
never executed: end of block
0
1232 if (arg[i + 1] == '?' || arg[i + 1] == '[' ||
arg[i + 1] == '?'Description
TRUEnever evaluated
FALSEnever evaluated
arg[i + 1] == '['Description
TRUEnever evaluated
FALSEnever evaluated
0
1233 arg[i + 1] == '*' || arg[i + 1] == '\\') {
arg[i + 1] == '*'Description
TRUEnever evaluated
FALSEnever evaluated
arg[i + 1] == '\\'Description
TRUEnever evaluated
FALSEnever evaluated
0
1234 /*-
1235 * Special case for sftp: append-
1236 * escaped glob sequence --
1237 * glob will undo one level of-
1238 * escaping.-
1239 */-
1240 argvs[j++] = arg[i++];-
1241 argvs[j++] = arg[i];-
1242 } else {
never executed: end of block
0
1243 /* Unescape everything */-
1244 /* XXX support \n and friends? */-
1245 i++;-
1246 argvs[j++] = arg[i];-
1247 }
never executed: end of block
0
1248 }-
1249 } else if (arg[i] == '#') {
arg[i] == '#'Description
TRUEnever evaluated
FALSEnever evaluated
0
1250 if (state == MA_SQUOTE || state == MA_DQUOTE)
state == MA_SQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
state == MA_DQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
0
1251 argvs[j++] = arg[i];
never executed: argvs[j++] = arg[i];
0
1252 else-
1253 goto string_done;
never executed: goto string_done;
0
1254 } else if (arg[i] == '\0') {
arg[i] == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1255 if (state == MA_SQUOTE || state == MA_DQUOTE) {
state == MA_SQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
state == MA_DQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
0
1256 if (sloppy) {
sloppyDescription
TRUEnever evaluated
FALSEnever evaluated
0
1257 state = MA_UNQUOTED;-
1258 if (terminated != NULL)
terminated != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1259 *terminated = 0;
never executed: *terminated = 0;
0
1260 goto string_done;
never executed: goto string_done;
0
1261 }-
1262 error("Unterminated quoted argument");-
1263 return NULL;
never executed: return ((void *)0) ;
0
1264 }-
1265 string_done:
code before this statement never executed: string_done:
0
1266 if (state == MA_UNQUOTED) {
state == MA_UNQUOTEDDescription
TRUEnever evaluated
FALSEnever evaluated
0
1267 argvs[j++] = '\0';-
1268 argc++;-
1269 }
never executed: end of block
0
1270 break;
never executed: break;
0
1271 } else {-
1272 if (state == MA_START) {
state == MA_STARTDescription
TRUEnever evaluated
FALSEnever evaluated
0
1273 argv[argc] = argvs + j;-
1274 state = MA_UNQUOTED;-
1275 if (lastquote != NULL)
lastquote != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1276 *lastquote = '\0';
never executed: *lastquote = '\0';
0
1277 }
never executed: end of block
0
1278 if ((state == MA_SQUOTE || state == MA_DQUOTE) &&
state == MA_SQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
state == MA_DQUOTEDescription
TRUEnever evaluated
FALSEnever evaluated
0
1279 (arg[i] == '?' || arg[i] == '[' || arg[i] == '*')) {
arg[i] == '?'Description
TRUEnever evaluated
FALSEnever evaluated
arg[i] == '['Description
TRUEnever evaluated
FALSEnever evaluated
arg[i] == '*'Description
TRUEnever evaluated
FALSEnever evaluated
0
1280 /*-
1281 * Special case for sftp: escape quoted-
1282 * glob(3) wildcards. NB. string can grow-
1283 * here.-
1284 */-
1285 if (j >= sizeof(argvs) - 3)
j >= sizeof(argvs) - 3Description
TRUEnever evaluated
FALSEnever evaluated
0
1286 goto args_too_longs;
never executed: goto args_too_longs;
0
1287 argvs[j++] = '\\';-
1288 argvs[j++] = arg[i];-
1289 } else
never executed: end of block
0
1290 argvs[j++] = arg[i];
never executed: argvs[j++] = arg[i];
0
1291 }-
1292 i++;-
1293 }
never executed: end of block
0
1294 *argcp = argc;-
1295 return argv;
never executed: return argv;
0
1296}-
1297-
1298static int-
1299parse_args(const char **cpp, int *ignore_errors, int *aflag,-
1300 int *fflag, int *hflag, int *iflag, int *lflag, int *pflag,-
1301 int *rflag, int *sflag,-
1302 unsigned long *n_arg, char **path1, char **path2)-
1303{-
1304 const char *cmd, *cp = *cpp;-
1305 char *cp2, **argv;-
1306 int base = 0;-
1307 long l;-
1308 int path1_mandatory = 0, i, cmdnum, optidx, argc;-
1309-
1310 /* Skip leading whitespace */-
1311 cp = cp + strspn(cp, WHITESPACE);-
1312-
1313 /* Check for leading '-' (disable error processing) */-
1314 *ignore_errors = 0;-
1315 if (*cp == '-') {
*cp == '-'Description
TRUEnever evaluated
FALSEnever evaluated
0
1316 *ignore_errors = 1;-
1317 cp++;-
1318 cp = cp + strspn(cp, WHITESPACE);-
1319 }
never executed: end of block
0
1320-
1321 /* Ignore blank lines and lines which begin with comment '#' char */-
1322 if (*cp == '\0' || *cp == '#')
*cp == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
*cp == '#'Description
TRUEnever evaluated
FALSEnever evaluated
0
1323 return (0);
never executed: return (0);
0
1324-
1325 if ((argv = makeargv(cp, &argc, 0, NULL, NULL)) == NULL)
(argv = makear...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1326 return -1;
never executed: return -1;
0
1327-
1328 /* Figure out which command we have */-
1329 for (i = 0; cmds[i].c != NULL; i++) {
cmds[i].c != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1330 if (argv[0] != NULL && strcasecmp(cmds[i].c, argv[0]) == 0)
argv[0] != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
strcasecmp(cmd... argv[0]) == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1331 break;
never executed: break;
0
1332 }
never executed: end of block
0
1333 cmdnum = cmds[i].n;-
1334 cmd = cmds[i].c;-
1335-
1336 /* Special case */-
1337 if (*cp == '!') {
*cp == '!'Description
TRUEnever evaluated
FALSEnever evaluated
0
1338 cp++;-
1339 cmdnum = I_SHELL;-
1340 } else if (cmdnum == -1) {
never executed: end of block
cmdnum == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1341 error("Invalid command.");-
1342 return -1;
never executed: return -1;
0
1343 }-
1344-
1345 /* Get arguments and parse flags */-
1346 *aflag = *fflag = *hflag = *iflag = *lflag = *pflag = 0;-
1347 *rflag = *sflag = 0;-
1348 *path1 = *path2 = NULL;-
1349 optidx = 1;-
1350 switch (cmdnum) {-
1351 case I_GET:
never executed: case I_GET:
0
1352 case I_REGET:
never executed: case I_REGET:
0
1353 case I_REPUT:
never executed: case I_REPUT:
0
1354 case I_PUT:
never executed: case I_PUT:
0
1355 if ((optidx = parse_getput_flags(cmd, argv, argc,
(optidx = pars... rflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1356 aflag, fflag, pflag, rflag)) == -1)
(optidx = pars... rflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1357 return -1;
never executed: return -1;
0
1358 /* Get first pathname (mandatory) */-
1359 if (argc - optidx < 1) {
argc - optidx < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1360 error("You must specify at least one path after a "-
1361 "%s command.", cmd);-
1362 return -1;
never executed: return -1;
0
1363 }-
1364 *path1 = xstrdup(argv[optidx]);-
1365 /* Get second pathname (optional) */-
1366 if (argc - optidx > 1) {
argc - optidx > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1367 *path2 = xstrdup(argv[optidx + 1]);-
1368 /* Destination is not globbed */-
1369 undo_glob_escape(*path2);-
1370 }
never executed: end of block
0
1371 break;
never executed: break;
0
1372 case I_LINK:
never executed: case I_LINK:
0
1373 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
(optidx = pars... sflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1374 return -1;
never executed: return -1;
0
1375 goto parse_two_paths;
never executed: goto parse_two_paths;
0
1376 case I_RENAME:
never executed: case I_RENAME:
0
1377 if ((optidx = parse_rename_flags(cmd, argv, argc, lflag)) == -1)
(optidx = pars... lflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1378 return -1;
never executed: return -1;
0
1379 goto parse_two_paths;
never executed: goto parse_two_paths;
0
1380 case I_SYMLINK:
never executed: case I_SYMLINK:
0
1381 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
(optidx = pars..., argc)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1382 return -1;
never executed: return -1;
0
1383 parse_two_paths:
code before this statement never executed: parse_two_paths:
0
1384 if (argc - optidx < 2) {
argc - optidx < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1385 error("You must specify two paths after a %s "-
1386 "command.", cmd);-
1387 return -1;
never executed: return -1;
0
1388 }-
1389 *path1 = xstrdup(argv[optidx]);-
1390 *path2 = xstrdup(argv[optidx + 1]);-
1391 /* Paths are not globbed */-
1392 undo_glob_escape(*path1);-
1393 undo_glob_escape(*path2);-
1394 break;
never executed: break;
0
1395 case I_RM:
never executed: case I_RM:
0
1396 case I_MKDIR:
never executed: case I_MKDIR:
0
1397 case I_RMDIR:
never executed: case I_RMDIR:
0
1398 case I_LMKDIR:
never executed: case I_LMKDIR:
0
1399 path1_mandatory = 1;-
1400 /* FALLTHROUGH */-
1401 case I_CHDIR:
code before this statement never executed: case I_CHDIR:
never executed: case I_CHDIR:
0
1402 case I_LCHDIR:
never executed: case I_LCHDIR:
0
1403 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
(optidx = pars..., argc)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1404 return -1;
never executed: return -1;
0
1405 /* Get pathname (mandatory) */-
1406 if (argc - optidx < 1) {
argc - optidx < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1407 if (!path1_mandatory)
!path1_mandatoryDescription
TRUEnever evaluated
FALSEnever evaluated
0
1408 break; /* return a NULL path1 */
never executed: break;
0
1409 error("You must specify a path after a %s command.",-
1410 cmd);-
1411 return -1;
never executed: return -1;
0
1412 }-
1413 *path1 = xstrdup(argv[optidx]);-
1414 /* Only "rm" globs */-
1415 if (cmdnum != I_RM)
cmdnum != I_RMDescription
TRUEnever evaluated
FALSEnever evaluated
0
1416 undo_glob_escape(*path1);
never executed: undo_glob_escape(*path1);
0
1417 break;
never executed: break;
0
1418 case I_DF:
never executed: case I_DF:
0
1419 if ((optidx = parse_df_flags(cmd, argv, argc, hflag,
(optidx = pars... iflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1420 iflag)) == -1)
(optidx = pars... iflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1421 return -1;
never executed: return -1;
0
1422 /* Default to current directory if no path specified */-
1423 if (argc - optidx < 1)
argc - optidx < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1424 *path1 = NULL;
never executed: *path1 = ((void *)0) ;
0
1425 else {-
1426 *path1 = xstrdup(argv[optidx]);-
1427 undo_glob_escape(*path1);-
1428 }
never executed: end of block
0
1429 break;
never executed: break;
0
1430 case I_LS:
never executed: case I_LS:
0
1431 if ((optidx = parse_ls_flags(argv, argc, lflag)) == -1)
(optidx = pars... lflag)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1432 return(-1);
never executed: return(-1);
0
1433 /* Path is optional */-
1434 if (argc - optidx > 0)
argc - optidx > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1435 *path1 = xstrdup(argv[optidx]);
never executed: *path1 = xstrdup(argv[optidx]);
0
1436 break;
never executed: break;
0
1437 case I_LLS:
never executed: case I_LLS:
0
1438 /* Skip ls command and following whitespace */-
1439 cp = cp + strlen(cmd) + strspn(cp, WHITESPACE);-
1440 case I_SHELL:
code before this statement never executed: case I_SHELL:
never executed: case I_SHELL:
0
1441 /* Uses the rest of the line */-
1442 break;
never executed: break;
0
1443 case I_LUMASK:
never executed: case I_LUMASK:
0
1444 case I_CHMOD:
never executed: case I_CHMOD:
0
1445 base = 8;-
1446 /* FALLTHROUGH */-
1447 case I_CHOWN:
code before this statement never executed: case I_CHOWN:
never executed: case I_CHOWN:
0
1448 case I_CHGRP:
never executed: case I_CHGRP:
0
1449 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
(optidx = pars..., argc)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1450 return -1;
never executed: return -1;
0
1451 /* Get numeric arg (mandatory) */-
1452 if (argc - optidx < 1)
argc - optidx < 1Description
TRUEnever evaluated
FALSEnever evaluated
0
1453 goto need_num_arg;
never executed: goto need_num_arg;
0
1454 errno = 0;-
1455 l = strtol(argv[optidx], &cp2, base);-
1456 if (cp2 == argv[optidx] || *cp2 != '\0' ||
cp2 == argv[optidx]Description
TRUEnever evaluated
FALSEnever evaluated
*cp2 != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1457 ((l == LONG_MIN || l == LONG_MAX) && errno == ERANGE) ||
l == (-0x7ffff...fffffffL - 1L)Description
TRUEnever evaluated
FALSEnever evaluated
l == 0x7fffffffffffffffLDescription
TRUEnever evaluated
FALSEnever evaluated
(*__errno_location ()) == 34Description
TRUEnever evaluated
FALSEnever evaluated
0
1458 l < 0) {
l < 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1459 need_num_arg:-
1460 error("You must supply a numeric argument "-
1461 "to the %s command.", cmd);-
1462 return -1;
never executed: return -1;
0
1463 }-
1464 *n_arg = l;-
1465 if (cmdnum == I_LUMASK)
cmdnum == I_LUMASKDescription
TRUEnever evaluated
FALSEnever evaluated
0
1466 break;
never executed: break;
0
1467 /* Get pathname (mandatory) */-
1468 if (argc - optidx < 2) {
argc - optidx < 2Description
TRUEnever evaluated
FALSEnever evaluated
0
1469 error("You must specify a path after a %s command.",-
1470 cmd);-
1471 return -1;
never executed: return -1;
0
1472 }-
1473 *path1 = xstrdup(argv[optidx + 1]);-
1474 break;
never executed: break;
0
1475 case I_QUIT:
never executed: case I_QUIT:
0
1476 case I_PWD:
never executed: case I_PWD:
0
1477 case I_LPWD:
never executed: case I_LPWD:
0
1478 case I_HELP:
never executed: case I_HELP:
0
1479 case I_VERSION:
never executed: case I_VERSION:
0
1480 case I_PROGRESS:
never executed: case I_PROGRESS:
0
1481 if ((optidx = parse_no_flags(cmd, argv, argc)) == -1)
(optidx = pars..., argc)) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1482 return -1;
never executed: return -1;
0
1483 break;
never executed: break;
0
1484 default:
never executed: default:
0
1485 fatal("Command not implemented");-
1486 }
never executed: end of block
0
1487-
1488 *cpp = cp;-
1489 return(cmdnum);
never executed: return(cmdnum);
0
1490}-
1491-
1492static int-
1493parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,-
1494 const char *startdir, int err_abort)-
1495{-
1496 char *path1, *path2, *tmp;-
1497 int ignore_errors = 0, aflag = 0, fflag = 0, hflag = 0,-
1498 iflag = 0;-
1499 int lflag = 0, pflag = 0, rflag = 0, sflag = 0;-
1500 int cmdnum, i;-
1501 unsigned long n_arg = 0;-
1502 Attrib a, *aa;-
1503 char path_buf[PATH_MAX];-
1504 int err = 0;-
1505 glob_t g;-
1506-
1507 path1 = path2 = NULL;-
1508 cmdnum = parse_args(&cmd, &ignore_errors, &aflag, &fflag, &hflag,-
1509 &iflag, &lflag, &pflag, &rflag, &sflag, &n_arg, &path1, &path2);-
1510 if (ignore_errors != 0)
ignore_errors != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1511 err_abort = 0;
never executed: err_abort = 0;
0
1512-
1513 memset(&g, 0, sizeof(g));-
1514-
1515 /* Perform command */-
1516 switch (cmdnum) {-
1517 case 0:
never executed: case 0:
0
1518 /* Blank line */-
1519 break;
never executed: break;
0
1520 case -1:
never executed: case -1:
0
1521 /* Unrecognized command */-
1522 err = -1;-
1523 break;
never executed: break;
0
1524 case I_REGET:
never executed: case I_REGET:
0
1525 aflag = 1;-
1526 /* FALLTHROUGH */-
1527 case I_GET:
code before this statement never executed: case I_GET:
never executed: case I_GET:
0
1528 err = process_get(conn, path1, path2, *pwd, pflag,-
1529 rflag, aflag, fflag);-
1530 break;
never executed: break;
0
1531 case I_REPUT:
never executed: case I_REPUT:
0
1532 aflag = 1;-
1533 /* FALLTHROUGH */-
1534 case I_PUT:
code before this statement never executed: case I_PUT:
never executed: case I_PUT:
0
1535 err = process_put(conn, path1, path2, *pwd, pflag,-
1536 rflag, aflag, fflag);-
1537 break;
never executed: break;
0
1538 case I_RENAME:
never executed: case I_RENAME:
0
1539 path1 = make_absolute(path1, *pwd);-
1540 path2 = make_absolute(path2, *pwd);-
1541 err = do_rename(conn, path1, path2, lflag);-
1542 break;
never executed: break;
0
1543 case I_SYMLINK:
never executed: case I_SYMLINK:
0
1544 sflag = 1;-
1545 /* FALLTHROUGH */-
1546 case I_LINK:
code before this statement never executed: case I_LINK:
never executed: case I_LINK:
0
1547 if (!sflag)
!sflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1548 path1 = make_absolute(path1, *pwd);
never executed: path1 = make_absolute(path1, *pwd);
0
1549 path2 = make_absolute(path2, *pwd);-
1550 err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
sflagDescription
TRUEnever evaluated
FALSEnever evaluated
0
1551 break;
never executed: break;
0
1552 case I_RM:
never executed: case I_RM:
0
1553 path1 = make_absolute(path1, *pwd);-
1554 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);-
1555 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1556 if (!quiet)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
1557 mprintf("Removing %s\n", g.gl_pathv[i]);
never executed: mprintf("Removing %s\n", g.gl_pathv[i]);
0
1558 err = do_rm(conn, g.gl_pathv[i]);-
1559 if (err != 0 && err_abort)
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
0
1560 break;
never executed: break;
0
1561 }
never executed: end of block
0
1562 break;
never executed: break;
0
1563 case I_MKDIR:
never executed: case I_MKDIR:
0
1564 path1 = make_absolute(path1, *pwd);-
1565 attrib_clear(&a);-
1566 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;-
1567 a.perm = 0777;-
1568 err = do_mkdir(conn, path1, &a, 1);-
1569 break;
never executed: break;
0
1570 case I_RMDIR:
never executed: case I_RMDIR:
0
1571 path1 = make_absolute(path1, *pwd);-
1572 err = do_rmdir(conn, path1);-
1573 break;
never executed: break;
0
1574 case I_CHDIR:
never executed: case I_CHDIR:
0
1575 if (path1 == NULL || *path1 == '\0')
path1 == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*path1 == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1576 path1 = xstrdup(startdir);
never executed: path1 = xstrdup(startdir);
0
1577 path1 = make_absolute(path1, *pwd);-
1578 if ((tmp = do_realpath(conn, path1)) == NULL) {
(tmp = do_real...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1579 err = 1;-
1580 break;
never executed: break;
0
1581 }-
1582 if ((aa = do_stat(conn, tmp, 0)) == NULL) {
(aa = do_stat(...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1583 free(tmp);-
1584 err = 1;-
1585 break;
never executed: break;
0
1586 }-
1587 if (!(aa->flags & SSH2_FILEXFER_ATTR_PERMISSIONS)) {
!(aa->flags & 0x00000004)Description
TRUEnever evaluated
FALSEnever evaluated
0
1588 error("Can't change directory: Can't check target");-
1589 free(tmp);-
1590 err = 1;-
1591 break;
never executed: break;
0
1592 }-
1593 if (!S_ISDIR(aa->perm)) {
! (((( aa->per... == (0040000))Description
TRUEnever evaluated
FALSEnever evaluated
0
1594 error("Can't change directory: \"%s\" is not "-
1595 "a directory", tmp);-
1596 free(tmp);-
1597 err = 1;-
1598 break;
never executed: break;
0
1599 }-
1600 free(*pwd);-
1601 *pwd = tmp;-
1602 break;
never executed: break;
0
1603 case I_LS:
never executed: case I_LS:
0
1604 if (!path1) {
!path1Description
TRUEnever evaluated
FALSEnever evaluated
0
1605 do_ls_dir(conn, *pwd, *pwd, lflag);-
1606 break;
never executed: break;
0
1607 }-
1608-
1609 /* Strip pwd off beginning of non-absolute paths */-
1610 tmp = NULL;-
1611 if (*path1 != '/')
*path1 != '/'Description
TRUEnever evaluated
FALSEnever evaluated
0
1612 tmp = *pwd;
never executed: tmp = *pwd;
0
1613-
1614 path1 = make_absolute(path1, *pwd);-
1615 err = do_globbed_ls(conn, path1, tmp, lflag);-
1616 break;
never executed: break;
0
1617 case I_DF:
never executed: case I_DF:
0
1618 /* Default to current directory if no path specified */-
1619 if (path1 == NULL)
path1 == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
1620 path1 = xstrdup(*pwd);
never executed: path1 = xstrdup(*pwd);
0
1621 path1 = make_absolute(path1, *pwd);-
1622 err = do_df(conn, path1, hflag, iflag);-
1623 break;
never executed: break;
0
1624 case I_LCHDIR:
never executed: case I_LCHDIR:
0
1625 if (path1 == NULL || *path1 == '\0')
path1 == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
*path1 == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
1626 path1 = xstrdup("~");
never executed: path1 = xstrdup("~");
0
1627 tmp = tilde_expand_filename(path1, getuid());-
1628 free(path1);-
1629 path1 = tmp;-
1630 if (chdir(path1) == -1) {
chdir(path1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1631 error("Couldn't change local directory to "-
1632 "\"%s\": %s", path1, strerror(errno));-
1633 err = 1;-
1634 }
never executed: end of block
0
1635 break;
never executed: break;
0
1636 case I_LMKDIR:
never executed: case I_LMKDIR:
0
1637 if (mkdir(path1, 0777) == -1) {
mkdir(path1, 0777) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
1638 error("Couldn't create local directory "-
1639 "\"%s\": %s", path1, strerror(errno));-
1640 err = 1;-
1641 }
never executed: end of block
0
1642 break;
never executed: break;
0
1643 case I_LLS:
never executed: case I_LLS:
0
1644 local_do_ls(cmd);-
1645 break;
never executed: break;
0
1646 case I_SHELL:
never executed: case I_SHELL:
0
1647 local_do_shell(cmd);-
1648 break;
never executed: break;
0
1649 case I_LUMASK:
never executed: case I_LUMASK:
0
1650 umask(n_arg);-
1651 printf("Local umask: %03lo\n", n_arg);-
1652 break;
never executed: break;
0
1653 case I_CHMOD:
never executed: case I_CHMOD:
0
1654 path1 = make_absolute(path1, *pwd);-
1655 attrib_clear(&a);-
1656 a.flags |= SSH2_FILEXFER_ATTR_PERMISSIONS;-
1657 a.perm = n_arg;-
1658 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);-
1659 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1660 if (!quiet)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
1661 mprintf("Changing mode on %s\n",
never executed: mprintf("Changing mode on %s\n", g.gl_pathv[i]);
0
1662 g.gl_pathv[i]);
never executed: mprintf("Changing mode on %s\n", g.gl_pathv[i]);
0
1663 err = do_setstat(conn, g.gl_pathv[i], &a);-
1664 if (err != 0 && err_abort)
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
0
1665 break;
never executed: break;
0
1666 }
never executed: end of block
0
1667 break;
never executed: break;
0
1668 case I_CHOWN:
never executed: case I_CHOWN:
0
1669 case I_CHGRP:
never executed: case I_CHGRP:
0
1670 path1 = make_absolute(path1, *pwd);-
1671 remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g);-
1672 for (i = 0; g.gl_pathv[i] && !interrupted; i++) {
g.gl_pathv[i]Description
TRUEnever evaluated
FALSEnever evaluated
!interruptedDescription
TRUEnever evaluated
FALSEnever evaluated
0
1673 if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) {
!(aa = do_stat..._pathv[i], 0))Description
TRUEnever evaluated
FALSEnever evaluated
0
1674 if (err_abort) {
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
0
1675 err = -1;-
1676 break;
never executed: break;
0
1677 } else-
1678 continue;
never executed: continue;
0
1679 }-
1680 if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) {
!(aa->flags & 0x00000002)Description
TRUEnever evaluated
FALSEnever evaluated
0
1681 error("Can't get current ownership of "-
1682 "remote file \"%s\"", g.gl_pathv[i]);-
1683 if (err_abort) {
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
0
1684 err = -1;-
1685 break;
never executed: break;
0
1686 } else-
1687 continue;
never executed: continue;
0
1688 }-
1689 aa->flags &= SSH2_FILEXFER_ATTR_UIDGID;-
1690 if (cmdnum == I_CHOWN) {
cmdnum == I_CHOWNDescription
TRUEnever evaluated
FALSEnever evaluated
0
1691 if (!quiet)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
1692 mprintf("Changing owner on %s\n",
never executed: mprintf("Changing owner on %s\n", g.gl_pathv[i]);
0
1693 g.gl_pathv[i]);
never executed: mprintf("Changing owner on %s\n", g.gl_pathv[i]);
0
1694 aa->uid = n_arg;-
1695 } else {
never executed: end of block
0
1696 if (!quiet)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
1697 mprintf("Changing group on %s\n",
never executed: mprintf("Changing group on %s\n", g.gl_pathv[i]);
0
1698 g.gl_pathv[i]);
never executed: mprintf("Changing group on %s\n", g.gl_pathv[i]);
0
1699 aa->gid = n_arg;-
1700 }
never executed: end of block
0
1701 err = do_setstat(conn, g.gl_pathv[i], aa);-
1702 if (err != 0 && err_abort)
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
0
1703 break;
never executed: break;
0
1704 }
never executed: end of block
0
1705 break;
never executed: break;
0
1706 case I_PWD:
never executed: case I_PWD:
0
1707 mprintf("Remote working directory: %s\n", *pwd);-
1708 break;
never executed: break;
0
1709 case I_LPWD:
never executed: case I_LPWD:
0
1710 if (!getcwd(path_buf, sizeof(path_buf))) {
!getcwd(path_b...eof(path_buf))Description
TRUEnever evaluated
FALSEnever evaluated
0
1711 error("Couldn't get local cwd: %s", strerror(errno));-
1712 err = -1;-
1713 break;
never executed: break;
0
1714 }-
1715 mprintf("Local working directory: %s\n", path_buf);-
1716 break;
never executed: break;
0
1717 case I_QUIT:
never executed: case I_QUIT:
0
1718 /* Processed below */-
1719 break;
never executed: break;
0
1720 case I_HELP:
never executed: case I_HELP:
0
1721 help();-
1722 break;
never executed: break;
0
1723 case I_VERSION:
never executed: case I_VERSION:
0
1724 printf("SFTP protocol version %u\n", sftp_proto_version(conn));-
1725 break;
never executed: break;
0
1726 case I_PROGRESS:
never executed: case I_PROGRESS:
0
1727 showprogress = !showprogress;-
1728 if (showprogress)
showprogressDescription
TRUEnever evaluated
FALSEnever evaluated
0
1729 printf("Progress meter enabled\n");
never executed: printf("Progress meter enabled\n");
0
1730 else-
1731 printf("Progress meter disabled\n");
never executed: printf("Progress meter disabled\n");
0
1732 break;
never executed: break;
0
1733 default:
never executed: default:
0
1734 fatal("%d is not implemented", cmdnum);-
1735 }
never executed: end of block
0
1736-
1737 if (g.gl_pathc)
g.gl_pathcDescription
TRUEnever evaluated
FALSEnever evaluated
0
1738 globfree(&g);
never executed: _ssh__compat_globfree(&g);
0
1739 free(path1);-
1740 free(path2);-
1741-
1742 /* If an unignored error occurs in batch mode we should abort. */-
1743 if (err_abort && err != 0)
err_abortDescription
TRUEnever evaluated
FALSEnever evaluated
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
1744 return (-1);
never executed: return (-1);
0
1745 else if (cmdnum == I_QUIT)
cmdnum == I_QUITDescription
TRUEnever evaluated
FALSEnever evaluated
0
1746 return (1);
never executed: return (1);
0
1747-
1748 return (0);
never executed: return (0);
0
1749}-
1750-
1751#ifdef USE_LIBEDIT-
1752static char *-
1753prompt(EditLine *el)-
1754{-
1755 return ("sftp> ");-
1756}-
1757-
1758/* Display entries in 'list' after skipping the first 'len' chars */-
1759static void-
1760complete_display(char **list, u_int len)-
1761{-
1762 u_int y, m = 0, width = 80, columns = 1, colspace = 0, llen;-
1763 struct winsize ws;-
1764 char *tmp;-
1765-
1766 /* Count entries for sort and find longest */-
1767 for (y = 0; list[y]; y++)-
1768 m = MAXIMUM(m, strlen(list[y]));-
1769-
1770 if (ioctl(fileno(stdin), TIOCGWINSZ, &ws) != -1)-
1771 width = ws.ws_col;-
1772-
1773 m = m > len ? m - len : 0;-
1774 columns = width / (m + 2);-
1775 columns = MAXIMUM(columns, 1);-
1776 colspace = width / columns;-
1777 colspace = MINIMUM(colspace, width);-
1778-
1779 printf("\n");-
1780 m = 1;-
1781 for (y = 0; list[y]; y++) {-
1782 llen = strlen(list[y]);-
1783 tmp = llen > len ? list[y] + len : "";-
1784 mprintf("%-*s", colspace, tmp);-
1785 if (m >= columns) {-
1786 printf("\n");-
1787 m = 1;-
1788 } else-
1789 m++;-
1790 }-
1791 printf("\n");-
1792}-
1793-
1794/*-
1795 * Given a "list" of words that begin with a common prefix of "word",-
1796 * attempt to find an autocompletion to extends "word" by the next-
1797 * characters common to all entries in "list".-
1798 */-
1799static char *-
1800complete_ambiguous(const char *word, char **list, size_t count)-
1801{-
1802 if (word == NULL)-
1803 return NULL;-
1804-
1805 if (count > 0) {-
1806 u_int y, matchlen = strlen(list[0]);-
1807-
1808 /* Find length of common stem */-
1809 for (y = 1; list[y]; y++) {-
1810 u_int x;-
1811-
1812 for (x = 0; x < matchlen; x++)-
1813 if (list[0][x] != list[y][x])-
1814 break;-
1815-
1816 matchlen = x;-
1817 }-
1818-
1819 if (matchlen > strlen(word)) {-
1820 char *tmp = xstrdup(list[0]);-
1821-
1822 tmp[matchlen] = '\0';-
1823 return tmp;-
1824 }-
1825 }-
1826-
1827 return xstrdup(word);-
1828}-
1829-
1830/* Autocomplete a sftp command */-
1831static int-
1832complete_cmd_parse(EditLine *el, char *cmd, int lastarg, char quote,-
1833 int terminated)-
1834{-
1835 u_int y, count = 0, cmdlen, tmplen;-
1836 char *tmp, **list, argterm[3];-
1837 const LineInfo *lf;-
1838-
1839 list = xcalloc((sizeof(cmds) / sizeof(*cmds)) + 1, sizeof(char *));-
1840-
1841 /* No command specified: display all available commands */-
1842 if (cmd == NULL) {-
1843 for (y = 0; cmds[y].c; y++)-
1844 list[count++] = xstrdup(cmds[y].c);-
1845-
1846 list[count] = NULL;-
1847 complete_display(list, 0);-
1848-
1849 for (y = 0; list[y] != NULL; y++)-
1850 free(list[y]);-
1851 free(list);-
1852 return count;-
1853 }-
1854-
1855 /* Prepare subset of commands that start with "cmd" */-
1856 cmdlen = strlen(cmd);-
1857 for (y = 0; cmds[y].c; y++) {-
1858 if (!strncasecmp(cmd, cmds[y].c, cmdlen))-
1859 list[count++] = xstrdup(cmds[y].c);-
1860 }-
1861 list[count] = NULL;-
1862-
1863 if (count == 0) {-
1864 free(list);-
1865 return 0;-
1866 }-
1867-
1868 /* Complete ambiguous command */-
1869 tmp = complete_ambiguous(cmd, list, count);-
1870 if (count > 1)-
1871 complete_display(list, 0);-
1872-
1873 for (y = 0; list[y]; y++)-
1874 free(list[y]);-
1875 free(list);-
1876-
1877 if (tmp != NULL) {-
1878 tmplen = strlen(tmp);-
1879 cmdlen = strlen(cmd);-
1880 /* If cmd may be extended then do so */-
1881 if (tmplen > cmdlen)-
1882 if (el_insertstr(el, tmp + cmdlen) == -1)-
1883 fatal("el_insertstr failed.");-
1884 lf = el_line(el);-
1885 /* Terminate argument cleanly */-
1886 if (count == 1) {-
1887 y = 0;-
1888 if (!terminated)-
1889 argterm[y++] = quote;-
1890 if (lastarg || *(lf->cursor) != ' ')-
1891 argterm[y++] = ' ';-
1892 argterm[y] = '\0';-
1893 if (y > 0 && el_insertstr(el, argterm) == -1)-
1894 fatal("el_insertstr failed.");-
1895 }-
1896 free(tmp);-
1897 }-
1898-
1899 return count;-
1900}-
1901-
1902/*-
1903 * Determine whether a particular sftp command's arguments (if any)-
1904 * represent local or remote files.-
1905 */-
1906static int-
1907complete_is_remote(char *cmd) {-
1908 int i;-
1909-
1910 if (cmd == NULL)-
1911 return -1;-
1912-
1913 for (i = 0; cmds[i].c; i++) {-
1914 if (!strncasecmp(cmd, cmds[i].c, strlen(cmds[i].c)))-
1915 return cmds[i].t;-
1916 }-
1917-
1918 return -1;-
1919}-
1920-
1921/* Autocomplete a filename "file" */-
1922static int-
1923complete_match(EditLine *el, struct sftp_conn *conn, char *remote_path,-
1924 char *file, int remote, int lastarg, char quote, int terminated)-
1925{-
1926 glob_t g;-
1927 char *tmp, *tmp2, ins[8];-
1928 u_int i, hadglob, pwdlen, len, tmplen, filelen, cesc, isesc, isabs;-
1929 int clen;-
1930 const LineInfo *lf;-
1931-
1932 /* Glob from "file" location */-
1933 if (file == NULL)-
1934 tmp = xstrdup("*");-
1935 else-
1936 xasprintf(&tmp, "%s*", file);-
1937-
1938 /* Check if the path is absolute. */-
1939 isabs = tmp[0] == '/';-
1940-
1941 memset(&g, 0, sizeof(g));-
1942 if (remote != LOCAL) {-
1943 tmp = make_absolute(tmp, remote_path);-
1944 remote_glob(conn, tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);-
1945 } else-
1946 glob(tmp, GLOB_DOOFFS|GLOB_MARK, NULL, &g);-
1947-
1948 /* Determine length of pwd so we can trim completion display */-
1949 for (hadglob = tmplen = pwdlen = 0; tmp[tmplen] != 0; tmplen++) {-
1950 /* Terminate counting on first unescaped glob metacharacter */-
1951 if (tmp[tmplen] == '*' || tmp[tmplen] == '?') {-
1952 if (tmp[tmplen] != '*' || tmp[tmplen + 1] != '\0')-
1953 hadglob = 1;-
1954 break;-
1955 }-
1956 if (tmp[tmplen] == '\\' && tmp[tmplen + 1] != '\0')-
1957 tmplen++;-
1958 if (tmp[tmplen] == '/')-
1959 pwdlen = tmplen + 1; /* track last seen '/' */-
1960 }-
1961 free(tmp);-
1962 tmp = NULL;-
1963-
1964 if (g.gl_matchc == 0)-
1965 goto out;-
1966-
1967 if (g.gl_matchc > 1)-
1968 complete_display(g.gl_pathv, pwdlen);-
1969-
1970 /* Don't try to extend globs */-
1971 if (file == NULL || hadglob)-
1972 goto out;-
1973-
1974 tmp2 = complete_ambiguous(file, g.gl_pathv, g.gl_matchc);-
1975 tmp = path_strip(tmp2, isabs ? NULL : remote_path);-
1976 free(tmp2);-
1977-
1978 if (tmp == NULL)-
1979 goto out;-
1980-
1981 tmplen = strlen(tmp);-
1982 filelen = strlen(file);-
1983-
1984 /* Count the number of escaped characters in the input string. */-
1985 cesc = isesc = 0;-
1986 for (i = 0; i < filelen; i++) {-
1987 if (!isesc && file[i] == '\\' && i + 1 < filelen){-
1988 isesc = 1;-
1989 cesc++;-
1990 } else-
1991 isesc = 0;-
1992 }-
1993-
1994 if (tmplen > (filelen - cesc)) {-
1995 tmp2 = tmp + filelen - cesc;-
1996 len = strlen(tmp2);-
1997 /* quote argument on way out */-
1998 for (i = 0; i < len; i += clen) {-
1999 if ((clen = mblen(tmp2 + i, len - i)) < 0 ||-
2000 (size_t)clen > sizeof(ins) - 2)-
2001 fatal("invalid multibyte character");-
2002 ins[0] = '\\';-
2003 memcpy(ins + 1, tmp2 + i, clen);-
2004 ins[clen + 1] = '\0';-
2005 switch (tmp2[i]) {-
2006 case '\'':-
2007 case '"':-
2008 case '\\':-
2009 case '\t':-
2010 case '[':-
2011 case ' ':-
2012 case '#':-
2013 case '*':-
2014 if (quote == '\0' || tmp2[i] == quote) {-
2015 if (el_insertstr(el, ins) == -1)-
2016 fatal("el_insertstr "-
2017 "failed.");-
2018 break;-
2019 }-
2020 /* FALLTHROUGH */-
2021 default:-
2022 if (el_insertstr(el, ins + 1) == -1)-
2023 fatal("el_insertstr failed.");-
2024 break;-
2025 }-
2026 }-
2027 }-
2028-
2029 lf = el_line(el);-
2030 if (g.gl_matchc == 1) {-
2031 i = 0;-
2032 if (!terminated && quote != '\0')-
2033 ins[i++] = quote;-
2034 if (*(lf->cursor - 1) != '/' &&-
2035 (lastarg || *(lf->cursor) != ' '))-
2036 ins[i++] = ' ';-
2037 ins[i] = '\0';-
2038 if (i > 0 && el_insertstr(el, ins) == -1)-
2039 fatal("el_insertstr failed.");-
2040 }-
2041 free(tmp);-
2042-
2043 out:-
2044 globfree(&g);-
2045 return g.gl_matchc;-
2046}-
2047-
2048/* tab-completion hook function, called via libedit */-
2049static unsigned char-
2050complete(EditLine *el, int ch)-
2051{-
2052 char **argv, *line, quote;-
2053 int argc, carg;-
2054 u_int cursor, len, terminated, ret = CC_ERROR;-
2055 const LineInfo *lf;-
2056 struct complete_ctx *complete_ctx;-
2057-
2058 lf = el_line(el);-
2059 if (el_get(el, EL_CLIENTDATA, (void**)&complete_ctx) != 0)-
2060 fatal("%s: el_get failed", __func__);-
2061-
2062 /* Figure out which argument the cursor points to */-
2063 cursor = lf->cursor - lf->buffer;-
2064 line = xmalloc(cursor + 1);-
2065 memcpy(line, lf->buffer, cursor);-
2066 line[cursor] = '\0';-
2067 argv = makeargv(line, &carg, 1, &quote, &terminated);-
2068 free(line);-
2069-
2070 /* Get all the arguments on the line */-
2071 len = lf->lastchar - lf->buffer;-
2072 line = xmalloc(len + 1);-
2073 memcpy(line, lf->buffer, len);-
2074 line[len] = '\0';-
2075 argv = makeargv(line, &argc, 1, NULL, NULL);-
2076-
2077 /* Ensure cursor is at EOL or a argument boundary */-
2078 if (line[cursor] != ' ' && line[cursor] != '\0' &&-
2079 line[cursor] != '\n') {-
2080 free(line);-
2081 return ret;-
2082 }-
2083-
2084 if (carg == 0) {-
2085 /* Show all available commands */-
2086 complete_cmd_parse(el, NULL, argc == carg, '\0', 1);-
2087 ret = CC_REDISPLAY;-
2088 } else if (carg == 1 && cursor > 0 && line[cursor - 1] != ' ') {-
2089 /* Handle the command parsing */-
2090 if (complete_cmd_parse(el, argv[0], argc == carg,-
2091 quote, terminated) != 0)-
2092 ret = CC_REDISPLAY;-
2093 } else if (carg >= 1) {-
2094 /* Handle file parsing */-
2095 int remote = complete_is_remote(argv[0]);-
2096 char *filematch = NULL;-
2097-
2098 if (carg > 1 && line[cursor-1] != ' ')-
2099 filematch = argv[carg - 1];-
2100-
2101 if (remote != 0 &&-
2102 complete_match(el, complete_ctx->conn,-
2103 *complete_ctx->remote_pathp, filematch,-
2104 remote, carg == argc, quote, terminated) != 0)-
2105 ret = CC_REDISPLAY;-
2106 }-
2107-
2108 free(line);-
2109 return ret;-
2110}-
2111#endif /* USE_LIBEDIT */-
2112-
2113static int-
2114interactive_loop(struct sftp_conn *conn, char *file1, char *file2)-
2115{-
2116 char *remote_path;-
2117 char *dir = NULL, *startdir = NULL;-
2118 char cmd[2048];-
2119 int err, interactive;-
2120 EditLine *el = NULL;-
2121#ifdef USE_LIBEDIT-
2122 History *hl = NULL;-
2123 HistEvent hev;-
2124 extern char *__progname;-
2125 struct complete_ctx complete_ctx;-
2126-
2127 if (!batchmode && isatty(STDIN_FILENO)) {-
2128 if ((el = el_init(__progname, stdin, stdout, stderr)) == NULL)-
2129 fatal("Couldn't initialise editline");-
2130 if ((hl = history_init()) == NULL)-
2131 fatal("Couldn't initialise editline history");-
2132 history(hl, &hev, H_SETSIZE, 100);-
2133 el_set(el, EL_HIST, history, hl);-
2134-
2135 el_set(el, EL_PROMPT, prompt);-
2136 el_set(el, EL_EDITOR, "emacs");-
2137 el_set(el, EL_TERMINAL, NULL);-
2138 el_set(el, EL_SIGNAL, 1);-
2139 el_source(el, NULL);-
2140-
2141 /* Tab Completion */-
2142 el_set(el, EL_ADDFN, "ftp-complete",-
2143 "Context sensitive argument completion", complete);-
2144 complete_ctx.conn = conn;-
2145 complete_ctx.remote_pathp = &remote_path;-
2146 el_set(el, EL_CLIENTDATA, (void*)&complete_ctx);-
2147 el_set(el, EL_BIND, "^I", "ftp-complete", NULL);-
2148 /* enable ctrl-left-arrow and ctrl-right-arrow */-
2149 el_set(el, EL_BIND, "\\e[1;5C", "em-next-word", NULL);-
2150 el_set(el, EL_BIND, "\\e[5C", "em-next-word", NULL);-
2151 el_set(el, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL);-
2152 el_set(el, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL);-
2153 /* make ^w match ksh behaviour */-
2154 el_set(el, EL_BIND, "^w", "ed-delete-prev-word", NULL);-
2155 }-
2156#endif /* USE_LIBEDIT */-
2157-
2158 remote_path = do_realpath(conn, ".");-
2159 if (remote_path == NULL)
remote_path == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2160 fatal("Need cwd");
never executed: fatal("Need cwd");
0
2161 startdir = xstrdup(remote_path);-
2162-
2163 if (file1 != NULL) {
file1 != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2164 dir = xstrdup(file1);-
2165 dir = make_absolute(dir, remote_path);-
2166-
2167 if (remote_is_dir(conn, dir) && file2 == NULL) {
remote_is_dir(conn, dir)Description
TRUEnever evaluated
FALSEnever evaluated
file2 == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2168 if (!quiet)
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
2169 mprintf("Changing to: %s\n", dir);
never executed: mprintf("Changing to: %s\n", dir);
0
2170 snprintf(cmd, sizeof cmd, "cd \"%s\"", dir);-
2171 if (parse_dispatch_command(conn, cmd,
parse_dispatch...rtdir, 1) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2172 &remote_path, startdir, 1) != 0) {
parse_dispatch...rtdir, 1) != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2173 free(dir);-
2174 free(startdir);-
2175 free(remote_path);-
2176 free(conn);-
2177 return (-1);
never executed: return (-1);
0
2178 }-
2179 } else {
never executed: end of block
0
2180 /* XXX this is wrong wrt quoting */-
2181 snprintf(cmd, sizeof cmd, "get%s %s%s%s",-
2182 global_aflag ? " -a" : "", dir,-
2183 file2 == NULL ? "" : " ",-
2184 file2 == NULL ? "" : file2);-
2185 err = parse_dispatch_command(conn, cmd,-
2186 &remote_path, startdir, 1);-
2187 free(dir);-
2188 free(startdir);-
2189 free(remote_path);-
2190 free(conn);-
2191 return (err);
never executed: return (err);
0
2192 }-
2193 free(dir);-
2194 }
never executed: end of block
0
2195-
2196 setvbuf(stdout, NULL, _IOLBF, 0);-
2197 setvbuf(infile, NULL, _IOLBF, 0);-
2198-
2199 interactive = !batchmode && isatty(STDIN_FILENO);
!batchmodeDescription
TRUEnever evaluated
FALSEnever evaluated
isatty( 0 )Description
TRUEnever evaluated
FALSEnever evaluated
0
2200 err = 0;-
2201 for (;;) {-
2202 char *cp;-
2203-
2204 signal(SIGINT, SIG_IGN);-
2205-
2206 if (el == NULL) {
el == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2207 if (interactive)
interactiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
2208 printf("sftp> ");
never executed: printf("sftp> ");
0
2209 if (fgets(cmd, sizeof(cmd), infile) == NULL) {
fgets(cmd, siz...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2210 if (interactive)
interactiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
2211 printf("\n");
never executed: printf("\n");
0
2212 break;
never executed: break;
0
2213 }-
2214 if (!interactive) { /* Echo command */
!interactiveDescription
TRUEnever evaluated
FALSEnever evaluated
0
2215 mprintf("sftp> %s", cmd);-
2216 if (strlen(cmd) > 0 &&
strlen(cmd) > 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2217 cmd[strlen(cmd) - 1] != '\n')
cmd[strlen(cmd) - 1] != '\n'Description
TRUEnever evaluated
FALSEnever evaluated
0
2218 printf("\n");
never executed: printf("\n");
0
2219 }
never executed: end of block
0
2220 } else {
never executed: end of block
0
2221#ifdef USE_LIBEDIT-
2222 const char *line;-
2223 int count = 0;-
2224-
2225 if ((line = el_gets(el, &count)) == NULL ||-
2226 count <= 0) {-
2227 printf("\n");-
2228 break;-
2229 }-
2230 history(hl, &hev, H_ENTER, line);-
2231 if (strlcpy(cmd, line, sizeof(cmd)) >= sizeof(cmd)) {-
2232 fprintf(stderr, "Error: input line too long\n");-
2233 continue;-
2234 }-
2235#endif /* USE_LIBEDIT */-
2236 }
never executed: end of block
0
2237-
2238 cp = strrchr(cmd, '\n');-
2239 if (cp)
cpDescription
TRUEnever evaluated
FALSEnever evaluated
0
2240 *cp = '\0';
never executed: *cp = '\0';
0
2241-
2242 /* Handle user interrupts gracefully during commands */-
2243 interrupted = 0;-
2244 signal(SIGINT, cmd_interrupt);-
2245-
2246 err = parse_dispatch_command(conn, cmd, &remote_path,-
2247 startdir, batchmode);-
2248 if (err != 0)
err != 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2249 break;
never executed: break;
0
2250 }
never executed: end of block
0
2251 signal(SIGCHLD, SIG_DFL);-
2252 free(remote_path);-
2253 free(startdir);-
2254 free(conn);-
2255-
2256#ifdef USE_LIBEDIT-
2257 if (el != NULL)-
2258 el_end(el);-
2259#endif /* USE_LIBEDIT */-
2260-
2261 /* err == 1 signifies normal "quit" exit */-
2262 return (err >= 0 ? 0 : -1);
never executed: return (err >= 0 ? 0 : -1);
err >= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2263}-
2264-
2265static void-
2266connect_to_server(char *path, char **args, int *in, int *out)-
2267{-
2268 int c_in, c_out;-
2269-
2270#ifdef USE_PIPES-
2271 int pin[2], pout[2];-
2272-
2273 if ((pipe(pin) == -1) || (pipe(pout) == -1))-
2274 fatal("pipe: %s", strerror(errno));-
2275 *in = pin[0];-
2276 *out = pout[1];-
2277 c_in = pout[0];-
2278 c_out = pin[1];-
2279#else /* USE_PIPES */-
2280 int inout[2];-
2281-
2282 if (socketpair(AF_UNIX, SOCK_STREAM, 0, inout) == -1)
socketpair( 1 ..., inout) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2283 fatal("socketpair: %s", strerror(errno));
never executed: fatal("socketpair: %s", strerror( (*__errno_location ()) ));
0
2284 *in = *out = inout[0];-
2285 c_in = c_out = inout[1];-
2286#endif /* USE_PIPES */-
2287-
2288 if ((sshpid = fork()) == -1)
(sshpid = fork()) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2289 fatal("fork: %s", strerror(errno));
never executed: fatal("fork: %s", strerror( (*__errno_location ()) ));
0
2290 else if (sshpid == 0) {
sshpid == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2291 if ((dup2(c_in, STDIN_FILENO) == -1) ||
(dup2(c_in, 0 ) == -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2292 (dup2(c_out, STDOUT_FILENO) == -1)) {
(dup2(c_out, 1 ) == -1)Description
TRUEnever evaluated
FALSEnever evaluated
0
2293 fprintf(stderr, "dup2: %s\n", strerror(errno));-
2294 _exit(1);-
2295 }
never executed: end of block
0
2296 close(*in);-
2297 close(*out);-
2298 close(c_in);-
2299 close(c_out);-
2300-
2301 /*-
2302 * The underlying ssh is in the same process group, so we must-
2303 * ignore SIGINT if we want to gracefully abort commands,-
2304 * otherwise the signal will make it to the ssh process and-
2305 * kill it too. Contrawise, since sftp sends SIGTERMs to the-
2306 * underlying ssh, it must *not* ignore that signal.-
2307 */-
2308 signal(SIGINT, SIG_IGN);-
2309 signal(SIGTERM, SIG_DFL);-
2310 execvp(path, args);-
2311 fprintf(stderr, "exec: %s: %s\n", path, strerror(errno));-
2312 _exit(1);-
2313 }
never executed: end of block
0
2314-
2315 signal(SIGTERM, killchild);-
2316 signal(SIGINT, killchild);-
2317 signal(SIGHUP, killchild);-
2318 signal(SIGTSTP, suspchild);-
2319 signal(SIGTTIN, suspchild);-
2320 signal(SIGTTOU, suspchild);-
2321 signal(SIGCHLD, sigchld_handler);-
2322 close(c_in);-
2323 close(c_out);-
2324}
never executed: end of block
0
2325-
2326static void-
2327usage(void)-
2328{-
2329 extern char *__progname;-
2330-
2331 fprintf(stderr,-
2332 "usage: %s [-46aCfpqrv] [-B buffer_size] [-b batchfile] [-c cipher]\n"-
2333 " [-D sftp_server_path] [-F ssh_config] "-
2334 "[-i identity_file] [-l limit]\n"-
2335 " [-o ssh_option] [-P port] [-R num_requests] "-
2336 "[-S program]\n"-
2337 " [-s subsystem | sftp_server] destination\n",-
2338 __progname);-
2339 exit(1);
never executed: exit(1);
0
2340}-
2341-
2342int-
2343main(int argc, char **argv)-
2344{-
2345 int in, out, ch, err, tmp, port = -1;-
2346 char *host = NULL, *user, *cp, *file2 = NULL;-
2347 int debug_level = 0, sshver = 2;-
2348 char *file1 = NULL, *sftp_server = NULL;-
2349 char *ssh_program = _PATH_SSH_PROGRAM, *sftp_direct = NULL;-
2350 const char *errstr;-
2351 LogLevel ll = SYSLOG_LEVEL_INFO;-
2352 arglist args;-
2353 extern int optind;-
2354 extern char *optarg;-
2355 struct sftp_conn *conn;-
2356 size_t copy_buffer_len = DEFAULT_COPY_BUFLEN;-
2357 size_t num_requests = DEFAULT_NUM_REQUESTS;-
2358 long long limit_kbps = 0;-
2359-
2360 ssh_malloc_init(); /* must be called before any mallocs */-
2361 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */-
2362 sanitise_stdfd();-
2363 msetlocale();-
2364-
2365 __progname = ssh_get_progname(argv[0]);-
2366 memset(&args, '\0', sizeof(args));-
2367 args.list = NULL;-
2368 addargs(&args, "%s", ssh_program);-
2369 addargs(&args, "-oForwardX11 no");-
2370 addargs(&args, "-oForwardAgent no");-
2371 addargs(&args, "-oPermitLocalCommand no");-
2372 addargs(&args, "-oClearAllForwardings yes");-
2373-
2374 ll = SYSLOG_LEVEL_INFO;-
2375 infile = stdin;-
2376-
2377 while ((ch = getopt(argc, argv,
(ch = BSDgetop...P:R:") ) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2378 "1246afhpqrvCc:D:i:l:o:s:S:b:B:F:P:R:")) != -1) {
(ch = BSDgetop...P:R:") ) != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2379 switch (ch) {-
2380 /* Passed through to ssh(1) */-
2381 case '4':
never executed: case '4':
0
2382 case '6':
never executed: case '6':
0
2383 case 'C':
never executed: case 'C':
0
2384 addargs(&args, "-%c", ch);-
2385 break;
never executed: break;
0
2386 /* Passed through to ssh(1) with argument */-
2387 case 'F':
never executed: case 'F':
0
2388 case 'c':
never executed: case 'c':
0
2389 case 'i':
never executed: case 'i':
0
2390 case 'o':
never executed: case 'o':
0
2391 addargs(&args, "-%c", ch);-
2392 addargs(&args, "%s", optarg);-
2393 break;
never executed: break;
0
2394 case 'q':
never executed: case 'q':
0
2395 ll = SYSLOG_LEVEL_ERROR;-
2396 quiet = 1;-
2397 showprogress = 0;-
2398 addargs(&args, "-%c", ch);-
2399 break;
never executed: break;
0
2400 case 'P':
never executed: case 'P':
0
2401 port = a2port(optarg);-
2402 if (port <= 0)
port <= 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2403 fatal("Bad port \"%s\"\n", optarg);
never executed: fatal("Bad port \"%s\"\n", BSDoptarg);
0
2404 break;
never executed: break;
0
2405 case 'v':
never executed: case 'v':
0
2406 if (debug_level < 3) {
debug_level < 3Description
TRUEnever evaluated
FALSEnever evaluated
0
2407 addargs(&args, "-v");-
2408 ll = SYSLOG_LEVEL_DEBUG1 + debug_level;-
2409 }
never executed: end of block
0
2410 debug_level++;-
2411 break;
never executed: break;
0
2412 case '1':
never executed: case '1':
0
2413 sshver = 1;-
2414 if (sftp_server == NULL)
sftp_server == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2415 sftp_server = _PATH_SFTP_SERVER;
never executed: sftp_server = "/var/tmp/openssh-test/libexec/sftp-server";
0
2416 break;
never executed: break;
0
2417 case '2':
never executed: case '2':
0
2418 sshver = 2;-
2419 break;
never executed: break;
0
2420 case 'a':
never executed: case 'a':
0
2421 global_aflag = 1;-
2422 break;
never executed: break;
0
2423 case 'B':
never executed: case 'B':
0
2424 copy_buffer_len = strtol(optarg, &cp, 10);-
2425 if (copy_buffer_len == 0 || *cp != '\0')
copy_buffer_len == 0Description
TRUEnever evaluated
FALSEnever evaluated
*cp != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
2426 fatal("Invalid buffer size \"%s\"", optarg);
never executed: fatal("Invalid buffer size \"%s\"", BSDoptarg);
0
2427 break;
never executed: break;
0
2428 case 'b':
never executed: case 'b':
0
2429 if (batchmode)
batchmodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2430 fatal("Batch file already specified.");
never executed: fatal("Batch file already specified.");
0
2431-
2432 /* Allow "-" as stdin */-
2433 if (strcmp(optarg, "-") != 0 &&
never executed: __result = (((const unsigned char *) (const char *) ( BSDoptarg ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
never executed: __result = (((const unsigned char *) (const char *) ( "-" ))[3] - __s2[3]);
never executed: end of block
never executed: end of block
__extension__ ... )))); }) != 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s1_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 0Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 1Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
__s2_len > 2Description
TRUEnever evaluated
FALSEnever evaluated
__result == 0Description
TRUEnever evaluated
FALSEnever evaluated
0
2434 (infile = fopen(optarg, "r")) == NULL)
(infile = fope...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2435 fatal("%s (%s).", strerror(errno), optarg);
never executed: fatal("%s (%s).", strerror( (*__errno_location ()) ), BSDoptarg);
0
2436 showprogress = 0;-
2437 quiet = batchmode = 1;-
2438 addargs(&args, "-obatchmode yes");-
2439 break;
never executed: break;
0
2440 case 'f':
never executed: case 'f':
0
2441 global_fflag = 1;-
2442 break;
never executed: break;
0
2443 case 'p':
never executed: case 'p':
0
2444 global_pflag = 1;-
2445 break;
never executed: break;
0
2446 case 'D':
never executed: case 'D':
0
2447 sftp_direct = optarg;-
2448 break;
never executed: break;
0
2449 case 'l':
never executed: case 'l':
0
2450 limit_kbps = strtonum(optarg, 1, 100 * 1024 * 1024,-
2451 &errstr);-
2452 if (errstr != NULL)
errstr != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2453 usage();
never executed: usage();
0
2454 limit_kbps *= 1024; /* kbps */-
2455 break;
never executed: break;
0
2456 case 'r':
never executed: case 'r':
0
2457 global_rflag = 1;-
2458 break;
never executed: break;
0
2459 case 'R':
never executed: case 'R':
0
2460 num_requests = strtol(optarg, &cp, 10);-
2461 if (num_requests == 0 || *cp != '\0')
num_requests == 0Description
TRUEnever evaluated
FALSEnever evaluated
*cp != '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
2462 fatal("Invalid number of requests \"%s\"",
never executed: fatal("Invalid number of requests \"%s\"", BSDoptarg);
0
2463 optarg);
never executed: fatal("Invalid number of requests \"%s\"", BSDoptarg);
0
2464 break;
never executed: break;
0
2465 case 's':
never executed: case 's':
0
2466 sftp_server = optarg;-
2467 break;
never executed: break;
0
2468 case 'S':
never executed: case 'S':
0
2469 ssh_program = optarg;-
2470 replacearg(&args, 0, "%s", ssh_program);-
2471 break;
never executed: break;
0
2472 case 'h':
never executed: case 'h':
0
2473 default:
never executed: default:
0
2474 usage();-
2475 }
never executed: end of block
0
2476 }-
2477-
2478 if (!isatty(STDERR_FILENO))
!isatty( 2 )Description
TRUEnever evaluated
FALSEnever evaluated
0
2479 showprogress = 0;
never executed: showprogress = 0;
0
2480-
2481 log_init(argv[0], ll, SYSLOG_FACILITY_USER, 1);-
2482-
2483 if (sftp_direct == NULL) {
sftp_direct == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2484 if (optind == argc || argc > (optind + 2))
BSDoptind == argcDescription
TRUEnever evaluated
FALSEnever evaluated
argc > (BSDoptind + 2)Description
TRUEnever evaluated
FALSEnever evaluated
0
2485 usage();
never executed: usage();
0
2486 argv += optind;-
2487-
2488 switch (parse_uri("sftp", *argv, &user, &host, &tmp, &file1)) {-
2489 case -1:
never executed: case -1:
0
2490 usage();-
2491 break;
never executed: break;
0
2492 case 0:
never executed: case 0:
0
2493 if (tmp != -1)
tmp != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2494 port = tmp;
never executed: port = tmp;
0
2495 break;
never executed: break;
0
2496 default:
never executed: default:
0
2497 if (parse_user_host_path(*argv, &user, &host,
parse_user_hos... &file1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2498 &file1) == -1) {
parse_user_hos... &file1) == -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2499 /* Treat as a plain hostname. */-
2500 host = xstrdup(*argv);-
2501 host = cleanhostname(host);-
2502 }
never executed: end of block
0
2503 break;
never executed: break;
0
2504 }-
2505 file2 = *(argv + 1);-
2506-
2507 if (!*host) {
!*hostDescription
TRUEnever evaluated
FALSEnever evaluated
0
2508 fprintf(stderr, "Missing hostname\n");-
2509 usage();-
2510 }
never executed: end of block
0
2511-
2512 if (port != -1)
port != -1Description
TRUEnever evaluated
FALSEnever evaluated
0
2513 addargs(&args, "-oPort %d", port);
never executed: addargs(&args, "-oPort %d", port);
0
2514 if (user != NULL) {
user != ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2515 addargs(&args, "-l");-
2516 addargs(&args, "%s", user);-
2517 }
never executed: end of block
0
2518 addargs(&args, "-oProtocol %d", sshver);-
2519-
2520 /* no subsystem if the server-spec contains a '/' */-
2521 if (sftp_server == NULL || strchr(sftp_server, '/') == NULL)
sftp_server == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
(__extension__...== ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
__builtin_constant_p ( '/' )Description
TRUEnever evaluated
FALSEnever evaluated
!__builtin_con... sftp_server )Description
TRUEnever evaluated
FALSEnever evaluated
( '/' ) == '\0'Description
TRUEnever evaluated
FALSEnever evaluated
0
2522 addargs(&args, "-s");
never executed: addargs(&args, "-s");
0
2523-
2524 addargs(&args, "--");-
2525 addargs(&args, "%s", host);-
2526 addargs(&args, "%s", (sftp_server != NULL ?-
2527 sftp_server : "sftp"));-
2528-
2529 connect_to_server(ssh_program, args.list, &in, &out);-
2530 } else {
never executed: end of block
0
2531 args.list = NULL;-
2532 addargs(&args, "sftp-server");-
2533-
2534 connect_to_server(sftp_direct, args.list, &in, &out);-
2535 }
never executed: end of block
0
2536 freeargs(&args);-
2537-
2538 conn = do_init(in, out, copy_buffer_len, num_requests, limit_kbps);-
2539 if (conn == NULL)
conn == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2540 fatal("Couldn't initialise connection to server");
never executed: fatal("Couldn't initialise connection to server");
0
2541-
2542 if (!quiet) {
!quietDescription
TRUEnever evaluated
FALSEnever evaluated
0
2543 if (sftp_direct == NULL)
sftp_direct == ((void *)0)Description
TRUEnever evaluated
FALSEnever evaluated
0
2544 fprintf(stderr, "Connected to %s.\n", host);
never executed: fprintf( stderr , "Connected to %s.\n", host);
0
2545 else-
2546 fprintf(stderr, "Attached to %s.\n", sftp_direct);
never executed: fprintf( stderr , "Attached to %s.\n", sftp_direct);
0
2547 }-
2548-
2549 err = interactive_loop(conn, file1, file2);-
2550-
2551#if !defined(USE_PIPES)-
2552 shutdown(in, SHUT_RDWR);-
2553 shutdown(out, SHUT_RDWR);-
2554#endif-
2555-
2556 close(in);-
2557 close(out);-
2558 if (batchmode)
batchmodeDescription
TRUEnever evaluated
FALSEnever evaluated
0
2559 fclose(infile);
never executed: fclose(infile);
0
2560-
2561 while (waitpid(sshpid, NULL, 0) == -1 && sshpid > 1)
waitpid(sshpid...)0) , 0) == -1Description
TRUEnever evaluated
FALSEnever evaluated
sshpid > 1Description
TRUEnever evaluated
FALSEnever evaluated
0
2562 if (errno != EINTR)
(*__errno_location ()) != 4Description
TRUEnever evaluated
FALSEnever evaluated
0
2563 fatal("Couldn't wait for ssh process: %s",
never executed: fatal("Couldn't wait for ssh process: %s", strerror( (*__errno_location ()) ));
0
2564 strerror(errno));
never executed: fatal("Couldn't wait for ssh process: %s", strerror( (*__errno_location ()) ));
0
2565-
2566 exit(err == 0 ? 0 : 1);
never executed: exit(err == 0 ? 0 : 1);
0
2567}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.2.2