Check-in [d5695157d0]
Not logged in
Overview

SHA1 Hash:d5695157d0caade4fc251dcfbeb1ac8e8602f672
Date: 2009-11-11 16:21:19
User: drh
Comment:Deal with windows filename aliasing in the "all" command. Ticket 974618fe5a8. Also display the home directory for windows users with the "info" command since the home directory is non-obvious in windows.
Timelines: ancestors | descendants | both | trunk
Other Links: files | ZIP archive | manifest

Tags And Properties
Changes
[hide diffs]

Modified src/allrepo.c from [22228def76] to [eac34f25f8].

@@ -111,18 +111,22 @@
     fossil_fatal("\"all\" subcommand should be one of: "
                  "list ls push pull rebuild sync");
   }
   zFossil = quoteFilename(g.argv[0]);
   nMissing = 0;
-  db_prepare(&q, "SELECT substr(name, 6) FROM global_config"
-                 " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1");
+  db_prepare(&q,
+     "SELECT DISTINCT substr(name, 6) COLLATE nocase"
+     "  FROM global_config"
+     " WHERE substr(name, 1, 5)=='repo:' ORDER BY 1"
+  );
   while( db_step(&q)==SQLITE_ROW ){
     const char *zFilename = db_column_text(&q, 0);
     if( access(zFilename, 0) ){
       nMissing++;
       continue;
     }
+    if( !file_is_canonical(zFilename) ) nMissing++;
     if( zCmd[0]=='l' ){
       printf("%s\n", zFilename);
       continue;
     }
     zQFilename = quoteFilename(zFilename);
@@ -132,11 +136,11 @@
     portable_system(zSyscmd);
     free(zSyscmd);
     free(zQFilename);
   }
 
-  /* If any repositories hows names appear in the ~/.fossil file could not
+  /* If any repositories whose names appear in the ~/.fossil file could not
   ** be found, remove those names from the ~/.fossil file.
   */
   if( nMissing ){
     db_begin_transaction();
     db_reset(&q);
@@ -143,13 +147,22 @@
     while( db_step(&q)==SQLITE_ROW ){
       const char *zFilename = db_column_text(&q, 0);
       if( access(zFilename, 0) ){
         char *zRepo = mprintf("repo:%s", zFilename);
         db_unset(zRepo, 1);
+        free(zRepo);
+      }else if( !file_is_canonical(zFilename) ){
+        Blob cname;
+        char *zRepo = mprintf("repo:%s", zFilename);
+        db_unset(zRepo, 1);
+        free(zRepo);
+        file_canonical_name(zFilename, &cname);
+        zRepo = mprintf("repo:%s", blob_str(&cname));
+        db_set(zRepo, "1", 1);
         free(zRepo);
       }
     }
     db_reset(&q);
     db_end_transaction(0);
   }
   db_finalize(&q);
 }

Modified src/db.c from [1d7cecfa32] to [39a38ca81b].

@@ -701,10 +701,11 @@
   if( zHome==0 ){
     db_err("cannot locate home directory - "
            "please set the HOME environment variable");
   }
 #endif
+  g.zHome = mprintf("%/", zHome);
 #ifdef __MINGW32__
   /* . filenames give some window systems problems and many apps problems */
   zDbName = mprintf("%//_fossil", zHome);
 #else
   zDbName = mprintf("%s/.fossil", zHome);

Modified src/file.c from [146394c81a] to [7be765ce11].

@@ -213,10 +213,15 @@
 **
 ** Changes are made in-place.  Return the new name length.
 */
 int file_simplify_name(char *z, int n){
   int i, j;
+#ifdef __MINGW32__
+  for(i=0; i<n; i++){
+    if( z[i]=='\\' ) z[i] = '/';
+  }
+#endif
   while( n>1 && z[n-1]=='/' ){ n--; }
   for(i=j=0; i<n; i++){
     if( z[i]=='/' ){
       if( z[i+1]=='/' ) continue;
       if( z[i+1]=='.' && i+2<n && z[i+2]=='/' ){
@@ -277,10 +282,36 @@
   for(i=2; i<g.argc; i++){
     file_canonical_name(g.argv[i], &x);
     printf("%s\n", blob_buffer(&x));
     blob_reset(&x);
   }
+}
+
+/*
+** Return TRUE if the given filename is canonical.
+**
+** Canonical names are full pathnames using "/" not "\" and which
+** contain no "/./" or "/../" terms.
+*/
+int file_is_canonical(const char *z){
+  int i;
+  if( z[0]!='/'
+#ifdef __MINGW32__
+    && (z[0]==0 || z[1]!=':' || z[2]!='/')
+#endif
+  ) return 0;
+
+  for(i=0; z[i]; i++){
+    if( z[i]=='\\' ) return 0;
+    if( z[i]=='/' ){
+      if( z[i+1]=='.' ){
+        if( z[i+2]=='/' || z[i+2]==0 ) return 0;
+        if( z[i+2]=='.' && (z[i+3]=='/' || z[i+3]==0) ) return 0;
+      }
+    }
+  }
+  return 1;
 }
 
 /*
 ** Compute a pathname for a file or directory that is relative
 ** to the current directory.

Modified src/info.c from [07a09dc029] to [dd6de258e1].

@@ -127,10 +127,15 @@
          /* 012345678901234 */
     db_record_repository_filename(0);
     printf("project-name: %s\n", db_get("project-name", "<unnamed>"));
     printf("repository:   %s\n", db_lget("repository", ""));
     printf("local-root:   %s\n", g.zLocalRoot);
+#ifdef __MINGW32__
+    if( g.zHome ){
+      printf("user-home:  : %s\n", g.zHome);
+    }
+#endif
     printf("project-code: %s\n", db_get("project-code", ""));
     printf("server-code:  %s\n", db_get("server-code", ""));
     vid = db_lget_int("checkout", 0);
     if( vid==0 ){
       printf("checkout:     nil\n");

Modified src/main.c from [e990b4f28d] to [0e2e1d04fd].

@@ -61,10 +61,11 @@
   int useAttach;          /* True if global_config is attached to repository */
   int configOpen;         /* True if the config database is open */
   long long int now;      /* Seconds since 1970 */
   int repositoryOpen;     /* True if the main repository database is open */
   char *zRepositoryName;  /* Name of the repository database */
+  const char *zHome;      /* Name of user home directory */
   int localOpen;          /* True if the local database is open */
   char *zLocalRoot;       /* The directory holding the  local database */
   int minPrefix;          /* Number of digits needed for a distinct UUID */
   int fSqlTrace;          /* True if -sqltrace flag is present */
   int fSqlPrint;          /* True if -sqlprint flag is present */