RFile *open_existing_file(char *name, uint64 *size, unsigned long *mtime, unsigned long *atime) { HANDLE h; RFile *ret; h = CreateFile(name, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (h == INVALID_HANDLE_VALUE) return NULL; ret = snew(RFile); ret->h = h; if (size) size->lo=GetFileSize(h, &(size->hi)); if (mtime || atime) { FILETIME actime, wrtime; GetFileTime(h, NULL, &actime, &wrtime); if (atime) TIME_WIN_TO_POSIX(actime, *atime); if (mtime) TIME_WIN_TO_POSIX(wrtime, *mtime); } return ret; }
/* * Execute the source part of the SCP protocol. */ static void source(char *src) { char buf[2048]; unsigned long size; char *last; HANDLE f; DWORD attr; unsigned long i; unsigned long stat_bytes; time_t stat_starttime, stat_lasttime; attr = GetFileAttributes(src); if (attr == (DWORD)-1) { run_err("%s: No such file or directory", src); return; } if ((attr & FILE_ATTRIBUTE_DIRECTORY) != 0) { if (recursive) { /* * Avoid . and .. directories. */ char *p; p = strrchr(src, '/'); if (!p) p = strrchr(src, '\\'); if (!p) p = src; else p++; if (!strcmp(p, ".") || !strcmp(p, "..")) /* skip . and .. */; else rsource(src); } else { run_err("%s: not a regular file", src); } return; } if ((last = strrchr(src, '/')) == NULL) last = src; else last++; if (strrchr(last, '\\') != NULL) last = strrchr(last, '\\') + 1; if (last == src && strchr(src, ':') != NULL) last = strchr(src, ':') + 1; f = CreateFile(src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (f == INVALID_HANDLE_VALUE) { run_err("%s: Cannot open file", src); return; } if (preserve) { FILETIME actime, wrtime; unsigned long mtime, atime; GetFileTime(f, NULL, &actime, &wrtime); TIME_WIN_TO_POSIX(actime, atime); TIME_WIN_TO_POSIX(wrtime, mtime); sprintf(buf, "T%lu 0 %lu 0\n", mtime, atime); ssh_send(buf, strlen(buf)); if (response()) return; } size = GetFileSize(f, NULL); sprintf(buf, "C0644 %lu %s\n", size, last); if (verbose) fprintf(stderr, "Sending file modes: %s", buf); ssh_send(buf, strlen(buf)); if (response()) return; if (statistics) { stat_bytes = 0; stat_starttime = time(NULL); stat_lasttime = 0; } for (i = 0; i < size; i += 4096) { char transbuf[4096]; DWORD j, k = 4096; if (i + k > size) k = size - i; if (! ReadFile(f, transbuf, k, &j, NULL) || j != k) { if (statistics) printf("\n"); bump("%s: Read error", src); } ssh_send(transbuf, k); if (statistics) { stat_bytes += k; if (time(NULL) != stat_lasttime || i + k == size) { stat_lasttime = time(NULL); print_stats(last, size, stat_bytes, stat_starttime, stat_lasttime); } } } CloseHandle(f); ssh_send("", 1); (void) response(); }