Fossil SCM
Fix the file_copy() procedure so that it automatically creates directories leading up to the destination file.
Commit
f991688730b21e4a8974bc169e3fe259efe41229
Parent
59e26ebe9484524…
2 files changed
+7
-38
+36
+7
-38
| --- src/blob.c | ||
| +++ src/blob.c | ||
| @@ -786,48 +786,17 @@ | ||
| 786 | 786 | return nWrote; |
| 787 | 787 | } |
| 788 | 788 | #endif |
| 789 | 789 | fwrite(blob_buffer(pBlob), 1, nWrote, stdout); |
| 790 | 790 | }else{ |
| 791 | - int i, nName; | |
| 792 | - char *zName, zBuf[1000]; | |
| 793 | - | |
| 794 | - nName = strlen(zFilename); | |
| 795 | - if( nName>=sizeof(zBuf) ){ | |
| 796 | - zName = mprintf("%s", zFilename); | |
| 797 | - }else{ | |
| 798 | - zName = zBuf; | |
| 799 | - memcpy(zName, zFilename, nName+1); | |
| 800 | - } | |
| 801 | - nName = file_simplify_name(zName, nName, 0); | |
| 802 | - for(i=1; i<nName; i++){ | |
| 803 | - if( zName[i]=='/' ){ | |
| 804 | - zName[i] = 0; | |
| 805 | -#if defined(_WIN32) || defined(__CYGWIN__) | |
| 806 | - /* | |
| 807 | - ** On Windows, local path looks like: C:/develop/project/file.txt | |
| 808 | - ** The if stops us from trying to create a directory of a drive letter | |
| 809 | - ** C: in this example. | |
| 810 | - */ | |
| 811 | - if( !(i==2 && zName[1]==':') ){ | |
| 812 | -#endif | |
| 813 | - if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){ | |
| 814 | - fossil_fatal_recursive("unable to create directory %s", zName); | |
| 815 | - return 0; | |
| 816 | - } | |
| 817 | -#if defined(_WIN32) || defined(__CYGWIN__) | |
| 818 | - } | |
| 819 | -#endif | |
| 820 | - zName[i] = '/'; | |
| 821 | - } | |
| 822 | - } | |
| 823 | - out = fossil_fopen(zName, "wb"); | |
| 824 | - if( out==0 ){ | |
| 825 | - fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); | |
| 826 | - return 0; | |
| 827 | - } | |
| 828 | - if( zName!=zBuf ) free(zName); | |
| 791 | + file_mkfolder(zFilename, 1); | |
| 792 | + out = fossil_fopen(zFilename, "wb"); | |
| 793 | + if( out==0 ){ | |
| 794 | + fossil_fatal_recursive("unable to open file \"%s\" for writing", | |
| 795 | + zFilename); | |
| 796 | + return 0; | |
| 797 | + } | |
| 829 | 798 | blob_is_init(pBlob); |
| 830 | 799 | nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 831 | 800 | fclose(out); |
| 832 | 801 | if( nWrote!=blob_size(pBlob) ){ |
| 833 | 802 | fossil_fatal_recursive("short write: %d of %d bytes to %s", nWrote, |
| 834 | 803 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -786,48 +786,17 @@ | |
| 786 | return nWrote; |
| 787 | } |
| 788 | #endif |
| 789 | fwrite(blob_buffer(pBlob), 1, nWrote, stdout); |
| 790 | }else{ |
| 791 | int i, nName; |
| 792 | char *zName, zBuf[1000]; |
| 793 | |
| 794 | nName = strlen(zFilename); |
| 795 | if( nName>=sizeof(zBuf) ){ |
| 796 | zName = mprintf("%s", zFilename); |
| 797 | }else{ |
| 798 | zName = zBuf; |
| 799 | memcpy(zName, zFilename, nName+1); |
| 800 | } |
| 801 | nName = file_simplify_name(zName, nName, 0); |
| 802 | for(i=1; i<nName; i++){ |
| 803 | if( zName[i]=='/' ){ |
| 804 | zName[i] = 0; |
| 805 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 806 | /* |
| 807 | ** On Windows, local path looks like: C:/develop/project/file.txt |
| 808 | ** The if stops us from trying to create a directory of a drive letter |
| 809 | ** C: in this example. |
| 810 | */ |
| 811 | if( !(i==2 && zName[1]==':') ){ |
| 812 | #endif |
| 813 | if( file_mkdir(zName, 1) && file_isdir(zName)!=1 ){ |
| 814 | fossil_fatal_recursive("unable to create directory %s", zName); |
| 815 | return 0; |
| 816 | } |
| 817 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 818 | } |
| 819 | #endif |
| 820 | zName[i] = '/'; |
| 821 | } |
| 822 | } |
| 823 | out = fossil_fopen(zName, "wb"); |
| 824 | if( out==0 ){ |
| 825 | fossil_fatal_recursive("unable to open file \"%s\" for writing", zName); |
| 826 | return 0; |
| 827 | } |
| 828 | if( zName!=zBuf ) free(zName); |
| 829 | blob_is_init(pBlob); |
| 830 | nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 831 | fclose(out); |
| 832 | if( nWrote!=blob_size(pBlob) ){ |
| 833 | fossil_fatal_recursive("short write: %d of %d bytes to %s", nWrote, |
| 834 |
| --- src/blob.c | |
| +++ src/blob.c | |
| @@ -786,48 +786,17 @@ | |
| 786 | return nWrote; |
| 787 | } |
| 788 | #endif |
| 789 | fwrite(blob_buffer(pBlob), 1, nWrote, stdout); |
| 790 | }else{ |
| 791 | file_mkfolder(zFilename, 1); |
| 792 | out = fossil_fopen(zFilename, "wb"); |
| 793 | if( out==0 ){ |
| 794 | fossil_fatal_recursive("unable to open file \"%s\" for writing", |
| 795 | zFilename); |
| 796 | return 0; |
| 797 | } |
| 798 | blob_is_init(pBlob); |
| 799 | nWrote = fwrite(blob_buffer(pBlob), 1, blob_size(pBlob), out); |
| 800 | fclose(out); |
| 801 | if( nWrote!=blob_size(pBlob) ){ |
| 802 | fossil_fatal_recursive("short write: %d of %d bytes to %s", nWrote, |
| 803 |
+36
| --- src/file.c | ||
| +++ src/file.c | ||
| @@ -393,10 +393,11 @@ | ||
| 393 | 393 | FILE *in, *out; |
| 394 | 394 | int got; |
| 395 | 395 | char zBuf[8192]; |
| 396 | 396 | in = fossil_fopen(zFrom, "rb"); |
| 397 | 397 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 398 | + file_mkfolder(zTo, 0); | |
| 398 | 399 | out = fossil_fopen(zTo, "wb"); |
| 399 | 400 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 400 | 401 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 401 | 402 | fwrite(zBuf, 1, got, out); |
| 402 | 403 | } |
| @@ -516,10 +517,45 @@ | ||
| 516 | 517 | fossil_filename_free(zMbcs); |
| 517 | 518 | return rc; |
| 518 | 519 | } |
| 519 | 520 | return 0; |
| 520 | 521 | } |
| 522 | + | |
| 523 | +/* | |
| 524 | +** Create the tree of directories in which zFilename belongs, if that sequence | |
| 525 | +** of directories does not already exist. | |
| 526 | +*/ | |
| 527 | +void file_mkfolder(const char *zFilename, int forceFlag){ | |
| 528 | + int i, nName; | |
| 529 | + char *zName; | |
| 530 | + | |
| 531 | + nName = strlen(zFilename); | |
| 532 | + zName = mprintf("%s", zFilename); | |
| 533 | + nName = file_simplify_name(zName, nName, 0); | |
| 534 | + for(i=1; i<nName; i++){ | |
| 535 | + if( zName[i]=='/' ){ | |
| 536 | + zName[i] = 0; | |
| 537 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
| 538 | + /* | |
| 539 | + ** On Windows, local path looks like: C:/develop/project/file.txt | |
| 540 | + ** The if stops us from trying to create a directory of a drive letter | |
| 541 | + ** C: in this example. | |
| 542 | + */ | |
| 543 | + if( !(i==2 && zName[1]==':') ){ | |
| 544 | +#endif | |
| 545 | + if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){ | |
| 546 | + fossil_fatal_recursive("unable to create directory %s", zName); | |
| 547 | + return; | |
| 548 | + } | |
| 549 | +#if defined(_WIN32) || defined(__CYGWIN__) | |
| 550 | + } | |
| 551 | +#endif | |
| 552 | + zName[i] = '/'; | |
| 553 | + } | |
| 554 | + } | |
| 555 | + free(zName); | |
| 556 | +} | |
| 521 | 557 | |
| 522 | 558 | /* |
| 523 | 559 | ** Removes the directory named in the argument, if it exists. The directory |
| 524 | 560 | ** must be empty and cannot be the current directory or the root directory. |
| 525 | 561 | ** |
| 526 | 562 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -393,10 +393,11 @@ | |
| 393 | FILE *in, *out; |
| 394 | int got; |
| 395 | char zBuf[8192]; |
| 396 | in = fossil_fopen(zFrom, "rb"); |
| 397 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 398 | out = fossil_fopen(zTo, "wb"); |
| 399 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 400 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 401 | fwrite(zBuf, 1, got, out); |
| 402 | } |
| @@ -516,10 +517,45 @@ | |
| 516 | fossil_filename_free(zMbcs); |
| 517 | return rc; |
| 518 | } |
| 519 | return 0; |
| 520 | } |
| 521 | |
| 522 | /* |
| 523 | ** Removes the directory named in the argument, if it exists. The directory |
| 524 | ** must be empty and cannot be the current directory or the root directory. |
| 525 | ** |
| 526 |
| --- src/file.c | |
| +++ src/file.c | |
| @@ -393,10 +393,11 @@ | |
| 393 | FILE *in, *out; |
| 394 | int got; |
| 395 | char zBuf[8192]; |
| 396 | in = fossil_fopen(zFrom, "rb"); |
| 397 | if( in==0 ) fossil_fatal("cannot open \"%s\" for reading", zFrom); |
| 398 | file_mkfolder(zTo, 0); |
| 399 | out = fossil_fopen(zTo, "wb"); |
| 400 | if( out==0 ) fossil_fatal("cannot open \"%s\" for writing", zTo); |
| 401 | while( (got=fread(zBuf, 1, sizeof(zBuf), in))>0 ){ |
| 402 | fwrite(zBuf, 1, got, out); |
| 403 | } |
| @@ -516,10 +517,45 @@ | |
| 517 | fossil_filename_free(zMbcs); |
| 518 | return rc; |
| 519 | } |
| 520 | return 0; |
| 521 | } |
| 522 | |
| 523 | /* |
| 524 | ** Create the tree of directories in which zFilename belongs, if that sequence |
| 525 | ** of directories does not already exist. |
| 526 | */ |
| 527 | void file_mkfolder(const char *zFilename, int forceFlag){ |
| 528 | int i, nName; |
| 529 | char *zName; |
| 530 | |
| 531 | nName = strlen(zFilename); |
| 532 | zName = mprintf("%s", zFilename); |
| 533 | nName = file_simplify_name(zName, nName, 0); |
| 534 | for(i=1; i<nName; i++){ |
| 535 | if( zName[i]=='/' ){ |
| 536 | zName[i] = 0; |
| 537 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 538 | /* |
| 539 | ** On Windows, local path looks like: C:/develop/project/file.txt |
| 540 | ** The if stops us from trying to create a directory of a drive letter |
| 541 | ** C: in this example. |
| 542 | */ |
| 543 | if( !(i==2 && zName[1]==':') ){ |
| 544 | #endif |
| 545 | if( file_mkdir(zName, forceFlag) && file_isdir(zName)!=1 ){ |
| 546 | fossil_fatal_recursive("unable to create directory %s", zName); |
| 547 | return; |
| 548 | } |
| 549 | #if defined(_WIN32) || defined(__CYGWIN__) |
| 550 | } |
| 551 | #endif |
| 552 | zName[i] = '/'; |
| 553 | } |
| 554 | } |
| 555 | free(zName); |
| 556 | } |
| 557 | |
| 558 | /* |
| 559 | ** Removes the directory named in the argument, if it exists. The directory |
| 560 | ** must be empty and cannot be the current directory or the root directory. |
| 561 | ** |
| 562 |