Changes On Branch winFiles
Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Changes In Branch winFiles Excluding Merge-Ins

This is equivalent to a diff from 43631b087b to e94c7cc4de

2012-03-20
14:03
Merge the winFiles branch into trunk. check-in: 135ed93375 user: drh tags: trunk
2012-03-19
11:58
Avoid a valgrind warning in the side-by-side diff logic. check-in: 9262546e43 user: drh tags: trunk
05:24
Modify file_simplify_name to accept a parameter used to determine if the trailing slash, if any, should be retained. Make use of this when converting the local root to its canonical form. Closed-Leaf check-in: e94c7cc4de user: mistachkin tags: winFiles
04:48
In file_tree_name, since the file name argument is converted to its canonical form prior to the memcmp, the local root must be as well. On Windows, normalize drive letters to uppercase when converting a file name to its canonical form and fix construction of temporary file names used with the gdiff command when the --from and --to options are pres... check-in: 6be0898b2c user: mistachkin tags: winFiles
2012-03-18
23:44
Fix compiler warnings and update custom makefile. check-in: 43631b087b user: mistachkin tags: trunk
16:37
Minor cleanups and tinkering in /json/dir. check-in: c1963c49b0 user: stephan tags: trunk

Changes to src/add.c.

   239    239     
   240    240     /* Load the names of all files that are to be added into sfile temp table */
   241    241     for(i=2; i<g.argc; i++){
   242    242       char *zName;
   243    243       int isDir;
   244    244       Blob fullName;
   245    245   
   246         -    file_canonical_name(g.argv[i], &fullName);
          246  +    file_canonical_name(g.argv[i], &fullName, 0);
   247    247       zName = blob_str(&fullName);
   248    248       isDir = file_wd_isdir(zName);
   249    249       if( isDir==1 ){
   250    250         vfile_scan(&fullName, nRoot-1, includeDotFiles, pIgnore);
   251    251       }else if( isDir==0 ){
   252    252         fossil_fatal("not found: %s", zName);
   253    253       }else if( file_access(zName, R_OK) ){

Changes to src/allrepo.c.

   166    166           db_unset(zRepo, 1);
   167    167           free(zRepo);
   168    168         }else if( !file_is_canonical(zFilename) ){
   169    169           Blob cname;
   170    170           char *zRepo = mprintf("repo:%s", zFilename);
   171    171           db_unset(zRepo, 1);
   172    172           free(zRepo);
   173         -        file_canonical_name(zFilename, &cname);
          173  +        file_canonical_name(zFilename, &cname, 0);
   174    174           zRepo = mprintf("repo:%s", blob_str(&cname));
   175    175           db_set(zRepo, "1", 1);
   176    176           free(zRepo);
   177    177         }
   178    178       }
   179    179       db_reset(&q);
   180    180       db_end_transaction(0);
   181    181     }
   182    182     db_finalize(&q);
   183    183   }

Changes to src/blob.c.

    88     88   */
    89     89   int fossil_islower(char c){ return c>='a' && c<='z'; }
    90     90   int fossil_isupper(char c){ return c>='A' && c<='Z'; }
    91     91   int fossil_isdigit(char c){ return c>='0' && c<='9'; }
    92     92   int fossil_tolower(char c){
    93     93     return fossil_isupper(c) ? c - 'A' + 'a' : c;
    94     94   }
           95  +int fossil_toupper(char c){
           96  +  return fossil_islower(c) ? c - 'a' + 'A' : c;
           97  +}
    95     98   int fossil_isalpha(char c){
    96     99     return (c>='a' && c<='z') || (c>='A' && c<='Z');
    97    100   }
    98    101   int fossil_isalnum(char c){
    99    102     return (c>='a' && c<='z') || (c>='A' && c<='Z') || (c>='0' && c<='9');
   100    103   }
   101    104   
