Index: Makefile ================================================================== --- Makefile +++ Makefile @@ -59,13 +59,16 @@ # You should not need to change anything below this line ############################################################################### # # Automatic platform-specific options. HOST_OS!= uname -s +# Some makes use a different syntax +HOST_OS_ALT :sh = uname -s LIB.SunOS= -lsocket -lnsl LIB += $(LIB.$(HOST_OS)) +LIB += $(LIB.$(HOST_OS_ALT)) TCC.DragonFly += -DUSE_PREAD TCC.FreeBSD += -DUSE_PREAD TCC.NetBSD += -DUSE_PREAD TCC.OpenBSD += -DUSE_PREAD Index: src/add.c ================================================================== --- src/add.c +++ src/add.c @@ -60,11 +60,11 @@ "manifest.uuid", }; if( N>=0 && N=count(azName) && N +*/ +char *db_get_versionable_setting(const char *zName, char *zDefault){ + char *s = 0; + if( db_open_local() ){ + /* See if there's a versioned setting */ + Blob versionedPathname; + blob_zero(&versionedPathname); + blob_appendf(&versionedPathname, "%s/.fossil-settings/%s", g.zLocalRoot, zName); + char *zVersionedPathname = blob_str(&versionedPathname); + if( file_size(zVersionedPathname) >= 0 ){ + /* File exists, and contains the value for this setting. Load from the file. */ + Blob setting; + blob_zero(&setting); + if( blob_read_from_file(&setting, zVersionedPathname) >= 0 ){ + s = strdup(blob_str(&setting)); + } + blob_reset(&setting); + } + blob_reset(&versionedPathname); + } + if( s != 0 ){ + return s; + } + /* Fall back to settings in the database */ + return db_get(zName, zDefault); +} +int db_get_versionable_setting_boolean(const char *zName, int dflt){ + char *zVal = db_get_versionable_setting(zName, dflt ? "on" : "off"); + if( is_truth(zVal) ) return 1; + if( is_false(zVal) ) return 0; + return dflt; +} + /* ** Get and set values from the CONFIG, GLOBAL_CONFIG and VVAR table in the ** repository and local databases. */ @@ -1652,10 +1688,11 @@ { "editor", 0, 16, "" }, { "gdiff-command", 0, 16, "gdiff" }, { "gmerge-command",0, 40, "" }, { "https-login", 0, 0, "off" }, { "ignore-glob", 0, 40, "" }, + { "empty-dirs", 0, 40, "" }, { "http-port", 0, 16, "8080" }, { "localauth", 0, 0, "off" }, { "main-branch", 0, 40, "trunk" }, { "manifest", 0, 0, "off" }, { "max-upload", 0, 25, "250000" }, Index: src/glob.c ================================================================== --- src/glob.c +++ src/glob.c @@ -110,24 +110,24 @@ p = fossil_malloc( sizeof(*p) + nList+1 ); memset(p, 0, sizeof(*p)); z = (char*)&p[1]; memcpy(z, zPatternList, nList+1); while( z[0] ){ - while( z[0]==',' || z[0]==' ' ) z++; /* Skip leading spaces */ + while( z[0]==',' || z[0]==' ' || z[0]=='\n' || z[0]=='\r' ) z++; /* Skip leading spaces and newlines */ if( z[0]=='\'' || z[0]=='"' ){ delimiter = z[0]; z++; }else{ delimiter = ','; } if( z[0]==0 ) break; p->azPattern = fossil_realloc(p->azPattern, (p->nPattern+1)*sizeof(char*) ); p->azPattern[p->nPattern++] = z; - for(i=0; z[i] && z[i]!=delimiter; i++){} + for(i=0; z[i] && z[i]!=delimiter && z[i]!='\n' && z[i]!='\r'; i++){} if( delimiter==',' ){ - /* Remove trailing spaces on a comma-delimited pattern */ - for(j=i; j>1 && z[j-1]==' '; j--){} + /* Remove trailing spaces / newlines on a comma-delimited pattern */ + for(j=i; j>1 && (z[j-1]==' ' || z[j-1]=='\n' || z[j-1]=='\r'); j--){} if( jrDate - 2440587.5)*86400.0; - if( db_get_boolean("manifest", 0) ){ + if( db_get_versionable_setting_boolean("manifest", 0) ){ blob_append(&filename, "manifest", -1); zName = blob_str(&filename); tar_add_file(zName, &mfile, 0, mTime); sha1sum_blob(&mfile, &hash); blob_reset(&mfile); Index: src/update.c ================================================================== --- src/update.c +++ src/update.c @@ -115,10 +115,13 @@ } if( !nochangeFlag && db_exists("SELECT 1 FROM vmerge") ){ fossil_fatal("cannot update an uncommitted merge"); } if( !nochangeFlag && !internalUpdate ) autosync(AUTOSYNC_PULL); + + /* Create any empty directories now, as well as after the update, so changes in settings are reflected now */ + ensure_empty_dirs_created(); if( internalUpdate ){ tid = internalUpdate; }else if( g.argc>=3 ){ if( strcmp(g.argv[2], "current")==0 ){ @@ -435,10 +438,11 @@ ** Clean up the mid and pid VFILE entries. Then commit the changes. */ if( nochangeFlag ){ db_end_transaction(1); /* With --nochange, rollback changes */ }else{ + ensure_empty_dirs_created(); if( g.argc<=3 ){ /* All files updated. Shift the current checkout to the target. */ db_multi_exec("DELETE FROM vfile WHERE vid!=%d", tid); checkout_set_all_exe(vid); manifest_to_disk(tid); @@ -450,10 +454,35 @@ } if( !internalUpdate ) undo_finish(); db_end_transaction(0); } } + +/* +** Make sure empty directories are created +*/ +void ensure_empty_dirs_created() +{ + /* Make empty directories? */ + char *zEmptyDirs = db_get_versionable_setting("empty-dirs", 0); + if( zEmptyDirs!=0 ){ + Blob dirsList, line; + blob_zero(&dirsList); + blob_init(&dirsList, zEmptyDirs, strlen(zEmptyDirs)); + while( blob_line(&dirsList, &line) ){ + if( blob_buffer(&line)[0]=='#' ) continue; + Blob dirName; + int l = blob_token(&line, &dirName); + if(l > 0) { + /* Try and create the directory */ + if( file_mkdir(blob_str(&dirName), 0)!=0 ) { + fossil_warning("couldn't create empty-dir %s", blob_str(&dirName)); + } + } + } + } +} /* ** Get the contents of a file within the checking "revision". If ** revision==NULL then get the file content for the current checkout. Index: src/user.c ================================================================== --- src/user.c +++ src/user.c @@ -19,10 +19,14 @@ ** querying information about users. */ #include "config.h" #include "user.h" +#if defined(__sun__) || defined(sun) + /* On Solaris, getpass() will only return up to 8 characters. getpassphrase() returns up to 257. */ + #define getpass getpassphrase +#endif /* ** Strip leading and trailing space from a string and add the string ** onto the end of a blob. */ Index: src/zip.c ================================================================== --- src/zip.c +++ src/zip.c @@ -337,11 +337,11 @@ pManifest = manifest_get(rid, CFTYPE_MANIFEST); if( pManifest ){ char *zName; zip_set_timedate(pManifest->rDate); - if( db_get_boolean("manifest", 0) ){ + if( db_get_versionable_setting_boolean("manifest", 0) ){ blob_append(&filename, "manifest", -1); zName = blob_str(&filename); zip_add_folders(zName); zip_add_file(zName, &mfile, 0); sha1sum_blob(&mfile, &hash);