Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Make "win32-longpath" the default VFS on win32, eliminating all path limitations (up to ~32767 chars). TODO: eliminate use of the the function _wstati64(), that appears to be the only Win32 function left which cannot handle such long paths. Everything else needed is done. |
|---|---|
| Timelines: | family | ancestors | descendants | both | win32-longpath |
| Files: | files | file ages | folders |
| SHA1: |
1b9893bdc8e8ec9885f3c18175210525 |
| User & Date: | jan.nijtmans 2013-12-12 09:37:52.753 |
Context
|
2013-12-12
| ||
| 11:16 | Bug-fix: didn't compile on win32, and handle extended UNC paths correctly. check-in: da8d516fe1 user: jan.nijtmans tags: win32-longpath | |
| 09:37 | Make "win32-longpath" the default VFS on win32, eliminating all path limitations (up to ~32767 chars). TODO: eliminate use of the the function _wstati64(), that appears to be the only Win32 function left which cannot handle such long paths. Everything else needed is done. check-in: 1b9893bdc8 user: jan.nijtmans tags: win32-longpath | |
| 08:43 | Put back 'win32-longpath' VFS as default for Cygwin: Cygwin doesn't suffer from path limitations (at least, not until 4096 chars), so usage of the 'win32' VFS is not reasonable as default. check-in: a76039815d user: jan.nijtmans tags: trunk | |
|
2013-12-11
| ||
| 13:00 | As it turns out that _wstati64() cannot handled the special "\\?\" prefix, work around that. Otherwise the win32-longpath VFS is quite useless for fossil. Maybe a better solution should be worked out, not using _wstati64() at all. check-in: bb440899d3 user: jan.nijtmans tags: trunk | |
Changes
Changes to src/db.c.
| ︙ | ︙ | |||
713 714 715 716 717 718 719 |
int rc;
sqlite3 *db;
#if defined(__CYGWIN__)
zDbName = fossil_utf8_to_filename(zDbName);
#endif
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
| | > > > > | 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 |
int rc;
sqlite3 *db;
#if defined(__CYGWIN__)
zDbName = fossil_utf8_to_filename(zDbName);
#endif
if( g.fSqlTrace ) fossil_trace("-- sqlite3_open: [%s]\n", zDbName);
rc = sqlite3_open_v2(
zDbName, &db,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
g.zVfsName
);
if( rc!=SQLITE_OK ){
db_err("[%s]: %s", zDbName, sqlite3_errmsg(db));
}
sqlite3_busy_timeout(db, 5000);
sqlite3_wal_autocheckpoint(db, 1); /* Set to checkpoint frequently */
sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
sqlite3_create_function(db, "checkin_mtime", 2, SQLITE_ANY, 0,
|
| ︙ | ︙ |
Changes to src/login.c.
| ︙ | ︙ | |||
693 694 695 696 697 698 699 |
zOtherRepo = db_text(0,
"SELECT value FROM config WHERE name='peer-repo-%q'",
zCode
);
if( zOtherRepo==0 ) return 0; /* No such peer repository */
| | > > > > | 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 |
zOtherRepo = db_text(0,
"SELECT value FROM config WHERE name='peer-repo-%q'",
zCode
);
if( zOtherRepo==0 ) return 0; /* No such peer repository */
rc = sqlite3_open_v2(
zOtherRepo, &pOther,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
g.zVfsName
);
if( rc==SQLITE_OK ){
sqlite3_create_function(pOther,"now",0,SQLITE_ANY,0,db_now_function,0,0);
sqlite3_create_function(pOther, "constant_time_cmp", 2, SQLITE_UTF8, 0,
constant_time_cmp_function, 0, 0);
sqlite3_busy_timeout(pOther, 5000);
zSQL = mprintf(
"SELECT cexpire FROM user"
|
| ︙ | ︙ | |||
1370 1371 1372 1373 1374 1375 1376 |
const char *zLabel = db_column_text(&q, 0);
db_multi_exec(
"DELETE FROM config WHERE name GLOB 'peer-*-%q'",
&zLabel[10]
);
continue;
}
| | > > > > | 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 |
const char *zLabel = db_column_text(&q, 0);
db_multi_exec(
"DELETE FROM config WHERE name GLOB 'peer-*-%q'",
&zLabel[10]
);
continue;
}
rc = sqlite3_open_v2(
zRepoName, &pPeer,
SQLITE_OPEN_READWRITE,
g.zVfsName
);
if( rc!=SQLITE_OK ){
blob_appendf(&err, "%s%s: %s%s", zPrefix, zRepoName,
sqlite3_errmsg(pPeer), zSuffix);
nErr++;
sqlite3_close(pPeer);
continue;
}
|
| ︙ | ︙ | |||
1457 1458 1459 1460 1461 1462 1463 |
}
/* Make sure the other repository is a valid Fossil database */
if( file_size(zRepo)<0 ){
*pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo);
return;
}
| | > > > > | 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 |
}
/* Make sure the other repository is a valid Fossil database */
if( file_size(zRepo)<0 ){
*pzErrMsg = mprintf("repository file \"%s\" does not exist", zRepo);
return;
}
rc = sqlite3_open_v2(
zRepo, &pOther,
SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
g.zVfsName
);
if( rc!=SQLITE_OK ){
*pzErrMsg = mprintf(sqlite3_errmsg(pOther));
}else{
rc = sqlite3_exec(pOther, "SELECT count(*) FROM user", 0, 0, pzErrMsg);
}
sqlite3_close(pOther);
if( rc ) return;
|
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
** All global variables are in this structure.
*/
struct Global {
int argc; char **argv; /* Command-line arguments to the program */
char *nameOfExe; /* Full path of executable. */
const char *zErrlog; /* Log errors to this file, if not NULL */
int isConst; /* True if the output is unchanging */
sqlite3 *db; /* The connection to the databases */
sqlite3 *dbConfig; /* Separate connection for global_config table */
int useAttach; /* True if global_config is attached to repository */
const char *zConfigDbName;/* Path of the config database. NULL if not open */
sqlite3_int64 now; /* Seconds since 1970 */
int repositoryOpen; /* True if the main repository database is open */
char *zRepositoryName; /* Name of the repository database */
| > | 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
** All global variables are in this structure.
*/
struct Global {
int argc; char **argv; /* Command-line arguments to the program */
char *nameOfExe; /* Full path of executable. */
const char *zErrlog; /* Log errors to this file, if not NULL */
int isConst; /* True if the output is unchanging */
const char *zVfsName; /* The VFS to use for database connections */
sqlite3 *db; /* The connection to the databases */
sqlite3 *dbConfig; /* Separate connection for global_config table */
int useAttach; /* True if global_config is attached to repository */
const char *zConfigDbName;/* Path of the config database. NULL if not open */
sqlite3_int64 now; /* Seconds since 1970 */
int repositoryOpen; /* True if the main repository database is open */
char *zRepositoryName; /* Name of the repository database */
|
| ︙ | ︙ | |||
547 548 549 550 551 552 553 |
#if defined(_WIN32)
int _CRT_glob = 0x0001; /* See MinGW bug #2062 */
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
| < | 548 549 550 551 552 553 554 555 556 557 558 559 560 561 |
#if defined(_WIN32)
int _CRT_glob = 0x0001; /* See MinGW bug #2062 */
#endif
int main(int argc, char **argv)
#endif
{
const char *zCmdName = "unknown";
int idx;
int rc;
sqlite3_config(SQLITE_CONFIG_SINGLETHREAD);
sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
memset(&g, 0, sizeof(g));
g.now = time(0);
g.httpHeader = empty_blob;
|
| ︙ | ︙ | |||
575 576 577 578 579 580 581 | expand_args_option(argc, argv); #ifdef FOSSIL_ENABLE_TCL memset(&g.tcl, 0, sizeof(TclContext)); g.tcl.argc = g.argc; g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */ #endif g.mainTimerId = fossil_timer_start(); | | | | < | | | > | | | | 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 |
expand_args_option(argc, argv);
#ifdef FOSSIL_ENABLE_TCL
memset(&g.tcl, 0, sizeof(TclContext));
g.tcl.argc = g.argc;
g.tcl.argv = copy_args(g.argc, g.argv); /* save full arguments */
#endif
g.mainTimerId = fossil_timer_start();
g.zVfsName = find_option("vfs",0,1);
if( g.zVfsName==0 ){
g.zVfsName = fossil_getenv("FOSSIL_VFS");
#if defined(_WIN32) || defined(__CYGWIN__)
if( g.zVfsName==0 && sqlite3_libversion_number()>=3008001 ){
g.zVfsName = "win32-longpath";
}
#endif
}
if( g.zVfsName ){
sqlite3_vfs *pVfs = sqlite3_vfs_find(g.zVfsName);
if( pVfs ){
sqlite3_vfs_register(pVfs, 1);
}else{
fossil_fatal("no such VFS: \"%s\"", g.zVfsName);
}
}
if( fossil_getenv("GATEWAY_INTERFACE")!=0 && !find_option("nocgi", 0, 0)){
zCmdName = "cgi";
g.isHTTP = 1;
}else if( g.argc<2 ){
fossil_print(
|
| ︙ | ︙ |
Changes to src/sqlcmd.c.
| ︙ | ︙ | |||
122 123 124 125 126 127 128 |
sqlcmd_decompress, 0, 0);
re_add_sql_func(db);
g.repositoryOpen = 1;
g.db = db;
return SQLITE_OK;
}
| < < < < < | 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
sqlcmd_decompress, 0, 0);
re_add_sql_func(db);
g.repositoryOpen = 1;
g.db = db;
return SQLITE_OK;
}
/*
** COMMAND: sqlite3
**
** Usage: %fossil sqlite3 ?DATABASE? ?OPTIONS?
**
** Run the standalone sqlite3 command-line shell on DATABASE with OPTIONS.
** If DATABASE is omitted, then the repository that serves the working
** directory is opened.
**
** WARNING: Careless use of this command can corrupt a Fossil repository
** in ways that are unrecoverable. Be sure you know what you are doing before
** running any SQL commands that modifies the repository database.
*/
void sqlite3_cmd(void){
extern int sqlite3_shell(int, char**);
db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
db_close(1);
sqlite3_shutdown();
sqlite3_shell(g.argc-1, g.argv+1);
g.db = 0;
}
/*
** This routine is called by the patched sqlite3 command-line shell in order
** to load the name and database connection for the open Fossil database.
*/
void fossil_open(const char **pzRepoName){
sqlite3_auto_extension((void(*)(void))sqlcmd_autoinit);
*pzRepoName = g.zRepositoryName;
}
|
Changes to src/sqlite3.c.
| ︙ | ︙ | |||
35123 35124 35125 35126 35127 35128 35129 | } #endif /* ** Convert a UTF-8 filename into whatever form the underlying ** operating system wants filenames in. Space to hold the result ** is obtained from malloc and must be freed by the calling | | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | | 35123 35124 35125 35126 35127 35128 35129 35130 35131 35132 35133 35134 35135 35136 35137 35138 35139 35140 35141 35142 35143 35144 35145 35146 35147 35148 35149 35150 35151 35152 35153 35154 35155 35156 35157 35158 35159 35160 35161 35162 35163 35164 35165 35166 35167 35168 35169 35170 35171 |
}
#endif
/*
** Convert a UTF-8 filename into whatever form the underlying
** operating system wants filenames in. Space to hold the result
** is obtained from malloc and must be freed by the calling
** function. When running on NT and zFilename is absolute, the
** resulting path is guaranteed to start with "\\?\".
*/
static void *winConvertFromUtf8Filename(const char *zFilename){
void *zConverted = 0;
if( osIsNT() ){
int nChar;
LPWSTR zWideFilename;
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, NULL, 0);
if( nChar==0 ){
return 0;
}
zWideFilename = sqlite3MallocZero( (nChar*sizeof(zWideFilename[0]))+12 );
if( zWideFilename==0 ){
return 0;
}
if( winIsDirSep(zFilename[0]) && winIsDirSep(zFilename[1]) ){
memcpy(zWideFilename, L"\\\\?\\UNC\\", 16);
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+6,
nChar);
}else if( winIsDriveLetterAndColon(zFilename) && winIsDirSep(zFilename[2])) {
memcpy(zWideFilename, L"\\\\?\\", 8);
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename+4,
nChar);
zWideFilename[6] = '\\';
}else{
nChar = osMultiByteToWideChar(CP_UTF8, 0, zFilename, -1, zWideFilename,
nChar);
}
if( nChar==0 ){
sqlite3_free(zWideFilename);
zWideFilename = 0;
}
zConverted = zWideFilename;
}
#ifdef SQLITE_WIN32_HAS_ANSI
else{
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);
}
#endif
/* caller will handle out of memory */
|
| ︙ | ︙ | |||
36059 36060 36061 36062 36063 36064 36065 |
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
| > | > > > | 36088 36089 36090 36091 36092 36093 36094 36095 36096 36097 36098 36099 36100 36101 36102 36103 36104 36105 36106 |
** for converting the relative path name to an absolute
** one by prepending the data directory and a backslash.
*/
sqlite3_snprintf(MIN(nFull, pVfs->mxPathname), zFull, "%s%c%s",
sqlite3_data_directory, winGetDirSep(), zRelative);
return SQLITE_OK;
}
if( osIsNT() ){
zConverted = winUtf8ToUnicode(zRelative);
}else{
zConverted = sqlite3_win32_utf8_to_mbcs(zFilename);;
}
if( zConverted==0 ){
return SQLITE_IOERR_NOMEM;
}
if( osIsNT() ){
LPWSTR zTemp;
nByte = osGetFullPathNameW((LPCWSTR)zConverted, 0, 0, 0);
if( nByte==0 ){
|
| ︙ | ︙ |
Changes to src/utf8.c.
| ︙ | ︙ | |||
189 190 191 192 193 194 195 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
| | < > > > > | > > > > > > > > | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 |
**
** See: <http://cygwin.com/cygwin-ug-net/using-specialnames.html>
**
*/
void *fossil_utf8_to_filename(const char *zUtf8){
#ifdef _WIN32
int nChar = MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, 0, 0);
wchar_t *zUnicode = sqlite3_malloc( (nChar+6) * 2 );
wchar_t *wUnicode = zUnicode;
if( zUnicode==0 ){
return 0;
}
/* If path starts with "<drive>:/" or "<drive>:\", don't translate the ':' */
if( fossil_isalpha(zUtf8[0]) && zUtf8[1]==':'
&& (zUtf8[2]=='\\' || zUtf8[2]=='/')) {
/* Convert to extended path. */
memcpy(zUnicode, L"\\\\?\\", 8);
wUnicode += 4;
MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar);
wUnicode[2] = '\\';
wUnicode += 3;
}else if( (zUtf8[0]=='\\' || zUtf8[0]=='/') &&
(zUtf8[1]=='\\' || zUtf8[1]=='/') && zUtf8[2]!='?' ) {
/* Convert to extended UNC path. */
memcpy(zUnicode, L"\\\\?\\UNC\\", 16);
wUnicode += 8;
MultiByteToWideChar(CP_UTF8, 0, zUtf8+2, -1, wUnicode, nChar);
}else{
MultiByteToWideChar(CP_UTF8, 0, zUtf8, -1, wUnicode, nChar);
}
while( *wUnicode != '\0' ){
if ( (*wUnicode < ' ') || wcschr(L"\"*:<>?|", *wUnicode) ){
*wUnicode |= 0xF000;
}else if( *wUnicode == '/' ){
*wUnicode = '\\';
}
|
| ︙ | ︙ |