... and there's a Unix port of PSCP. Ooh.
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 25 Aug 2003 14:30:59 +0000 (14:30 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Mon, 25 Aug 2003 14:30:59 +0000 (14:30 +0000)
git-svn-id: svn://svn.tartarus.org/sgt/putty@3422 cda61777-01e9-0310-a592-d414129be87e

psftp.h
scp.c
unix/uxsftp.c
winsftp.c

diff --git a/psftp.h b/psftp.h
index 8eb1187..44911f5 100644 (file)
--- a/psftp.h
+++ b/psftp.h
@@ -141,4 +141,10 @@ void finish_wildcard_matching(WildcardMatcher *dir);
  */\r
 int create_directory(char *name);\r
 \r
+/*\r
+ * Concatenate a directory name and a file name. The way this is\r
+ * done will depend on the OS.\r
+ */\r
+char *dir_file_cat(char *dir, char *file);\r
+\r
 #endif /* PUTTY_PSFTP_H */\r
diff --git a/scp.c b/scp.c
index 53cb60a..00852bc 100644 (file)
--- a/scp.c
+++ b/scp.c
@@ -1711,7 +1711,7 @@ static void sink(char *targ, char *src)
            }
 
            if (targ[0] != '\0')
-               destfname = dupcat(targ, "\\", striptarget, NULL);
+               destfname = dir_file_cat(targ, striptarget);
            else
                destfname = dupstr(striptarget);
        } else {
index d1989f8..69d4c45 100644 (file)
@@ -4,8 +4,13 @@
 \r
 #include <sys/time.h>\r
 #include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <fcntl.h>\r
+#include <dirent.h>\r
 #include <unistd.h>\r
+#include <utime.h>\r
 #include <errno.h>\r
+#include <assert.h>\r
 \r
 #include "putty.h"\r
 #include "psftp.h"\r
@@ -109,6 +114,211 @@ char *psftp_getcwd(void)
     }\r
 }\r
 \r
