diff -wru puppy_1.11/puppy.c puppy_1.11-new/puppy.c --- puppy_1.11/puppy.c 2005-08-27 20:09:46.000000000 +0300 +++ puppy_1.11-new/puppy.c 2006-08-30 18:27:35.000000000 +0300 @@ -93,6 +93,110 @@ #define E_GLOBAL_LOCK 8 #define E_RESET_DEVICE 9 +static int flag_encode = 0; + +char *path_decode(char *path) { + char *p = path; + char *buf, *b; + + if (!flag_encode) { + return strdup(path); + } + + buf = (char *)malloc(strlen(path) + 1); + if (!buf) { + fprintf(stderr, "ERROR: Out of memory - exiting\n"); + exit(1); + } + b = buf; + + while (*p) { + int d1, d0; + + switch (*p) { + case '%': + if (p[1] == 0 || p[2] == 0) goto err; + + if (p[1] >= '0' && p[1] <= '9') { + d1 = p[1] - '0'; + } else { + d1 = (p[1] | 0x20) - 'a' + 10; + } + if (d1 < 0 || d1 > 15) goto err; + + if (p[2] >= '0' && p[2] <= '9') { + d0 = p[2] - '0'; + } else { + d0 = (p[2] | 0x20) - 'a' + 10; + } + if (d0 < 0 || d0 > 15) goto err; + + *b++ = 16*d1 + d0; + p += 3; + + break; + + case '/': + *b++ = '\\'; + p++; + break; + + default: + *b++ = *p++; + break; + } + } + + *b = 0; + return buf; + +err: + fprintf(stderr, "ERROR: Illegal path encoding\n"); + free(buf); + return 0; +} + +static char *path_encode(char *path) { + char *p = path; + char *buf, *b; + + if (!flag_encode) { + return strdup(path); + } + + buf = (char *)(malloc(3*strlen(path) + 1)); + if (!buf) { + fprintf(stderr, "ERROR: Out of memory - exiting\n"); + exit(1); + } + b = buf; + + while (*p) { + char c = *p++; + int np = 0; + + if (c < 'A') np = 1; + if (c > 'z') np = 1; + if (c > 'Z' && c < 'a') np = 1; + if (c >= '0' && c <= '9') np = 0; +#if 0 + // this is not exactly a path (from dir) + if (c == '\\') np = 0; +#endif + if (c == '.') np = 0; + + if (np) { + sprintf(b, "%%%02x", c); + b += 3; + } else { + *b++ = c; + } + } + + *b = 0; + return buf; +} + int main(int argc, char *argv[]) { struct usb_device_descriptor devDesc; @@ -442,11 +546,16 @@ return -EPROTO; } -int do_hdd_dir(int fd, char *path) +int do_hdd_dir(int fd, char *Path) { int r; + char *path; + path = path_decode(Path); + if (!path) return E_INVALID_ARGS; r = send_cmd_hdd_dir(fd, path); + free(path); + if(r < 0) { return -EPROTO; @@ -486,6 +595,7 @@ struct typefile *entries = (struct typefile *) p->data; int i; time_t timestamp; + char *path; for(i = 0; (i < count); i++) { @@ -509,12 +619,14 @@ * that puppy runs on are the same. Given the limitations on the length of * USB cables, this condition is likely to be satisfied. */ timestamp = tfdt_to_time(&entries[i].stamp); + path = path_encode((char *)entries[i].name); printf("%c %20llu %24.24s %s\n", type, get_u64(&entries[i].size), - ctime(×tamp), entries[i].name); + ctime(×tamp), path); + free(path); } } -int do_hdd_file_put(int fd, char *srcPath, char *dstPath) +int do_hdd_file_put(int fd, char *srcPath, char *DstPath) { int result = -EPROTO; time_t startTime = time(NULL); @@ -531,6 +643,7 @@ struct stat64 srcStat; __u64 fileSize; __u64 byteCount = 0; + char *dstPath = 0; trace(4, fprintf(stderr, "%s\n", __func__)); @@ -558,6 +671,8 @@ goto out; } + dstPath = path_decode(DstPath); + if (!dstPath) return E_INVALID_ARGS; r = send_cmd_hdd_file_send(fd, PUT, dstPath); if(r < 0) { @@ -685,11 +800,12 @@ finalStats(byteCount, startTime); out: + if (dstPath) free(dstPath); close(src); return result; } -int do_hdd_file_get(int fd, char *srcPath, char *dstPath) +int do_hdd_file_get(int fd, char *SrcPath, char *dstPath) { int result = -EPROTO; time_t startTime = time(NULL); @@ -704,6 +820,7 @@ int update = 0; __u64 byteCount = 0; struct utimbuf mod_utime_buf = { 0, 0 }; + char *srcPath = 0; dst = open64(dstPath, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); @@ -714,6 +831,8 @@ return errno; } + srcPath = path_decode(SrcPath); + if (!srcPath) return E_INVALID_ARGS; r = send_cmd_hdd_file_send(fd, GET, srcPath); if(r < 0) { @@ -815,15 +934,21 @@ finalStats(byteCount, startTime); out: + if (srcPath) free(srcPath); close(dst); return result; } -int do_hdd_del(int fd, char *path) +int do_hdd_del(int fd, char *Path) { int r; + char *path; + path = path_decode(Path); + if (!path) return E_INVALID_ARGS; r = send_cmd_hdd_del(fd, path); + free(path); + if(r < 0) { return -EPROTO; @@ -851,11 +976,23 @@ return -EPROTO; } -int do_hdd_rename(int fd, char *srcPath, char *dstPath) +int do_hdd_rename(int fd, char *SrcPath, char *DstPath) { int r; + char *srcPath, *dstPath; + + srcPath = path_decode(SrcPath); + if (!srcPath) return E_INVALID_ARGS; + dstPath = path_decode(DstPath); + if (!dstPath) { + free(srcPath); + return E_INVALID_ARGS; + } r = send_cmd_hdd_rename(fd, srcPath, dstPath); + free(srcPath); + free(dstPath); + if(r < 0) { return -EPROTO; @@ -883,11 +1020,16 @@ return -EPROTO; } -int do_hdd_mkdir(int fd, char *path) +int do_hdd_mkdir(int fd, char *Path) { int r; + char *path; + path = path_decode(Path); + if (!path) return E_INVALID_ARGS; r = send_cmd_hdd_create_dir(fd, path); + free(path); + if(r < 0) { return -EPROTO; @@ -955,7 +1097,7 @@ void usage(char *myName) { char *usageString = - "Usage: %s [-pPqv] [-d ] -c [args]\n" + "Usage: %s [-pPqve] [-d ] -c [args]\n" " -p - packet header output to stderr\n" " -P - full packet dump output to stderr\n" " -q - quiet transfers - no progress updates\n" @@ -963,6 +1105,7 @@ " -d - USB device (must be usbfs)\n" " for example /proc/bus/usb/001/003\n" " -c - one of size, dir, get, put, rename, delete, mkdir, reboot, cancel, turbo\n" + " -e - encode/decode paths using URL escapes %%xx\n" " args - optional arguments, as required by each command\n\n" "Version: " PUPPY_RELEASE ", Compiled: " __DATE__ "\n"; fprintf(stderr, usageString, myName); @@ -974,10 +1117,14 @@ extern int optind; int c; - while((c = getopt(argc, argv, "pPqvd:c:")) != -1) + while((c = getopt(argc, argv, "epPqvd:c:")) != -1) { switch (c) { + case 'e': + flag_encode = 1; + break; + case 'v': verbose++; break;