I fixed the most things.

It took me a while to figure out what that code does, so I think the
comments are usefull for everybody who tries to read it.

The file type information comes from this special remglob2() function.
There is no equivalent thing in the context of mput().  So I check the
local file type with stat(2) and S_ISDIR().

The makedir() function has no return value, so it is not posible at the
moment to detect an error inside that function.

Here is the current diff.

bye,
Jan

Index: cmds.c
===================================================================
RCS file: /cvs/src/usr.bin/ftp/cmds.c,v
retrieving revision 1.70
diff -u -p -r1.70 cmds.c
--- cmds.c      5 May 2009 19:35:30 -0000       1.70
+++ cmds.c      13 Jul 2012 01:10:57 -0000
@@ -231,15 +231,32 @@ mput(int argc, char *argv[])
        extern int optind, optreset;
        int ch, i, restartit = 0;
        sig_t oldintr;
-       char *cmd, *tp;
+       char *cmd, *tp, *xargv[] = {argv[0], NULL, NULL};
+       const char *errstr;
+       static int depth = 0, max_depth = 0;
 
        optind = optreset = 1;
 
-       while ((ch = getopt(argc, argv, "c")) != -1) {
+       if (depth)
+               depth++;
+
+       while ((ch = getopt(argc, argv, "cd:r")) != -1) {
                switch(ch) {
                case 'c':
                        restartit = 1;
                        break;
+               case 'd':
+                       max_depth = strtonum(optarg, 0, INT_MAX, &errstr);
+                       if (errstr != NULL) {
+                               fprintf(ttyout, "bad depth value, %s: %s\n",
+                                   errstr, optarg);
+                               code = -1;
+                               return;
+                       }
+                       break;
+               case 'r':
+                       depth = 1;
+                       break;
                default:
                        goto usage;
                }
@@ -247,7 +264,8 @@ mput(int argc, char *argv[])
 
        if (argc - optind < 1 && !another(&argc, &argv, "local-files")) {
 usage:
-               fprintf(ttyout, "usage: %s [-c] local-files\n", argv[0]);
+               fprintf(ttyout, "usage: %s [-cr] [-d depth] local-files\n",
+                   argv[0]);
                code = -1;
                return;
        }
@@ -318,11 +336,13 @@ usage:
                mflag = 0;
                return;
        }
+
        for (i = 1; i < argc; i++) {
                char **cpp;
                glob_t gl;
                int flags;
 
+               /* Copy files without word expansion */
                if (!doglob) {
                        if (mflag && confirm(argv[0], argv[i])) {
                                tp = (ntflag) ? dotrans(argv[i]) : argv[i];
@@ -348,6 +368,7 @@ usage:
                        continue;
                }
 
+               /* expanding file names */
                memset(&gl, 0, sizeof(gl));
                flags = GLOB_BRACE|GLOB_NOCHECK|GLOB_QUOTE|GLOB_TILDE;
                if (glob(argv[i], flags, NULL, &gl) || gl.gl_pathc == 0) {
@@ -355,8 +376,58 @@ usage:
                        globfree(&gl);
                        continue;
                }
+
+               /* traverse all expanded file names */
                for (cpp = gl.gl_pathv; cpp && *cpp != NULL; cpp++) {
+                       struct stat filestat;
+
                        if (mflag && confirm(argv[0], *cpp)) {
+
+                               /*
+                                * If file is a directory then create a new one
+                                * at the remote machine.
+                                */
+                               stat(*cpp, &filestat);
+
+                               if (S_ISDIR(filestat.st_mode)) {
+
+                                       if (depth == max_depth)
+                                               continue;
+
+                                       xargv[1] = *cpp;
+                                       makedir(2, xargv);
+
+                                       /*
+                                        * Copy the hole directory recursivly.
+                                        */
+                                       if (chdir(*cpp) != 0) {
+                                               warn("local: %s", *cpp);
+                                               continue;
+                                       }
+
+                                       xargv[1] = *cpp;
+                                       cd(2, xargv);
+                                       if (dirchange != 1) {
+                                               mflag = 0;
+                                               goto out;
+                                       }
+
+                                       xargv[1] = "*";
+                                       mput(2, xargv);
+
+                                       xargv[1] = "..";
+                                       cd(2, xargv);
+                                       if (dirchange != 1)
+                                               mflag = 0;
+
+ out:
+                                       if (chdir("..") != 0) {
+                                               warn("local: %s", *cpp);
+                                               mflag = 0;
+                                       }
+                                       continue;
+                               }
+
                                tp = (ntflag) ? dotrans(*cpp) : *cpp;
                                tp = (mapflag) ? domap(tp) : tp;
                                if (restartit == 1) {
@@ -380,8 +451,13 @@ usage:
                }
                globfree(&gl);
        }
+
        (void)signal(SIGINT, oldintr);
-       mflag = 0;
+
+       if (depth)
+               depth--;
+       if (depth == 0 || mflag == 0)
+               depth = max_depth = mflag = 0;
 }
 
 void
Index: ftp.1
===================================================================
RCS file: /cvs/src/usr.bin/ftp/ftp.1,v
retrieving revision 1.82
diff -u -p -r1.82 ftp.1
--- ftp.1       30 Apr 2012 13:41:26 -0000      1.82
+++ ftp.1       13 Jul 2012 01:10:58 -0000
@@ -664,7 +664,8 @@ on the remote machine.
 A synonym for
 .Ic page .
 .It Xo Ic mput
-.Op Fl c
+.Op Fl cr
+.Op Fl d Ar depth
 .Ar local-files
 .Xc
 Expand wild cards in the list of local files given as arguments
@@ -683,9 +684,21 @@ settings.
 If the
 .Fl c
 flag is specified then
+The options are as follows:
+.Bl -tag -width Ds
+.It Fl c
+Use
 .Ic reput
-is used instead of
+instead of
 .Ic put .
+.It Fl d Ar depth
+Specify the maximum recursion level
+.Ar depth .
+The default is 0, which means unlimited.
+.It Fl r
+Recursively descend the directory tree, transferring all files and
+directories.
+.El
 .It Xo Ic msend
 .Op Fl c
 .Ar local-files

Reply via email to