................................................................................
   789    792       nName = strlen(zFilename);
   790    793       if( nName>=sizeof(zBuf) ){
   791    794         zName = mprintf("%s", zFilename);
   792    795       }else{
   793    796         zName = zBuf;
   794    797         memcpy(zName, zFilename, nName+1);
   795    798       }
   796         -    nName = file_simplify_name(zName, nName);
          799  +    nName = file_simplify_name(zName, nName, 0);
   797    800       for(i=1; i<nName; i++){
   798    801         if( zName[i]=='/' ){
   799    802           zName[i] = 0;
   800    803   #if defined(_WIN32)
   801    804           /*
   802    805           ** On Windows, local path looks like: C:/develop/project/file.txt
   803    806           ** The if stops us from trying to create a directory of a drive letter

Changes to src/checkin.c.

    53     53       const char *zDisplayName = zPathname;
    54     54       int isDeleted = db_column_int(&q, 1);
    55     55       int isChnged = db_column_int(&q,2);
    56     56       int isNew = db_column_int(&q,3)==0;
    57     57       int isRenamed = db_column_int(&q,4);
    58     58       char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
    59     59       if( cwdRelative ){
    60         -      file_relative_name(zFullName, &rewrittenPathname);
           60  +      file_relative_name(zFullName, &rewrittenPathname, 0);
    61     61         zDisplayName = blob_str(&rewrittenPathname);
    62     62         if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
    63     63           zDisplayName += 2;  /* no unnecessary ./ prefix */
    64     64         }
    65     65       }
    66     66       blob_append(report, zPrefix, nPrefix);
    67     67       if( isDeleted ){
................................................................................
   311    311     }
   312    312     db_multi_exec("DELETE FROM sfile WHERE x IN (SELECT pathname FROM vfile)");
   313    313     blob_zero(&rewrittenPathname);
   314    314     while( db_step(&q)==SQLITE_ROW ){
   315    315       zDisplayName = zPathname = db_column_text(&q, 0);
   316    316       if( cwdRelative ) {
   317    317         char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
   318         -      file_relative_name(zFullName, &rewrittenPathname);
          318  +      file_relative_name(zFullName, &rewrittenPathname, 0);
   319    319         free(zFullName);
   320    320         zDisplayName = blob_str(&rewrittenPathname);
   321    321         if( zDisplayName[0]=='.' && zDisplayName[1]=='/' ){
   322    322           zDisplayName += 2;  /* no unnecessary ./ prefix */
   323    323         }
   324    324       }
   325    325       fossil_print("%s\n", zDisplayName);
................................................................................
   824    824       }else{
   825    825         lastNl++;
   826    826         if( lastNl>1000 ) return;   /* Binary if any line longer than 1000 */
   827    827       }
   828    828     }
   829    829     if( nCrNl ){
   830    830       char c;
   831         -    file_relative_name(zFilename, &fname);
          831  +    file_relative_name(zFilename, &fname, 0);
   832    832       blob_zero(&ans);
   833    833       zMsg = mprintf(
   834    834            "%s contains CR/NL line endings; commit anyhow (yes/no/all)?", 
   835    835            blob_str(&fname));
   836    836       prompt_user(zMsg, &ans);
   837    837       fossil_free(zMsg);
   838    838       c = blob_str(&ans)[0];

Changes to src/clone.c.

   148    148       db_set("content-schema", CONTENT_SCHEMA, 0);
   149    149       db_set("aux-schema", AUX_SCHEMA, 0);
   150    150       db_set("last-sync-url", g.argv[2], 0);
   151    151       if( g.zSSLIdentity!=0 ){
   152    152         /* If the --ssl-identity option was specified, store it as a setting */
   153    153         Blob fn;
   154    154         blob_zero(&fn);
   155         -      file_canonical_name(g.zSSLIdentity, &fn);
          155  +      file_canonical_name(g.zSSLIdentity, &fn, 0);
   156    156         db_set("ssl-identity", blob_str(&fn), 0);
   157    157         blob_reset(&fn);
   158    158       }
   159    159       db_multi_exec(
   160    160         "REPLACE INTO config(name,value,mtime)"
   161    161         " VALUES('server-code', lower(hex(randomblob(20))), now());"
   162    162       );

Changes to src/db.c.

  1033   1033     if( g.argc!=3 ){
  1034   1034       usage("PATHNAME");
  1035   1035     }
  1036   1036     if( db_open_local()==0 ){
  1037   1037       fossil_fatal("not in a local checkout");
  1038   1038       return;
  1039   1039     }
  1040         -  file_canonical_name(g.argv[2], &repo);
         1040  +  file_canonical_name(g.argv[2], &repo, 0);
  1041   1041     zRepo = blob_str(&repo);
  1042   1042     if( file_access(zRepo, 0) ){
  1043   1043       fossil_fatal("no such file: %s", zRepo);
  1044   1044     }
  1045   1045     db_open_or_attach(zRepo, "test_repo");
  1046   1046     db_lset("repository", blob_str(&repo));
  1047   1047     db_close(1);
................................................................................
  1696   1696   */
  1697   1697   void db_record_repository_filename(const char *zName){
  1698   1698     Blob full;
  1699   1699     if( zName==0 ){
  1700   1700       if( !g.localOpen ) return;
  1701   1701       zName = db_repository_filename();
  1702   1702     }
  1703         -  file_canonical_name(zName, &full);
         1703  +  file_canonical_name(zName, &full, 0);
  1704   1704     db_swap_connections();
  1705   1705     db_multi_exec(
  1706   1706        "INSERT OR IGNORE INTO global_config(name,value)"
  1707   1707        "VALUES('repo:%q',1)",
  1708   1708        blob_str(&full)
  1709   1709     );
  1710   1710     if( g.localOpen && g.zLocalRoot && g.zLocalRoot[0] ){
         1711  +    Blob localRoot;
         1712  +    file_canonical_name(g.zLocalRoot, &localRoot, 1);
  1711   1713       db_multi_exec(
  1712   1714         "REPLACE INTO global_config(name, value)"
  1713   1715         "VALUES('ckout:%q','%q');",
  1714         -      g.zLocalRoot, blob_str(&full)
         1716  +      blob_str(&localRoot), blob_str(&full)
  1715   1717       );
         1718  +    blob_reset(&localRoot);
  1716   1719     }
  1717   1720     db_swap_connections();
  1718   1721     blob_reset(&full);
  1719   1722   }
  1720   1723   
  1721   1724   /*
  1722   1725   ** COMMAND: open
................................................................................
  1747   1750     allowNested = find_option("nested",0,0)!=0;
  1748   1751     if( g.argc!=3 && g.argc!=4 ){
  1749   1752       usage("REPOSITORY-FILENAME ?VERSION?");
  1750   1753     }
  1751   1754     if( !allowNested && db_open_local() ){
  1752   1755       fossil_panic("already within an open tree rooted at %s", g.zLocalRoot);
  1753   1756     }
  1754         -  file_canonical_name(g.argv[2], &path);
         1757  +  file_canonical_name(g.argv[2], &path, 0);
  1755   1758     db_open_repository(blob_str(&path));
  1756   1759     db_init_database("./_FOSSIL_", zLocalSchema, (char*)0);
  1757   1760     db_delete_on_failure("./_FOSSIL_");
  1758   1761     db_open_local();
  1759   1762     db_lset("repository", g.argv[2]);
  1760   1763     db_record_repository_filename(blob_str(&path));
  1761   1764     vid = db_int(0, "SELECT pid FROM plink y"

Changes to src/diffcmd.c.

    17     17   **
    18     18   ** This file contains code used to implement the "diff" command
    19     19   */
    20     20   #include "config.h"
    21     21   #include "diffcmd.h"
    22     22   #include <assert.h>
    23     23   
           24  +/*
           25  +** Use the right null device for the platform.
           26  +*/
           27  +#if defined(_WIN32)
           28  +#  define NULL_DEVICE "NUL"
           29  +#else
           30  +#  define NULL_DEVICE "/dev/null"
           31  +#endif
           32  +
    24     33   /*
    25     34   ** Print the "Index:" message that patches wants to see at the top of a diff.
    26     35   */
    27     36   void diff_print_index(const char *zFile, int diffFlags){
    28     37     if( (diffFlags & (DIFF_SIDEBYSIDE|DIFF_BRIEF))==0 ){
    29     38       char *z = mprintf("Index: %s\n%.66c\n", zFile, '=');
    30     39       fossil_print("%s", z);
................................................................................
    74     83       Blob out;                 /* Diff output text */
    75     84       Blob file2;               /* Content of zFile2 */
    76     85       const char *zName2;       /* Name of zFile2 for display */
    77     86   
    78     87       /* Read content of zFile2 into memory */
    79     88       blob_zero(&file2);
    80     89       if( file_wd_size(zFile2)<0 ){
    81         -      zName2 = "/dev/null";
           90  +      zName2 = NULL_DEVICE;
    82     91       }else{
    83     92         if( file_wd_islink(zFile2) ){
    84     93           blob_read_link(&file2, zFile2);
    85     94         }else{
    86     95           blob_read_from_file(&file2, zFile2);
    87     96         }
    88     97         zName2 = zName;
................................................................................
   281    290       int srcid = db_column_int(&q, 4);
   282    291       int isLink = db_column_int(&q, 5);
   283    292       char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname);
   284    293       char *zToFree = zFullName;
   285    294       int showDiff = 1;
   286    295       if( isDeleted ){
   287    296         fossil_print("DELETED  %s\n", zPathname);
   288         -      if( !asNewFile ){ showDiff = 0; zFullName = "/dev/null"; }
          297  +      if( !asNewFile ){ showDiff = 0; zFullName = NULL_DEVICE; }
   289    298       }else if( file_access(zFullName, 0) ){
   290    299         fossil_print("MISSING  %s\n", zPathname);
   291    300         if( !asNewFile ){ showDiff = 0; }
   292    301       }else if( isNew ){
   293    302         fossil_print("ADDED    %s\n", zPathname);
   294    303         srcid = 0;
   295    304         if( !asNewFile ){ showDiff = 0; }

Changes to src/file.c.

    26     26   #include <sys/types.h>
    27     27   #include <sys/stat.h>
    28     28   #include <unistd.h>
    29     29   #include <string.h>
    30     30   #include <errno.h>
    31     31   #include "file.h"
    32     32   
           33  +/*
           34  +** On Windows, include the Platform SDK header file.
           35  +*/
           36  +#ifdef _WIN32
           37  +# include <windows.h>
           38  +#endif
           39  +
    33     40   /*
    34     41   ** The file status information from the most recent stat() call.
    35     42   **
    36     43   ** Use _stati64 rather than stat on windows, in order to handle files
    37     44   ** larger than 2GB.
    38     45   */
    39     46   #if defined(_WIN32) && (defined(__MSVCRT__) || defined(_MSC_VER))
................................................................................
   166    173       nName = strlen(zLinkFile);
   167    174       if( nName>=sizeof(zBuf) ){
   168    175         zName = mprintf("%s", zLinkFile);
   169    176       }else{
   170    177         zName = zBuf;
   171    178         memcpy(zName, zLinkFile, nName+1);
   172    179       }
   173         -    nName = file_simplify_name(zName, nName);
          180  +    nName = file_simplify_name(zName, nName, 0);
   174    181       for(i=1; i<nName; i++){
   175    182         if( zName[i]=='/' ){
   176    183           zName[i] = 0;
   177    184             if( file_mkdir(zName, 1) ){
   178    185               fossil_fatal_recursive("unable to create directory %s", zName);
   179    186               return;
   180    187             }
................................................................................
   257    264   ** other than a directory.
   258    265   */
   259    266   int file_isdir(const char *zFilename){
   260    267     int rc;
   261    268   
   262    269     if( zFilename ){
   263    270       char *zFN = mprintf("%s", zFilename);
   264         -    file_simplify_name(zFN, -1);
          271  +    file_simplify_name(zFN, -1, 0);
   265    272       rc = getStat(zFN, 0);
   266    273       free(zFN);
   267    274     }else{
   268    275       rc = getStat(0, 0);
   269    276     }
   270    277     return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
   271    278   }
................................................................................
   274    281   ** Same as file_isdir(), but takes into account symlinks.
   275    282   */
   276    283   int file_wd_isdir(const char *zFilename){
   277    284     int rc;
   278    285   
   279    286     if( zFilename ){
   280    287       char *zFN = mprintf("%s", zFilename);
   281         -    file_simplify_name(zFN, -1);
          288  +    file_simplify_name(zFN, -1, 0);
   282    289       rc = getStat(zFN, 1);
   283    290       free(zFN);
   284    291     }else{
   285    292       rc = getStat(0, 1);
   286    293     }
   287    294     return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2);
   288    295   }
................................................................................
   312    319     z = mprintf("%s-%s", zBase, zSuffix);
   313    320     while( file_size(z)>=0 ){
   314    321       fossil_free(z);
   315    322       z = mprintf("%s-%s-%d", zBase, zSuffix, cnt++);
   316    323     }
   317    324     if( relFlag ){
   318    325       Blob x;
   319         -    file_relative_name(z, &x);
          326  +    file_relative_name(z, &x, 0);
   320    327       fossil_free(z);
   321    328       z = blob_str(&x);
   322    329     }
   323    330     return z;
   324    331   }
   325    332   
   326    333   /*
................................................................................
   471    478   **
   472    479   **  * Convert all \ into / on windows
   473    480   **  * removing any trailing and duplicate /
   474    481   **  * removing /./
   475    482   **  * removing /A/../
   476    483   **
   477    484   ** Changes are made in-place.  Return the new name length.
          485  +** If the slash parameter is non-zero, the trailing slash, if any,
          486  +** is retained.
   478    487   */
   479         -int file_simplify_name(char *z, int n){
          488  +int file_simplify_name(char *z, int n, int slash){
   480    489     int i, j;
   481    490     if( n<0 ) n = strlen(z);
   482    491   
   483    492     /* On windows convert all \ characters to / */
   484    493   #if defined(_WIN32)
   485    494     for(i=0; i<n; i++){
   486    495       if( z[i]=='\\' ) z[i] = '/';
   487    496     }
   488    497   #endif
   489    498   
   490    499     /* Removing trailing "/" characters */
   491         -  while( n>1 && z[n-1]=='/' ){ n--; }
          500  +  if ( !slash ){
          501  +    while( n>1 && z[n-1]=='/' ){ n--; }
          502  +  }
   492    503   
   493    504     /* Remove duplicate '/' characters.  Except, two // at the beginning
   494    505     ** of a pathname is allowed since this is important on windows. */
   495    506     for(i=j=1; i<n; i++){
   496    507       z[j++] = z[i];
   497    508       while( z[i]=='/' && i<n-1 && z[i+1]=='/' ) i++;
   498    509     }
................................................................................
   538    549   */
   539    550   void cmd_test_simplify_name(void){
   540    551     int i;
   541    552     char *z;
   542    553     for(i=2; i<g.argc; i++){
   543    554       z = mprintf("%s", g.argv[i]);
   544    555       fossil_print("[%s] -> ", z);
   545         -    file_simplify_name(z, -1);
          556  +    file_simplify_name(z, -1, 0);
   546    557       fossil_print("[%s]\n", z);
   547    558       fossil_free(z);
   548    559     }
   549    560   }
   550    561   
   551    562   /*
   552    563   ** Get the current working directory.
................................................................................
   604    615   
   605    616   /*
   606    617   ** Compute a canonical pathname for a file or directory.
   607    618   ** Make the name absolute if it is relative.
   608    619   ** Remove redundant / characters
   609    620   ** Remove all /./ path elements.
   610    621   ** Convert /A/../ to just /
          622  +** If the slash parameter is non-zero, the trailing slash, if any,
          623  +** is retained.
   611    624   */
   612         -void file_canonical_name(const char *zOrigName, Blob *pOut){
          625  +void file_canonical_name(const char *zOrigName, Blob *pOut, int slash){
   613    626     if( file_is_absolute_path(zOrigName) ){
          627  +#if defined(_WIN32)
          628  +    char *zOut;
          629  +#endif
   614    630       blob_set(pOut, zOrigName);
   615    631       blob_materialize(pOut);
          632  +#if defined(_WIN32)
          633  +    /*
          634  +    ** On Windows, normalize the drive letter to upper case.
          635  +    */
          636  +    zOut = blob_str(pOut);
          637  +    if( fossil_isalpha(zOut[0]) && zOut[1]==':' ){
          638  +      zOut[0] = fossil_toupper(zOut[0]);
          639  +    }
          640  +#endif
   616    641     }else{
   617    642       char zPwd[2000];
   618    643       file_getcwd(zPwd, sizeof(zPwd)-strlen(zOrigName));
          644  +#if defined(_WIN32)
          645  +    /*
          646  +    ** On Windows, normalize the drive letter to upper case.
          647  +    */
          648  +    if( fossil_isalpha(zPwd[0]) && zPwd[1]==':' ){
          649  +      zPwd[0] = fossil_toupper(zPwd[0]);
          650  +    }
          651  +#endif
   619    652       blob_zero(pOut);
   620    653       blob_appendf(pOut, "%//%/", zPwd, zOrigName);
   621    654     }
   622         -  blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut)));
          655  +  blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
          656  +                                       blob_size(pOut), slash));
   623    657   }
   624    658   
   625    659   /*
   626    660   ** COMMAND:  test-canonical-name
   627    661   ** Usage: %fossil test-canonical-name FILENAME...
   628    662   **
   629    663   ** Test the operation of the canonical name generator.
................................................................................
   632    666   void cmd_test_canonical_name(void){
   633    667     int i;
   634    668     Blob x;
   635    669     blob_zero(&x);
   636    670     for(i=2; i<g.argc; i++){
   637    671       char zBuf[100];
   638    672       const char *zName = g.argv[i];
   639         -    file_canonical_name(zName, &x);
          673  +    file_canonical_name(zName, &x, 0);
   640    674       fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x));
   641    675       blob_reset(&x);
   642    676       sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zName));
   643    677       fossil_print("  file_size   = %s\n", zBuf);
   644    678       sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zName));
   645    679       fossil_print("  file_mtime  = %s\n", zBuf);
   646    680       fossil_print("  file_isfile = %d\n", file_wd_isfile(zName));
................................................................................
   686    720     if( fossil_isalpha(zIn[0]) && zIn[1]==':' ) zIn += 2;
   687    721   #endif
   688    722     return zIn;
   689    723   }
   690    724   
   691    725   /*
   692    726   ** Compute a pathname for a file or directory that is relative
   693         -** to the current directory.
          727  +** to the current directory.  If the slash parameter is non-zero,
          728  +** the trailing slash, if any, is retained.
   694    729   */
   695         -void file_relative_name(const char *zOrigName, Blob *pOut){
          730  +void file_relative_name(const char *zOrigName, Blob *pOut, int slash){
   696    731     char *zPath;
   697    732     blob_set(pOut, zOrigName);
   698         -  blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut))); 
          733  +  blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
          734  +                                       blob_size(pOut), slash));
   699    735     zPath = file_without_drive_letter(blob_buffer(pOut));
   700    736     if( zPath[0]=='/' ){
   701    737       int i, j;
   702    738       Blob tmp;
   703    739       char *zPwd;
   704    740       char zBuf[2000];
   705    741       zPwd = zBuf;
................................................................................
   751    787   ** Test the operation of the relative name generator.
   752    788   */
   753    789   void cmd_test_relative_name(void){
   754    790     int i;
   755    791     Blob x;
   756    792     blob_zero(&x);
   757    793     for(i=2; i<g.argc; i++){
   758         -    file_relative_name(g.argv[i], &x);
          794  +    file_relative_name(g.argv[i], &x, 0);
   759    795       fossil_print("%s\n", blob_buffer(&x));
   760    796       blob_reset(&x);
   761    797     }
   762    798   }
   763    799   
   764    800   /*
   765    801   ** Compute a pathname for a file relative to the root of the local
................................................................................
   766    802   ** tree.  Return TRUE on success.  On failure, print and error
   767    803   ** message and quit if the errFatal flag is true.  If errFatal is
   768    804   ** false, then simply return 0.
   769    805   **
   770    806   ** The root of the tree is defined by the g.zLocalRoot variable.
   771    807   */
   772    808   int file_tree_name(const char *zOrigName, Blob *pOut, int errFatal){
   773         -  int n;
          809  +  Blob localRoot;
          810  +  int nLocalRoot;
          811  +  char *zLocalRoot;
   774    812     Blob full;
   775    813     int nFull;
   776    814     char *zFull;
   777    815   
   778    816     blob_zero(pOut);
   779    817     db_must_be_within_tree();
   780         -  file_canonical_name(zOrigName, &full);
   781         -  n = strlen(g.zLocalRoot);
   782         -  assert( n>0 && g.zLocalRoot[n-1]=='/' );
          818  +  file_canonical_name(g.zLocalRoot, &localRoot, 1);
          819  +  nLocalRoot = blob_size(&localRoot);
          820  +  zLocalRoot = blob_buffer(&localRoot);
          821  +  assert( nLocalRoot>0 && zLocalRoot[nLocalRoot-1]=='/' );
          822  +  file_canonical_name(zOrigName, &full, 0);
   783    823     nFull = blob_size(&full);
   784    824     zFull = blob_buffer(&full);
   785    825   
   786    826     /* Special case.  zOrigName refers to g.zLocalRoot directory. */
   787         -  if( nFull==n-1 && memcmp(g.zLocalRoot, zFull, nFull)==0 ){
          827  +  if( nFull==nLocalRoot-1 && memcmp(zLocalRoot, zFull, nFull)==0 ){
   788    828       blob_append(pOut, ".", 1);
          829  +    blob_reset(&localRoot);
          830  +    blob_reset(&full);
   789    831       return 1;
   790    832     }
   791    833   
   792         -  if( nFull<=n || memcmp(g.zLocalRoot, zFull, n) ){
          834  +  if( nFull<=nLocalRoot || memcmp(zLocalRoot, zFull, nLocalRoot) ){
          835  +    blob_reset(&localRoot);
   793    836       blob_reset(&full);
   794    837       if( errFatal ){
   795    838         fossil_fatal("file outside of checkout tree: %s", zOrigName);
   796    839       }
   797    840       return 0;
   798    841     }
   799         -  blob_append(pOut, &zFull[n], nFull-n);
          842  +  blob_append(pOut, &zFull[nLocalRoot], nFull-nLocalRoot);
          843  +  blob_reset(&localRoot);
          844  +  blob_reset(&full);
   800    845     return 1;
   801    846   }
   802    847   
   803    848   /*
   804    849   ** COMMAND:  test-tree-name
   805    850   **
   806    851   ** Test the operation of the tree name generator.
................................................................................
   859    904   }
   860    905   
   861    906   /*
   862    907   ** Construct a random temporary filename into zBuf[].
   863    908   */
   864    909   void file_tempname(int nBuf, char *zBuf){
   865    910     static const char *azDirs[] = {
          911  +#if defined(_WIN32)
          912  +     0, /* GetTempPath */
          913  +     0, /* TEMP */
          914  +     0, /* TMP */
          915  +#else
   866    916        "/var/tmp",
   867    917        "/usr/tmp",
   868    918        "/tmp",
   869    919        "/temp",
          920  +#endif
   870    921        ".",
   871    922     };
   872    923     static const unsigned char zChars[] =
   873    924       "abcdefghijklmnopqrstuvwxyz"
   874    925       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
   875    926       "0123456789";
   876    927     unsigned int i, j;
   877    928     const char *zDir = ".";
   878    929     int cnt = 0;
          930  +
          931  +#if defined(_WIN32)
          932  +  char zTmpPath[MAX_PATH];
          933  +
          934  +  if( GetTempPath(sizeof(zTmpPath), zTmpPath) ){
          935  +    azDirs[0] = zTmpPath;
          936  +  }
          937  +
          938  +  azDirs[1] = fossil_getenv("TEMP");
          939  +  azDirs[2] = fossil_getenv("TMP");
          940  +#endif
          941  +
   879    942     
   880    943     for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
          944  +    if( azDirs[i]==0 ) continue;
   881    945       if( !file_isdir(azDirs[i]) ) continue;
   882    946       zDir = azDirs[i];
   883    947       break;
   884    948     }
   885    949   
   886    950     /* Check that the output buffer is large enough for the temporary file 
   887    951     ** name. If it is not, return SQLITE_ERROR.
................................................................................
   896    960       j = (int)strlen(zBuf);
   897    961       sqlite3_randomness(15, &zBuf[j]);
   898    962       for(i=0; i<15; i++, j++){
   899    963         zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
   900    964       }
   901    965       zBuf[j] = 0;
   902    966     }while( file_size(zBuf)>=0 );
          967  +
          968  +#if defined(_WIN32)
          969  +  fossil_mbcs_free((char *)azDirs[1]);
          970  +  fossil_mbcs_free((char *)azDirs[2]);
          971  +#endif
   903    972   }
   904    973   
   905    974   
   906    975   /*
   907    976   ** Return true if a file named zName exists and has identical content
   908    977   ** to the blob pContent.  If zName does not exist or if the content is
   909    978   ** different in any way, then return false.
................................................................................
   928    997   
   929    998   
   930    999   /**************************************************************************
   931   1000   ** The following routines translate between MBCS and UTF8 on windows.
   932   1001   ** Since everything is always UTF8 on unix, these routines are no-ops
   933   1002   ** there.
   934   1003   */
   935         -#ifdef _WIN32
   936         -# include <windows.h>
   937         -#endif
   938   1004   
   939   1005   /*
   940   1006   ** Translate MBCS to UTF8.  Return a pointer to the translated text.  
   941   1007   ** Call fossil_mbcs_free() to deallocate any memory used to store the
   942   1008   ** returned pointer when done.
   943   1009   */
   944   1010   char *fossil_mbcs_to_utf8(const char *zMbcs){

Changes to src/login.c.

  1402   1402     char *zSql;                /* SQL to run on all peers */
  1403   1403     const char *zSelf;         /* The ATTACH name of our repository */
  1404   1404   
  1405   1405     *pzErrMsg = 0;   /* Default to no errors */
  1406   1406     zSelf = db_name("repository");
  1407   1407   
  1408   1408     /* Get the full pathname of the other repository */  
  1409         -  file_canonical_name(zRepo, &fullName);
         1409  +  file_canonical_name(zRepo, &fullName, 0);
  1410   1410     zRepo = mprintf(blob_str(&fullName));
  1411   1411     blob_reset(&fullName);
  1412   1412   
  1413   1413     /* Get the full pathname for our repository.  Also the project code
  1414   1414     ** and project name for ourself. */
  1415         -  file_canonical_name(g.zRepositoryName, &fullName);
         1415  +  file_canonical_name(g.zRepositoryName, &fullName, 0);
  1416   1416     zSelfRepo = mprintf(blob_str(&fullName));
  1417   1417     blob_reset(&fullName);
  1418   1418     zSelfProjCode = db_get("project-code", "unknown");
  1419   1419     zSelfLabel = db_get("project-name", 0);
  1420   1420     if( zSelfLabel==0 ){
  1421   1421       zSelfLabel = zSelfProjCode;
  1422   1422     }

Changes to src/main.c.

  1110   1110   #if !defined(_WIN32)
  1111   1111     if( getuid()==0 ){
  1112   1112       int i;
  1113   1113       struct stat sStat;
  1114   1114       Blob dir;
  1115   1115       char *zDir;
  1116   1116   
  1117         -    file_canonical_name(zRepo, &dir);
         1117  +    file_canonical_name(zRepo, &dir, 0);
  1118   1118       zDir = blob_str(&dir);
  1119   1119       if( file_isdir(zDir)==1 ){
  1120   1120         if( chdir(zDir) || chroot(zDir) || chdir("/") ){
  1121   1121           fossil_fatal("unable to chroot into %s", zDir);
  1122   1122         }
  1123   1123         zRepo = "/";
  1124   1124       }else{
................................................................................
  1286   1286             zAltRepo += jj+1;
  1287   1287           }else{
  1288   1288             zUser = "nobody";
  1289   1289           }
  1290   1290           if( g.zLogin==0 ) zUser = "nobody";
  1291   1291           if( zAltRepo[0]!='/' ){
  1292   1292             zAltRepo = mprintf("%s/../%s", g.zRepositoryName, zAltRepo);
  1293         -          file_simplify_name(zAltRepo, -1);
         1293  +          file_simplify_name(zAltRepo, -1, 0);
  1294   1294           }
  1295   1295           db_close(1);
  1296   1296           db_open_repository(zAltRepo);
  1297   1297           login_as_user(zUser);
  1298   1298           g.perm.Password = 0;
  1299   1299           zPath += i;
  1300   1300           nHost = g.zTop - g.zBaseURL;
................................................................................
  1548   1548   ** is disallowed.
  1549   1549   */
  1550   1550   static void find_server_repository(int disallowDir){
  1551   1551     if( g.argc<3 ){
  1552   1552       db_must_be_within_tree();
  1553   1553     }else if( !disallowDir && file_isdir(g.argv[2])==1 ){
  1554   1554       g.zRepositoryName = mprintf("%s", g.argv[2]);
  1555         -    file_simplify_name(g.zRepositoryName, -1);
         1555  +    file_simplify_name(g.zRepositoryName, -1, 0);
  1556   1556     }else{
  1557   1557       db_open_repository(g.argv[2]);
  1558   1558     }
  1559   1559   }
  1560   1560   
  1561   1561   /*
  1562   1562   ** undocumented format:

Changes to src/makemake.tcl.

   467    467   
   468    468   #### These libraries MUST appear in the same order as they do for Tcl
   469    469   #    or linking with it will not work (exact reason unknown).
   470    470   #
   471    471   ifdef FOSSIL_ENABLE_TCL
   472    472   LIB += -lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32
   473    473   else
   474         -LIB += -lws2_32
          474  +LIB += -lkernel32 -lws2_32
   475    475   endif
   476    476   
   477    477   #### Tcl shell for use in running the fossil test suite.  This is only
   478    478   #    used for testing.
   479    479   #
   480    480   TCLSH = tclsh
   481    481   

Changes to src/setup.c.

   949    949     const char *zPw = PD("pw", "");
   950    950     const char *zNewName = PD("newname", "New Login Group");
   951    951   
   952    952     login_check_credentials();
   953    953     if( !g.perm.Setup ){
   954    954       login_needed();
   955    955     }
   956         -  file_canonical_name(g.zRepositoryName, &fullName);
          956  +  file_canonical_name(g.zRepositoryName, &fullName, 0);
   957    957     zSelfRepo = mprintf(blob_str(&fullName));
   958    958     blob_reset(&fullName);
   959    959     if( P("join")!=0 ){
   960    960       login_group_join(zRepo, zLogin, zPw, zNewName, &zErrMsg);
   961    961     }else if( P("leave") ){
   962    962       login_group_leave(&zErrMsg);
   963    963     }

Changes to src/url.c.

   185    185       }
   186    186     }else{
   187    187       fossil_panic("unknown repository: %s", zUrl);
   188    188     }
   189    189     if( g.urlIsFile ){
   190    190       Blob cfile;
   191    191       dehttpize(zFile);  
   192         -    file_canonical_name(zFile, &cfile);
          192  +    file_canonical_name(zFile, &cfile, 0);
   193    193       free(zFile);
   194    194       g.urlProtocol = "file";
   195    195       g.urlPath = "";
   196    196       g.urlName = mprintf("%b", &cfile);
   197    197       g.urlCanonical = mprintf("file://%T", g.urlName);
   198    198       blob_reset(&cfile);
   199    199     }

Changes to src/winhttp.c.

   594    594       zNotFound = find_option("notfound", 0, 1);
   595    595       zLocalAuth = find_option("localauth", 0, 0);
   596    596       zRepository = find_option("repository", "R", 1);
   597    597       if( !zRepository ){
   598    598         db_must_be_within_tree();
   599    599       }else if( file_isdir(zRepository)==1 ){
   600    600         g.zRepositoryName = mprintf("%s", zRepository);
   601         -      file_simplify_name(g.zRepositoryName, -1);
          601  +      file_simplify_name(g.zRepositoryName, -1, 0);
   602    602       }else{
   603    603         db_open_repository(zRepository);
   604    604       }
   605    605       db_close(0);
   606    606       verify_all_options();
   607    607       if( g.argc>4 ) fossil_fatal("to much arguments for create method.");
   608    608       /* Build the fully-qualified path to the service binary file. */

Changes to win/Makefile.mingw.

   148    148   
   149    149   #### These libraries MUST appear in the same order as they do for Tcl
   150    150   #    or linking with it will not work (exact reason unknown).
   151    151   #
   152    152   ifdef FOSSIL_ENABLE_TCL
   153    153   LIB += -lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32
   154    154   else
   155         -LIB += -lws2_32
          155  +LIB += -lkernel32 -lws2_32
   156    156   endif
   157    157   
   158    158   #### Tcl shell for use in running the fossil test suite.  This is only
   159    159   #    used for testing.
   160    160   #
   161    161   TCLSH = tclsh
   162    162   

Changes to win/Makefile.mingw.mistachkin.

    33     33   
    34     34   #### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
    35     35   #
    36     36   FOSSIL_ENABLE_SSL = 1
    37     37   
    38     38   #### Enable scripting support via Tcl/Tk
    39     39   #
    40         -FOSSIL_ENABLE_TCL = 1
           40  +# FOSSIL_ENABLE_TCL = 1
    41     41   
    42     42   #### Use the Tcl source directory instead of the install directory?
    43     43   #    This is useful when Tcl has been compiled statically with MinGW.
    44     44   #
    45     45   FOSSIL_TCL_SOURCE = 1
    46     46   
    47     47   #### The directories where the zlib include and library files are located.
................................................................................
   148    148   
   149    149   #### These libraries MUST appear in the same order as they do for Tcl
   150    150   #    or linking with it will not work (exact reason unknown).
   151    151   #
   152    152   ifdef FOSSIL_ENABLE_TCL
   153    153   LIB += -lnetapi32 -lkernel32 -luser32 -ladvapi32 -lws2_32
   154    154   else
   155         -LIB += -lws2_32
          155  +LIB += -lkernel32 -lws2_32
   156    156   endif
   157    157   
   158    158   #### Tcl shell for use in running the fossil test suite.  This is only
   159    159   #    used for testing.
   160    160   #
   161    161   TCLSH = tclsh
   162    162