summaryrefslogtreecommitdiff
path: root/sftp.c
diff options
context:
space:
mode:
authorDarren Tucker <dtucker@zip.com.au>2010-12-05 09:02:47 +1100
committerDarren Tucker <dtucker@zip.com.au>2010-12-05 09:02:47 +1100
commitaf1f90925494deba97a4b877798cf250f7dc75cf (patch)
treec6e44e388c2bd4ca0caad6ce9f422576fe650b57 /sftp.c
parentadab6f12992c522e1208fa2bdf89ce572840ccf8 (diff)
- djm@cvs.openbsd.org 2010/12/04 00:18:01
[sftp-server.c sftp.1 sftp-client.h sftp.c PROTOCOL sftp-client.c] add a protocol extension to support a hard link operation. It is available through the "ln" command in the client. The old "ln" behaviour of creating a symlink is available using its "-s" option or through the preexisting "symlink" command; based on a patch from miklos AT szeredi.hu in bz#1555; ok markus@
Diffstat (limited to 'sftp.c')
-rw-r--r--sftp.c53
1 files changed, 43 insertions, 10 deletions
diff --git a/sftp.c b/sftp.c
index d605505ea..ab667f5a5 100644
--- a/sftp.c
+++ b/sftp.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sftp.c,v 1.131 2010/10/23 22:06:12 sthen Exp $ */ 1/* $OpenBSD: sftp.c,v 1.132 2010/12/04 00:18:01 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org> 3 * Copyright (c) 2001-2004 Damien Miller <djm@openbsd.org>
4 * 4 *
@@ -132,6 +132,7 @@ extern char *__progname;
132#define I_GET 5 132#define I_GET 5
133#define I_HELP 6 133#define I_HELP 6
134#define I_LCHDIR 7 134#define I_LCHDIR 7
135#define I_LINK 25
135#define I_LLS 8 136#define I_LLS 8
136#define I_LMKDIR 9 137#define I_LMKDIR 9
137#define I_LPWD 10 138#define I_LPWD 10
@@ -176,7 +177,7 @@ static const struct CMD cmds[] = {
176 { "lchdir", I_LCHDIR, LOCAL }, 177 { "lchdir", I_LCHDIR, LOCAL },
177 { "lls", I_LLS, LOCAL }, 178 { "lls", I_LLS, LOCAL },
178 { "lmkdir", I_LMKDIR, LOCAL }, 179 { "lmkdir", I_LMKDIR, LOCAL },
179 { "ln", I_SYMLINK, REMOTE }, 180 { "ln", I_LINK, REMOTE },
180 { "lpwd", I_LPWD, LOCAL }, 181 { "lpwd", I_LPWD, LOCAL },
181 { "ls", I_LS, REMOTE }, 182 { "ls", I_LS, REMOTE },
182 { "lumask", I_LUMASK, NOARGS }, 183 { "lumask", I_LUMASK, NOARGS },
@@ -240,7 +241,7 @@ help(void)
240 "lcd path Change local directory to 'path'\n" 241 "lcd path Change local directory to 'path'\n"
241 "lls [ls-options [path]] Display local directory listing\n" 242 "lls [ls-options [path]] Display local directory listing\n"
242 "lmkdir path Create local directory\n" 243 "lmkdir path Create local directory\n"
243 "ln oldpath newpath Symlink remote file\n" 244 "ln [-s] oldpath newpath Link remote file (-s for symlink)\n"
244 "lpwd Print local working directory\n" 245 "lpwd Print local working directory\n"
245 "ls [-1afhlnrSt] [path] Display remote directory listing\n" 246 "ls [-1afhlnrSt] [path] Display remote directory listing\n"
246 "lumask umask Set local umask to 'umask'\n" 247 "lumask umask Set local umask to 'umask'\n"
@@ -377,6 +378,30 @@ parse_getput_flags(const char *cmd, char **argv, int argc, int *pflag,
377} 378}
378 379
379static int 380static int
381parse_link_flags(const char *cmd, char **argv, int argc, int *sflag)
382{
383 extern int opterr, optind, optopt, optreset;
384 int ch;
385
386 optind = optreset = 1;
387 opterr = 0;
388
389 *sflag = 0;
390 while ((ch = getopt(argc, argv, "s")) != -1) {
391 switch (ch) {
392 case 's':
393 *sflag = 1;
394 break;
395 default:
396 error("%s: Invalid flag -%c", cmd, optopt);
397 return -1;
398 }
399 }
400
401 return optind;
402}
403
404static int
380parse_ls_flags(char **argv, int argc, int *lflag) 405parse_ls_flags(char **argv, int argc, int *lflag)
381{ 406{
382 extern int opterr, optind, optopt, optreset; 407 extern int opterr, optind, optopt, optreset;
@@ -1088,7 +1113,7 @@ makeargv(const char *arg, int *argcp, int sloppy, char *lastquote,
1088 1113
1089static int 1114static int
1090parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag, 1115parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1091 int *hflag, unsigned long *n_arg, char **path1, char **path2) 1116 int *hflag, int *sflag, unsigned long *n_arg, char **path1, char **path2)
1092{ 1117{
1093 const char *cmd, *cp = *cpp; 1118 const char *cmd, *cp = *cpp;
1094 char *cp2, **argv; 1119 char *cp2, **argv;
@@ -1138,7 +1163,8 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1138 switch (cmdnum) { 1163 switch (cmdnum) {
1139 case I_GET: 1164 case I_GET:
1140 case I_PUT: 1165 case I_PUT:
1141 if ((optidx = parse_getput_flags(cmd, argv, argc, pflag, rflag)) == -1) 1166 if ((optidx = parse_getput_flags(cmd, argv, argc,
1167 pflag, rflag)) == -1)
1142 return -1; 1168 return -1;
1143 /* Get first pathname (mandatory) */ 1169 /* Get first pathname (mandatory) */
1144 if (argc - optidx < 1) { 1170 if (argc - optidx < 1) {
@@ -1154,8 +1180,11 @@ parse_args(const char **cpp, int *pflag, int *rflag, int *lflag, int *iflag,
1154 undo_glob_escape(*path2); 1180 undo_glob_escape(*path2);
1155 } 1181 }
1156 break; 1182 break;
1157 case I_RENAME: 1183 case I_LINK:
1184 if ((optidx = parse_link_flags(cmd, argv, argc, sflag)) == -1)
1185 return -1;
1158 case I_SYMLINK: 1186 case I_SYMLINK:
1187 case I_RENAME:
1159 if (argc - optidx < 2) { 1188 if (argc - optidx < 2) {
1160 error("You must specify two paths after a %s " 1189 error("You must specify two paths after a %s "
1161 "command.", cmd); 1190 "command.", cmd);
@@ -1258,7 +1287,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1258 int err_abort) 1287 int err_abort)
1259{ 1288{
1260 char *path1, *path2, *tmp; 1289 char *path1, *path2, *tmp;
1261 int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i; 1290 int pflag = 0, rflag = 0, lflag = 0, iflag = 0, hflag = 0, sflag = 0;
1291 int cmdnum, i;
1262 unsigned long n_arg = 0; 1292 unsigned long n_arg = 0;
1263 Attrib a, *aa; 1293 Attrib a, *aa;
1264 char path_buf[MAXPATHLEN]; 1294 char path_buf[MAXPATHLEN];
@@ -1266,8 +1296,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1266 glob_t g; 1296 glob_t g;
1267 1297
1268 path1 = path2 = NULL; 1298 path1 = path2 = NULL;
1269 cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag, &n_arg, 1299 cmdnum = parse_args(&cmd, &pflag, &rflag, &lflag, &iflag, &hflag,
1270 &path1, &path2); 1300 &sflag, &n_arg, &path1, &path2);
1271 1301
1272 if (iflag != 0) 1302 if (iflag != 0)
1273 err_abort = 0; 1303 err_abort = 0;
@@ -1295,8 +1325,11 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd,
1295 err = do_rename(conn, path1, path2); 1325 err = do_rename(conn, path1, path2);
1296 break; 1326 break;
1297 case I_SYMLINK: 1327 case I_SYMLINK:
1328 sflag = 1;
1329 case I_LINK:
1330 path1 = make_absolute(path1, *pwd);
1298 path2 = make_absolute(path2, *pwd); 1331 path2 = make_absolute(path2, *pwd);
1299 err = do_symlink(conn, path1, path2); 1332 err = (sflag ? do_symlink : do_hardlink)(conn, path1, path2);
1300 break; 1333 break;
1301 case I_RM: 1334 case I_RM:
1302 path1 = make_absolute(path1, *pwd); 1335 path1 = make_absolute(path1, *pwd);