+struct RFile {\r
+    int fd;\r
+};\r
+\r
+RFile *open_existing_file(char *name, unsigned long *size,\r
+                         unsigned long *mtime, unsigned long *atime)\r
+{\r
+    int fd;\r
+    RFile *ret;\r
+\r
+    fd = open(name, O_RDONLY);\r
+    if (fd < 0)\r
+       return NULL;\r
+\r
+    ret = snew(RFile);\r
+    ret->fd = fd;\r
+\r
+    if (size || mtime || atime) {\r
+       struct stat statbuf;\r
+       if (fstat(fd, &statbuf) < 0) {\r
+           fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));\r
+           memset(&statbuf, 0, sizeof(statbuf));\r
+       }\r
+\r
+       if (size)\r
+           *size = statbuf.st_size;\r
+\r
+       if (mtime)\r
+           *mtime = statbuf.st_mtime;\r
+\r
+       if (atime)\r
+           *atime = statbuf.st_atime;\r
+    }\r
+\r
+    return ret;\r
+}\r
+\r
+int read_from_file(RFile *f, void *buffer, int length)\r
+{\r
+    return read(f->fd, buffer, length);\r
+}\r
+\r
+void close_rfile(RFile *f)\r
+{\r
+    close(f->fd);\r
+    sfree(f);\r
+}\r
+\r
+struct WFile {\r
+    int fd;\r
+    char *name;\r
+};\r
+\r
+WFile *open_new_file(char *name)\r
+{\r
+    int fd;\r
+    WFile *ret;\r
+\r
+    fd = open(name, O_CREAT | O_TRUNC | O_WRONLY, 0666);\r
+    if (fd < 0)\r
+       return NULL;\r
+\r
+    ret = snew(WFile);\r
+    ret->fd = fd;\r
+    ret->name = dupstr(name);\r
+\r
+    return ret;\r
+}\r
+\r
+int write_to_file(WFile *f, void *buffer, int length)\r
+{\r
+    char *p = (char *)buffer;\r
+    int so_far = 0;\r
+\r
+    /* Keep trying until we've really written as much as we can. */\r
+    while (length > 0) {\r
+       int ret = write(f->fd, p, length);\r
+\r
+       if (ret < 0)\r
+           return ret;\r
+\r
+       if (ret == 0)\r
+           break;\r
+\r
+       p += ret;\r
+       length -= ret;\r
+       so_far += ret;\r
+    }\r
+\r
+    return so_far;\r
+}\r
+\r
+void set_file_times(WFile *f, unsigned long mtime, unsigned long atime)\r
+{\r
+    struct utimbuf ut;\r
+\r
+    ut.actime = atime;\r
+    ut.modtime = mtime;\r
+\r
+    utime(f->name, &ut);\r
+}\r
+\r
+/* Closes and frees the WFile */\r
+void close_wfile(WFile *f)\r
+{\r
+    close(f->fd);\r
+    sfree(f->name);\r
+    sfree(f);\r
+}\r
+\r
+int file_type(char *name)\r
+{\r
+    struct stat statbuf;\r
+\r
+    if (stat(name, &statbuf) < 0) {\r
+       if (errno != ENOENT)\r
+           fprintf(stderr, "%s: stat: %s\n", name, strerror(errno));\r
+       return FILE_TYPE_NONEXISTENT;\r
+    }\r
+\r
+    if (S_ISREG(statbuf.st_mode))\r
+       return FILE_TYPE_FILE;\r
+\r
+    if (S_ISDIR(statbuf.st_mode))\r
+       return FILE_TYPE_DIRECTORY;\r
+\r
+    return FILE_TYPE_WEIRD;\r
+}\r
+\r
+struct DirHandle {\r
+    DIR *dir;\r
+};\r
+\r
+DirHandle *open_directory(char *name)\r
+{\r
+    DIR *dir;\r
+    DirHandle *ret;\r
+\r
+    dir = opendir(name);\r
+    if (!dir)\r
+       return NULL;\r
+\r
+    ret = snew(DirHandle);\r
+    ret->dir = dir;\r
+    return ret;\r
+}\r
+\r
+char *read_filename(DirHandle *dir)\r
+{\r
+    struct dirent *de;\r
+\r
+    do {\r
+       de = readdir(dir->dir);\r
+       if (de == NULL)\r
+           return NULL;\r
+    } while ((de->d_name[0] == '.' &&\r
+             (de->d_name[1] == '\0' ||\r
+              (de->d_name[1] == '.' && de->d_name[2] == '\0'))));\r
+\r
+    return dupstr(de->d_name);\r
+}\r
+\r
+void close_directory(DirHandle *dir)\r
+{\r
+    closedir(dir->dir);\r
+    sfree(dir);\r
+}\r
+\r
+int test_wildcard(char *name, int cmdline)\r
+{\r
+    /*\r
+     * On Unix, we currently don't support local wildcards at all.\r
+     * We will have to do so (FIXME) once PSFTP starts implementing\r
+     * mput, but until then we can assume `cmdline' is always set.\r
+     */\r
+    struct stat statbuf;\r
+\r
+    assert(cmdline);\r
+    if (stat(name, &statbuf) < 0)\r
+       return WCTYPE_NONEXISTENT;\r
+    else\r
+       return WCTYPE_FILENAME;\r
+}\r
+\r
+/*\r
+ * Actually return matching file names for a local wildcard. FIXME:\r
+ * we currently don't support this at all.\r
+ */\r
+struct WildcardMatcher {\r
+    int x;\r
+};\r
+WildcardMatcher *begin_wildcard_matching(char *name) { return NULL; }\r
+char *wildcard_get_filename(WildcardMatcher *dir) { return NULL; }\r
+void finish_wildcard_matching(WildcardMatcher *dir) {}\r
+\r
+int create_directory(char *name)\r
+{\r
+    return mkdir(name, 0777) == 0;\r
+}\r
+\r
+char *dir_file_cat(char *dir, char *file)\r
+{\r
+    return dupcat(dir, "/", file, NULL);\r
+}\r
+\r
 /*\r
  * Wait for some network data and process it.\r
  */\r
index a4dafd4..6687210 100644 (file)
--- a/winsftp.c
+++ b/winsftp.c
@@ -303,6 +303,7 @@ DirHandle *open_directory(char *name)
     h = FindFirstFile(findfile, &fdat);
     if (h == INVALID_HANDLE_VALUE)
        return NULL;
+    sfree(findfile);
 
     ret = snew(DirHandle);
     ret->h = h;
@@ -312,11 +313,18 @@ DirHandle *open_directory(char *name)
 
 char *read_filename(DirHandle *dir)
 {
-    if (!dir->name) {
+    while (!dir->name) {
        WIN32_FIND_DATA fdat;
        int ok = FindNextFile(dir->h, &fdat);
 
-       if (ok)
+       if (!ok)
+           return NULL;
+
+       if (fdat.cFileName[0] == '.' &&
+           (fdat.cFileName[1] == '\0' ||
+            (fdat.cFileName[1] == '.' && fdat.cFileName[2] == '\0')))
+           dir->name = NULL;
+       else
            dir->name = dupstr(fdat.cFileName);
     }
 
@@ -449,6 +457,11 @@ int create_directory(char *name)
     return CreateDirectory(name, NULL) != 0;
 }
 
+char *dir_file_cat(char *dir, char *file)
+{
+    return dupcat(dir, "\\", file, NULL);
+}
+
 /* ----------------------------------------------------------------------
  * Platform-specific network handling.
  */