Fossil SCM

If the 'allow-symlinks' option is enabled (or the '--no-dir-symlinks' flag is specified), do not traverse into symlinked directories.

mistachkin 2017-02-14 18:19 trunk merge
Commit 2375d6cbce933267059d1194fb8818404b89fec6
4 files changed +6 -8 +7 -2 +144 -25 +8 -7
+6 -8
--- src/checkin.c
+++ src/checkin.c
@@ -855,12 +855,10 @@
855855
856856
if( zIgnoreFlag==0 ){
857857
zIgnoreFlag = db_get("ignore-glob", 0);
858858
}
859859
pIgnore = glob_create(zIgnoreFlag);
860
- /* Always consider symlinks. */
861
- g.allowSymlinks = db_allow_symlinks_by_default();
862860
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
863861
glob_free(pIgnore);
864862
865863
blob_zero(&report);
866864
status_report(&report, flags);
@@ -902,13 +900,14 @@
902900
**
903901
** The default values for --clean, --ignore, and --keep are determined by
904902
** the (versionable) clean-glob, ignore-glob, and keep-glob settings.
905903
**
906904
** The --verily option ignores the keep-glob and ignore-glob settings and
907
-** turns on --force, --emptydirs, --dotfiles, and --disable-undo. Use the
908
-** --verily option when you really want to clean up everything. Extreme
909
-** care should be exercised when using the --verily option.
905
+** turns on the options --force, --emptydirs, --dotfiles, --disable-undo,
906
+** and --no-dir-symlinks. Use the --verily option when you really want
907
+** to clean up everything. Extreme care should be exercised when using
908
+** the --verily option.
910909
**
911910
** Options:
912911
** --allckouts Check for empty directories within any checkouts
913912
** that may be nested within the current one. This
914913
** option should be used with great care because the
@@ -999,11 +998,12 @@
999998
verilyFlag = allFileFlag = allDirFlag = 1;
1000999
emptyDirsFlag = 1;
10011000
disableUndo = 1;
10021001
scanFlags |= SCAN_ALL;
10031002
zCleanFlag = 0;
1004
- g.fNoDirSymlinks = 1;
1003
+ g.fNoDirSymlinks = 1; /* Forbid symlink directory traversal. */
1004
+ g.allowSymlinks = 1; /* Treat symlink files as content. */
10051005
}
10061006
if( zIgnoreFlag==0 && !verilyFlag ){
10071007
zIgnoreFlag = db_get("ignore-glob", 0);
10081008
}
10091009
if( zKeepFlag==0 && !verilyFlag ){
@@ -1016,12 +1016,10 @@
10161016
verify_all_options();
10171017
pIgnore = glob_create(zIgnoreFlag);
10181018
pKeep = glob_create(zKeepFlag);
10191019
pClean = glob_create(zCleanFlag);
10201020
nRoot = (int)strlen(g.zLocalRoot);
1021
- /* Always consider symlinks. */
1022
- g.allowSymlinks = db_allow_symlinks_by_default();
10231021
if( !dirsOnlyFlag ){
10241022
Stmt q;
10251023
Blob repo;
10261024
if( !dryRunFlag && !disableUndo ) undo_begin();
10271025
locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
10281026
--- src/checkin.c
+++ src/checkin.c
@@ -855,12 +855,10 @@
855
856 if( zIgnoreFlag==0 ){
857 zIgnoreFlag = db_get("ignore-glob", 0);
858 }
859 pIgnore = glob_create(zIgnoreFlag);
860 /* Always consider symlinks. */
861 g.allowSymlinks = db_allow_symlinks_by_default();
862 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
863 glob_free(pIgnore);
864
865 blob_zero(&report);
866 status_report(&report, flags);
@@ -902,13 +900,14 @@
902 **
903 ** The default values for --clean, --ignore, and --keep are determined by
904 ** the (versionable) clean-glob, ignore-glob, and keep-glob settings.
905 **
906 ** The --verily option ignores the keep-glob and ignore-glob settings and
907 ** turns on --force, --emptydirs, --dotfiles, and --disable-undo. Use the
908 ** --verily option when you really want to clean up everything. Extreme
909 ** care should be exercised when using the --verily option.
 
910 **
911 ** Options:
912 ** --allckouts Check for empty directories within any checkouts
913 ** that may be nested within the current one. This
914 ** option should be used with great care because the
@@ -999,11 +998,12 @@
999 verilyFlag = allFileFlag = allDirFlag = 1;
1000 emptyDirsFlag = 1;
1001 disableUndo = 1;
1002 scanFlags |= SCAN_ALL;
1003 zCleanFlag = 0;
1004 g.fNoDirSymlinks = 1;
 
1005 }
1006 if( zIgnoreFlag==0 && !verilyFlag ){
1007 zIgnoreFlag = db_get("ignore-glob", 0);
1008 }
1009 if( zKeepFlag==0 && !verilyFlag ){
@@ -1016,12 +1016,10 @@
1016 verify_all_options();
1017 pIgnore = glob_create(zIgnoreFlag);
1018 pKeep = glob_create(zKeepFlag);
1019 pClean = glob_create(zCleanFlag);
1020 nRoot = (int)strlen(g.zLocalRoot);
1021 /* Always consider symlinks. */
1022 g.allowSymlinks = db_allow_symlinks_by_default();
1023 if( !dirsOnlyFlag ){
1024 Stmt q;
1025 Blob repo;
1026 if( !dryRunFlag && !disableUndo ) undo_begin();
1027 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
1028
--- src/checkin.c
+++ src/checkin.c
@@ -855,12 +855,10 @@
855
856 if( zIgnoreFlag==0 ){
857 zIgnoreFlag = db_get("ignore-glob", 0);
858 }
859 pIgnore = glob_create(zIgnoreFlag);
 
 
860 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
861 glob_free(pIgnore);
862
863 blob_zero(&report);
864 status_report(&report, flags);
@@ -902,13 +900,14 @@
900 **
901 ** The default values for --clean, --ignore, and --keep are determined by
902 ** the (versionable) clean-glob, ignore-glob, and keep-glob settings.
903 **
904 ** The --verily option ignores the keep-glob and ignore-glob settings and
905 ** turns on the options --force, --emptydirs, --dotfiles, --disable-undo,
906 ** and --no-dir-symlinks. Use the --verily option when you really want
907 ** to clean up everything. Extreme care should be exercised when using
908 ** the --verily option.
909 **
910 ** Options:
911 ** --allckouts Check for empty directories within any checkouts
912 ** that may be nested within the current one. This
913 ** option should be used with great care because the
@@ -999,11 +998,12 @@
998 verilyFlag = allFileFlag = allDirFlag = 1;
999 emptyDirsFlag = 1;
1000 disableUndo = 1;
1001 scanFlags |= SCAN_ALL;
1002 zCleanFlag = 0;
1003 g.fNoDirSymlinks = 1; /* Forbid symlink directory traversal. */
1004 g.allowSymlinks = 1; /* Treat symlink files as content. */
1005 }
1006 if( zIgnoreFlag==0 && !verilyFlag ){
1007 zIgnoreFlag = db_get("ignore-glob", 0);
1008 }
1009 if( zKeepFlag==0 && !verilyFlag ){
@@ -1016,12 +1016,10 @@
1016 verify_all_options();
1017 pIgnore = glob_create(zIgnoreFlag);
1018 pKeep = glob_create(zKeepFlag);
1019 pClean = glob_create(zCleanFlag);
1020 nRoot = (int)strlen(g.zLocalRoot);
 
 
1021 if( !dirsOnlyFlag ){
1022 Stmt q;
1023 Blob repo;
1024 if( !dryRunFlag && !disableUndo ) undo_begin();
1025 locate_unmanaged_files(g.argc-2, g.argv+2, scanFlags, pIgnore);
1026
+7 -2
--- src/db.c
+++ src/db.c
@@ -1436,12 +1436,17 @@
14361436
}
14371437
14381438
/*
14391439
** Returns non-zero if support for symlinks is currently enabled.
14401440
*/
1441
-int db_allow_symlinks(void){
1442
- return g.allowSymlinks;
1441
+int db_allow_symlinks(int traversal){
1442
+ if( traversal ){
1443
+ if( g.allowSymlinks ) return 1;
1444
+ return g.fNoDirSymlinks;
1445
+ }else{
1446
+ return g.allowSymlinks;
1447
+ }
14431448
}
14441449
14451450
/*
14461451
** Open the repository database given by zDbName. If zDbName==NULL then
14471452
** get the name from the already open local database.
14481453
--- src/db.c
+++ src/db.c
@@ -1436,12 +1436,17 @@
1436 }
1437
1438 /*
1439 ** Returns non-zero if support for symlinks is currently enabled.
1440 */
1441 int db_allow_symlinks(void){
1442 return g.allowSymlinks;
 
 
 
 
 
1443 }
1444
1445 /*
1446 ** Open the repository database given by zDbName. If zDbName==NULL then
1447 ** get the name from the already open local database.
1448
--- src/db.c
+++ src/db.c
@@ -1436,12 +1436,17 @@
1436 }
1437
1438 /*
1439 ** Returns non-zero if support for symlinks is currently enabled.
1440 */
1441 int db_allow_symlinks(int traversal){
1442 if( traversal ){
1443 if( g.allowSymlinks ) return 1;
1444 return g.fNoDirSymlinks;
1445 }else{
1446 return g.allowSymlinks;
1447 }
1448 }
1449
1450 /*
1451 ** Open the repository database given by zDbName. If zDbName==NULL then
1452 ** get the name from the already open local database.
1453
+144 -25
--- src/file.c
+++ src/file.c
@@ -85,15 +85,20 @@
8585
/*
8686
** Fill stat buf with information received from stat() or lstat().
8787
** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on.
8888
**
8989
*/
90
-static int fossil_stat(const char *zFilename, struct fossilStat *buf, int isWd){
90
+static int fossil_stat(
91
+ const char *zFilename, /* name of file or directory to inspect. */
92
+ struct fossilStat *buf, /* pointer to buffer where info should go. */
93
+ int isWd, /* non-zero to consider look at symlink itself. */
94
+ int forceWd /* non-zero to force look at symlink itself. */
95
+){
9196
int rc;
9297
void *zMbcs = fossil_utf8_to_path(zFilename, 0);
9398
#if !defined(_WIN32)
94
- if( isWd && db_allow_symlinks() ){
99
+ if( isWd && (forceWd || db_allow_symlinks(0)) ){
95100
rc = lstat(zMbcs, buf);
96101
}else{
97102
rc = stat(zMbcs, buf);
98103
}
99104
#else
@@ -100,10 +105,18 @@
100105
rc = win32_stat(zMbcs, buf, isWd);
101106
#endif
102107
fossil_path_free(zMbcs);
103108
return rc;
104109
}
110
+
111
+/*
112
+** Clears the fileStat variable and its associated validity flag.
113
+*/
114
+static void resetStat(){
115
+ fileStatValid = 0;
116
+ memset(&fileStat, 0, sizeof(struct fossilStat));
117
+}
105118
106119
/*
107120
** Fill in the fileStat variable for the file named zFilename.
108121
** If zFilename==0, then use the previous value of fileStat if
109122
** there is a previous value.
@@ -115,11 +128,11 @@
115128
static int getStat(const char *zFilename, int isWd){
116129
int rc = 0;
117130
if( zFilename==0 ){
118131
if( fileStatValid==0 ) rc = 1;
119132
}else{
120
- if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){
133
+ if( fossil_stat(zFilename, &fileStat, isWd, 0)!=0 ){
121134
fileStatValid = 0;
122135
rc = 1;
123136
}else{
124137
fileStatValid = 1;
125138
rc = 0;
@@ -157,10 +170,26 @@
157170
** Same as file_mtime(), but takes into account symlinks.
158171
*/
159172
i64 file_wd_mtime(const char *zFilename){
160173
return getStat(zFilename, 1) ? -1 : fileStat.st_mtime;
161174
}
175
+
176
+/*
177
+** Return the mode bits for a file. Return -1 if the file does not
178
+** exist. If zFilename is NULL return the size of the most recently
179
+** stat-ed file.
180
+*/
181
+int file_mode(const char *zFilename){
182
+ return getStat(zFilename, 0) ? -1 : fileStat.st_mode;
183
+}
184
+
185
+/*
186
+** Same as file_mode(), but takes into account symlinks.
187
+*/
188
+int file_wd_mode(const char *zFilename){
189
+ return getStat(zFilename, 1) ? -1 : fileStat.st_mode;
190
+}
162191
163192
/*
164193
** Return TRUE if the named file is an ordinary file or symlink
165194
** and symlinks are allowed.
166195
** Return false for directories, devices, fifos, etc.
@@ -191,11 +220,11 @@
191220
**
192221
** Arguments: target file (symlink will point to it), link file
193222
**/
194223
void symlink_create(const char *zTargetFile, const char *zLinkFile){
195224
#if !defined(_WIN32)
196
- if( db_allow_symlinks() ){
225
+ if( db_allow_symlinks(0) ){
197226
int i, nName;
198227
char *zName, zBuf[1000];
199228
200229
nName = strlen(zLinkFile);
201230
if( nName>=sizeof(zBuf) ){
@@ -248,11 +277,11 @@
248277
int file_wd_perm(const char *zFilename){
249278
#if !defined(_WIN32)
250279
if( !getStat(zFilename, 1) ){
251280
if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 )
252281
return PERM_EXE;
253
- else if( db_allow_symlinks() && S_ISLNK(fileStat.st_mode) )
282
+ else if( db_allow_symlinks(0) && S_ISLNK(fileStat.st_mode) )
254283
return PERM_LNK;
255284
}
256285
#endif
257286
return PERM_REG;
258287
}
@@ -301,19 +330,21 @@
301330
** but is something other than a directory.
302331
*/
303332
int file_wd_isdir(const char *zFilename){
304333
int rc;
305334
char *zFN;
335
+ struct fossilStat dirFileStat;
306336
307337
zFN = mprintf("%s", zFilename);
308338
file_simplify_name(zFN, -1, 0);
309
- rc = getStat(zFN, 1);
339
+ memset(&dirFileStat, 0, sizeof(struct fossilStat));
340
+ rc = fossil_stat(zFN, &dirFileStat, 1, 1);
310341
if( rc ){
311342
rc = 0; /* It does not exist at all. */
312
- }else if( S_ISDIR(fileStat.st_mode) ){
343
+ }else if( S_ISDIR(dirFileStat.st_mode) ){
313344
rc = 1; /* It exists and is a real directory. */
314
- }else if( !g.fNoDirSymlinks && S_ISLNK(fileStat.st_mode) ){
345
+ }else if( !db_allow_symlinks(1) && S_ISLNK(dirFileStat.st_mode) ){
315346
Blob content;
316347
blob_read_link(&content, zFN); /* It exists and is a link. */
317348
rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318349
blob_reset(&content);
319350
}else{
@@ -480,11 +511,11 @@
480511
*/
481512
int file_wd_setexe(const char *zFilename, int onoff){
482513
int rc = 0;
483514
#if !defined(_WIN32)
484515
struct stat buf;
485
- if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
516
+ if( fossil_stat(zFilename, &buf, 1, 0)!=0 || S_ISLNK(buf.st_mode) ) return 0;
486517
if( onoff ){
487518
int targetMode = (buf.st_mode & 0444)>>2;
488519
if( (buf.st_mode & 0100)==0 ){
489520
chmod(zFilename, buf.st_mode | targetMode);
490521
rc = 1;
@@ -932,39 +963,123 @@
932963
}
933964
#endif
934965
blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
935966
blob_size(pOut), slash));
936967
}
968
+
969
+/*
970
+** Emits the effective or raw stat() information for the specified
971
+** file or directory, optionally preserving the trailing slash and
972
+** resetting the cached stat() information.
973
+*/
974
+static void emitFileStat(
975
+ const char *zPath,
976
+ int raw,
977
+ int slash,
978
+ int reset
979
+){
980
+ char zBuf[100];
981
+ Blob x;
982
+ memset(zBuf, 0, sizeof(zBuf));
983
+ blob_zero(&x);
984
+ file_canonical_name(zPath, &x, slash);
985
+ fossil_print("%s[%s] -> [%s]\n", raw ? "RAW " : "", zPath, blob_buffer(&x));
986
+ blob_reset(&x);
987
+ if( raw ){
988
+ int rc;
989
+ struct fossilStat testFileStat;
990
+ memset(&testFileStat, 0, sizeof(struct fossilStat));
991
+ rc = fossil_stat(zPath, &testFileStat, 0, 0);
992
+ fossil_print(" stat_rc = %d\n", rc);
993
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size);
994
+ fossil_print(" stat_size = %s\n", zBuf);
995
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime);
996
+ fossil_print(" stat_mtime = %s\n", zBuf);
997
+ fossil_print(" stat_mode = %d\n", testFileStat.st_mode);
998
+ memset(&testFileStat, 0, sizeof(struct fossilStat));
999
+ rc = fossil_stat(zPath, &testFileStat, 1, 1);
1000
+ fossil_print(" l_stat_rc = %d\n", rc);
1001
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size);
1002
+ fossil_print(" l_stat_size = %s\n", zBuf);
1003
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime);
1004
+ fossil_print(" l_stat_mtime = %s\n", zBuf);
1005
+ fossil_print(" l_stat_mode = %d\n", testFileStat.st_mode);
1006
+ }else{
1007
+ if( reset ) resetStat();
1008
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zPath));
1009
+ fossil_print(" file_size = %s\n", zBuf);
1010
+ sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zPath));
1011
+ fossil_print(" file_mtime = %s\n", zBuf);
1012
+ fossil_print(" file_mode = %d\n", file_wd_mode(zPath));
1013
+ fossil_print(" file_isfile = %d\n", file_wd_isfile(zPath));
1014
+ fossil_print(" file_isfile_or_link = %d\n", file_wd_isfile_or_link(zPath));
1015
+ fossil_print(" file_islink = %d\n", file_wd_islink(zPath));
1016
+ fossil_print(" file_isexe = %d\n", file_wd_isexe(zPath));
1017
+ fossil_print(" file_isdir = %d\n", file_wd_isdir(zPath));
1018
+ if( reset ) resetStat();
1019
+ }
1020
+}
1021
+
1022
+/*
1023
+** COMMAND: test-file-environment
1024
+**
1025
+** Usage: %fossil test-file-environment FILENAME...
1026
+**
1027
+** Display the effective file handling subsystem "settings" and then
1028
+** display file system information about the files specified, if any.
1029
+**
1030
+** Options:
1031
+**
1032
+** --open-config Open the configuration database first.
1033
+** --slash Trailing slashes, if any, are retained.
1034
+** --reset Reset cached stat() info for each file.
1035
+*/
1036
+void cmd_test_file_environment(void){
1037
+ int i;
1038
+ int slashFlag = find_option("slash",0,0)!=0;
1039
+ int resetFlag = find_option("reset",0,0)!=0;
1040
+ if( find_option("open-config", 0, 0)!=0 ){
1041
+ Th_OpenConfig(1);
1042
+ }
1043
+ fossil_print("Th_IsLocalOpen() = %d\n", Th_IsLocalOpen());
1044
+ fossil_print("Th_IsRepositoryOpen() = %d\n", Th_IsRepositoryOpen());
1045
+ fossil_print("Th_IsConfigOpen() = %d\n", Th_IsConfigOpen());
1046
+ fossil_print("filenames_are_case_sensitive() = %d\n",
1047
+ filenames_are_case_sensitive());
1048
+ fossil_print("db_allow_symlinks_by_default() = %d\n",
1049
+ db_allow_symlinks_by_default());
1050
+ fossil_print("db_allow_symlinks(0) = %d\n", db_allow_symlinks(0));
1051
+ fossil_print("db_allow_symlinks(1) = %d\n", db_allow_symlinks(1));
1052
+ for(i=2; i<g.argc; i++){
1053
+ emitFileStat(g.argv[i], 1, slashFlag, resetFlag);
1054
+ emitFileStat(g.argv[i], 0, slashFlag, resetFlag);
1055
+ }
1056
+}
9371057
9381058
/*
9391059
** COMMAND: test-canonical-name
9401060
**
9411061
** Usage: %fossil test-canonical-name FILENAME...
9421062
**
9431063
** Test the operation of the canonical name generator.
9441064
** Also test Fossil's ability to measure attributes of a file.
1065
+**
1066
+** Options:
1067
+**
1068
+** --open-config Open the configuration database first.
1069
+** --slash Trailing slashes, if any, are retained.
1070
+** --reset Reset cached stat() info for each file.
9451071
*/
9461072
void cmd_test_canonical_name(void){
9471073
int i;
948
- Blob x;
9491074
int slashFlag = find_option("slash",0,0)!=0;
950
- blob_zero(&x);
1075
+ int resetFlag = find_option("reset",0,0)!=0;
1076
+ if( find_option("open-config", 0, 0)!=0 ){
1077
+ Th_OpenConfig(1);
1078
+ }
9511079
for(i=2; i<g.argc; i++){
952
- char zBuf[100];
953
- const char *zName = g.argv[i];
954
- file_canonical_name(zName, &x, slashFlag);
955
- fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x));
956
- blob_reset(&x);
957
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zName));
958
- fossil_print(" file_size = %s\n", zBuf);
959
- sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zName));
960
- fossil_print(" file_mtime = %s\n", zBuf);
961
- fossil_print(" file_isfile = %d\n", file_wd_isfile(zName));
962
- fossil_print(" file_isfile_or_link = %d\n",file_wd_isfile_or_link(zName));
963
- fossil_print(" file_islink = %d\n", file_wd_islink(zName));
964
- fossil_print(" file_isexe = %d\n", file_wd_isexe(zName));
965
- fossil_print(" file_isdir = %d\n", file_wd_isdir(zName));
1080
+ emitFileStat(g.argv[i], 0, slashFlag, resetFlag);
9661081
}
9671082
}
9681083
9691084
/*
9701085
** Return TRUE if the given filename is canonical.
@@ -1075,10 +1190,14 @@
10751190
10761191
/*
10771192
** COMMAND: test-relative-name
10781193
**
10791194
** Test the operation of the relative name generator.
1195
+**
1196
+** Options:
1197
+**
1198
+** --slash Trailing slashes, if any, are retained.
10801199
*/
10811200
void cmd_test_relative_name(void){
10821201
int i;
10831202
Blob x;
10841203
int slashFlag = find_option("slash",0,0)!=0;
10851204
--- src/file.c
+++ src/file.c
@@ -85,15 +85,20 @@
85 /*
86 ** Fill stat buf with information received from stat() or lstat().
87 ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on.
88 **
89 */
90 static int fossil_stat(const char *zFilename, struct fossilStat *buf, int isWd){
 
 
 
 
 
91 int rc;
92 void *zMbcs = fossil_utf8_to_path(zFilename, 0);
93 #if !defined(_WIN32)
94 if( isWd && db_allow_symlinks() ){
95 rc = lstat(zMbcs, buf);
96 }else{
97 rc = stat(zMbcs, buf);
98 }
99 #else
@@ -100,10 +105,18 @@
100 rc = win32_stat(zMbcs, buf, isWd);
101 #endif
102 fossil_path_free(zMbcs);
103 return rc;
104 }
 
 
 
 
 
 
 
 
105
106 /*
107 ** Fill in the fileStat variable for the file named zFilename.
108 ** If zFilename==0, then use the previous value of fileStat if
109 ** there is a previous value.
@@ -115,11 +128,11 @@
115 static int getStat(const char *zFilename, int isWd){
116 int rc = 0;
117 if( zFilename==0 ){
118 if( fileStatValid==0 ) rc = 1;
119 }else{
120 if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){
121 fileStatValid = 0;
122 rc = 1;
123 }else{
124 fileStatValid = 1;
125 rc = 0;
@@ -157,10 +170,26 @@
157 ** Same as file_mtime(), but takes into account symlinks.
158 */
159 i64 file_wd_mtime(const char *zFilename){
160 return getStat(zFilename, 1) ? -1 : fileStat.st_mtime;
161 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
163 /*
164 ** Return TRUE if the named file is an ordinary file or symlink
165 ** and symlinks are allowed.
166 ** Return false for directories, devices, fifos, etc.
@@ -191,11 +220,11 @@
191 **
192 ** Arguments: target file (symlink will point to it), link file
193 **/
194 void symlink_create(const char *zTargetFile, const char *zLinkFile){
195 #if !defined(_WIN32)
196 if( db_allow_symlinks() ){
197 int i, nName;
198 char *zName, zBuf[1000];
199
200 nName = strlen(zLinkFile);
201 if( nName>=sizeof(zBuf) ){
@@ -248,11 +277,11 @@
248 int file_wd_perm(const char *zFilename){
249 #if !defined(_WIN32)
250 if( !getStat(zFilename, 1) ){
251 if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 )
252 return PERM_EXE;
253 else if( db_allow_symlinks() && S_ISLNK(fileStat.st_mode) )
254 return PERM_LNK;
255 }
256 #endif
257 return PERM_REG;
258 }
@@ -301,19 +330,21 @@
301 ** but is something other than a directory.
302 */
303 int file_wd_isdir(const char *zFilename){
304 int rc;
305 char *zFN;
 
306
307 zFN = mprintf("%s", zFilename);
308 file_simplify_name(zFN, -1, 0);
309 rc = getStat(zFN, 1);
 
310 if( rc ){
311 rc = 0; /* It does not exist at all. */
312 }else if( S_ISDIR(fileStat.st_mode) ){
313 rc = 1; /* It exists and is a real directory. */
314 }else if( !g.fNoDirSymlinks && S_ISLNK(fileStat.st_mode) ){
315 Blob content;
316 blob_read_link(&content, zFN); /* It exists and is a link. */
317 rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
318 blob_reset(&content);
319 }else{
@@ -480,11 +511,11 @@
480 */
481 int file_wd_setexe(const char *zFilename, int onoff){
482 int rc = 0;
483 #if !defined(_WIN32)
484 struct stat buf;
485 if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0;
486 if( onoff ){
487 int targetMode = (buf.st_mode & 0444)>>2;
488 if( (buf.st_mode & 0100)==0 ){
489 chmod(zFilename, buf.st_mode | targetMode);
490 rc = 1;
@@ -932,39 +963,123 @@
932 }
933 #endif
934 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
935 blob_size(pOut), slash));
936 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
938 /*
939 ** COMMAND: test-canonical-name
940 **
941 ** Usage: %fossil test-canonical-name FILENAME...
942 **
943 ** Test the operation of the canonical name generator.
944 ** Also test Fossil's ability to measure attributes of a file.
 
 
 
 
 
 
945 */
946 void cmd_test_canonical_name(void){
947 int i;
948 Blob x;
949 int slashFlag = find_option("slash",0,0)!=0;
950 blob_zero(&x);
 
 
 
951 for(i=2; i<g.argc; i++){
952 char zBuf[100];
953 const char *zName = g.argv[i];
954 file_canonical_name(zName, &x, slashFlag);
955 fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x));
956 blob_reset(&x);
957 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zName));
958 fossil_print(" file_size = %s\n", zBuf);
959 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zName));
960 fossil_print(" file_mtime = %s\n", zBuf);
961 fossil_print(" file_isfile = %d\n", file_wd_isfile(zName));
962 fossil_print(" file_isfile_or_link = %d\n",file_wd_isfile_or_link(zName));
963 fossil_print(" file_islink = %d\n", file_wd_islink(zName));
964 fossil_print(" file_isexe = %d\n", file_wd_isexe(zName));
965 fossil_print(" file_isdir = %d\n", file_wd_isdir(zName));
966 }
967 }
968
969 /*
970 ** Return TRUE if the given filename is canonical.
@@ -1075,10 +1190,14 @@
1075
1076 /*
1077 ** COMMAND: test-relative-name
1078 **
1079 ** Test the operation of the relative name generator.
 
 
 
 
1080 */
1081 void cmd_test_relative_name(void){
1082 int i;
1083 Blob x;
1084 int slashFlag = find_option("slash",0,0)!=0;
1085
--- src/file.c
+++ src/file.c
@@ -85,15 +85,20 @@
85 /*
86 ** Fill stat buf with information received from stat() or lstat().
87 ** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on.
88 **
89 */
90 static int fossil_stat(
91 const char *zFilename, /* name of file or directory to inspect. */
92 struct fossilStat *buf, /* pointer to buffer where info should go. */
93 int isWd, /* non-zero to consider look at symlink itself. */
94 int forceWd /* non-zero to force look at symlink itself. */
95 ){
96 int rc;
97 void *zMbcs = fossil_utf8_to_path(zFilename, 0);
98 #if !defined(_WIN32)
99 if( isWd && (forceWd || db_allow_symlinks(0)) ){
100 rc = lstat(zMbcs, buf);
101 }else{
102 rc = stat(zMbcs, buf);
103 }
104 #else
@@ -100,10 +105,18 @@
105 rc = win32_stat(zMbcs, buf, isWd);
106 #endif
107 fossil_path_free(zMbcs);
108 return rc;
109 }
110
111 /*
112 ** Clears the fileStat variable and its associated validity flag.
113 */
114 static void resetStat(){
115 fileStatValid = 0;
116 memset(&fileStat, 0, sizeof(struct fossilStat));
117 }
118
119 /*
120 ** Fill in the fileStat variable for the file named zFilename.
121 ** If zFilename==0, then use the previous value of fileStat if
122 ** there is a previous value.
@@ -115,11 +128,11 @@
128 static int getStat(const char *zFilename, int isWd){
129 int rc = 0;
130 if( zFilename==0 ){
131 if( fileStatValid==0 ) rc = 1;
132 }else{
133 if( fossil_stat(zFilename, &fileStat, isWd, 0)!=0 ){
134 fileStatValid = 0;
135 rc = 1;
136 }else{
137 fileStatValid = 1;
138 rc = 0;
@@ -157,10 +170,26 @@
170 ** Same as file_mtime(), but takes into account symlinks.
171 */
172 i64 file_wd_mtime(const char *zFilename){
173 return getStat(zFilename, 1) ? -1 : fileStat.st_mtime;
174 }
175
176 /*
177 ** Return the mode bits for a file. Return -1 if the file does not
178 ** exist. If zFilename is NULL return the size of the most recently
179 ** stat-ed file.
180 */
181 int file_mode(const char *zFilename){
182 return getStat(zFilename, 0) ? -1 : fileStat.st_mode;
183 }
184
185 /*
186 ** Same as file_mode(), but takes into account symlinks.
187 */
188 int file_wd_mode(const char *zFilename){
189 return getStat(zFilename, 1) ? -1 : fileStat.st_mode;
190 }
191
192 /*
193 ** Return TRUE if the named file is an ordinary file or symlink
194 ** and symlinks are allowed.
195 ** Return false for directories, devices, fifos, etc.
@@ -191,11 +220,11 @@
220 **
221 ** Arguments: target file (symlink will point to it), link file
222 **/
223 void symlink_create(const char *zTargetFile, const char *zLinkFile){
224 #if !defined(_WIN32)
225 if( db_allow_symlinks(0) ){
226 int i, nName;
227 char *zName, zBuf[1000];
228
229 nName = strlen(zLinkFile);
230 if( nName>=sizeof(zBuf) ){
@@ -248,11 +277,11 @@
277 int file_wd_perm(const char *zFilename){
278 #if !defined(_WIN32)
279 if( !getStat(zFilename, 1) ){
280 if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 )
281 return PERM_EXE;
282 else if( db_allow_symlinks(0) && S_ISLNK(fileStat.st_mode) )
283 return PERM_LNK;
284 }
285 #endif
286 return PERM_REG;
287 }
@@ -301,19 +330,21 @@
330 ** but is something other than a directory.
331 */
332 int file_wd_isdir(const char *zFilename){
333 int rc;
334 char *zFN;
335 struct fossilStat dirFileStat;
336
337 zFN = mprintf("%s", zFilename);
338 file_simplify_name(zFN, -1, 0);
339 memset(&dirFileStat, 0, sizeof(struct fossilStat));
340 rc = fossil_stat(zFN, &dirFileStat, 1, 1);
341 if( rc ){
342 rc = 0; /* It does not exist at all. */
343 }else if( S_ISDIR(dirFileStat.st_mode) ){
344 rc = 1; /* It exists and is a real directory. */
345 }else if( !db_allow_symlinks(1) && S_ISLNK(dirFileStat.st_mode) ){
346 Blob content;
347 blob_read_link(&content, zFN); /* It exists and is a link. */
348 rc = file_wd_isdir(blob_str(&content)); /* Points to directory? */
349 blob_reset(&content);
350 }else{
@@ -480,11 +511,11 @@
511 */
512 int file_wd_setexe(const char *zFilename, int onoff){
513 int rc = 0;
514 #if !defined(_WIN32)
515 struct stat buf;
516 if( fossil_stat(zFilename, &buf, 1, 0)!=0 || S_ISLNK(buf.st_mode) ) return 0;
517 if( onoff ){
518 int targetMode = (buf.st_mode & 0444)>>2;
519 if( (buf.st_mode & 0100)==0 ){
520 chmod(zFilename, buf.st_mode | targetMode);
521 rc = 1;
@@ -932,39 +963,123 @@
963 }
964 #endif
965 blob_resize(pOut, file_simplify_name(blob_buffer(pOut),
966 blob_size(pOut), slash));
967 }
968
969 /*
970 ** Emits the effective or raw stat() information for the specified
971 ** file or directory, optionally preserving the trailing slash and
972 ** resetting the cached stat() information.
973 */
974 static void emitFileStat(
975 const char *zPath,
976 int raw,
977 int slash,
978 int reset
979 ){
980 char zBuf[100];
981 Blob x;
982 memset(zBuf, 0, sizeof(zBuf));
983 blob_zero(&x);
984 file_canonical_name(zPath, &x, slash);
985 fossil_print("%s[%s] -> [%s]\n", raw ? "RAW " : "", zPath, blob_buffer(&x));
986 blob_reset(&x);
987 if( raw ){
988 int rc;
989 struct fossilStat testFileStat;
990 memset(&testFileStat, 0, sizeof(struct fossilStat));
991 rc = fossil_stat(zPath, &testFileStat, 0, 0);
992 fossil_print(" stat_rc = %d\n", rc);
993 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size);
994 fossil_print(" stat_size = %s\n", zBuf);
995 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime);
996 fossil_print(" stat_mtime = %s\n", zBuf);
997 fossil_print(" stat_mode = %d\n", testFileStat.st_mode);
998 memset(&testFileStat, 0, sizeof(struct fossilStat));
999 rc = fossil_stat(zPath, &testFileStat, 1, 1);
1000 fossil_print(" l_stat_rc = %d\n", rc);
1001 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_size);
1002 fossil_print(" l_stat_size = %s\n", zBuf);
1003 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", testFileStat.st_mtime);
1004 fossil_print(" l_stat_mtime = %s\n", zBuf);
1005 fossil_print(" l_stat_mode = %d\n", testFileStat.st_mode);
1006 }else{
1007 if( reset ) resetStat();
1008 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zPath));
1009 fossil_print(" file_size = %s\n", zBuf);
1010 sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zPath));
1011 fossil_print(" file_mtime = %s\n", zBuf);
1012 fossil_print(" file_mode = %d\n", file_wd_mode(zPath));
1013 fossil_print(" file_isfile = %d\n", file_wd_isfile(zPath));
1014 fossil_print(" file_isfile_or_link = %d\n", file_wd_isfile_or_link(zPath));
1015 fossil_print(" file_islink = %d\n", file_wd_islink(zPath));
1016 fossil_print(" file_isexe = %d\n", file_wd_isexe(zPath));
1017 fossil_print(" file_isdir = %d\n", file_wd_isdir(zPath));
1018 if( reset ) resetStat();
1019 }
1020 }
1021
1022 /*
1023 ** COMMAND: test-file-environment
1024 **
1025 ** Usage: %fossil test-file-environment FILENAME...
1026 **
1027 ** Display the effective file handling subsystem "settings" and then
1028 ** display file system information about the files specified, if any.
1029 **
1030 ** Options:
1031 **
1032 ** --open-config Open the configuration database first.
1033 ** --slash Trailing slashes, if any, are retained.
1034 ** --reset Reset cached stat() info for each file.
1035 */
1036 void cmd_test_file_environment(void){
1037 int i;
1038 int slashFlag = find_option("slash",0,0)!=0;
1039 int resetFlag = find_option("reset",0,0)!=0;
1040 if( find_option("open-config", 0, 0)!=0 ){
1041 Th_OpenConfig(1);
1042 }
1043 fossil_print("Th_IsLocalOpen() = %d\n", Th_IsLocalOpen());
1044 fossil_print("Th_IsRepositoryOpen() = %d\n", Th_IsRepositoryOpen());
1045 fossil_print("Th_IsConfigOpen() = %d\n", Th_IsConfigOpen());
1046 fossil_print("filenames_are_case_sensitive() = %d\n",
1047 filenames_are_case_sensitive());
1048 fossil_print("db_allow_symlinks_by_default() = %d\n",
1049 db_allow_symlinks_by_default());
1050 fossil_print("db_allow_symlinks(0) = %d\n", db_allow_symlinks(0));
1051 fossil_print("db_allow_symlinks(1) = %d\n", db_allow_symlinks(1));
1052 for(i=2; i<g.argc; i++){
1053 emitFileStat(g.argv[i], 1, slashFlag, resetFlag);
1054 emitFileStat(g.argv[i], 0, slashFlag, resetFlag);
1055 }
1056 }
1057
1058 /*
1059 ** COMMAND: test-canonical-name
1060 **
1061 ** Usage: %fossil test-canonical-name FILENAME...
1062 **
1063 ** Test the operation of the canonical name generator.
1064 ** Also test Fossil's ability to measure attributes of a file.
1065 **
1066 ** Options:
1067 **
1068 ** --open-config Open the configuration database first.
1069 ** --slash Trailing slashes, if any, are retained.
1070 ** --reset Reset cached stat() info for each file.
1071 */
1072 void cmd_test_canonical_name(void){
1073 int i;
 
1074 int slashFlag = find_option("slash",0,0)!=0;
1075 int resetFlag = find_option("reset",0,0)!=0;
1076 if( find_option("open-config", 0, 0)!=0 ){
1077 Th_OpenConfig(1);
1078 }
1079 for(i=2; i<g.argc; i++){
1080 emitFileStat(g.argv[i], 0, slashFlag, resetFlag);
 
 
 
 
 
 
 
 
 
 
 
 
 
1081 }
1082 }
1083
1084 /*
1085 ** Return TRUE if the given filename is canonical.
@@ -1075,10 +1190,14 @@
1190
1191 /*
1192 ** COMMAND: test-relative-name
1193 **
1194 ** Test the operation of the relative name generator.
1195 **
1196 ** Options:
1197 **
1198 ** --slash Trailing slashes, if any, are retained.
1199 */
1200 void cmd_test_relative_name(void){
1201 int i;
1202 Blob x;
1203 int slashFlag = find_option("slash",0,0)!=0;
1204
+8 -7
--- src/th_main.c
+++ src/th_main.c
@@ -21,10 +21,18 @@
2121
#include "config.h"
2222
#include "th_main.h"
2323
#include "sqlite3.h"
2424
2525
#if INTERFACE
26
+/*
27
+** These macros are used within this file to detect if the repository and
28
+** configuration ("user") database are currently open.
29
+*/
30
+#define Th_IsLocalOpen() (g.localOpen)
31
+#define Th_IsRepositoryOpen() (g.repositoryOpen)
32
+#define Th_IsConfigOpen() (g.zConfigDbName!=0)
33
+
2634
/*
2735
** Flag parameters to the Th_FossilInit() routine used to control the
2836
** interpreter creation and initialization process.
2937
*/
3038
#define TH_INIT_NONE ((u32)0x00000000) /* No flags. */
@@ -59,17 +67,10 @@
5967
*/
6068
#define NO_COMMAND_HOOK_ERROR "no such command: command_hook"
6169
#define NO_WEBPAGE_HOOK_ERROR "no such command: webpage_hook"
6270
#endif
6371
64
-/*
65
-** These macros are used within this file to detect if the repository and
66
-** configuration ("user") database are currently open.
67
-*/
68
-#define Th_IsRepositoryOpen() (g.repositoryOpen)
69
-#define Th_IsConfigOpen() (g.zConfigDbName!=0)
70
-
7172
/*
7273
** Global variable counting the number of outstanding calls to malloc()
7374
** made by the th1 implementation. This is used to catch memory leaks
7475
** in the interpreter. Obviously, it also means th1 is not threadsafe.
7576
*/
7677
--- src/th_main.c
+++ src/th_main.c
@@ -21,10 +21,18 @@
21 #include "config.h"
22 #include "th_main.h"
23 #include "sqlite3.h"
24
25 #if INTERFACE
 
 
 
 
 
 
 
 
26 /*
27 ** Flag parameters to the Th_FossilInit() routine used to control the
28 ** interpreter creation and initialization process.
29 */
30 #define TH_INIT_NONE ((u32)0x00000000) /* No flags. */
@@ -59,17 +67,10 @@
59 */
60 #define NO_COMMAND_HOOK_ERROR "no such command: command_hook"
61 #define NO_WEBPAGE_HOOK_ERROR "no such command: webpage_hook"
62 #endif
63
64 /*
65 ** These macros are used within this file to detect if the repository and
66 ** configuration ("user") database are currently open.
67 */
68 #define Th_IsRepositoryOpen() (g.repositoryOpen)
69 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
70
71 /*
72 ** Global variable counting the number of outstanding calls to malloc()
73 ** made by the th1 implementation. This is used to catch memory leaks
74 ** in the interpreter. Obviously, it also means th1 is not threadsafe.
75 */
76
--- src/th_main.c
+++ src/th_main.c
@@ -21,10 +21,18 @@
21 #include "config.h"
22 #include "th_main.h"
23 #include "sqlite3.h"
24
25 #if INTERFACE
26 /*
27 ** These macros are used within this file to detect if the repository and
28 ** configuration ("user") database are currently open.
29 */
30 #define Th_IsLocalOpen() (g.localOpen)
31 #define Th_IsRepositoryOpen() (g.repositoryOpen)
32 #define Th_IsConfigOpen() (g.zConfigDbName!=0)
33
34 /*
35 ** Flag parameters to the Th_FossilInit() routine used to control the
36 ** interpreter creation and initialization process.
37 */
38 #define TH_INIT_NONE ((u32)0x00000000) /* No flags. */
@@ -59,17 +67,10 @@
67 */
68 #define NO_COMMAND_HOOK_ERROR "no such command: command_hook"
69 #define NO_WEBPAGE_HOOK_ERROR "no such command: webpage_hook"
70 #endif
71
 
 
 
 
 
 
 
72 /*
73 ** Global variable counting the number of outstanding calls to malloc()
74 ** made by the th1 implementation. This is used to catch memory leaks
75 ** in the interpreter. Obviously, it also means th1 is not threadsafe.
76 */
77

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button