Fossil SCM
Fix --chdir on Windows/Cygwin when using non-ascii characters or characters invalid for win32 filenames. On Cygwin, allow enter_chroot_jail() using win32 paths as well.
Commit
12bc63aae53e482cd769c07d814cc8254847760d
Parent
e09d84f297f3018…
2 files changed
+21
+3
-3
+21
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -313,10 +313,31 @@ | ||
| 313 | 313 | int rc = access(zMbcs, flags); |
| 314 | 314 | #endif |
| 315 | 315 | fossil_filename_free(zMbcs); |
| 316 | 316 | return rc; |
| 317 | 317 | } |
| 318 | + | |
| 319 | +/* | |
| 320 | +** Wrapper around the chdir() system call. | |
| 321 | +** If bChroot=1, do a chroot to this dir as well | |
| 322 | +** (UNIX only) | |
| 323 | +*/ | |
| 324 | +int file_chdir(const char *zChDir, int bChroot){ | |
| 325 | +#ifdef _WIN32 | |
| 326 | + wchar_t *zPath = fossil_utf8_to_filename(zChDir); | |
| 327 | + int rc = _wchdir(zPath); | |
| 328 | +#else | |
| 329 | + char *zPath = fossil_utf8_to_filename(zChDir); | |
| 330 | + int rc = chdir(zPath); | |
| 331 | + if( !rc && bChroot ){ | |
| 332 | + rc = chroot(zPath); | |
| 333 | + if( !rc ) rc = chdir("/"); | |
| 334 | + } | |
| 335 | +#endif | |
| 336 | + fossil_filename_free(zPath); | |
| 337 | + return rc; | |
| 338 | +} | |
| 318 | 339 | |
| 319 | 340 | /* |
| 320 | 341 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 321 | 342 | ** |
| 322 | 343 | ** Make the name relative to the working directory if relFlag is true. |
| 323 | 344 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -313,10 +313,31 @@ | |
| 313 | int rc = access(zMbcs, flags); |
| 314 | #endif |
| 315 | fossil_filename_free(zMbcs); |
| 316 | return rc; |
| 317 | } |
| 318 | |
| 319 | /* |
| 320 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 321 | ** |
| 322 | ** Make the name relative to the working directory if relFlag is true. |
| 323 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -313,10 +313,31 @@ | |
| 313 | int rc = access(zMbcs, flags); |
| 314 | #endif |
| 315 | fossil_filename_free(zMbcs); |
| 316 | return rc; |
| 317 | } |
| 318 | |
| 319 | /* |
| 320 | ** Wrapper around the chdir() system call. |
| 321 | ** If bChroot=1, do a chroot to this dir as well |
| 322 | ** (UNIX only) |
| 323 | */ |
| 324 | int file_chdir(const char *zChDir, int bChroot){ |
| 325 | #ifdef _WIN32 |
| 326 | wchar_t *zPath = fossil_utf8_to_filename(zChDir); |
| 327 | int rc = _wchdir(zPath); |
| 328 | #else |
| 329 | char *zPath = fossil_utf8_to_filename(zChDir); |
| 330 | int rc = chdir(zPath); |
| 331 | if( !rc && bChroot ){ |
| 332 | rc = chroot(zPath); |
| 333 | if( !rc ) rc = chdir("/"); |
| 334 | } |
| 335 | #endif |
| 336 | fossil_filename_free(zPath); |
| 337 | return rc; |
| 338 | } |
| 339 | |
| 340 | /* |
| 341 | ** Find an unused filename similar to zBase with zSuffix appended. |
| 342 | ** |
| 343 | ** Make the name relative to the working directory if relFlag is true. |
| 344 |
+3
-3
| --- src/main.c | ||
| +++ src/main.c | ||
| @@ -559,11 +559,11 @@ | ||
| 559 | 559 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 560 | 560 | g.zLogin = find_option("user", "U", 1); |
| 561 | 561 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 562 | 562 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 563 | 563 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 564 | - if( zChdir && chdir(zChdir) ){ | |
| 564 | + if( zChdir && file_chdir(zChdir, 0) ){ | |
| 565 | 565 | fossil_fatal("unable to change directories to %s", zChdir); |
| 566 | 566 | } |
| 567 | 567 | if( find_option("help",0,0)!=0 ){ |
| 568 | 568 | /* --help anywhere on the command line is translated into |
| 569 | 569 | ** "fossil help argv[1] argv[2]..." */ |
| @@ -1086,20 +1086,20 @@ | ||
| 1086 | 1086 | char *zDir; |
| 1087 | 1087 | |
| 1088 | 1088 | file_canonical_name(zRepo, &dir, 0); |
| 1089 | 1089 | zDir = blob_str(&dir); |
| 1090 | 1090 | if( file_isdir(zDir)==1 ){ |
| 1091 | - if( chdir(zDir) || chroot(zDir) || chdir("/") ){ | |
| 1091 | + if( file_chdir(zDir, 1) ){ | |
| 1092 | 1092 | fossil_fatal("unable to chroot into %s", zDir); |
| 1093 | 1093 | } |
| 1094 | 1094 | zRepo = "/"; |
| 1095 | 1095 | }else{ |
| 1096 | 1096 | for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){} |
| 1097 | 1097 | if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo); |
| 1098 | 1098 | if( i>0 ){ |
| 1099 | 1099 | zDir[i] = 0; |
| 1100 | - if( chdir(zDir) || chroot(zDir) || chdir("/") ){ | |
| 1100 | + if( file_chdir(zDir, 1) ){ | |
| 1101 | 1101 | fossil_fatal("unable to chroot into %s", zDir); |
| 1102 | 1102 | } |
| 1103 | 1103 | zDir[i] = '/'; |
| 1104 | 1104 | } |
| 1105 | 1105 | zRepo = &zDir[i]; |
| 1106 | 1106 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -559,11 +559,11 @@ | |
| 559 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 560 | g.zLogin = find_option("user", "U", 1); |
| 561 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 562 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 563 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 564 | if( zChdir && chdir(zChdir) ){ |
| 565 | fossil_fatal("unable to change directories to %s", zChdir); |
| 566 | } |
| 567 | if( find_option("help",0,0)!=0 ){ |
| 568 | /* --help anywhere on the command line is translated into |
| 569 | ** "fossil help argv[1] argv[2]..." */ |
| @@ -1086,20 +1086,20 @@ | |
| 1086 | char *zDir; |
| 1087 | |
| 1088 | file_canonical_name(zRepo, &dir, 0); |
| 1089 | zDir = blob_str(&dir); |
| 1090 | if( file_isdir(zDir)==1 ){ |
| 1091 | if( chdir(zDir) || chroot(zDir) || chdir("/") ){ |
| 1092 | fossil_fatal("unable to chroot into %s", zDir); |
| 1093 | } |
| 1094 | zRepo = "/"; |
| 1095 | }else{ |
| 1096 | for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){} |
| 1097 | if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo); |
| 1098 | if( i>0 ){ |
| 1099 | zDir[i] = 0; |
| 1100 | if( chdir(zDir) || chroot(zDir) || chdir("/") ){ |
| 1101 | fossil_fatal("unable to chroot into %s", zDir); |
| 1102 | } |
| 1103 | zDir[i] = '/'; |
| 1104 | } |
| 1105 | zRepo = &zDir[i]; |
| 1106 |
| --- src/main.c | |
| +++ src/main.c | |
| @@ -559,11 +559,11 @@ | |
| 559 | g.fHttpTrace = find_option("httptrace", 0, 0)!=0; |
| 560 | g.zLogin = find_option("user", "U", 1); |
| 561 | g.zSSLIdentity = find_option("ssl-identity", 0, 1); |
| 562 | if( find_option("utc",0,0) ) g.fTimeFormat = 1; |
| 563 | if( find_option("localtime",0,0) ) g.fTimeFormat = 2; |
| 564 | if( zChdir && file_chdir(zChdir, 0) ){ |
| 565 | fossil_fatal("unable to change directories to %s", zChdir); |
| 566 | } |
| 567 | if( find_option("help",0,0)!=0 ){ |
| 568 | /* --help anywhere on the command line is translated into |
| 569 | ** "fossil help argv[1] argv[2]..." */ |
| @@ -1086,20 +1086,20 @@ | |
| 1086 | char *zDir; |
| 1087 | |
| 1088 | file_canonical_name(zRepo, &dir, 0); |
| 1089 | zDir = blob_str(&dir); |
| 1090 | if( file_isdir(zDir)==1 ){ |
| 1091 | if( file_chdir(zDir, 1) ){ |
| 1092 | fossil_fatal("unable to chroot into %s", zDir); |
| 1093 | } |
| 1094 | zRepo = "/"; |
| 1095 | }else{ |
| 1096 | for(i=strlen(zDir)-1; i>0 && zDir[i]!='/'; i--){} |
| 1097 | if( zDir[i]!='/' ) fossil_panic("bad repository name: %s", zRepo); |
| 1098 | if( i>0 ){ |
| 1099 | zDir[i] = 0; |
| 1100 | if( file_chdir(zDir, 1) ){ |
| 1101 | fossil_fatal("unable to chroot into %s", zDir); |
| 1102 | } |
| 1103 | zDir[i] = '/'; |
| 1104 | } |
| 1105 | zRepo = &zDir[i]; |
| 1106 |