Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch symlinks Excluding Merge-Ins
This is equivalent to a diff from 8d703ff956 to 4e586a2d8e
2011-09-08
| ||
13:02 | Merge fixes and refactoring from symlinks branch. check-in: c05f6afaf2 user: dmitry tags: trunk | |
12:59 | Fix Windows build. Closed-Leaf check-in: 4e586a2d8e user: dmitry tags: symlinks | |
11:59 | Introduce new file_wd_* functions that use stat() or lstat() depending on 'allow-symlinks' setting, and use them when dealing with files inside the working directory. Make file_* functions always use stat() as before merging symlink support. Fix renaming of symlinks when merging (via new function symlink_copy()). Rename create_symlink() to symlin... check-in: 8a0c546990 user: dmitry tags: symlinks | |
11:52 | Merge latest trunk into symlinks branch. check-in: 981e5c62e3 user: dmitry tags: symlinks | |
2011-09-07
| ||
08:12 | Make it easier to use Events as quick notes: Display the title just above the text on Event pages. If there's no title in the wiki text, use the comment as a title. Leaf check-in: 27a4518e13 user: ben tags: ben-minorchanges | |
2011-09-06
| ||
20:12 | catch up with trunk. Remove C++ style comments from http_ssl.c. check-in: 0f1c41bc20 user: martin.weber tags: msw-hack | |
13:23 | Close A and LI tags when displaying new and deleted files in timeline. check-in: 8d703ff956 user: dmitry tags: trunk | |
2011-09-04
| ||
01:28 | Update the built-in SQLite to the latest 3.7.8-alpha version that contains the improved merge-sort logic. check-in: 0cf5416002 user: drh tags: trunk | |
Changes to src/add.c.
106 106 db_multi_exec("UPDATE vfile SET deleted=0" 107 107 " WHERE pathname=%Q COLLATE %s", zPath, zCollate); 108 108 }else{ 109 109 char *zFullname = mprintf("%s%s", g.zLocalRoot, zPath); 110 110 db_multi_exec( 111 111 "INSERT INTO vfile(vid,deleted,rid,mrid,pathname,isexe,islink)" 112 112 "VALUES(%d,0,0,0,%Q,%d,%d)", 113 - vid, zPath, file_isexe(zFullname), file_islink(zFullname)); 113 + vid, zPath, file_wd_isexe(zFullname), file_wd_islink(zFullname)); 114 114 fossil_free(zFullname); 115 115 } 116 116 if( db_changes() ){ 117 117 fossil_print("ADDED %s\n", zPath); 118 118 return 1; 119 119 }else{ 120 120 fossil_print("SKIP %s\n", zPath); ................................................................................ 424 424 ); 425 425 while( db_step(&q)==SQLITE_ROW ){ 426 426 const char * zFile; 427 427 const char * zPath; 428 428 429 429 zFile = db_column_text(&q, 0); 430 430 zPath = db_column_text(&q, 1); 431 - if( !file_isfile_or_link(zPath) ){ 431 + if( !file_wd_isfile_or_link(zPath) ){ 432 432 if( !isTest ){ 433 433 db_multi_exec("UPDATE vfile SET deleted=1 WHERE pathname=%Q", zFile); 434 434 } 435 435 fossil_print("DELETED %s\n", zFile); 436 436 nDelete++; 437 437 } 438 438 }
Changes to src/blob.c.
679 679 int blob_read_from_file(Blob *pBlob, const char *zFilename){ 680 680 int size, got; 681 681 FILE *in; 682 682 if( zFilename==0 || zFilename[0]==0 683 683 || (zFilename[0]=='-' && zFilename[1]==0) ){ 684 684 return blob_read_from_channel(pBlob, stdin, -1); 685 685 } 686 - size = file_size(zFilename); 686 + size = file_wd_size(zFilename); 687 687 blob_zero(pBlob); 688 688 if( size<0 ){ 689 689 fossil_fatal("no such file: %s", zFilename); 690 690 } 691 691 if( size==0 ){ 692 692 return 0; 693 693 }
Changes to src/checkin.c.
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 ){ 68 68 blob_appendf(report, "DELETED %s\n", zDisplayName); 69 - }else if( !file_isfile_or_link(zFullName) ){ 69 + }else if( !file_wd_isfile_or_link(zFullName) ){ 70 70 if( file_access(zFullName, 0)==0 ){ 71 71 blob_appendf(report, "NOT_A_FILE %s\n", zDisplayName); 72 72 if( missingIsFatal ){ 73 73 fossil_warning("not a file: %s", zDisplayName); 74 74 nErr++; 75 75 } 76 76 }else{ ................................................................................ 225 225 char *zFullName = mprintf("%s%s", g.zLocalRoot, zPathname); 226 226 if( isBrief ){ 227 227 fossil_print("%s\n", zPathname); 228 228 }else if( isNew ){ 229 229 fossil_print("ADDED %s\n", zPathname); 230 230 }else if( isDeleted ){ 231 231 fossil_print("DELETED %s\n", zPathname); 232 - }else if( !file_isfile_or_link(zFullName) ){ 232 + }else if( !file_wd_isfile_or_link(zFullName) ){ 233 233 if( file_access(zFullName, 0)==0 ){ 234 234 fossil_print("NOT_A_FILE %s\n", zPathname); 235 235 }else{ 236 236 fossil_print("MISSING %s\n", zPathname); 237 237 } 238 238 }else if( chnged ){ 239 239 fossil_print("EDITED %s\n", zPathname); ................................................................................ 659 659 #if !defined(_WIN32) 660 660 /* For unix, extract the "executable" permission bit directly from 661 661 ** the filesystem. On windows, the "executable" bit is retained 662 662 ** unchanged from the original. 663 663 */ 664 664 blob_resize(&filename, nBasename); 665 665 blob_append(&filename, zName, -1); 666 - isexe = file_isexe(blob_str(&filename)); 666 + isexe = file_wd_isexe(blob_str(&filename)); 667 667 668 668 /* For unix, check if the file on the filesystem is symlink. 669 669 ** On windows, the bit is retained unchanged from original. 670 670 */ 671 - isLink = file_islink(blob_str(&filename)); 671 + isLink = file_wd_islink(blob_str(&filename)); 672 672 #endif 673 673 if( isexe ){ 674 674 zPerm = " x"; 675 675 }else if( isLink ){ 676 676 zPerm = " l"; /* note: symlinks don't have executable bit on unix */ 677 677 }else{ 678 678 zPerm = ""; ................................................................................ 1069 1069 1070 1070 id = db_column_int(&q, 0); 1071 1071 zFullname = db_column_text(&q, 1); 1072 1072 rid = db_column_int(&q, 2); 1073 1073 crnlOk = db_column_int(&q, 3); 1074 1074 1075 1075 blob_zero(&content); 1076 - if( file_islink(zFullname) ){ 1076 + if( file_wd_islink(zFullname) ){ 1077 1077 /* Instead of file content, put link destination path */ 1078 1078 blob_read_link(&content, zFullname); 1079 1079 }else{ 1080 1080 blob_read_from_file(&content, zFullname); 1081 1081 } 1082 1082 if( !crnlOk ) cr_warning(&content, zFullname); 1083 1083 nrid = content_put(&content);
Changes to src/checkout.c.
111 111 blob_appendf(&filename, "%s/", g.zLocalRoot); 112 112 baseLen = blob_size(&filename); 113 113 manifest_file_rewind(pManifest); 114 114 while( (pFile = manifest_file_next(pManifest, 0))!=0 ){ 115 115 int isExe; 116 116 blob_append(&filename, pFile->zName, -1); 117 117 isExe = pFile->zPerm && strstr(pFile->zPerm, "x"); 118 - file_setexe(blob_str(&filename), isExe); 118 + file_wd_setexe(blob_str(&filename), isExe); 119 119 set_or_clear_isexe(pFile->zName, vid, isExe); 120 120 blob_resize(&filename, baseLen); 121 121 } 122 122 blob_reset(&filename); 123 123 manifest_destroy(pManifest); 124 124 } 125 125
Changes to src/diffcmd.c.
69 69 if( zDiffCmd==0 ){ 70 70 Blob out; /* Diff output text */ 71 71 Blob file2; /* Content of zFile2 */ 72 72 const char *zName2; /* Name of zFile2 for display */ 73 73 74 74 /* Read content of zFile2 into memory */ 75 75 blob_zero(&file2); 76 - if( file_size(zFile2)<0 ){ 76 + if( file_wd_size(zFile2)<0 ){ 77 77 zName2 = "/dev/null"; 78 78 }else{ 79 - if( file_islink(zFile2) ){ 79 + if( file_wd_islink(zFile2) ){ 80 80 blob_read_link(&file2, zFile2); 81 81 }else{ 82 82 blob_read_from_file(&file2, zFile2); 83 83 } 84 84 zName2 = zName; 85 85 } 86 86 ................................................................................ 191 191 const char *zFileTreeName 192 192 ){ 193 193 Blob fname; 194 194 Blob content; 195 195 int isLink; 196 196 file_tree_name(zFileTreeName, &fname, 1); 197 197 historical_version_of_file(zFrom, blob_str(&fname), &content, &isLink, 0, 0); 198 - if( !isLink != !file_islink(zFrom) ){ 198 + if( !isLink != !file_wd_islink(zFrom) ){ 199 199 diff_printf("cannot compute difference between symlink and regular file\n"); 200 200 }else{ 201 201 diff_file(&content, zFileTreeName, zFileTreeName, zDiffCmd, ignoreEolWs); 202 202 } 203 203 blob_reset(&content); 204 204 blob_reset(&fname); 205 205 } ................................................................................ 286 286 }else if( isChnged==3 ){ 287 287 diff_printf("ADDED_BY_MERGE %s\n", zPathname); 288 288 srcid = 0; 289 289 if( !asNewFile ){ showDiff = 0; } 290 290 } 291 291 if( showDiff ){ 292 292 Blob content; 293 - if( !isLink != !file_islink(zFullName) ){ 293 + if( !isLink != !file_wd_islink(zFullName) ){ 294 294 diff_print_index(zPathname); 295 295 diff_printf("--- %s\n+++ %s\n", zPathname, zPathname); 296 296 diff_printf("cannot compute difference between symlink and regular file\n"); 297 297 continue; 298 298 } 299 299 if( srcid>0 ){ 300 300 content_get(srcid, &content);
Changes to src/file.c.
11 11 ** 12 12 ** Author contact information: 13 13 ** drh@hwaci.com 14 14 ** http://www.hwaci.com/drh/ 15 15 ** 16 16 ******************************************************************************* 17 17 ** 18 -** File utilities 18 +** File utilities. 19 +** 20 +** Functions named file_* are generic functions that always follow symlinks. 21 +** 22 +** Functions named file_wd_* are to be used for files inside working 23 +** directories. They follow symlinks depending on 'allow-symlinks' setting. 19 24 */ 20 25 #include "config.h" 21 26 #include <sys/types.h> 22 27 #include <sys/stat.h> 23 28 #include <unistd.h> 24 29 #include <string.h> 25 30 #include <errno.h> ................................................................................ 30 35 ** 31 36 ** Use _stati64 rather than stat on windows, in order to handle files 32 37 ** larger than 2GB. 33 38 */ 34 39 #if defined(_WIN32) && defined(__MSVCRT__) 35 40 # define stat _stati64 36 41 #endif 42 +/* 43 +** On Windows S_ISLNK always returns FALSE. 44 +*/ 45 +#if defined(_WIN32) 46 +# define S_ISLNK(x) (0) 47 +#endif 37 48 static int fileStatValid = 0; 38 49 static struct stat fileStat; 39 50 40 -static int fossil_stat(const char *zFilename, struct stat *buf){ 51 +/* 52 +** Fill stat buf with information received from stat() or lstat(). 53 +** lstat() is called on Unix if isWd is TRUE and allow-symlinks setting is on. 54 +** 55 +*/ 56 +static int fossil_stat(const char *zFilename, struct stat *buf, int isWd){ 41 57 #if !defined(_WIN32) 42 - if( g.allowSymlinks ){ 58 + if( isWd && g.allowSymlinks ){ 43 59 return lstat(zFilename, buf); 44 60 }else{ 45 61 return stat(zFilename, buf); 46 62 } 47 63 #else 48 - return stat(zFilename, buf); 64 + int rc = 0; 65 + char *zMbcs = fossil_utf8_to_mbcs(zFilename); 66 + rc = stat(zMbcs, buf); 67 + fossil_mbcs_free(zMbcs); 68 + return rc; 49 69 #endif 50 70 } 51 71 52 72 /* 53 73 ** Fill in the fileStat variable for the file named zFilename. 54 74 ** If zFilename==0, then use the previous value of fileStat if 55 75 ** there is a previous value. 56 76 ** 77 +** If isWd is TRUE, do lstat() instead of stat() if allow-symlinks is on. 78 +** 57 79 ** Return the number of errors. No error messages are generated. 58 80 */ 59 -static int getStat(const char *zFilename){ 81 +static int getStat(const char *zFilename, int isWd){ 60 82 int rc = 0; 61 83 if( zFilename==0 ){ 62 84 if( fileStatValid==0 ) rc = 1; 63 85 }else{ 64 - char *zMbcs = fossil_utf8_to_mbcs(zFilename); 65 - if( fossil_stat(zMbcs, &fileStat)!=0 ){ 86 + if( fossil_stat(zFilename, &fileStat, isWd)!=0 ){ 66 87 fileStatValid = 0; 67 88 rc = 1; 68 89 }else{ 69 90 fileStatValid = 1; 70 91 rc = 0; 71 92 } 72 - fossil_mbcs_free(zMbcs); 73 93 } 74 94 return rc; 75 95 } 76 - 77 96 78 97 /* 79 98 ** Return the size of a file in bytes. Return -1 if the file does not 80 99 ** exist. If zFilename is NULL, return the size of the most recently 81 100 ** stat-ed file. 82 101 */ 83 102 i64 file_size(const char *zFilename){ 84 - return getStat(zFilename) ? -1 : fileStat.st_size; 103 + return getStat(zFilename, 0) ? -1 : fileStat.st_size; 104 +} 105 + 106 +/* 107 +** Same as file_size(), but takes into account symlinks. 108 +*/ 109 +i64 file_wd_size(const char *zFilename){ 110 + return getStat(zFilename, 1) ? -1 : fileStat.st_size; 85 111 } 86 112 87 113 /* 88 114 ** Return the modification time for a file. Return -1 if the file 89 115 ** does not exist. If zFilename is NULL return the size of the most 90 116 ** recently stat-ed file. 91 117 */ 92 118 i64 file_mtime(const char *zFilename){ 93 - return getStat(zFilename) ? -1 : fileStat.st_mtime; 119 + return getStat(zFilename, 0) ? -1 : fileStat.st_mtime; 120 +} 121 + 122 +/* 123 +** Same as file_mtime(), but takes into account symlinks. 124 +*/ 125 +i64 file_wd_mtime(const char *zFilename){ 126 + return getStat(zFilename, 1) ? -1 : fileStat.st_mtime; 94 127 } 95 128 96 129 /* 97 130 ** Return TRUE if the named file is an ordinary file or symlink 98 131 ** and symlinks are allowed. 99 132 ** Return false for directories, devices, fifos, etc. 100 133 */ 101 -int file_isfile_or_link(const char *zFilename){ 102 -#if !defined(_WIN32) 103 - if ( g.allowSymlinks ){ 104 - return getStat(zFilename) ? 0 : S_ISREG(fileStat.st_mode) || S_ISLNK(fileStat.st_mode); 105 - } 106 -#endif 107 - return getStat(zFilename) ? 0 : S_ISREG(fileStat.st_mode); 134 +int file_wd_isfile_or_link(const char *zFilename){ 135 + return getStat(zFilename, 1) ? 0 : S_ISREG(fileStat.st_mode) || 136 + S_ISLNK(fileStat.st_mode); 108 137 } 109 138 110 139 /* 111 140 ** Return TRUE if the named file is an ordinary file. Return false 112 141 ** for directories, devices, fifos, symlinks, etc. 113 142 */ 114 143 int file_isfile(const char *zFilename){ 115 - return getStat(zFilename) ? 0 : S_ISREG(fileStat.st_mode); 144 + return getStat(zFilename, 0) ? 0 : S_ISREG(fileStat.st_mode); 145 +} 146 + 147 +int file_wd_isfile(const char *zFilename){ 148 + return getStat(zFilename, 1) ? 0 : S_ISREG(fileStat.st_mode); 116 149 } 117 150 118 151 /* 119 152 ** Create symlink to file on Unix, or plain-text file with 120 153 ** symlink target if "allow-symlinks" is off or we're on Windows. 121 154 ** 122 155 ** Arguments: target file (symlink will point to it), link file 123 156 **/ 124 -void create_symlink(const char *zTargetFile, const char *zLinkFile){ 157 +void symlink_create(const char *zTargetFile, const char *zLinkFile){ 125 158 #if !defined(_WIN32) 126 159 if( g.allowSymlinks ){ 127 160 int i, nName; 128 161 char *zName, zBuf[1000]; 129 162 130 163 nName = strlen(zLinkFile); 131 164 if( nName>=sizeof(zBuf) ){ ................................................................................ 155 188 { 156 189 Blob content; 157 190 blob_set(&content, zTargetFile); 158 191 blob_write_to_file(&content, zLinkFile); 159 192 blob_reset(&content); 160 193 } 161 194 } 195 + 196 +/* 197 +** Copy symbolic link from zFrom to zTo. 198 +*/ 199 +void symlink_copy(const char *zFrom, const char *zTo){ 200 + Blob content; 201 + blob_read_link(&content, zFrom); 202 + symlink_create(blob_str(&content), zTo); 203 + blob_reset(&content); 204 +} 162 205 163 206 /* 164 207 ** Return file permissions (normal, executable, or symlink): 165 208 ** - PERM_EXE if file is executable; 166 209 ** - PERM_LNK on Unix if file is symlink and allow-symlinks option is on; 167 210 ** - PERM_REG for all other cases (regular file, directory, fifo, etc). 168 211 */ 169 -int file_perm(const char *zFilename){ 170 - if( getStat(zFilename) ) return PERM_REG; 212 +int file_wd_perm(const char *zFilename){ 213 + if( getStat(zFilename, 1) ) return PERM_REG; 171 214 #if defined(_WIN32) 172 215 # if defined(__DMC__) || defined(_MSC_VER) 173 216 # define S_IXUSR _S_IEXEC 174 217 # endif 175 218 if( S_ISREG(fileStat.st_mode) && ((S_IXUSR)&fileStat.st_mode)!=0 ) 176 219 return PERM_EXE; 177 220 else ................................................................................ 187 230 #endif 188 231 } 189 232 190 233 /* 191 234 ** Return TRUE if the named file is an executable. Return false 192 235 ** for directories, devices, fifos, symlinks, etc. 193 236 */ 194 -int file_isexe(const char *zFilename){ 195 - return file_perm(zFilename)==PERM_EXE; 237 +int file_wd_isexe(const char *zFilename){ 238 + return file_wd_perm(zFilename)==PERM_EXE; 196 239 } 197 240 198 241 /* 199 242 ** Return TRUE if the named file is a symlink and symlinks are allowed. 200 243 ** Return false for all other cases. 201 244 ** 202 245 ** On Windows, always return False. 203 246 */ 204 -int file_islink(const char *zFilename){ 205 - return file_perm(zFilename)==PERM_LNK; 247 +int file_wd_islink(const char *zFilename){ 248 + return file_wd_perm(zFilename)==PERM_LNK; 206 249 } 207 250 208 251 /* 209 252 ** Return 1 if zFilename is a directory. Return 0 if zFilename 210 253 ** does not exist. Return 2 if zFilename exists but is something 211 254 ** other than a directory. 212 255 */ 213 256 int file_isdir(const char *zFilename){ 214 257 int rc; 215 258 216 259 if( zFilename ){ 217 260 char *zFN = mprintf("%s", zFilename); 218 261 file_simplify_name(zFN, -1); 219 - rc = getStat(zFN); 262 + rc = getStat(zFN, 0); 263 + free(zFN); 264 + }else{ 265 + rc = getStat(0, 0); 266 + } 267 + return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); 268 +} 269 + 270 +/* 271 +** Same as file_isdir(), but takes into account symlinks. 272 +*/ 273 +int file_wd_isdir(const char *zFilename){ 274 + int rc; 275 + 276 + if( zFilename ){ 277 + char *zFN = mprintf("%s", zFilename); 278 + file_simplify_name(zFN, -1); 279 + rc = getStat(zFN, 1); 220 280 free(zFN); 221 281 }else{ 222 - rc = getStat(0); 282 + rc = getStat(0, 1); 223 283 } 224 -#if !defined(_WIN32) 225 - if( g.allowSymlinks ){ 226 - return rc ? 0 : (S_ISDIR(fileStat.st_mode) && !S_ISLNK(fileStat.st_mode) ? 1 : 2); 227 - }else{ 228 - return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); 229 - } 230 -#else 231 284 return rc ? 0 : (S_ISDIR(fileStat.st_mode) ? 1 : 2); 232 -#endif 233 285 } 286 + 234 287 235 288 /* 236 289 ** Wrapper around the access() system call. 237 290 */ 238 291 int file_access(const char *zFilename, int flags){ 239 292 char *zMbcs = fossil_utf8_to_mbcs(zFilename); 240 293 int rc = access(zMbcs, flags); ................................................................................ 298 351 fclose(out); 299 352 } 300 353 301 354 /* 302 355 ** Set or clear the execute bit on a file. Return true if a change 303 356 ** occurred and false if this routine is a no-op. 304 357 */ 305 -int file_setexe(const char *zFilename, int onoff){ 358 +int file_wd_setexe(const char *zFilename, int onoff){ 306 359 int rc = 0; 307 360 #if !defined(_WIN32) 308 361 struct stat buf; 309 - if( fossil_stat(zFilename, &buf)!=0 || S_ISLNK(buf.st_mode) ) return 0; 362 + if( fossil_stat(zFilename, &buf, 1)!=0 || S_ISLNK(buf.st_mode) ) return 0; 310 363 if( onoff ){ 311 364 int targetMode = (buf.st_mode & 0444)>>2; 312 365 if( (buf.st_mode & 0111)!=targetMode ){ 313 366 chmod(zFilename, buf.st_mode | targetMode); 314 367 rc = 1; 315 368 } 316 369 }else{ ................................................................................ 567 620 blob_zero(&x); 568 621 for(i=2; i<g.argc; i++){ 569 622 char zBuf[100]; 570 623 const char *zName = g.argv[i]; 571 624 file_canonical_name(zName, &x); 572 625 fossil_print("[%s] -> [%s]\n", zName, blob_buffer(&x)); 573 626 blob_reset(&x); 574 - sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_size(zName)); 627 + sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_size(zName)); 575 628 fossil_print(" file_size = %s\n", zBuf); 576 - sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_mtime(zName)); 629 + sqlite3_snprintf(sizeof(zBuf), zBuf, "%lld", file_wd_mtime(zName)); 577 630 fossil_print(" file_mtime = %s\n", zBuf); 578 - fossil_print(" file_isfile = %d\n", file_isfile(zName)); 579 - fossil_print(" file_isfile_or_link = %d\n", file_isfile_or_link(zName)); 580 - fossil_print(" file_islink = %d\n", file_islink(zName)); 581 - fossil_print(" file_isexe = %d\n", file_isexe(zName)); 582 - fossil_print(" file_isdir = %d\n", file_isdir(zName)); 631 + fossil_print(" file_isfile = %d\n", file_wd_isfile(zName)); 632 + fossil_print(" file_isfile_or_link = %d\n",file_wd_isfile_or_link(zName)); 633 + fossil_print(" file_islink = %d\n", file_wd_islink(zName)); 634 + fossil_print(" file_isexe = %d\n", file_wd_isexe(zName)); 635 + fossil_print(" file_isdir = %d\n", file_wd_isdir(zName)); 583 636 } 584 637 } 585 638 586 639 /* 587 640 ** Return TRUE if the given filename is canonical. 588 641 ** 589 642 ** Canonical names are full pathnames using "/" not "\" and which ................................................................................ 844 897 i64 iSize; 845 898 int rc; 846 899 Blob onDisk; 847 900 848 901 iSize = file_size(zName); 849 902 if( iSize<0 ) return 0; 850 903 if( iSize!=blob_size(pContent) ) return 0; 851 - if( file_islink(zName) ){ 904 + if( file_wd_islink(zName) ){ 852 905 blob_read_link(&onDisk, zName); 853 906 }else{ 854 907 blob_read_from_file(&onDisk, zName); 855 908 } 856 909 rc = blob_compare(&onDisk, pContent); 857 910 blob_reset(&onDisk); 858 911 return rc==0;
Changes to src/merge.c.
389 389 /* Do a 3-way merge of idp->idm into idp->idv. The results go into idv. */ 390 390 if( detailFlag ){ 391 391 fossil_print("MERGE %s (pivot=%d v1=%d v2=%d)\n", 392 392 zName, ridp, ridm, ridv); 393 393 }else{ 394 394 fossil_print("MERGE %s\n", zName); 395 395 } 396 - if( islinkv || islinkm /* || file_islink(zFullPath) */ ){ 396 + if( islinkv || islinkm /* || file_wd_islink(zFullPath) */ ){ 397 397 fossil_print("***** Cannot merge symlink %s\n", zName); 398 398 nConflict++; 399 399 }else{ 400 400 undo_save(zName); 401 401 zFullPath = mprintf("%s/%s", g.zLocalRoot, zName); 402 402 content_get(ridp, &p); 403 403 content_get(ridm, &m); ................................................................................ 406 406 blob_zero(&r); 407 407 }else{ 408 408 rc = merge_3way(&p, zFullPath, &m, &r); 409 409 } 410 410 if( rc>=0 ){ 411 411 if( !nochangeFlag ){ 412 412 blob_write_to_file(&r, zFullPath); 413 - file_setexe(zFullPath, isExe); 413 + file_wd_setexe(zFullPath, isExe); 414 414 } 415 415 db_multi_exec("UPDATE vfile SET mtime=0 WHERE id=%d", idv); 416 416 if( rc>0 ){ 417 417 fossil_print("***** %d merge conflicts in %s\n", rc, zName); 418 418 nConflict++; 419 419 } 420 420 }else{ ................................................................................ 478 478 db_multi_exec( 479 479 "UPDATE vfile SET pathname=%Q, origname=coalesce(origname,pathname)" 480 480 " WHERE id=%d AND vid=%d", zNewName, idv, vid 481 481 ); 482 482 if( !nochangeFlag ){ 483 483 char *zFullOldPath = mprintf("%s%s", g.zLocalRoot, zOldName); 484 484 char *zFullNewPath = mprintf("%s%s", g.zLocalRoot, zNewName); 485 - file_copy(zFullOldPath, zFullNewPath); 485 + if( file_wd_islink(zFullOldPath) ){ 486 + symlink_copy(zFullOldPath, zFullNewPath); 487 + }else{ 488 + file_copy(zFullOldPath, zFullNewPath); 489 + } 486 490 file_delete(zFullOldPath); 487 491 free(zFullNewPath); 488 492 free(zFullOldPath); 489 493 } 490 494 } 491 495 db_finalize(&q); 492 496
Changes to src/merge3.c.
420 420 azSubst[0] = "%baseline"; azSubst[1] = zPivot; 421 421 azSubst[2] = "%original"; azSubst[3] = zOrig; 422 422 azSubst[4] = "%merge"; azSubst[5] = zOther; 423 423 azSubst[6] = "%output"; azSubst[7] = zOut; 424 424 zCmd = string_subst(zGMerge, 8, azSubst); 425 425 printf("%s\n", zCmd); fflush(stdout); 426 426 fossil_system(zCmd); 427 - if( file_size(zOut)>=0 ){ 427 + if( file_wd_size(zOut)>=0 ){ 428 428 blob_read_from_file(pOut, zOut); 429 429 file_delete(zPivot); 430 430 file_delete(zOrig); 431 431 file_delete(zOther); 432 432 file_delete(zOut); 433 433 } 434 434 fossil_free(zCmd);
Changes to src/sha1.c.
279 279 */ 280 280 int sha1sum_file(const char *zFilename, Blob *pCksum){ 281 281 FILE *in; 282 282 SHA1Context ctx; 283 283 unsigned char zResult[20]; 284 284 char zBuf[10240]; 285 285 286 - if( file_islink(zFilename) ){ 286 + if( file_wd_islink(zFilename) ){ 287 287 /* Instead of file content, return sha1 of link destination path */ 288 288 Blob destinationPath; 289 289 int rc; 290 290 291 291 blob_read_link(&destinationPath, zFilename); 292 292 rc = sha1sum_blob(&destinationPath, pCksum); 293 293 blob_reset(&destinationPath);
Changes to src/stash.c.
87 87 while( db_step(&q)==SQLITE_ROW ){ 88 88 int deleted = db_column_int(&q, 0); 89 89 int rid = db_column_int(&q, 3); 90 90 const char *zName = db_column_text(&q, 4); 91 91 const char *zOrig = db_column_text(&q, 5); 92 92 char *zPath = mprintf("%s%s", g.zLocalRoot, zName); 93 93 Blob content; 94 - int isNewLink = file_islink(zPath); 94 + int isNewLink = file_wd_islink(zPath); 95 95 96 96 db_bind_int(&ins, ":rid", rid); 97 97 db_bind_int(&ins, ":isadd", rid==0); 98 98 db_bind_int(&ins, ":isrm", deleted); 99 99 db_bind_int(&ins, ":isexe", db_column_int(&q, 1)); 100 100 db_bind_int(&ins, ":islink", db_column_int(&q, 2)); 101 101 db_bind_text(&ins, ":orig", zOrig); ................................................................................ 198 198 char *zNPath = mprintf("%s%s", g.zLocalRoot, zNew); 199 199 Blob delta; 200 200 undo_save(zNew); 201 201 blob_zero(&delta); 202 202 if( rid==0 ){ 203 203 db_ephemeral_blob(&q, 6, &delta); 204 204 blob_write_to_file(&delta, zNPath); 205 - file_setexe(zNPath, isExec); 205 + file_wd_setexe(zNPath, isExec); 206 206 fossil_print("ADD %s\n", zNew); 207 207 }else if( isRemoved ){ 208 208 fossil_print("DELETE %s\n", zOrig); 209 209 file_delete(zOPath); 210 210 }else{ 211 211 Blob a, b, out, disk; 212 - int isNewLink = file_islink(zOPath); 212 + int isNewLink = file_wd_islink(zOPath); 213 213 db_ephemeral_blob(&q, 6, &delta); 214 214 if( isNewLink ){ 215 215 blob_read_link(&disk, zOPath); 216 216 }else{ 217 217 blob_read_from_file(&disk, zOPath); 218 218 } 219 219 content_get(rid, &a); 220 220 blob_delta_apply(&a, &delta, &b); 221 221 if( blob_compare(&disk, &a)==0 && isLink == isNewLink ){ 222 222 if( isLink || isNewLink ){ 223 223 file_delete(zNPath); 224 224 } 225 225 if( isLink ){ 226 - create_symlink(blob_str(&b), zNPath); 226 + symlink_create(blob_str(&b), zNPath); 227 227 }else{ 228 228 blob_write_to_file(&b, zNPath); 229 229 } 230 - file_setexe(zNPath, isExec); 230 + file_wd_setexe(zNPath, isExec); 231 231 fossil_print("UPDATE %s\n", zNew); 232 232 }else{ 233 233 int rc; 234 234 if( isLink || isNewLink ){ 235 235 rc = -1; 236 236 blob_zero(&b); /* because we reset it later */ 237 237 fossil_print("***** Cannot merge symlink %s\n", zNew); 238 238 }else{ 239 239 rc = merge_3way(&a, zOPath, &b, &out); 240 240 blob_write_to_file(&out, zNPath); 241 241 blob_reset(&out); 242 - file_setexe(zNPath, isExec); 242 + file_wd_setexe(zNPath, isExec); 243 243 } 244 244 if( rc ){ 245 245 fossil_print("CONFLICT %s\n", zNew); 246 246 nConflict++; 247 247 }else{ 248 248 fossil_print("MERGE %s\n", zNew); 249 249 } ................................................................................ 288 288 if( rid==0 ){ 289 289 db_ephemeral_blob(&q, 6, &delta); 290 290 fossil_print("ADDED %s\n", zNew); 291 291 diff_print_index(zNew); 292 292 diff_file_mem(&empty, &delta, zNew, zDiffCmd, 0); 293 293 }else if( isRemoved ){ 294 294 fossil_print("DELETE %s\n", zOrig); 295 - if( file_islink(zOPath) ){ 295 + if( file_wd_islink(zOPath) ){ 296 296 blob_read_link(&delta, zOPath); 297 297 }else{ 298 298 blob_read_from_file(&delta, zOPath); 299 299 } 300 300 diff_print_index(zNew); 301 301 diff_file_mem(&delta, &empty, zOrig, zDiffCmd, 0); 302 302 }else{ 303 303 Blob a, b, disk; 304 - int isOrigLink = file_islink(zOPath); 304 + int isOrigLink = file_wd_islink(zOPath); 305 305 db_ephemeral_blob(&q, 6, &delta); 306 306 if( isOrigLink ){ 307 307 blob_read_link(&disk, zOPath); 308 308 }else{ 309 309 blob_read_from_file(&disk, zOPath); 310 310 } 311 311 fossil_print("CHANGED %s\n", zNew);
Changes to src/tar.c.
414 414 blob_reset(&tball.pax); 415 415 } 416 416 417 417 418 418 /* 419 419 ** COMMAND: test-tarball 420 420 ** 421 -** Generate a GZIP-compresssed tarball in the file given by the first argument 421 +** Generate a GZIP-compressed tarball in the file given by the first argument 422 422 ** that contains files given in the second and subsequent arguments. 423 423 */ 424 424 void test_tarball_cmd(void){ 425 425 int i; 426 426 Blob zip; 427 427 Blob file; 428 428 if( g.argc<3 ){ ................................................................................ 430 430 } 431 431 sqlite3_open(":memory:", &g.db); 432 432 tar_begin(); 433 433 for(i=3; i<g.argc; i++){ 434 434 blob_zero(&file); 435 435 blob_read_from_file(&file, g.argv[i]); 436 436 tar_add_file(g.argv[i], &file, 437 - file_perm(g.argv[i]), file_mtime(g.argv[i])); 437 + file_wd_perm(g.argv[i]), file_wd_mtime(g.argv[i])); 438 438 blob_reset(&file); 439 439 } 440 440 tar_finish(&zip); 441 441 blob_write_to_file(&zip, g.argv[2]); 442 442 } 443 443 444 444 /*
Changes to src/undo.c.
43 43 int new_exe; 44 44 int new_link; 45 45 int old_link; 46 46 Blob current; 47 47 Blob new; 48 48 zFullname = mprintf("%s/%s", g.zLocalRoot, zPathname); 49 49 old_link = db_column_int(&q, 3); 50 - new_link = file_islink(zFullname); 51 - new_exists = file_size(zFullname)>=0; 50 + new_link = file_wd_islink(zFullname); 51 + new_exists = file_wd_size(zFullname)>=0; 52 52 if( new_exists ){ 53 53 if( new_link ){ 54 54 blob_read_link(¤t, zFullname); 55 55 }else{ 56 56 blob_read_from_file(¤t, zFullname); 57 57 } 58 - new_exe = file_isexe(zFullname); 58 + new_exe = file_wd_isexe(zFullname); 59 59 }else{ 60 60 blob_zero(¤t); 61 61 new_exe = 0; 62 62 } 63 63 blob_zero(&new); 64 64 old_exists = db_column_int(&q, 1); 65 65 old_exe = db_column_int(&q, 2); ................................................................................ 72 72 }else{ 73 73 fossil_print("NEW %s\n", zPathname); 74 74 } 75 75 if( new_exists && (new_link || old_link) ){ 76 76 file_delete(zFullname); 77 77 } 78 78 if( old_link ){ 79 - create_symlink(blob_str(&new), zFullname); 79 + symlink_create(blob_str(&new), zFullname); 80 80 }else{ 81 81 blob_write_to_file(&new, zFullname); 82 82 } 83 - file_setexe(zFullname, old_exe); 83 + file_wd_setexe(zFullname, old_exe); 84 84 }else{ 85 85 fossil_print("DELETE %s\n", zPathname); 86 86 file_delete(zFullname); 87 87 } 88 88 blob_reset(&new); 89 89 free(zFullname); 90 90 db_finalize(&q); ................................................................................ 268 268 Blob content; 269 269 int existsFlag; 270 270 int isLink; 271 271 Stmt q; 272 272 273 273 if( !undoActive ) return; 274 274 zFullname = mprintf("%s%s", g.zLocalRoot, zPathname); 275 - existsFlag = file_size(zFullname)>=0; 276 - isLink = file_islink(zFullname); 275 + existsFlag = file_wd_size(zFullname)>=0; 276 + isLink = file_wd_islink(zFullname); 277 277 db_prepare(&q, 278 278 "INSERT OR IGNORE INTO" 279 279 " undo(pathname,redoflag,existsflag,isExe,isLink,content)" 280 280 " VALUES(%Q,0,%d,%d,%d,:c)", 281 - zPathname, existsFlag, file_isexe(zFullname), isLink 281 + zPathname, existsFlag, file_wd_isexe(zFullname), isLink 282 282 ); 283 283 if( existsFlag ){ 284 284 if( isLink ){ 285 285 blob_read_link(&content, zFullname); 286 286 }else{ 287 287 blob_read_from_file(&content, zFullname); 288 288 }
Changes to src/update.c.
365 365 undo_save(zName); 366 366 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); 367 367 }else if( idt>0 && idv>0 && ridt!=ridv && chnged==0 ){ 368 368 /* The file is unedited. Change it to the target version */ 369 369 undo_save(zName); 370 370 fossil_print("UPDATE %s\n", zName); 371 371 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); 372 - }else if( idt>0 && idv>0 && file_size(zFullPath)<0 ){ 372 + }else if( idt>0 && idv>0 && file_wd_size(zFullPath)<0 ){ 373 373 /* The file missing from the local check-out. Restore it to the 374 374 ** version that appears in the target. */ 375 375 fossil_print("UPDATE %s\n", zName); 376 376 undo_save(zName); 377 377 if( !nochangeFlag ) vfile_to_disk(0, idt, 0, 0); 378 378 }else if( idt==0 && idv>0 ){ 379 379 if( ridv==0 ){ ................................................................................ 396 396 Blob r, t, v; 397 397 int rc; 398 398 if( nameChng ){ 399 399 fossil_print("MERGE %s -> %s\n", zName, zNewName); 400 400 }else{ 401 401 fossil_print("MERGE %s\n", zName); 402 402 } 403 - if( islinkv || islinkt /* || file_islink(zFullPath) */ ){ 403 + if( islinkv || islinkt /* || file_wd_islink(zFullPath) */ ){ 404 404 fossil_print("***** Cannot merge symlink %s\n", zNewName); 405 405 nConflict++; 406 406 }else{ 407 407 undo_save(zName); 408 408 content_get(ridt, &t); 409 409 content_get(ridv, &v); 410 410 rc = merge_3way(&v, zFullPath, &t, &r); 411 411 if( rc>=0 ){ 412 412 if( !nochangeFlag ){ 413 413 blob_write_to_file(&r, zFullNewPath); 414 - file_setexe(zFullNewPath, isexe); 414 + file_wd_setexe(zFullNewPath, isexe); 415 415 } 416 416 if( rc>0 ){ 417 417 fossil_print("***** %d merge conflicts in %s\n", rc, zNewName); 418 418 nConflict++; 419 419 } 420 420 }else{ 421 421 if( !nochangeFlag ){ 422 422 blob_write_to_file(&t, zFullNewPath); 423 - file_setexe(zFullNewPath, isexe); 423 + file_wd_setexe(zFullNewPath, isexe); 424 424 } 425 425 fossil_print("***** Cannot merge binary file %s\n", zNewName); 426 426 nConflict++; 427 427 } 428 428 } 429 429 if( nameChng && !nochangeFlag ) file_delete(zFullPath); 430 430 blob_reset(&v); ................................................................................ 666 666 file_delete(zFull); 667 667 fossil_print("DELETE: %s\n", zFile); 668 668 } 669 669 db_multi_exec("DELETE FROM vfile WHERE pathname=%Q", zFile); 670 670 }else{ 671 671 sqlite3_int64 mtime; 672 672 undo_save(zFile); 673 - if( file_size(zFull)>=0 && (isLink || file_islink(zFull)) ){ 673 + if( file_wd_size(zFull)>=0 && (isLink || file_wd_islink(zFull)) ){ 674 674 file_delete(zFull); 675 675 } 676 676 if( isLink ){ 677 - create_symlink(blob_str(&record), zFull); 677 + symlink_create(blob_str(&record), zFull); 678 678 }else{ 679 679 blob_write_to_file(&record, zFull); 680 680 } 681 - file_setexe(zFull, isExe); 681 + file_wd_setexe(zFull, isExe); 682 682 fossil_print("REVERTED: %s\n", zFile); 683 - mtime = file_mtime(zFull); 683 + mtime = file_wd_mtime(zFull); 684 684 db_multi_exec( 685 685 "UPDATE vfile" 686 686 " SET mtime=%lld, chnged=0, deleted=0, isexe=%d, islink=%d, mrid=rid," 687 687 " pathname=coalesce(origname,pathname), origname=NULL" 688 688 " WHERE pathname=%Q", 689 689 mtime, isExe, isLink, zFile 690 690 );
Changes to src/vfile.c.
164 164 zName = db_column_text(&q, 1); 165 165 rid = db_column_int(&q, 2); 166 166 isDeleted = db_column_int(&q, 3); 167 167 oldChnged = db_column_int(&q, 4); 168 168 oldMtime = db_column_int64(&q, 7); 169 169 if( isDeleted ){ 170 170 chnged = 1; 171 - }else if( !file_isfile_or_link(zName) && file_size(0)>=0 ){ 171 + }else if( !file_wd_isfile_or_link(zName) && file_wd_size(0)>=0 ){ 172 172 if( notFileIsFatal ){ 173 173 fossil_warning("not an ordinary file: %s", zName); 174 174 nErr++; 175 175 } 176 176 chnged = 1; 177 177 }else if( oldChnged>=2 ){ 178 178 chnged = oldChnged; 179 179 }else if( rid==0 ){ 180 180 chnged = 1; 181 181 } 182 182 if( chnged!=1 ){ 183 183 i64 origSize = db_column_int64(&q, 6); 184 - currentMtime = file_mtime(0); 185 - if( origSize!=file_size(0) ){ 184 + currentMtime = file_wd_mtime(0); 185 + if( origSize!=file_wd_size(0) ){ 186 186 /* A file size change is definitive - the file has changed. No 187 187 ** need to check the sha1sum */ 188 188 chnged = 1; 189 189 } 190 190 } 191 191 if( chnged!=1 && (checkMtime==0 || currentMtime!=oldMtime) ){ 192 192 db_ephemeral_blob(&q, 5, &origCksum); ................................................................................ 245 245 zName = db_column_text(&q, 1); 246 246 rid = db_column_int(&q, 2); 247 247 isExe = db_column_int(&q, 3); 248 248 isLink = db_column_int(&q, 4); 249 249 content_get(rid, &content); 250 250 if( file_is_the_same(&content, zName) ){ 251 251 blob_reset(&content); 252 - if( file_setexe(zName, isExe) ){ 252 + if( file_wd_setexe(zName, isExe) ){ 253 253 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", 254 - file_mtime(zName), id); 254 + file_wd_mtime(zName), id); 255 255 } 256 256 continue; 257 257 } 258 - if( promptFlag && file_size(zName)>=0 ){ 258 + if( promptFlag && file_wd_size(zName)>=0 ){ 259 259 Blob ans; 260 260 char *zMsg; 261 261 char cReply; 262 262 zMsg = mprintf("overwrite %s (a=always/y/N)? ", zName); 263 263 prompt_user(zMsg, &ans); 264 264 free(zMsg); 265 265 cReply = blob_str(&ans)[0]; ................................................................................ 274 274 } 275 275 } 276 276 if( verbose ) fossil_print("%s\n", &zName[nRepos]); 277 277 if( file_isdir(zName) == 1 ){ 278 278 /*TODO(dchest): remove directories? */ 279 279 fossil_fatal("%s is directory, cannot overwrite\n", zName); 280 280 } 281 - if( file_size(zName)>=0 && (isLink || file_islink(zName)) ){ 281 + if( file_wd_size(zName)>=0 && (isLink || file_wd_islink(zName)) ){ 282 282 file_delete(zName); 283 283 } 284 284 if( isLink ){ 285 - create_symlink(blob_str(&content), zName); 285 + symlink_create(blob_str(&content), zName); 286 286 }else{ 287 287 blob_write_to_file(&content, zName); 288 288 } 289 - file_setexe(zName, isExe); 289 + file_wd_setexe(zName, isExe); 290 290 blob_reset(&content); 291 291 db_multi_exec("UPDATE vfile SET mtime=%lld WHERE id=%d", 292 - file_mtime(zName), id); 292 + file_wd_mtime(zName), id); 293 293 } 294 294 db_finalize(&q); 295 295 } 296 296 297 297 298 298 /* 299 299 ** Delete from the disk every file in VFILE vid. ................................................................................ 391 391 zPath = blob_str(pPath); 392 392 if( glob_match(pIgnore, &zPath[nPrefix+1]) ){ 393 393 /* do nothing */ 394 394 }else if( file_isdir(zPath)==1 ){ 395 395 if( !vfile_top_of_checkout(zPath) ){ 396 396 vfile_scan(pPath, nPrefix, allFlag, pIgnore); 397 397 } 398 - }else if( file_isfile_or_link(zPath) ){ 398 + }else if( file_wd_isfile_or_link(zPath) ){ 399 399 db_bind_text(&ins, ":file", &zPath[nPrefix+1]); 400 400 db_step(&ins); 401 401 db_reset(&ins); 402 402 } 403 403 blob_resize(pPath, origSize); 404 404 } 405 405 closedir(d); ................................................................................ 450 450 while( db_step(&q)==SQLITE_ROW ){ 451 451 const char *zFullpath = db_column_text(&q, 0); 452 452 const char *zName = db_column_text(&q, 1); 453 453 int isSelected = db_column_int(&q, 3); 454 454 455 455 if( isSelected ){ 456 456 md5sum_step_text(zName, -1); 457 - if( file_islink(zFullpath) ){ 457 + if( file_wd_islink(zFullpath) ){ 458 458 /* Instead of file content, use link destination path */ 459 459 Blob pathBuf; 460 460 461 461 sqlite3_snprintf(sizeof(zBuf), zBuf, " %ld\n", 462 462 blob_read_link(&pathBuf, zFullpath)); 463 463 md5sum_step_text(zBuf, -1); 464 464 md5sum_step_text(blob_str(&pathBuf), -1); ................................................................................ 522 522 md5sum_init(); 523 523 while( db_step(&q)==SQLITE_ROW ){ 524 524 const char *zFullpath = db_column_text(&q, 0); 525 525 const char *zName = db_column_text(&q, 1); 526 526 int rid = db_column_int(&q, 2); 527 527 528 528 blob_zero(&disk); 529 - if( file_islink(zFullpath) ){ 529 + if( file_wd_islink(zFullpath) ){ 530 530 rc = blob_read_link(&disk, zFullpath); 531 531 }else{ 532 532 rc = blob_read_from_file(&disk, zFullpath); 533 533 } 534 534 if( rc<0 ){ 535 535 fossil_print("ERROR: cannot read file [%s]\n", zFullpath); 536 536 blob_reset(&disk);
Changes to src/zip.c.
289 289 if( g.argc<3 ){ 290 290 usage("ARCHIVE FILE...."); 291 291 } 292 292 zip_open(); 293 293 for(i=3; i<g.argc; i++){ 294 294 blob_zero(&file); 295 295 blob_read_from_file(&file, g.argv[i]); 296 - zip_add_file(g.argv[i], &file, file_perm(g.argv[i])); 296 + zip_add_file(g.argv[i], &file, file_wd_perm(g.argv[i])); 297 297 blob_reset(&file); 298 298 } 299 299 zip_close(&zip); 300 300 blob_write_to_file(&zip, g.argv[2]); 301 301 } 302 302 303 303 /*