Fossil

Check-in [1c28a41cf1]
Login

Check-in [1c28a41cf1]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Merged main trunk into private branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | newbuild | ttmrichter
Files: files | file ages | folders
SHA1: 1c28a41cf1957b126173e7a79bcd2889e9684f9a
User & Date: michael 2010-07-09 16:25:09
Context
2010-07-09
16:57
Named the mingw32 fragment properly. Forced mingw32 to use GCC. ... (check-in: cd98f05dbe user: michael tags: newbuild, ttmrichter)
16:25
Merged main trunk into private branch. ... (check-in: 1c28a41cf1 user: michael tags: newbuild, ttmrichter)
16:23
Started the process of modifying the build system to permit more flexible and reliable cross-platform support. Currently the build system is set up for Linux (GCC or CLANG as the compiler) and for MinGW32 (GCC as the compiler). Of these, only the Linux builds have been tested so far and confirmed to work as expected. The way to use this new system is as follows: make Builds the default platform and compiler (linux and gcc). PLATFORM=mingw32 make Builds the mingw32 build (untested!) using the default compiler (gcc). COMPILER=clang make Builds the default platform (linux) using the clang compiler. Other platform and compiler fragment files can be added in the ./make directory based on the models already there. ... (check-in: d3252d7488 user: michael tags: newbuild, ttmrichter)
2010-07-08
17:57
Update the built-in sqlite3 to the latest development version. ... (check-in: 1e6ded9856 user: drh tags: trunk)
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/blob.c.

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
** This routine is called if a blob operation fails because we
** have run out of memory.
*/
static void blob_panic(void){
  static const char zErrMsg[] = "out of memory\n";
  write(2, zErrMsg, sizeof(zErrMsg)-1);
  exit(1);
}

/*
** A reallocation function that assumes that aData came from malloc().
** This function attempts to resize the buffer of the blob to hold
** newSize bytes.  
**







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
** This routine is called if a blob operation fails because we
** have run out of memory.
*/
static void blob_panic(void){
  static const char zErrMsg[] = "out of memory\n";
  write(2, zErrMsg, sizeof(zErrMsg)-1);
  fossil_exit(1);
}

/*
** A reallocation function that assumes that aData came from malloc().
** This function attempts to resize the buffer of the blob to hold
** newSize bytes.  
**

Changes to src/branch.c.

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  blob_appendf(&branch, "Z %b\n", &mcksum);
  if( !noSign && clearsign(&branch, &branch) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      db_end_transaction(1);
      exit(1);
    }
  }

  brid = content_put(&branch, 0, 0);
  if( brid==0 ){
    fossil_panic("trouble committing manifest: %s", g.zErrMsg);
  }







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  blob_appendf(&branch, "Z %b\n", &mcksum);
  if( !noSign && clearsign(&branch, &branch) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      db_end_transaction(1);
      fossil_exit(1);
    }
  }

  brid = content_put(&branch, 0, 0);
  if( brid==0 ){
    fossil_panic("trouble committing manifest: %s", g.zErrMsg);
  }

Changes to src/cgi.c.

347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  }
  cgi_append_header(zLocation);
  cgi_reset_content();
  cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL);
  cgi_set_status(302, "Moved Temporarily");
  free(zLocation);
  cgi_reply();
  exit(0);
}
void cgi_redirectf(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
  cgi_redirect(vmprintf(zFormat, ap));
  va_end(ap);
}







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
  }
  cgi_append_header(zLocation);
  cgi_reset_content();
  cgi_printf("<html>\n<p>Redirect to %h</p>\n</html>\n", zURL);
  cgi_set_status(302, "Moved Temporarily");
  free(zLocation);
  cgi_reply();
  fossil_exit(0);
}
void cgi_redirectf(const char *zFormat, ...){
  va_list ap;
  va_start(ap, zFormat);
  cgi_redirect(vmprintf(zFormat, ap));
  va_end(ap);
}
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
** zName and zValue are not copied and must not change or be
** deallocated after this routine returns.
*/
void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
  if( nAllocQP<=nUsedQP ){
    nAllocQP = nAllocQP*2 + 10;
    aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
    if( aParamQP==0 ) exit(1);
  }
  aParamQP[nUsedQP].zName = zName;
  aParamQP[nUsedQP].zValue = zValue;
  if( g.fHttpTrace ){
    fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
  }
  aParamQP[nUsedQP].seq = seqQP++;







|







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
** zName and zValue are not copied and must not change or be
** deallocated after this routine returns.
*/
void cgi_set_parameter_nocopy(const char *zName, const char *zValue){
  if( nAllocQP<=nUsedQP ){
    nAllocQP = nAllocQP*2 + 10;
    aParamQP = realloc( aParamQP, nAllocQP*sizeof(aParamQP[0]) );
    if( aParamQP==0 ) fossil_exit(1);
  }
  aParamQP[nUsedQP].zName = zName;
  aParamQP[nUsedQP].zValue = zValue;
  if( g.fHttpTrace ){
    fprintf(stderr, "# cgi: %s = [%s]\n", zName, zValue);
  }
  aParamQP[nUsedQP].seq = seqQP++;
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  if( len>0 && zType ){
    blob_zero(&g.cgiIn);
    if( strcmp(zType,"application/x-www-form-urlencoded")==0 
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = malloc( len+1 );
      if( z==0 ) exit(1);
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      if( zType[0]=='a' ){
        add_param_list(z, '&');
      }else{
        process_multipart_form_data(z, len);
      }







|







676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
  len = atoi(PD("CONTENT_LENGTH", "0"));
  g.zContentType = zType = P("CONTENT_TYPE");
  if( len>0 && zType ){
    blob_zero(&g.cgiIn);
    if( strcmp(zType,"application/x-www-form-urlencoded")==0 
         || strncmp(zType,"multipart/form-data",19)==0 ){
      z = malloc( len+1 );
      if( z==0 ) fossil_exit(1);
      len = fread(z, 1, len, g.httpIn);
      z[len] = 0;
      if( zType[0]=='a' ){
        add_param_list(z, '&');
      }else{
        process_multipart_form_data(z, len);
      }
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
*/
static void malformed_request(void){
  cgi_set_status(501, "Not Implemented");
  cgi_printf(
    "<html><body>Unrecognized HTTP Request</body></html>\n"
  );
  cgi_reply();
  exit(0);
}

/*
** Panic and die while processing a webpage.
*/
void cgi_panic(const char *zFormat, ...){
  va_list ap;
  cgi_reset_content();
  cgi_set_status(500, "Internal Server Error");
  cgi_printf(
    "<html><body><h1>Internal Server Error</h1>\n"
    "<plaintext>"
  );
  va_start(ap, zFormat);
  vxprintf(pContent,zFormat,ap);
  va_end(ap);
  cgi_reply();
  exit(1);
}

/*
** Remove the first space-delimited token from a string and return
** a pointer to it.  Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/







|

















|







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
*/
static void malformed_request(void){
  cgi_set_status(501, "Not Implemented");
  cgi_printf(
    "<html><body>Unrecognized HTTP Request</body></html>\n"
  );
  cgi_reply();
  fossil_exit(0);
}

/*
** Panic and die while processing a webpage.
*/
void cgi_panic(const char *zFormat, ...){
  va_list ap;
  cgi_reset_content();
  cgi_set_status(500, "Internal Server Error");
  cgi_printf(
    "<html><body><h1>Internal Server Error</h1>\n"
    "<plaintext>"
  );
  va_start(ap, zFormat);
  vxprintf(pContent,zFormat,ap);
  va_end(ap);
  cgi_reply();
  fossil_exit(1);
}

/*
** Remove the first space-delimited token from a string and return
** a pointer to it.  Add a NULL to the string to terminate the token.
** Make *zLeftOver point to the start of the next token.
*/
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
**
** Return 0 to each child as it runs.  If unable to establish a
** listening socket, return non-zero.
*/
int cgi_http_server(int mnPort, int mxPort, char *zBrowser){
#ifdef __MINGW32__
  /* Use win32_http_server() instead */
  exit(1);
#else
  int listener = -1;           /* The server socket */
  int connection;              /* A socket for each individual connection */
  fd_set readfds;              /* Set of file descriptors for select() */
  size_t lenaddr;              /* Length of the inaddr structure */
  int child;                   /* PID of the child process */
  int nchildren = 0;           /* Number of child processes */







|







1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
**
** Return 0 to each child as it runs.  If unable to establish a
** listening socket, return non-zero.
*/
int cgi_http_server(int mnPort, int mxPort, char *zBrowser){
#ifdef __MINGW32__
  /* Use win32_http_server() instead */
  fossil_exit(1);
#else
  int listener = -1;           /* The server socket */
  int connection;              /* A socket for each individual connection */
  fd_set readfds;              /* Set of file descriptors for select() */
  size_t lenaddr;              /* Length of the inaddr structure */
  int child;                   /* PID of the child process */
  int nchildren = 0;           /* Number of child processes */
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
    }
    /* Bury dead children */
    while( waitpid(0, 0, WNOHANG)>0 ){
      nchildren--;
    }
  }
  /* NOT REACHED */  
  exit(1);
#endif
}


/*
** Name of days and months.
*/







|







1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
    }
    /* Bury dead children */
    while( waitpid(0, 0, WNOHANG)>0 ){
      nchildren--;
    }
  }
  /* NOT REACHED */  
  fossil_exit(1);
#endif
}


/*
** Name of days and months.
*/
1354
1355
1356
1357
1358
1359
1360
1361
1362
void cgi_modified_since(time_t objectTime){
  const char *zIf = P("HTTP_IF_MODIFIED_SINCE");
  if( zIf==0 ) return;
  if( objectTime > cgi_rfc822_parsedate(zIf) ) return;
  cgi_set_status(304,"Not Modified");
  cgi_reset_content();
  cgi_reply();
  exit(0);
}







|

1354
1355
1356
1357
1358
1359
1360
1361
1362
void cgi_modified_since(time_t objectTime){
  const char *zIf = P("HTTP_IF_MODIFIED_SINCE");
  if( zIf==0 ) return;
  if( objectTime > cgi_rfc822_parsedate(zIf) ) return;
  cgi_set_status(304,"Not Modified");
  cgi_reset_content();
  cgi_reply();
  fossil_exit(0);
}

Changes to src/checkin.c.

689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
    free(zInit);
  }
  if( blob_size(&comment)==0 ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("empty check-in comment.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      db_end_transaction(1);
      exit(1);
    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }








<
|







689
690
691
692
693
694
695

696
697
698
699
700
701
702
703
    free(zInit);
  }
  if( blob_size(&comment)==0 ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("empty check-in comment.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){

      fossil_exit(1);
    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }

827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
  blob_appendf(&manifest, "Z %b\n", &mcksum);
  zManifestFile = mprintf("%smanifest", g.zLocalRoot);
  if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      db_end_transaction(1);
      exit(1);
    }
  }
  blob_write_to_file(&manifest, zManifestFile);
  blob_reset(&manifest);
  blob_read_from_file(&manifest, zManifestFile);
  free(zManifestFile);
  nvid = content_put(&manifest, 0, 0);







<
|







826
827
828
829
830
831
832

833
834
835
836
837
838
839
840
  blob_appendf(&manifest, "Z %b\n", &mcksum);
  zManifestFile = mprintf("%smanifest", g.zLocalRoot);
  if( !noSign && !g.markPrivate && clearsign(&manifest, &manifest) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){

      fossil_exit(1);
    }
  }
  blob_write_to_file(&manifest, zManifestFile);
  blob_reset(&manifest);
  blob_read_from_file(&manifest, zManifestFile);
  free(zManifestFile);
  nvid = content_put(&manifest, 0, 0);

Changes to src/db.c.

71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    cgi_printf("<h1>Database Error</h1>\n"
               "<pre>%h</pre><p>%s</p>", z, zRebuildMsg);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n\n%s", g.argv[0], z, zRebuildMsg);
  }
  db_force_rollback();
  exit(1);
}

static int nBegin = 0;      /* Nesting depth of BEGIN */
static int isNewRepo = 0;   /* True if the repository is newly created */
static int doRollback = 0;  /* True to force a rollback */
static int nCommitHook = 0; /* Number of commit hooks */
static struct sCommitHook {







|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    cgi_printf("<h1>Database Error</h1>\n"
               "<pre>%h</pre><p>%s</p>", z, zRebuildMsg);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n\n%s", g.argv[0], z, zRebuildMsg);
  }
  db_force_rollback();
  fossil_exit(1);
}

static int nBegin = 0;      /* Nesting depth of BEGIN */
static int isNewRepo = 0;   /* True if the repository is newly created */
static int doRollback = 0;  /* True to force a rollback */
static int nCommitHook = 0; /* Number of commit hooks */
static struct sCommitHook {
112
113
114
115
116
117
118

119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
  if( nBegin==0 ){
    db_multi_exec("BEGIN");
    sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
  }
  nBegin++;
}
void db_end_transaction(int rollbackFlag){

  if( nBegin<=0 ) return;
  if( rollbackFlag ) doRollback = 1;
  nBegin--;
  if( nBegin==0 ){
    int i;
    for(i=0; doRollback==0 && i<nCommitHook; i++){
      doRollback |= aHook[i].xHook();
    }
    db_multi_exec(doRollback ? "ROLLBACK" : "COMMIT");
    doRollback = 0;
  }
}
void db_force_rollback(void){
  static int busy = 0;
  if( busy ) return;
  busy = 1;
  undo_rollback();
  if( nBegin ){
    sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0);
    if( isNewRepo ){
      db_close();
      unlink(g.zRepositoryName);







>














|







112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  if( nBegin==0 ){
    db_multi_exec("BEGIN");
    sqlite3_commit_hook(g.db, db_verify_at_commit, 0);
  }
  nBegin++;
}
void db_end_transaction(int rollbackFlag){
  if( g.db==0 ) return;
  if( nBegin<=0 ) return;
  if( rollbackFlag ) doRollback = 1;
  nBegin--;
  if( nBegin==0 ){
    int i;
    for(i=0; doRollback==0 && i<nCommitHook; i++){
      doRollback |= aHook[i].xHook();
    }
    db_multi_exec(doRollback ? "ROLLBACK" : "COMMIT");
    doRollback = 0;
  }
}
void db_force_rollback(void){
  static int busy = 0;
  if( busy || g.db==0 ) return;
  busy = 1;
  undo_rollback();
  if( nBegin ){
    sqlite3_exec(g.db, "ROLLBACK", 0, 0, 0);
    if( isNewRepo ){
      db_close();
      unlink(g.zRepositoryName);
596
597
598
599
600
601
602

603
604
605
606
607
608
609
610
611
612
613
614

615
616
617
618
619
620

621
622
623
624
625
626
627
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );
  if( rc!=SQLITE_OK ){
    db_err(sqlite3_errmsg(db));
  }
  sqlite3_busy_timeout(db, 5000); 

  return db;
}


/*
** zDbName is the name of a database file.  If no other database
** file is open, then open this one.  If another database file is
** already open, then attach zDbName using the name zLabel.
*/
void db_open_or_attach(const char *zDbName, const char *zLabel){
  if( !g.db ){
    g.db = openDatabase(zDbName);

    db_connection_init();
  }else{
#ifdef __MINGW32__
    zDbName = sqlite3_win32_mbcs_to_utf8(zDbName);
#endif
    db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);

  }
}

/*
** Open the user database in "~/.fossil".  Create the database anew if
** it does not already exist.
**







>












>






>







597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );
  if( rc!=SQLITE_OK ){
    db_err(sqlite3_errmsg(db));
  }
  sqlite3_busy_timeout(db, 5000); 
  sqlite3_wal_autocheckpoint(db, 1);  /* Set to checkpoint frequently */
  return db;
}


/*
** zDbName is the name of a database file.  If no other database
** file is open, then open this one.  If another database file is
** already open, then attach zDbName using the name zLabel.
*/
void db_open_or_attach(const char *zDbName, const char *zLabel){
  if( !g.db ){
    g.db = openDatabase(zDbName);
    g.zRepoDb = "main";
    db_connection_init();
  }else{
#ifdef __MINGW32__
    zDbName = sqlite3_win32_mbcs_to_utf8(zDbName);
#endif
    db_multi_exec("ATTACH DATABASE %Q AS %s", zDbName, zLabel);
    g.zRepoDb = mprintf("%s", zLabel);
  }
}

/*
** Open the user database in "~/.fossil".  Create the database anew if
** it does not already exist.
**
892
893
894
895
896
897
898

899
900
901
902
903
904
905
** Close the database connection.
*/
void db_close(void){
  if( g.db==0 ) return;
  while( pAllStmt ){
    db_finalize(pAllStmt);
  }

  g.repositoryOpen = 0;
  g.localOpen = 0;
  g.configOpen = 0;
  sqlite3_close(g.db);
  g.db = 0;
}








>







896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
** Close the database connection.
*/
void db_close(void){
  if( g.db==0 ) return;
  while( pAllStmt ){
    db_finalize(pAllStmt);
  }
  db_end_transaction(1);
  g.repositoryOpen = 0;
  g.localOpen = 0;
  g.configOpen = 0;
  sqlite3_close(g.db);
  g.db = 0;
}

Changes to src/deltacmd.c.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
** Given two input files, create and output a delta that carries
** the first file into the second.
*/
void delta_create_cmd(void){
  Blob orig, target, delta;
  if( g.argc!=5 ){
    fprintf(stderr,"Usage: %s %s ORIGIN TARGET DELTA\n", g.argv[0], g.argv[1]);
    exit(1);
  }
  if( blob_read_from_file(&orig, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    exit(1);
  }
  if( blob_read_from_file(&target, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    exit(1);
  }
  blob_delta_create(&orig, &target, &delta);
  if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    exit(1);
  }
  blob_reset(&orig);
  blob_reset(&target);
  blob_reset(&delta);
}

/*







|



|



|




|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
** Given two input files, create and output a delta that carries
** the first file into the second.
*/
void delta_create_cmd(void){
  Blob orig, target, delta;
  if( g.argc!=5 ){
    fprintf(stderr,"Usage: %s %s ORIGIN TARGET DELTA\n", g.argv[0], g.argv[1]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&orig, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&target, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    fossil_exit(1);
  }
  blob_delta_create(&orig, &target, &delta);
  if( blob_write_to_file(&delta, g.argv[4])<blob_size(&delta) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    fossil_exit(1);
  }
  blob_reset(&orig);
  blob_reset(&target);
  blob_reset(&delta);
}

/*
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
** Given an input files and a delta, apply the delta to the input file
** and write the result.
*/
void delta_apply_cmd(void){
  Blob orig, target, delta;
  if( g.argc!=5 ){
    fprintf(stderr,"Usage: %s %s ORIGIN DELTA TARGET\n", g.argv[0], g.argv[1]);
    exit(1);
  }
  if( blob_read_from_file(&orig, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    exit(1);
  }
  if( blob_read_from_file(&delta, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    exit(1);
  }
  blob_delta_apply(&orig, &delta, &target);
  if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    exit(1);
  }
  blob_reset(&orig);
  blob_reset(&target);
  blob_reset(&delta);
}

/*







|



|



|




|







111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
** Given an input files and a delta, apply the delta to the input file
** and write the result.
*/
void delta_apply_cmd(void){
  Blob orig, target, delta;
  if( g.argc!=5 ){
    fprintf(stderr,"Usage: %s %s ORIGIN DELTA TARGET\n", g.argv[0], g.argv[1]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&orig, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&delta, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    fossil_exit(1);
  }
  blob_delta_apply(&orig, &delta, &target);
  if( blob_write_to_file(&target, g.argv[4])<blob_size(&target) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    fossil_exit(1);
  }
  blob_reset(&orig);
  blob_reset(&target);
  blob_reset(&delta);
}

/*

Changes to src/file.c.

276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  ){
    blob_set(pOut, zOrigName);
    blob_materialize(pOut);
  }else{
    char zPwd[2000];
    if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
      exit(1);
    }
    blob_zero(pOut);
    blob_appendf(pOut, "%//%/", zPwd, zOrigName);
  }
  blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut)));
}








|







276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
  ){
    blob_set(pOut, zOrigName);
    blob_materialize(pOut);
  }else{
    char zPwd[2000];
    if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
      fossil_exit(1);
    }
    blob_zero(pOut);
    blob_appendf(pOut, "%//%/", zPwd, zOrigName);
  }
  blob_resize(pOut, file_simplify_name(blob_buffer(pOut), blob_size(pOut)));
}

341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  zPath = blob_buffer(pOut);
  if( zPath[0]=='/' ){
    int i, j;
    Blob tmp;
    char zPwd[2000];
    if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
      exit(1);
    }
    for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){}
    if( zPath[i]==0 ){
      blob_reset(pOut);
      if( zPwd[i]==0 ){
        blob_append(pOut, ".", 1);
      }else{







|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
  zPath = blob_buffer(pOut);
  if( zPath[0]=='/' ){
    int i, j;
    Blob tmp;
    char zPwd[2000];
    if( getcwd(zPwd, sizeof(zPwd)-20)==0 ){
      fprintf(stderr, "pwd too big: max %d\n", (int)sizeof(zPwd)-20);
      fossil_exit(1);
    }
    for(i=1; zPath[i] && zPwd[i]==zPath[i]; i++){}
    if( zPath[i]==0 ){
      blob_reset(pOut);
      if( zPwd[i]==0 ){
        blob_append(pOut, ".", 1);
      }else{

Changes to src/main.c.

53
54
55
56
57
58
59

60
61
62
63
64
65
66
  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 */
  int configOpen;         /* True if the config database is open */
  long long int now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */
  char *zRepositoryName;  /* Name of the repository database */

  const char *zHome;      /* Name of user home directory */
  int localOpen;          /* True if the local database is open */
  char *zLocalRoot;       /* The directory holding the  local database */
  int minPrefix;          /* Number of digits needed for a distinct UUID */
  int fSqlTrace;          /* True if -sqltrace flag is present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */







>







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
  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 */
  int configOpen;         /* True if the config database is open */
  long long int now;      /* Seconds since 1970 */
  int repositoryOpen;     /* True if the main repository database is open */
  char *zRepositoryName;  /* Name of the repository database */
  char *zRepoDb;          /* SQLite database name for the repository */
  const char *zHome;      /* Name of user home directory */
  int localOpen;          /* True if the local database is open */
  char *zLocalRoot;       /* The directory holding the  local database */
  int minPrefix;          /* Number of digits needed for a distinct UUID */
  int fSqlTrace;          /* True if -sqltrace flag is present */
  int fSqlPrint;          /* True if -sqlprint flag is present */
  int fQuiet;             /* True if -quiet flag is present */
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254


255
256
257
258
259
260
261
262
263








264
265
266
267
268
269
270
}


/*
** This procedure runs first.
*/
int main(int argc, char **argv){
  const char *zCmdName;
  int idx;
  int rc;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;
  if( getenv("GATEWAY_INTERFACE")!=0 ){
    zCmdName = "cgi";
  }else if( argc<2 ){
    fprintf(stderr, "Usage: %s COMMAND ...\n", argv[0]);
    exit(1);
  }else{
    g.fQuiet = find_option("quiet", 0, 0)!=0;
    g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    zCmdName = argv[1];
  }
  rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
  if( rc==1 ){
    fprintf(stderr,"%s: unknown command: %s\n"
                   "%s: use \"help\" for more information\n",
                   argv[0], zCmdName, argv[0]);
    return 1;
  }else if( rc==2 ){
    fprintf(stderr,"%s: ambiguous command prefix: %s\n"
                   "%s: use \"help\" for more information\n",
                   argv[0], zCmdName, argv[0]);
    return 1;
  }
  aCommand[idx].xFunc();


  return 0;
}

/*
** The following variable becomes true while processing a fatal error
** or a panic.  If additional "recursive-fatal" errors occur while
** shutting down, the recursive errors are silently ignored.
*/
static int mainInFatalError = 0;









/*
** Print an error message, rollback all databases, and quit.  These
** routines never return.
*/
void fossil_panic(const char *zFormat, ...){
  char *z;







|











|













|




|


>
>









>
>
>
>
>
>
>
>







215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
}


/*
** This procedure runs first.
*/
int main(int argc, char **argv){
  const char *zCmdName = "unknown";
  int idx;
  int rc;

  sqlite3_config(SQLITE_CONFIG_LOG, fossil_sqlite_log, 0);
  g.now = time(0);
  g.argc = argc;
  g.argv = argv;
  if( getenv("GATEWAY_INTERFACE")!=0 ){
    zCmdName = "cgi";
  }else if( argc<2 ){
    fprintf(stderr, "Usage: %s COMMAND ...\n", argv[0]);
    fossil_exit(1);
  }else{
    g.fQuiet = find_option("quiet", 0, 0)!=0;
    g.fSqlTrace = find_option("sqltrace", 0, 0)!=0;
    g.fSqlPrint = find_option("sqlprint", 0, 0)!=0;
    g.fHttpTrace = find_option("httptrace", 0, 0)!=0;
    g.zLogin = find_option("user", "U", 1);
    zCmdName = argv[1];
  }
  rc = name_search(zCmdName, aCommand, count(aCommand), &idx);
  if( rc==1 ){
    fprintf(stderr,"%s: unknown command: %s\n"
                   "%s: use \"help\" for more information\n",
                   argv[0], zCmdName, argv[0]);
    fossil_exit(1);
  }else if( rc==2 ){
    fprintf(stderr,"%s: ambiguous command prefix: %s\n"
                   "%s: use \"help\" for more information\n",
                   argv[0], zCmdName, argv[0]);
    fossil_exit(1);
  }
  aCommand[idx].xFunc();
  fossil_exit(0);
  /*NOT_REACHED*/
  return 0;
}

/*
** The following variable becomes true while processing a fatal error
** or a panic.  If additional "recursive-fatal" errors occur while
** shutting down, the recursive errors are silently ignored.
*/
static int mainInFatalError = 0;

/*
** Exit.  Take care to close the database first.
*/
void fossil_exit(int rc){
  db_close();
  exit(rc);
}

/*
** Print an error message, rollback all databases, and quit.  These
** routines never return.
*/
void fossil_panic(const char *zFormat, ...){
  char *z;
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
    once = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  exit(1);
}
void fossil_fatal(const char *zFormat, ...){
  char *z;
  va_list ap;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.cgiOutput ){
    g.cgiOutput = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  exit(1);
}

/* This routine works like fossil_fatal() except that if called
** recursively, the recursive call is a no-op.
**
** Use this in places where an error might occur while doing
** fatal error shutdown processing.  Unlike fossil_panic() and







|
















|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
    once = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  fossil_exit(1);
}
void fossil_fatal(const char *zFormat, ...){
  char *z;
  va_list ap;
  mainInFatalError = 1;
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.cgiOutput ){
    g.cgiOutput = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  fossil_exit(1);
}

/* This routine works like fossil_fatal() except that if called
** recursively, the recursive call is a no-op.
**
** Use this in places where an error might occur while doing
** fatal error shutdown processing.  Unlike fossil_panic() and
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
    g.cgiOutput = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  exit(1);
}


/* Print a warning message */
void fossil_warning(const char *zFormat, ...){
  char *z;
  va_list ap;







|







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    g.cgiOutput = 0;
    cgi_printf("<p><font color=\"red\">%h</font></p>", z);
    cgi_reply();
  }else{
    fprintf(stderr, "%s: %s\n", g.argv[0], z);
  }
  db_force_rollback();
  fossil_exit(1);
}


/* Print a warning message */
void fossil_warning(const char *zFormat, ...){
  char *z;
  va_list ap;
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
}

/*
** Print a usage comment and quit
*/
void usage(const char *zFormat){
  fprintf(stderr, "Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat);
  exit(1);
}

/*
** Remove n elements from g.argv beginning with the i-th element.
*/
void remove_from_argv(int i, int n){
  int j;







|







397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
}

/*
** Print a usage comment and quit
*/
void usage(const char *zFormat){
  fprintf(stderr, "Usage: %s %s %s\n", g.argv[0], g.argv[1], zFormat);
  fossil_exit(1);
}

/*
** Remove n elements from g.argv beginning with the i-th element.
*/
void remove_from_argv(int i, int n){
  int j;

Changes to src/merge3.c.

301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
** Combine change in going from PIVOT->VERSION1 with the change going
** from PIVOT->VERSION2 and write the combined changes into MERGED.
*/
void delta_3waymerge_cmd(void){
  Blob pivot, v1, v2, merged;
  if( g.argc!=6 ){
    fprintf(stderr,"Usage: %s %s PIVOT V1 V2 MERGED\n", g.argv[0], g.argv[1]);
    exit(1);
  }
  if( blob_read_from_file(&pivot, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    exit(1);
  }
  if( blob_read_from_file(&v1, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    exit(1);
  }
  if( blob_read_from_file(&v2, g.argv[4])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[4]);
    exit(1);
  }
  blob_merge(&pivot, &v1, &v2, &merged);
  if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    exit(1);
  }
  blob_reset(&pivot);
  blob_reset(&v1);
  blob_reset(&v2);
  blob_reset(&merged);
}







|



|



|



|




|






301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
** Combine change in going from PIVOT->VERSION1 with the change going
** from PIVOT->VERSION2 and write the combined changes into MERGED.
*/
void delta_3waymerge_cmd(void){
  Blob pivot, v1, v2, merged;
  if( g.argc!=6 ){
    fprintf(stderr,"Usage: %s %s PIVOT V1 V2 MERGED\n", g.argv[0], g.argv[1]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&pivot, g.argv[2])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[2]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&v1, g.argv[3])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[3]);
    fossil_exit(1);
  }
  if( blob_read_from_file(&v2, g.argv[4])<0 ){
    fprintf(stderr,"cannot read %s\n", g.argv[4]);
    fossil_exit(1);
  }
  blob_merge(&pivot, &v1, &v2, &merged);
  if( blob_write_to_file(&merged, g.argv[5])<blob_size(&merged) ){
    fprintf(stderr,"cannot write %s\n", g.argv[4]);
    fossil_exit(1);
  }
  blob_reset(&pivot);
  blob_reset(&v1);
  blob_reset(&v2);
  blob_reset(&merged);
}

Changes to src/name.c.

363
364
365
366
367
368
369
370
    return 0;
  }else{
    rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name);
    blob_reset(&name);
  }
  return rid;
}








<
363
364
365
366
367
368
369

    return 0;
  }else{
    rid = db_int(0, "SELECT rid FROM blob WHERE uuid=%B", &name);
    blob_reset(&name);
  }
  return rid;
}

Changes to src/rebuild.c.

372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  if( !bForce ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("Scrubbing the repository will permanently remove user\n"
                "passwords and other information. Changes cannot be undone.\n"
                "Continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      exit(1);
    }
  }
  db_begin_transaction();
  db_multi_exec(
    "UPDATE user SET pw='';"
    "DELETE FROM config WHERE name GLOB 'last-sync-*';"
  );







|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
  if( !bForce ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("Scrubbing the repository will permanently remove user\n"
                "passwords and other information. Changes cannot be undone.\n"
                "Continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      fossil_exit(1);
    }
  }
  db_begin_transaction();
  db_multi_exec(
    "UPDATE user SET pw='';"
    "DELETE FROM config WHERE name GLOB 'last-sync-*';"
  );

Changes to src/sqlite3.c.

507
508
509
510
511
512
513







514
515
516
517
518
519
520
# define ALWAYS(X)      ((X)?1:(assert(0),0))
# define NEVER(X)       ((X)?(assert(0),1):0)
#else
# define ALWAYS(X)      (X)
# define NEVER(X)       (X)
#endif








/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
** a boolean expression that is usually true.  GCC is able to
** use these hints to generate better code, sometimes.
*/
#if defined(__GNUC__) && 0







>
>
>
>
>
>
>







507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
# define ALWAYS(X)      ((X)?1:(assert(0),0))
# define NEVER(X)       ((X)?(assert(0),1):0)
#else
# define ALWAYS(X)      (X)
# define NEVER(X)       (X)
#endif

/*
** Return true (non-zero) if the input is a integer that is too large
** to fit in 32-bits.  This macro is used inside of various testcase()
** macros to verify that we have tested SQLite for large-file support.
*/
#define IS_BIG_INT(X)  (((X)&(i64)0xffffffff)!=0)

/*
** The macro unlikely() is a hint that surrounds a boolean
** expression that is usually false.  Macro likely() surrounds
** a boolean expression that is usually true.  GCC is able to
** use these hints to generate better code, sometimes.
*/
#if defined(__GNUC__) && 0
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.0"
#define SQLITE_VERSION_NUMBER 3007000
#define SQLITE_SOURCE_ID      "2010-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.0"
#define SQLITE_VERSION_NUMBER 3007000
#define SQLITE_SOURCE_ID      "2010-07-08 17:40:38 e396184cd3bdb96e29ac33af5d1f631cac553341"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372



1373




1374
1375
1376
1377
1378
1379
1380
** SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
**
** The xRandomness(), xSleep(), and xCurrentTime() interfaces
** are not strictly a part of the filesystem, but they are
** included in the VFS structure for completeness.
** The xRandomness() function attempts to return nBytes bytes
** of good-quality randomness into zOut.  The return value is
** the actual number of bytes of randomness obtained.
** The xSleep() method causes the calling thread to sleep for at
** least the number of microseconds given.  The xCurrentTime()
** method returns a Julian Day Number for the current date and time.



**




*/
typedef struct sqlite3_vfs sqlite3_vfs;
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 2) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */







|
|






|
>
>
>
|
>
>
>
>







1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
** SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
**
** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
** interfaces are not strictly a part of the filesystem, but they are
** included in the VFS structure for completeness.
** The xRandomness() function attempts to return nBytes bytes
** of good-quality randomness into zOut.  The return value is
** the actual number of bytes of randomness obtained.
** The xSleep() method causes the calling thread to sleep for at
** least the number of microseconds given.  The xCurrentTime()
** method returns a Julian Day Number for the current date and time as
** a floating point value.
** The xCurrentTimeInt64() method returns, as an integer, the Julian
** Day Number multipled by 86400000 (the number of milliseconds in 
** a 24-hour day).  
** ^SQLite will use the xCurrentTimeInt64() method to get the current
** date and time if that method is available (if iVersion is 2 or 
** greater and the function pointer is not NULL) and will fall back
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
*/
typedef struct sqlite3_vfs sqlite3_vfs;
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 2) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};







<







1407
1408
1409
1410
1411
1412
1413

1414
1415
1416
1417
1418
1419
1420
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */

  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};
8557
8558
8559
8560
8561
8562
8563
8564
8565
8566
8567
8568
8569
8570
8571
  int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */
  u8 dfltJournalMode;           /* Default journal mode for attached dbs */
  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  u8 suppressErr;               /* Do not issue error messages if true */
  int nextPagesize;             /* Pagesize after VACUUM if >0 */
  int nTable;                   /* Number of tables in the database */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  u32 magic;                    /* Magic number for detect library misuse */







<







8570
8571
8572
8573
8574
8575
8576

8577
8578
8579
8580
8581
8582
8583
  int openFlags;                /* Flags passed to sqlite3_vfs.xOpen() */
  int errCode;                  /* Most recent error code (SQLITE_*) */
  int errMask;                  /* & result codes with this before returning */
  u8 autoCommit;                /* The auto-commit flag. */
  u8 temp_store;                /* 1: file 2: memory 0: default */
  u8 mallocFailed;              /* True if we have seen a malloc failure */
  u8 dfltLockMode;              /* Default locking-mode for attached dbs */

  signed char nextAutovac;      /* Autovac setting after VACUUM if >=0 */
  u8 suppressErr;               /* Do not issue error messages if true */
  int nextPagesize;             /* Pagesize after VACUUM if >0 */
  int nTable;                   /* Number of tables in the database */
  CollSeq *pDfltColl;           /* The default collating sequence (BINARY) */
  i64 lastRowid;                /* ROWID of most recent insert (see above) */
  u32 magic;                    /* Magic number for detect library misuse */
11325
11326
11327
11328
11329
11330
11331

11332
11333
11334

11335
11336
11337
11338
11339
11340
11341
#endif
#ifdef SQLITE_OMIT_CAST
  "OMIT_CAST",
#endif
#ifdef SQLITE_OMIT_CHECK
  "OMIT_CHECK",
#endif

#ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
  "OMIT_COMPILEOPTION_DIAGS",
#endif

#ifdef SQLITE_OMIT_COMPLETE
  "OMIT_COMPLETE",
#endif
#ifdef SQLITE_OMIT_COMPOUND_SELECT
  "OMIT_COMPOUND_SELECT",
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS







>
|
|
|
>







11337
11338
11339
11340
11341
11342
11343
11344
11345
11346
11347
11348
11349
11350
11351
11352
11353
11354
11355
#endif
#ifdef SQLITE_OMIT_CAST
  "OMIT_CAST",
#endif
#ifdef SQLITE_OMIT_CHECK
  "OMIT_CHECK",
#endif
/* // redundant
** #ifdef SQLITE_OMIT_COMPILEOPTION_DIAGS
**   "OMIT_COMPILEOPTION_DIAGS",
** #endif
*/
#ifdef SQLITE_OMIT_COMPLETE
  "OMIT_COMPLETE",
#endif
#ifdef SQLITE_OMIT_COMPOUND_SELECT
  "OMIT_COMPOUND_SELECT",
#endif
#ifdef SQLITE_OMIT_DATETIME_FUNCS
11361
11362
11363
11364
11365
11366
11367
11368
11369
11370
11371
11372
11373
11374
11375
11376
11377
#endif
#ifdef SQLITE_OMIT_FOREIGN_KEY
  "OMIT_FOREIGN_KEY",
#endif
#ifdef SQLITE_OMIT_GET_TABLE
  "OMIT_GET_TABLE",
#endif
#ifdef SQLITE_OMIT_GLOBALRECOVER
  "OMIT_GLOBALRECOVER",
#endif
#ifdef SQLITE_OMIT_INCRBLOB
  "OMIT_INCRBLOB",
#endif
#ifdef SQLITE_OMIT_INTEGRITY_CHECK
  "OMIT_INTEGRITY_CHECK",
#endif
#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION







<
<
<







11375
11376
11377
11378
11379
11380
11381



11382
11383
11384
11385
11386
11387
11388
#endif
#ifdef SQLITE_OMIT_FOREIGN_KEY
  "OMIT_FOREIGN_KEY",
#endif
#ifdef SQLITE_OMIT_GET_TABLE
  "OMIT_GET_TABLE",
#endif



#ifdef SQLITE_OMIT_INCRBLOB
  "OMIT_INCRBLOB",
#endif
#ifdef SQLITE_OMIT_INTEGRITY_CHECK
  "OMIT_INTEGRITY_CHECK",
#endif
#ifdef SQLITE_OMIT_LIKE_OPTIMIZATION
11441
11442
11443
11444
11445
11446
11447



11448
11449
11450
11451
11452
11453
11454
  "OMIT_VACUUM",
#endif
#ifdef SQLITE_OMIT_VIEW
  "OMIT_VIEW",
#endif
#ifdef SQLITE_OMIT_VIRTUALTABLE
  "OMIT_VIRTUALTABLE",



#endif
#ifdef SQLITE_OMIT_WSD
  "OMIT_WSD",
#endif
#ifdef SQLITE_OMIT_XFER_OPT
  "OMIT_XFER_OPT",
#endif







>
>
>







11452
11453
11454
11455
11456
11457
11458
11459
11460
11461
11462
11463
11464
11465
11466
11467
11468
  "OMIT_VACUUM",
#endif
#ifdef SQLITE_OMIT_VIEW
  "OMIT_VIEW",
#endif
#ifdef SQLITE_OMIT_VIRTUALTABLE
  "OMIT_VIRTUALTABLE",
#endif
#ifdef SQLITE_OMIT_WAL
  "OMIT_WAL",
#endif
#ifdef SQLITE_OMIT_WSD
  "OMIT_WSD",
#endif
#ifdef SQLITE_OMIT_XFER_OPT
  "OMIT_XFER_OPT",
#endif
28501
28502
28503
28504
28505
28506
28507
28508
28509
28510
28511
28512
28513
28514
28515
    unixDlError,          /* xDlError */                    \
    unixDlSym,            /* xDlSym */                      \
    unixDlClose,          /* xDlClose */                    \
    unixRandomness,       /* xRandomness */                 \
    unixSleep,            /* xSleep */                      \
    unixCurrentTime,      /* xCurrentTime */                \
    unixGetLastError,     /* xGetLastError */               \
    0,                    /* xRename */                     \
    unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
  }

  /*
  ** All default VFSes for unix are contained in the following array.
  **
  ** Note that the sqlite3_vfs.pNext field of the VFS object is modified







<







28515
28516
28517
28518
28519
28520
28521

28522
28523
28524
28525
28526
28527
28528
    unixDlError,          /* xDlError */                    \
    unixDlSym,            /* xDlSym */                      \
    unixDlClose,          /* xDlClose */                    \
    unixRandomness,       /* xRandomness */                 \
    unixSleep,            /* xSleep */                      \
    unixCurrentTime,      /* xCurrentTime */                \
    unixGetLastError,     /* xGetLastError */               \

    unixCurrentTimeInt64, /* xCurrentTimeInt64 */           \
  }

  /*
  ** All default VFSes for unix are contained in the following array.
  **
  ** Note that the sqlite3_vfs.pNext field of the VFS object is modified
29404
29405
29406
29407
29408
29409
29410

29411
29412
29413
29414
29415
29416
29417
  winFile *pFile = (winFile*)id;

  assert( id!=0 );
  assert( pFile->pShm==0 );
  OSTRACE(("CLOSE %d\n", pFile->h));
  do{
    rc = CloseHandle(pFile->h);

  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
  winceDestroyLock(pFile);
  if( pFile->zDeleteOnClose ){
    int cnt = 0;
    while(







>







29417
29418
29419
29420
29421
29422
29423
29424
29425
29426
29427
29428
29429
29430
29431
  winFile *pFile = (winFile*)id;

  assert( id!=0 );
  assert( pFile->pShm==0 );
  OSTRACE(("CLOSE %d\n", pFile->h));
  do{
    rc = CloseHandle(pFile->h);
    /* SimulateIOError( rc=0; cnt=MX_CLOSE_ATTEMPT; ); */
  }while( rc==0 && ++cnt < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
#if SQLITE_OS_WINCE
#define WINCE_DELETION_ATTEMPTS 3
  winceDestroyLock(pFile);
  if( pFile->zDeleteOnClose ){
    int cnt = 0;
    while(
29495
29496
29497
29498
29499
29500
29501

29502



29503
29504
29505
29506
29507
29508
29509
29510
29511
29512
29513
29514

29515



29516
29517
29518
29519
29520
29521
29522
  assert( id!=0 );
  SimulateIOError(return SQLITE_IOERR_WRITE);
  SimulateDiskfullError(return SQLITE_FULL);
  OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
    pFile->lastErrno = error;

    return SQLITE_FULL;



  }
  assert( amt>0 );
  while(
     amt>0
     && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
     && wrote>0
  ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  if( !rc || amt>(int)wrote ){
    pFile->lastErrno = GetLastError();

    return SQLITE_FULL;



  }
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
*/







>
|
>
>
>












>
|
>
>
>







29509
29510
29511
29512
29513
29514
29515
29516
29517
29518
29519
29520
29521
29522
29523
29524
29525
29526
29527
29528
29529
29530
29531
29532
29533
29534
29535
29536
29537
29538
29539
29540
29541
29542
29543
29544
  assert( id!=0 );
  SimulateIOError(return SQLITE_IOERR_WRITE);
  SimulateDiskfullError(return SQLITE_FULL);
  OSTRACE(("WRITE %d lock=%d\n", pFile->h, pFile->locktype));
  rc = SetFilePointer(pFile->h, lowerBits, &upperBits, FILE_BEGIN);
  if( rc==INVALID_SET_FILE_POINTER && (error=GetLastError())!=NO_ERROR ){
    pFile->lastErrno = error;
    if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
      return SQLITE_FULL;
    }else{
      return SQLITE_IOERR_WRITE;
    }
  }
  assert( amt>0 );
  while(
     amt>0
     && (rc = WriteFile(pFile->h, pBuf, amt, &wrote, 0))!=0
     && wrote>0
  ){
    amt -= wrote;
    pBuf = &((char*)pBuf)[wrote];
  }
  if( !rc || amt>(int)wrote ){
    pFile->lastErrno = GetLastError();
    if( pFile->lastErrno==ERROR_HANDLE_DISK_FULL ){
      return SQLITE_FULL;
    }else{
      return SQLITE_IOERR_WRITE;
    }
  }
  return SQLITE_OK;
}

/*
** Truncate an open file to a specified size
*/
29553
29554
29555
29556
29557
29558
29559
29560
29561
29562
29563
29564
29565
29566
29567









29568
29569
29570
29571
29572
29573
29574
29575







29576
29577
29578
29579
29580
29581
29582
29583
29584
29585
29586
29587
SQLITE_API int sqlite3_fullsync_count = 0;
#endif

/*
** Make sure all writes to a particular file are committed to disk.
*/
static int winSync(sqlite3_file *id, int flags){
#ifndef SQLITE_NO_SYNC
  winFile *pFile = (winFile*)id;

  assert( id!=0 );
  OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));
#else
  UNUSED_PARAMETER(id);
#endif









#ifndef SQLITE_TEST
  UNUSED_PARAMETER(flags);
#else
  if( flags & SQLITE_SYNC_FULL ){
    sqlite3_fullsync_count++;
  }
  sqlite3_sync_count++;
#endif







  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  ** no-op
  */
#ifdef SQLITE_NO_SYNC
    return SQLITE_OK;
#else
  if( FlushFileBuffers(pFile->h) ){
    return SQLITE_OK;
  }else{
    pFile->lastErrno = GetLastError();
    return SQLITE_IOERR;
  }







|

<
<
<



>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>




|







29575
29576
29577
29578
29579
29580
29581
29582
29583



29584
29585
29586
29587
29588
29589
29590
29591
29592
29593
29594
29595
29596
29597
29598
29599
29600
29601
29602
29603
29604
29605
29606
29607
29608
29609
29610
29611
29612
29613
29614
29615
29616
29617
29618
29619
29620
29621
29622
SQLITE_API int sqlite3_fullsync_count = 0;
#endif

/*
** Make sure all writes to a particular file are committed to disk.
*/
static int winSync(sqlite3_file *id, int flags){
#if !defined(NDEBUG) || !defined(SQLITE_NO_SYNC) || defined(SQLITE_DEBUG)
  winFile *pFile = (winFile*)id;



#else
  UNUSED_PARAMETER(id);
#endif

  assert( pFile );
  /* Check that one of SQLITE_SYNC_NORMAL or FULL was passed */
  assert((flags&0x0F)==SQLITE_SYNC_NORMAL
      || (flags&0x0F)==SQLITE_SYNC_FULL
  );

  OSTRACE(("SYNC %d lock=%d\n", pFile->h, pFile->locktype));

#ifndef SQLITE_TEST
  UNUSED_PARAMETER(flags);
#else
  if( flags & SQLITE_SYNC_FULL ){
    sqlite3_fullsync_count++;
  }
  sqlite3_sync_count++;
#endif

  /* Unix cannot, but some systems may return SQLITE_FULL from here. This
  ** line is to test that doing so does not cause any problems.
  */
  SimulateDiskfullError( return SQLITE_FULL );
  SimulateIOError( return SQLITE_IOERR; );

  /* If we compiled with the SQLITE_NO_SYNC flag, then syncing is a
  ** no-op
  */
#ifdef SQLITE_NO_SYNC
  return SQLITE_OK;
#else
  if( FlushFileBuffers(pFile->h) ){
    return SQLITE_OK;
  }else{
    pFile->lastErrno = GetLastError();
    return SQLITE_IOERR;
  }
29816
29817
29818
29819
29820
29821
29822


29823
29824
29825
29826
29827
29828
29829
** file by this or any other process. If such a lock is held, return
** non-zero, otherwise zero.
*/
static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
  int rc;
  winFile *pFile = (winFile*)id;



  assert( id!=0 );
  if( pFile->locktype>=RESERVED_LOCK ){
    rc = 1;
    OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
  }else{
    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
    if( rc ){







>
>







29851
29852
29853
29854
29855
29856
29857
29858
29859
29860
29861
29862
29863
29864
29865
29866
** file by this or any other process. If such a lock is held, return
** non-zero, otherwise zero.
*/
static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
  int rc;
  winFile *pFile = (winFile*)id;

  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );

  assert( id!=0 );
  if( pFile->locktype>=RESERVED_LOCK ){
    rc = 1;
    OSTRACE(("TEST WR-LOCK %d %d (local)\n", pFile->h, rc));
  }else{
    rc = LockFile(pFile->h, RESERVED_BYTE, 0, 1, 0);
    if( rc ){
29888
29889
29890
29891
29892
29893
29894

29895

29896
29897
29898
29899
29900
29901
29902
    }
    case SQLITE_LAST_ERRNO: {
      *(int*)pArg = (int)((winFile*)id)->lastErrno;
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_SIZE_HINT: {
      sqlite3_int64 sz = *(sqlite3_int64*)pArg;

      winTruncate(id, sz);

      return SQLITE_OK;
    }
  }
  return SQLITE_ERROR;
}

/*







>

>







29925
29926
29927
29928
29929
29930
29931
29932
29933
29934
29935
29936
29937
29938
29939
29940
29941
    }
    case SQLITE_LAST_ERRNO: {
      *(int*)pArg = (int)((winFile*)id)->lastErrno;
      return SQLITE_OK;
    }
    case SQLITE_FCNTL_SIZE_HINT: {
      sqlite3_int64 sz = *(sqlite3_int64*)pArg;
      SimulateIOErrorBenign(1);
      winTruncate(id, sz);
      SimulateIOErrorBenign(0);
      return SQLITE_OK;
    }
  }
  return SQLITE_ERROR;
}

/*
30099
30100
30101
30102
30103
30104
30105
30106

30107

30108


30109


30110
30111
30112
30113
30114
30115
30116
    if( p->nRef==0 ){
      int i;
      if( p->mutex ) sqlite3_mutex_free(p->mutex);
      for(i=0; i<p->nRegion; i++){
        UnmapViewOfFile(p->aRegion[i].pMap);
        CloseHandle(p->aRegion[i].hMap);
      }
      if( p->hFile.h != INVALID_HANDLE_VALUE ) {

        winClose((sqlite3_file *)&p->hFile);

      }


      if( deleteFlag ) winDelete(pVfs, p->zFilename, 0);


      *pp = p->pNext;
      sqlite3_free(p->aRegion);
      sqlite3_free(p);
    }else{
      pp = &p->pNext;
    }
  }







|
>

>

>
>
|
>
>







30138
30139
30140
30141
30142
30143
30144
30145
30146
30147
30148
30149
30150
30151
30152
30153
30154
30155
30156
30157
30158
30159
30160
30161
    if( p->nRef==0 ){
      int i;
      if( p->mutex ) sqlite3_mutex_free(p->mutex);
      for(i=0; i<p->nRegion; i++){
        UnmapViewOfFile(p->aRegion[i].pMap);
        CloseHandle(p->aRegion[i].hMap);
      }
      if( p->hFile.h != INVALID_HANDLE_VALUE ){
        SimulateIOErrorBenign(1);
        winClose((sqlite3_file *)&p->hFile);
        SimulateIOErrorBenign(0);
      }
      if( deleteFlag ){
        SimulateIOErrorBenign(1);
        winDelete(pVfs, p->zFilename, 0);
        SimulateIOErrorBenign(0);
      }
      *pp = p->pNext;
      sqlite3_free(p->aRegion);
      sqlite3_free(p);
    }else{
      pp = &p->pNext;
    }
  }
30504
30505
30506
30507
30508
30509
30510







30511
30512
30513
30514
30515
30516
30517
static int getTempname(int nBuf, char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  size_t i, j;
  char zTempPath[MAX_PATH+1];







  if( sqlite3_temp_directory ){
    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
  }else if( isNT() ){
    char *zMulti;
    WCHAR zWidePath[MAX_PATH];
    GetTempPathW(MAX_PATH-30, zWidePath);
    zMulti = unicodeToUtf8(zWidePath);







>
>
>
>
>
>
>







30549
30550
30551
30552
30553
30554
30555
30556
30557
30558
30559
30560
30561
30562
30563
30564
30565
30566
30567
30568
30569
static int getTempname(int nBuf, char *zBuf){
  static char zChars[] =
    "abcdefghijklmnopqrstuvwxyz"
    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    "0123456789";
  size_t i, j;
  char zTempPath[MAX_PATH+1];

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. 
  */
  SimulateIOError( return SQLITE_IOERR );

  if( sqlite3_temp_directory ){
    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
  }else if( isNT() ){
    char *zMulti;
    WCHAR zWidePath[MAX_PATH];
    GetTempPathW(MAX_PATH-30, zWidePath);
    zMulti = unicodeToUtf8(zWidePath);
30535
30536
30537
30538
30539
30540
30541








30542
30543

30544
30545
30546
30547
30548
30549
30550
30551

30552
30553
30554
30555
30556
30557
30558
      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
      free(zUtf8);
    }else{
      return SQLITE_NOMEM;
    }
#endif
  }








  for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;

  sqlite3_snprintf(nBuf-30, zBuf,
                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
  j = sqlite3Strlen30(zBuf);
  sqlite3_randomness(20, &zBuf[j]);
  for(i=0; i<20; i++, j++){
    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  }
  zBuf[j] = 0;

  OSTRACE(("TEMP FILENAME: %s\n", zBuf));
  return SQLITE_OK; 
}

/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero







>
>
>
>
>
>
>
>


>
|


|
|



>







30587
30588
30589
30590
30591
30592
30593
30594
30595
30596
30597
30598
30599
30600
30601
30602
30603
30604
30605
30606
30607
30608
30609
30610
30611
30612
30613
30614
30615
30616
30617
30618
30619
30620
      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
      free(zUtf8);
    }else{
      return SQLITE_NOMEM;
    }
#endif
  }

  /* Check that the output buffer is large enough for the temporary file 
  ** name. If it is not, return SQLITE_ERROR.
  */
  if( (sqlite3Strlen30(zTempPath) + sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
    return SQLITE_ERROR;
  }

  for(i=sqlite3Strlen30(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
  zTempPath[i] = 0;

  sqlite3_snprintf(nBuf-17, zBuf,
                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
  j = sqlite3Strlen30(zBuf);
  sqlite3_randomness(15, &zBuf[j]);
  for(i=0; i<15; i++, j++){
    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
  }
  zBuf[j] = 0;

  OSTRACE(("TEMP FILENAME: %s\n", zBuf));
  return SQLITE_OK; 
}

/*
** The return value of getLastErrorMsg
** is zero if the error message fits in the buffer, or non-zero
30788
30789
30790
30791
30792
30793
30794
30795
30796
30797



30798
30799
30800
30801
30802
30803
30804
30805
30806
30807
30808
  sqlite3_vfs *pVfs,          /* Not used on win32 */
  const char *zFilename,      /* Name of file to delete */
  int syncDir                 /* Not used on win32 */
){
  int cnt = 0;
  DWORD rc;
  DWORD error = 0;
  void *zConverted = convertUtf8Filename(zFilename);
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);



  if( zConverted==0 ){
    return SQLITE_NOMEM;
  }
  SimulateIOError(return SQLITE_IOERR_DELETE);
  if( isNT() ){
    do{
      DeleteFileW(zConverted);
    }while(   (   ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
               || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
           && (++cnt < MX_DELETION_ATTEMPTS)
           && (Sleep(100), 1) );







|


>
>
>



<







30850
30851
30852
30853
30854
30855
30856
30857
30858
30859
30860
30861
30862
30863
30864
30865

30866
30867
30868
30869
30870
30871
30872
  sqlite3_vfs *pVfs,          /* Not used on win32 */
  const char *zFilename,      /* Name of file to delete */
  int syncDir                 /* Not used on win32 */
){
  int cnt = 0;
  DWORD rc;
  DWORD error = 0;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);
  UNUSED_PARAMETER(syncDir);

  SimulateIOError(return SQLITE_IOERR_DELETE);
  zConverted = convertUtf8Filename(zFilename);
  if( zConverted==0 ){
    return SQLITE_NOMEM;
  }

  if( isNT() ){
    do{
      DeleteFileW(zConverted);
    }while(   (   ((rc = GetFileAttributesW(zConverted)) != INVALID_FILE_ATTRIBUTES)
               || ((error = GetLastError()) == ERROR_ACCESS_DENIED))
           && (++cnt < MX_DELETION_ATTEMPTS)
           && (Sleep(100), 1) );
30836
30837
30838
30839
30840
30841
30842
30843
30844



30845
30846
30847
30848


30849




















30850
30851
30852
30853
30854
30855
30856
  sqlite3_vfs *pVfs,         /* Not used on win32 */
  const char *zFilename,     /* Name of file to check */
  int flags,                 /* Type of test to make on this file */
  int *pResOut               /* OUT: Result */
){
  DWORD attr;
  int rc = 0;
  void *zConverted = convertUtf8Filename(zFilename);
  UNUSED_PARAMETER(pVfs);



  if( zConverted==0 ){
    return SQLITE_NOMEM;
  }
  if( isNT() ){


    attr = GetFileAttributesW((WCHAR*)zConverted);




















/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
** Since the ASCII version of these Windows API do not exist for WINCE,
** it's important to not reference them for WINCE builds.
*/
#if SQLITE_OS_WINCE==0
  }else{
    attr = GetFileAttributesA((char*)zConverted);







|

>
>
>




>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







30900
30901
30902
30903
30904
30905
30906
30907
30908
30909
30910
30911
30912
30913
30914
30915
30916
30917
30918
30919
30920
30921
30922
30923
30924
30925
30926
30927
30928
30929
30930
30931
30932
30933
30934
30935
30936
30937
30938
30939
30940
30941
30942
30943
30944
30945
  sqlite3_vfs *pVfs,         /* Not used on win32 */
  const char *zFilename,     /* Name of file to check */
  int flags,                 /* Type of test to make on this file */
  int *pResOut               /* OUT: Result */
){
  DWORD attr;
  int rc = 0;
  void *zConverted;
  UNUSED_PARAMETER(pVfs);

  SimulateIOError( return SQLITE_IOERR_ACCESS; );
  zConverted = convertUtf8Filename(zFilename);
  if( zConverted==0 ){
    return SQLITE_NOMEM;
  }
  if( isNT() ){
    WIN32_FILE_ATTRIBUTE_DATA sAttrData;
    memset(&sAttrData, 0, sizeof(sAttrData));
    if( GetFileAttributesExW((WCHAR*)zConverted,
                             GetFileExInfoStandard, 
                             &sAttrData) ){
      /* For an SQLITE_ACCESS_EXISTS query, treat a zero-length file
      ** as if it does not exist.
      */
      if(    flags==SQLITE_ACCESS_EXISTS
          && sAttrData.nFileSizeHigh==0 
          && sAttrData.nFileSizeLow==0 ){
        attr = INVALID_FILE_ATTRIBUTES;
      }else{
        attr = sAttrData.dwFileAttributes;
      }
    }else{
      if( GetLastError()!=ERROR_FILE_NOT_FOUND ){
        free(zConverted);
        return SQLITE_IOERR_ACCESS;
      }else{
        attr = INVALID_FILE_ATTRIBUTES;
      }
    }
/* isNT() is 1 if SQLITE_OS_WINCE==1, so this else is never executed. 
** Since the ASCII version of these Windows API do not exist for WINCE,
** it's important to not reference them for WINCE builds.
*/
#if SQLITE_OS_WINCE==0
  }else{
    attr = GetFileAttributesA((char*)zConverted);
30882
30883
30884
30885
30886
30887
30888

30889
30890
30891
30892
30893
30894

30895
30896
30897
30898
30899
30900
30901
30902
30903
30904







30905
30906
30907
30908
30909
30910
30911
  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
  const char *zRelative,        /* Possibly relative input path */
  int nFull,                    /* Size of output buffer in bytes */
  char *zFull                   /* Output buffer */
){
  
#if defined(__CYGWIN__)

  UNUSED_PARAMETER(nFull);
  cygwin_conv_to_full_win32_path(zRelative, zFull);
  return SQLITE_OK;
#endif

#if SQLITE_OS_WINCE

  UNUSED_PARAMETER(nFull);
  /* WinCE has no concept of a relative pathname, or so I am told. */
  sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
  return SQLITE_OK;
#endif

#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
  int nByte;
  void *zConverted;
  char *zOut;







  UNUSED_PARAMETER(nFull);
  zConverted = convertUtf8Filename(zRelative);
  if( isNT() ){
    WCHAR *zTemp;
    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
    zTemp = malloc( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){







>






>










>
>
>
>
>
>
>







30971
30972
30973
30974
30975
30976
30977
30978
30979
30980
30981
30982
30983
30984
30985
30986
30987
30988
30989
30990
30991
30992
30993
30994
30995
30996
30997
30998
30999
31000
31001
31002
31003
31004
31005
31006
31007
31008
31009
  sqlite3_vfs *pVfs,            /* Pointer to vfs object */
  const char *zRelative,        /* Possibly relative input path */
  int nFull,                    /* Size of output buffer in bytes */
  char *zFull                   /* Output buffer */
){
  
#if defined(__CYGWIN__)
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);
  cygwin_conv_to_full_win32_path(zRelative, zFull);
  return SQLITE_OK;
#endif

#if SQLITE_OS_WINCE
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);
  /* WinCE has no concept of a relative pathname, or so I am told. */
  sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
  return SQLITE_OK;
#endif

#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
  int nByte;
  void *zConverted;
  char *zOut;

  /* It's odd to simulate an io-error here, but really this is just
  ** using the io-error infrastructure to test that SQLite handles this
  ** function failing. This function could fail if, for example, the
  ** current working directory has been unlinked.
  */
  SimulateIOError( return SQLITE_ERROR );
  UNUSED_PARAMETER(nFull);
  zConverted = convertUtf8Filename(zRelative);
  if( isNT() ){
    WCHAR *zTemp;
    nByte = GetFullPathNameW((WCHAR*)zConverted, 0, 0, 0) + 3;
    zTemp = malloc( nByte*sizeof(zTemp[0]) );
    if( zTemp==0 ){
30965
30966
30967
30968
30969
30970
30971

30972

30973
30974
30975
30976
30977
30978
30979
  DWORD dwDummy;

  /*
  ** We need to get the full path name of the file
  ** to get the drive letter to look up the sector
  ** size.
  */

  rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);

  if( rc == SQLITE_OK )
  {
    void *zConverted = convertUtf8Filename(zFullpath);
    if( zConverted ){
      if( isNT() ){
        /* trim path to just drive reference */
        WCHAR *p = zConverted;







>

>







31063
31064
31065
31066
31067
31068
31069
31070
31071
31072
31073
31074
31075
31076
31077
31078
31079
  DWORD dwDummy;

  /*
  ** We need to get the full path name of the file
  ** to get the drive letter to look up the sector
  ** size.
  */
  SimulateIOErrorBenign(1);
  rc = winFullPathname(pVfs, zRelative, MAX_PATH, zFullpath);
  SimulateIOErrorBenign(0);
  if( rc == SQLITE_OK )
  {
    void *zConverted = convertUtf8Filename(zFullpath);
    if( zConverted ){
      if( isNT() ){
        /* trim path to just drive reference */
        WCHAR *p = zConverted;
31242
31243
31244
31245
31246
31247
31248
31249
31250
31251
31252
31253
31254
31255
31256
    winDlError,          /* xDlError */
    winDlSym,            /* xDlSym */
    winDlClose,          /* xDlClose */
    winRandomness,       /* xRandomness */
    winSleep,            /* xSleep */
    winCurrentTime,      /* xCurrentTime */
    winGetLastError,     /* xGetLastError */
    0,                   /* xRename */
    winCurrentTimeInt64, /* xCurrentTimeInt64 */
  };

  sqlite3_vfs_register(&winVfs, 1);
  return SQLITE_OK; 
}
SQLITE_API int sqlite3_os_end(void){ 







<







31342
31343
31344
31345
31346
31347
31348

31349
31350
31351
31352
31353
31354
31355
    winDlError,          /* xDlError */
    winDlSym,            /* xDlSym */
    winDlClose,          /* xDlClose */
    winRandomness,       /* xRandomness */
    winSleep,            /* xSleep */
    winCurrentTime,      /* xCurrentTime */
    winGetLastError,     /* xGetLastError */

    winCurrentTimeInt64, /* xCurrentTimeInt64 */
  };

  sqlite3_vfs_register(&winVfs, 1);
  return SQLITE_OK; 
}
SQLITE_API int sqlite3_os_end(void){ 
33979
33980
33981
33982
33983
33984
33985

33986
33987
33988
33989
33990
33991
33992
  void *pCodec;               /* First argument to xCodec... methods */
#endif
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
  PCache *pPCache;            /* Pointer to page cache object */
  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
#ifndef SQLITE_OMIT_WAL
  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */

#endif
};

/*
** The following global variables hold counters used for
** testing purposes only.  These variables do not exist in
** a non-testing build.  These variables are not thread-safe.







>







34078
34079
34080
34081
34082
34083
34084
34085
34086
34087
34088
34089
34090
34091
34092
  void *pCodec;               /* First argument to xCodec... methods */
#endif
  char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
  PCache *pPCache;            /* Pointer to page cache object */
  sqlite3_backup *pBackup;    /* Pointer to list of ongoing backup processes */
#ifndef SQLITE_OMIT_WAL
  Wal *pWal;                  /* Write-ahead log used by "journal_mode=wal" */
  char *zWal;                 /* File name for write-ahead log */
#endif
};

/*
** The following global variables hold counters used for
** testing purposes only.  These variables do not exist in
** a non-testing build.  These variables are not thread-safe.
35089
35090
35091
35092
35093
35094
35095















35096
35097
35098
35099
35100
35101
35102
  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;
}
















/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
** The page begins at offset *pOffset into the file. The *pOffset
** value is increased to the start of the next page in the journal.
**
** The isMainJrnl flag is true if this is the main rollback journal and







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







35189
35190
35191
35192
35193
35194
35195
35196
35197
35198
35199
35200
35201
35202
35203
35204
35205
35206
35207
35208
35209
35210
35211
35212
35213
35214
35215
35216
35217
  while( i>0 ){
    cksum += aData[i];
    i -= 200;
  }
  return cksum;
}

/*
** Report the current page size and number of reserved bytes back
** to the codec.
*/
#ifdef SQLITE_HAS_CODEC
static void pagerReportSize(Pager *pPager){
  if( pPager->xCodecSizeChng ){
    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
                           (int)pPager->nReserve);
  }
}
#else
# define pagerReportSize(X)     /* No-op if we do not support a codec */
#endif

/*
** Read a single page from either the journal file (if isMainJrnl==1) or
** from the sub-journal (if isMainJrnl==0) and playback that page.
** The page begins at offset *pOffset into the file. The *pOffset
** value is increased to the start of the next page in the journal.
**
** The isMainJrnl flag is true if this is the main rollback journal and
35181
35182
35183
35184
35185
35186
35187



35188
35189
35190

35191



35192


35193
35194
35195
35196
35197
35198
35199
    rc = read32bits(jfd, (*pOffset)-4, &cksum);
    if( rc ) return rc;
    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
      return SQLITE_DONE;
    }
  }




  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
    return rc;
  }





  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );



  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** An exception to the above rule: If the database is in no-sync mode
  ** and a page is moved during an incremental vacuum then the page may







>
>
>



>

>
>
>
|
>
>







35296
35297
35298
35299
35300
35301
35302
35303
35304
35305
35306
35307
35308
35309
35310
35311
35312
35313
35314
35315
35316
35317
35318
35319
35320
35321
35322
35323
    rc = read32bits(jfd, (*pOffset)-4, &cksum);
    if( rc ) return rc;
    if( !isSavepnt && pager_cksum(pPager, (u8*)aData)!=cksum ){
      return SQLITE_DONE;
    }
  }

  /* If this page has already been played by before during the current
  ** rollback, then don't bother to play it back again.
  */
  if( pDone && (rc = sqlite3BitvecSet(pDone, pgno))!=SQLITE_OK ){
    return rc;
  }
  assert( pPager->state==PAGER_RESERVED || pPager->state>=PAGER_EXCLUSIVE );

  /* When playing back page 1, restore the nReserve setting
  */
  if( pgno==1 && pPager->nReserve!=((u8*)aData)[20] ){
    pPager->nReserve = ((u8*)aData)[20];
    pagerReportSize(pPager);
  }

  /* If the pager is in RESERVED state, then there must be a copy of this
  ** page in the pager cache. In this case just update the pager cache,
  ** not the database file. The page is left marked dirty in this case.
  **
  ** An exception to the above rule: If the database is in no-sync mode
  ** and a page is moved during an incremental vacuum then the page may
35985
35986
35987
35988
35989
35990
35991
35992
35993
35994
35995
35996
35997
35998
35999
36000
36001
36002
36003
36004
36005
36006
36007
36008
36009
36010
36011
36012
36013
36014
36015
36016
36017
36018
36019
36020
36021
36022
36023
36024
36025
36026
36027
36028
36029
36030
    rc = sqlite3PagerPagecount(pPager, &dummy);
  }
  pPager->state = PAGER_SHARED;

  return rc;
}

/*
** Check for the existence of or delete the *-wal file that corresponds to
** the database opened by pPager.
**
** When pExists!=NULL, set *pExists to 1 if the *-wal file exists, or 0
** if the *-wal file does not exist.
**
** When pExists==NULL, delete the *-wal file if it exists, or the do
** nothing if the *-wal file does not exist.
**
** Return SQLITE_OK on success. If on an IO or OOM error occurs, return
** an SQLite error code.
*/
static int pagerCheckForOrDeleteWAL(Pager *pPager, int *pExists){
  int rc;                         /* Return code */
  char *zWal;                     /* Name of the WAL file */

  assert( !pPager->tempFile );
  zWal = sqlite3_mprintf("%s-wal", pPager->zFilename);
  if( !zWal ){
    rc = SQLITE_NOMEM;
  }else{
    if( pExists ){
      rc = sqlite3OsAccess(pPager->pVfs, zWal, SQLITE_ACCESS_EXISTS, pExists);
    }else{
      rc = sqlite3OsDelete(pPager->pVfs, zWal, 0);
    }
    sqlite3_free(zWal);
  }
  return rc;
}

/*
** Check if the *-wal file that corresponds to the database opened by pPager
** exists if the database is not empy, or verify that the *-wal file does
** not exist (by deleting it) if the database file is empty.
**
** If the database is not empty and the *-wal file exists, open the pager
** in WAL mode.  If the database is empty or if no *-wal file exists and







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







36109
36110
36111
36112
36113
36114
36115
































36116
36117
36118
36119
36120
36121
36122
    rc = sqlite3PagerPagecount(pPager, &dummy);
  }
  pPager->state = PAGER_SHARED;

  return rc;
}

































/*
** Check if the *-wal file that corresponds to the database opened by pPager
** exists if the database is not empy, or verify that the *-wal file does
** not exist (by deleting it) if the database file is empty.
**
** If the database is not empty and the *-wal file exists, open the pager
** in WAL mode.  If the database is empty or if no *-wal file exists and
36046
36047
36048
36049
36050
36051
36052
36053
36054
36055
36056


36057
36058
36059
36060
36061
36062
36063
  if( !pPager->tempFile ){
    int isWal;                    /* True if WAL file exists */
    int nPage;                    /* Size of the database file */
    assert( pPager->state>=SHARED_LOCK );
    rc = sqlite3PagerPagecount(pPager, &nPage);
    if( rc ) return rc;
    if( nPage==0 ){
      rc = pagerCheckForOrDeleteWAL(pPager, 0);
      isWal = 0;
    }else{
      rc = pagerCheckForOrDeleteWAL(pPager, &isWal);


    }
    if( rc==SQLITE_OK ){
      if( isWal ){
        pager_reset(pPager);
        rc = sqlite3PagerOpenWal(pPager, 0);
        if( rc==SQLITE_OK ){
          rc = pagerBeginReadTransaction(pPager);







|


|
>
>







36138
36139
36140
36141
36142
36143
36144
36145
36146
36147
36148
36149
36150
36151
36152
36153
36154
36155
36156
36157
  if( !pPager->tempFile ){
    int isWal;                    /* True if WAL file exists */
    int nPage;                    /* Size of the database file */
    assert( pPager->state>=SHARED_LOCK );
    rc = sqlite3PagerPagecount(pPager, &nPage);
    if( rc ) return rc;
    if( nPage==0 ){
      rc = sqlite3OsDelete(pPager->pVfs, pPager->zWal, 0);
      isWal = 0;
    }else{
      rc = sqlite3OsAccess(
          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &isWal
      );
    }
    if( rc==SQLITE_OK ){
      if( isWal ){
        pager_reset(pPager);
        rc = sqlite3PagerOpenWal(pPager, 0);
        if( rc==SQLITE_OK ){
          rc = pagerBeginReadTransaction(pPager);
36123
36124
36125
36126
36127
36128
36129

36130
36131
36132
36133
36134
36135
36136
    }
  }

  /* Set the database size back to the value it was before the savepoint 
  ** being reverted was opened.
  */
  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;


  if( !pSavepoint && pagerUseWal(pPager) ){
    return pagerRollbackWal(pPager);
  }

  /* Use pPager->journalOff as the effective size of the main rollback
  ** journal.  The actual file might be larger than this in







>







36217
36218
36219
36220
36221
36222
36223
36224
36225
36226
36227
36228
36229
36230
36231
    }
  }

  /* Set the database size back to the value it was before the savepoint 
  ** being reverted was opened.
  */
  pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize;
  pPager->changeCountDone = pPager->tempFile;

  if( !pSavepoint && pagerUseWal(pPager) ){
    return pagerRollbackWal(pPager);
  }

  /* Use pPager->journalOff as the effective size of the main rollback
  ** journal.  The actual file might be larger than this in
36323
36324
36325
36326
36327
36328
36329
36330
36331
36332
36333
36334
36335
36336
36337
36338
36339
36340
36341
36342
36343
36344
36345
36346
36347
36348
36349
36350
36351
  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
){  
  pPager->xBusyHandler = xBusyHandler;
  pPager->pBusyHandlerArg = pBusyHandlerArg;
}

/*
** Report the current page size and number of reserved bytes back
** to the codec.
*/
#ifdef SQLITE_HAS_CODEC
static void pagerReportSize(Pager *pPager){
  if( pPager->xCodecSizeChng ){
    pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize,
                           (int)pPager->nReserve);
  }
}
#else
# define pagerReportSize(X)     /* No-op if we do not support a codec */
#endif

/*
** Change the page size used by the Pager object. The new page size 
** is passed in *pPageSize.
**
** If the pager is in the error state when this function is called, it
** is a no-op. The value returned is the error state error code (i.e. 
** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL).







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







36418
36419
36420
36421
36422
36423
36424















36425
36426
36427
36428
36429
36430
36431
  int (*xBusyHandler)(void *),         /* Pointer to busy-handler function */
  void *pBusyHandlerArg                /* Argument to pass to xBusyHandler */
){  
  pPager->xBusyHandler = xBusyHandler;
  pPager->pBusyHandlerArg = pBusyHandlerArg;
}
















/*
** Change the page size used by the Pager object. The new page size 
** is passed in *pPageSize.
**
** If the pager is in the error state when this function is called, it
** is a no-op. The value returned is the error state error code (i.e. 
** one of SQLITE_IOERR, SQLITE_CORRUPT or SQLITE_FULL).
36477
36478
36479
36480
36481
36482
36483
36484
36485
36486
36487
36488
36489
36490
36491
36492
36493
36494
36495
36496
36497
36498
36499
  assert( isOpen(pPager->fd) || pPager->tempFile );

  /* This routine is only called by btree immediately after creating
  ** the Pager object.  There has not been an opportunity to transition
  ** to WAL mode yet.
  */
  assert( !pagerUseWal(pPager) );
#if 0
  if( pagerUseWal(pPager) ){
    int isInWal = 0;
    rc = sqlite3WalRead(pPager->pWal, 1, &isInWal, N, pDest);
    if( rc!=SQLITE_OK || isInWal ){
      return rc;
    }
  }
#endif

  if( isOpen(pPager->fd) ){
    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
    if( rc==SQLITE_IOERR_SHORT_READ ){
      rc = SQLITE_OK;
    }







<
<
<
<
<
<
<
<
<







36557
36558
36559
36560
36561
36562
36563









36564
36565
36566
36567
36568
36569
36570
  assert( isOpen(pPager->fd) || pPager->tempFile );

  /* This routine is only called by btree immediately after creating
  ** the Pager object.  There has not been an opportunity to transition
  ** to WAL mode yet.
  */
  assert( !pagerUseWal(pPager) );










  if( isOpen(pPager->fd) ){
    IOTRACE(("DBHDR %p 0 %d\n", pPager, N))
    rc = sqlite3OsRead(pPager->fd, pDest, N, 0);
    if( rc==SQLITE_IOERR_SHORT_READ ){
      rc = SQLITE_OK;
    }
36929
36930
36931
36932
36933
36934
36935
36936
36937
36938
36939
36940
36941
36942
36943
36944
36945
36946
36947
36948
36949
36950
36951
36952
36953
36954
36955
36956
36957
36958
36959
36960
36961
36962
36963
36964
36965
36966
36967
36968
36969
36970
36971
36972
36973
36974
36975

36976
36977
36978
36979
36980
36981
36982
** in Pager.dbFileVers[] is updated to match the new value stored in
** the database file.
**
** If everything is successful, SQLITE_OK is returned. If an IO error 
** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
** be obtained, SQLITE_BUSY is returned.
*/
static int pager_write_pagelist(PgHdr *pList){
  Pager *pPager;                       /* Pager object */
  int rc;                              /* Return code */

  if( NEVER(pList==0) ) return SQLITE_OK;
  pPager = pList->pPager;

  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
  ** database file. If there is already an EXCLUSIVE lock, the following
  ** call is a no-op.
  **
  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
  ** through an intermediate state PENDING.   A PENDING lock prevents new
  ** readers from attaching to the database but is unsufficient for us to
  ** write.  The idea of a PENDING lock is to prevent new readers from
  ** coming in while we wait for existing readers to clear.
  **
  ** While the pager is in the RESERVED state, the original database file
  ** is unchanged and we can rollback without having to playback the
  ** journal into the original database file.  Once we transition to
  ** EXCLUSIVE, it means the database file has been changed and any rollback
  ** will require a journal playback.
  */
  assert( !pagerUseWal(pList->pPager) );
  assert( pPager->state>=PAGER_RESERVED );
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);

  /* If the file is a temp-file has not yet been opened, open it now. It
  ** is not possible for rc to be other than SQLITE_OK if this branch
  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
  */
  if( !isOpen(pPager->fd) ){
    assert( pPager->tempFile && rc==SQLITE_OK );
    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
  }

  /* Before the first write, give the VFS a hint of what the final
  ** file size will be.
  */
  if( pPager->dbSize > (pPager->dbOrigSize+1) && isOpen(pPager->fd) ){

    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
  }

  while( rc==SQLITE_OK && pList ){
    Pgno pgno = pList->pgno;








|
<


<
<
<
















|















|
>







37000
37001
37002
37003
37004
37005
37006
37007

37008
37009



37010
37011
37012
37013
37014
37015
37016
37017
37018
37019
37020
37021
37022
37023
37024
37025
37026
37027
37028
37029
37030
37031
37032
37033
37034
37035
37036
37037
37038
37039
37040
37041
37042
37043
37044
37045
37046
37047
37048
37049
37050
** in Pager.dbFileVers[] is updated to match the new value stored in
** the database file.
**
** If everything is successful, SQLITE_OK is returned. If an IO error 
** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot
** be obtained, SQLITE_BUSY is returned.
*/
static int pager_write_pagelist(Pager *pPager, PgHdr *pList){

  int rc;                              /* Return code */




  /* At this point there may be either a RESERVED or EXCLUSIVE lock on the
  ** database file. If there is already an EXCLUSIVE lock, the following
  ** call is a no-op.
  **
  ** Moving the lock from RESERVED to EXCLUSIVE actually involves going
  ** through an intermediate state PENDING.   A PENDING lock prevents new
  ** readers from attaching to the database but is unsufficient for us to
  ** write.  The idea of a PENDING lock is to prevent new readers from
  ** coming in while we wait for existing readers to clear.
  **
  ** While the pager is in the RESERVED state, the original database file
  ** is unchanged and we can rollback without having to playback the
  ** journal into the original database file.  Once we transition to
  ** EXCLUSIVE, it means the database file has been changed and any rollback
  ** will require a journal playback.
  */
  assert( !pagerUseWal(pPager) );
  assert( pPager->state>=PAGER_RESERVED );
  rc = pager_wait_on_lock(pPager, EXCLUSIVE_LOCK);

  /* If the file is a temp-file has not yet been opened, open it now. It
  ** is not possible for rc to be other than SQLITE_OK if this branch
  ** is taken, as pager_wait_on_lock() is a no-op for temp-files.
  */
  if( !isOpen(pPager->fd) ){
    assert( pPager->tempFile && rc==SQLITE_OK );
    rc = pagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
  }

  /* Before the first write, give the VFS a hint of what the final
  ** file size will be.
  */
  assert( rc!=SQLITE_OK || isOpen(pPager->fd) );
  if( rc==SQLITE_OK && pPager->dbSize>(pPager->dbOrigSize+1) ){
    sqlite3_int64 szFile = pPager->pageSize * (sqlite3_int64)pPager->dbSize;
    sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_SIZE_HINT, &szFile);
  }

  while( rc==SQLITE_OK && pList ){
    Pgno pgno = pList->pgno;

37197
37198
37199
37200
37201
37202
37203
37204
37205
37206
37207
37208
37209
37210
37211
        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
    ) ){
      rc = subjournalPage(pPg);
    }
  
    /* Write the contents of the page out to the database file. */
    if( rc==SQLITE_OK ){
      rc = pager_write_pagelist(pPg);
    }
  }

  /* Mark the page as clean. */
  if( rc==SQLITE_OK ){
    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
    sqlite3PcacheMakeClean(pPg);







|







37265
37266
37267
37268
37269
37270
37271
37272
37273
37274
37275
37276
37277
37278
37279
        rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg)
    ) ){
      rc = subjournalPage(pPg);
    }
  
    /* Write the contents of the page out to the database file. */
    if( rc==SQLITE_OK ){
      rc = pager_write_pagelist(pPager, pPg);
    }
  }

  /* Mark the page as clean. */
  if( rc==SQLITE_OK ){
    PAGERTRACE(("STRESS %d page %d\n", PAGERID(pPager), pPg->pgno));
    sqlite3PcacheMakeClean(pPg);
37337
37338
37339
37340
37341
37342
37343



37344
37345
37346
37347
37348
37349
37350
37351
37352
37353
37354
37355
37356
37357
37358
37359
37360
37361
37362
37363
37364









37365
37366
37367
37368
37369
37370
37371
  pPtr = (u8 *)sqlite3MallocZero(
    ROUND8(sizeof(*pPager)) +      /* Pager structure */
    ROUND8(pcacheSize) +           /* PCache object */
    ROUND8(pVfs->szOsFile) +       /* The main db file */
    journalFileSize * 2 +          /* The two journal files */ 
    nPathname + 1 +                /* zFilename */
    nPathname + 8 + 1              /* zJournal */



  );
  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
  if( !pPtr ){
    sqlite3_free(zPathname);
    return SQLITE_NOMEM;
  }
  pPager =              (Pager*)(pPtr);
  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
  pPager->zFilename =    (char*)(pPtr += journalFileSize);
  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );

  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
  if( zPathname ){
    pPager->zJournal =   (char*)(pPtr += nPathname + 1);
    memcpy(pPager->zFilename, zPathname, nPathname);
    memcpy(pPager->zJournal, zPathname, nPathname);
    memcpy(&pPager->zJournal[nPathname], "-journal", 8);
    if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0;









    sqlite3_free(zPathname);
  }
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */







>
>
>




















|
>
>
>
>
>
>
>
>
>







37405
37406
37407
37408
37409
37410
37411
37412
37413
37414
37415
37416
37417
37418
37419
37420
37421
37422
37423
37424
37425
37426
37427
37428
37429
37430
37431
37432
37433
37434
37435
37436
37437
37438
37439
37440
37441
37442
37443
37444
37445
37446
37447
37448
37449
37450
37451
  pPtr = (u8 *)sqlite3MallocZero(
    ROUND8(sizeof(*pPager)) +      /* Pager structure */
    ROUND8(pcacheSize) +           /* PCache object */
    ROUND8(pVfs->szOsFile) +       /* The main db file */
    journalFileSize * 2 +          /* The two journal files */ 
    nPathname + 1 +                /* zFilename */
    nPathname + 8 + 1              /* zJournal */
#ifndef SQLITE_OMIT_WAL
    + nPathname + 4 + 1              /* zWal */
#endif
  );
  assert( EIGHT_BYTE_ALIGNMENT(SQLITE_INT_TO_PTR(journalFileSize)) );
  if( !pPtr ){
    sqlite3_free(zPathname);
    return SQLITE_NOMEM;
  }
  pPager =              (Pager*)(pPtr);
  pPager->pPCache =    (PCache*)(pPtr += ROUND8(sizeof(*pPager)));
  pPager->fd =   (sqlite3_file*)(pPtr += ROUND8(pcacheSize));
  pPager->sjfd = (sqlite3_file*)(pPtr += ROUND8(pVfs->szOsFile));
  pPager->jfd =  (sqlite3_file*)(pPtr += journalFileSize);
  pPager->zFilename =    (char*)(pPtr += journalFileSize);
  assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) );

  /* Fill in the Pager.zFilename and Pager.zJournal buffers, if required. */
  if( zPathname ){
    pPager->zJournal =   (char*)(pPtr += nPathname + 1);
    memcpy(pPager->zFilename, zPathname, nPathname);
    memcpy(pPager->zJournal, zPathname, nPathname);
    memcpy(&pPager->zJournal[nPathname], "-journal", 8);
    if( pPager->zFilename[0]==0 ){
      pPager->zJournal[0] = 0;
    }
#ifndef SQLITE_OMIT_WAL
    else{
      pPager->zWal = &pPager->zJournal[nPathname+8+1];
      memcpy(pPager->zWal, zPathname, nPathname);
      memcpy(&pPager->zWal[nPathname], "-wal", 4);
    }
#endif
    sqlite3_free(zPathname);
  }
  pPager->pVfs = pVfs;
  pPager->vfsFlags = vfsFlags;

  /* Open the pager file.
  */
38814
38815
38816
38817
38818
38819
38820
38821
38822
38823
38824
38825
38826
38827
38828
      ** used, this call will not create the journal file or perform any
      ** real IO.
      */
      rc = syncJournal(pPager);
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  
      /* Write all dirty pages to the database file. */
      rc = pager_write_pagelist(sqlite3PcacheDirtyList(pPager->pPCache));
      if( rc!=SQLITE_OK ){
        assert( rc!=SQLITE_IOERR_BLOCKED );
        goto commit_phase_one_exit;
      }
      sqlite3PcacheCleanAll(pPager->pPCache);
  
      /* If the file on disk is not the same size as the database image,







|







38894
38895
38896
38897
38898
38899
38900
38901
38902
38903
38904
38905
38906
38907
38908
      ** used, this call will not create the journal file or perform any
      ** real IO.
      */
      rc = syncJournal(pPager);
      if( rc!=SQLITE_OK ) goto commit_phase_one_exit;
  
      /* Write all dirty pages to the database file. */
      rc = pager_write_pagelist(pPager,sqlite3PcacheDirtyList(pPager->pPCache));
      if( rc!=SQLITE_OK ){
        assert( rc!=SQLITE_IOERR_BLOCKED );
        goto commit_phase_one_exit;
      }
      sqlite3PcacheCleanAll(pPager->pPCache);
  
      /* If the file on disk is not the same size as the database image,
39649
39650
39651
39652
39653
39654
39655
39656
39657
39658
39659
39660
39661
39662
39663
39664
  if( !pPager->tempFile && !pPager->pWal ){
    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;

    /* Open the connection to the log file. If this operation fails, 
    ** (e.g. due to malloc() failure), unlock the database file and 
    ** return an error code.
    */
    rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
                        pPager->zFilename, &pPager->pWal);
    if( rc==SQLITE_OK ){
      pPager->journalMode = PAGER_JOURNALMODE_WAL;
    }
  }else{
    *pisOpen = 1;
  }








|
<







39729
39730
39731
39732
39733
39734
39735
39736

39737
39738
39739
39740
39741
39742
39743
  if( !pPager->tempFile && !pPager->pWal ){
    if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;

    /* Open the connection to the log file. If this operation fails, 
    ** (e.g. due to malloc() failure), unlock the database file and 
    ** return an error code.
    */
    rc = sqlite3WalOpen(pPager->pVfs, pPager->fd, pPager->zWal, &pPager->pWal);

    if( rc==SQLITE_OK ){
      pPager->journalMode = PAGER_JOURNALMODE_WAL;
    }
  }else{
    *pisOpen = 1;
  }

39683
39684
39685
39686
39687
39688
39689

39690

39691
39692
39693
39694
39695
39696
39697
39698
39699
39700
39701
  ** it may need to be checkpointed before the connection can switch to
  ** rollback mode. Open it now so this can happen.
  */
  if( !pPager->pWal ){
    int logexists = 0;
    rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED);
    if( rc==SQLITE_OK ){

      rc = pagerCheckForOrDeleteWAL(pPager, &logexists);

    }
    if( rc==SQLITE_OK && logexists ){
      rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
                          pPager->zFilename, &pPager->pWal);
    }
  }
    
  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
  ** the database file, the log and log-summary files will be deleted.
  */
  if( rc==SQLITE_OK && pPager->pWal ){







>
|
>



|







39762
39763
39764
39765
39766
39767
39768
39769
39770
39771
39772
39773
39774
39775
39776
39777
39778
39779
39780
39781
39782
  ** it may need to be checkpointed before the connection can switch to
  ** rollback mode. Open it now so this can happen.
  */
  if( !pPager->pWal ){
    int logexists = 0;
    rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_SHARED);
    if( rc==SQLITE_OK ){
      rc = sqlite3OsAccess(
          pPager->pVfs, pPager->zWal, SQLITE_ACCESS_EXISTS, &logexists
      );
    }
    if( rc==SQLITE_OK && logexists ){
      rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
                          pPager->zWal, &pPager->pWal);
    }
  }
    
  /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on
  ** the database file, the log and log-summary files will be deleted.
  */
  if( rc==SQLITE_OK && pPager->pWal ){
40129
40130
40131
40132
40133
40134
40135
40136
40137
40138
40139
40140
40141
40142
40143
40144
40145
40146
40147
40148
40149
40150
40151
40152
40153
40154
40155
40156
40157
40158
40159
40160
40161
40162
40163
40164

/*
** Return the offset of frame iFrame in the write-ahead log file, 
** assuming a database page size of szPage bytes. The offset returned
** is to the start of the write-ahead log frame-header.
*/
#define walFrameOffset(iFrame, szPage) (                               \
  WAL_HDRSIZE + ((iFrame)-1)*((szPage)+WAL_FRAME_HDRSIZE)        \
)

/*
** An open write-ahead log file is represented by an instance of the
** following object.
*/
struct Wal {
  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
  sqlite3_file *pDbFd;       /* File handle for the database file */
  sqlite3_file *pWalFd;      /* File handle for WAL file */
  u32 iCallback;             /* Value to pass to log callback (or 0) */
  int nWiData;               /* Size of array apWiData */
  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
  u16 szPage;                /* Database page size */
  i16 readLock;              /* Which read lock is being held.  -1 for none */
  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
  u8 isWIndexOpen;           /* True if ShmOpen() called on pDbFd */
  u8 writeLock;              /* True if in a write transaction */
  u8 ckptLock;               /* True if holding a checkpoint lock */
  WalIndexHdr hdr;           /* Wal-index header for current transaction */
  char *zWalName;            /* Name of WAL file */
  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
  u8 lockError;              /* True if a locking error has occurred */
#endif
};

/*







|




















|







40210
40211
40212
40213
40214
40215
40216
40217
40218
40219
40220
40221
40222
40223
40224
40225
40226
40227
40228
40229
40230
40231
40232
40233
40234
40235
40236
40237
40238
40239
40240
40241
40242
40243
40244
40245

/*
** Return the offset of frame iFrame in the write-ahead log file, 
** assuming a database page size of szPage bytes. The offset returned
** is to the start of the write-ahead log frame-header.
*/
#define walFrameOffset(iFrame, szPage) (                               \
  WAL_HDRSIZE + ((iFrame)-1)*(i64)((szPage)+WAL_FRAME_HDRSIZE)         \
)

/*
** An open write-ahead log file is represented by an instance of the
** following object.
*/
struct Wal {
  sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
  sqlite3_file *pDbFd;       /* File handle for the database file */
  sqlite3_file *pWalFd;      /* File handle for WAL file */
  u32 iCallback;             /* Value to pass to log callback (or 0) */
  int nWiData;               /* Size of array apWiData */
  volatile u32 **apWiData;   /* Pointer to wal-index content in memory */
  u16 szPage;                /* Database page size */
  i16 readLock;              /* Which read lock is being held.  -1 for none */
  u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
  u8 isWIndexOpen;           /* True if ShmOpen() called on pDbFd */
  u8 writeLock;              /* True if in a write transaction */
  u8 ckptLock;               /* True if holding a checkpoint lock */
  WalIndexHdr hdr;           /* Wal-index header for current transaction */
  const char *zWalName;      /* Name of WAL file */
  u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
#ifdef SQLITE_DEBUG
  u8 lockError;              /* True if a locking error has occurred */
#endif
};

/*
40905
40906
40907
40908
40909
40910
40911
40912
40913

40914
40915
40916
40917
40918
40919
40920
40921
40922
40923
40924
40925
40926
40927
40928
40929
40930
40931
40932
40933
40934
40935
40936
40937
40938
40939
40940
40941
40942
40943
40944
40945
40946
40947
40948
40949
40950
40951
40952
40953
40954
40955
40956
40957
40958
40959
40960
40961
40962
40963
40964
40965
40966
40967
40968
40969
40970
40971
40972
40973
40974
40975
40976
40977
40978
40979
40980
  if( pWal->isWIndexOpen ){
    sqlite3OsShmClose(pWal->pDbFd, isDelete);
    pWal->isWIndexOpen = 0;
  }
}

/* 
** Open a connection to the WAL file associated with database zDbName.
** The database file must already be opened on connection pDbFd.

**
** A SHARED lock should be held on the database file when this function
** is called. The purpose of this SHARED lock is to prevent any other
** client from unlinking the WAL or wal-index file. If another process
** were to do this just after this client opened one of these files, the
** system would be badly broken.
**
** If the log file is successfully opened, SQLITE_OK is returned and 
** *ppWal is set to point to a new WAL handle. If an error occurs,
** an SQLite error code is returned and *ppWal is left unmodified.
*/
SQLITE_PRIVATE int sqlite3WalOpen(
  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
  sqlite3_file *pDbFd,            /* The open database file */
  const char *zDbName,            /* Name of the database file */
  Wal **ppWal                     /* OUT: Allocated Wal handle */
){
  int rc;                         /* Return Code */
  Wal *pRet;                      /* Object to allocate and return */
  int flags;                      /* Flags passed to OsOpen() */
  char *zWal;                     /* Name of write-ahead log file */
  int nWal;                       /* Length of zWal in bytes */

  assert( zDbName && zDbName[0] );
  assert( pDbFd );

  /* In the amalgamation, the os_unix.c and os_win.c source files come before
  ** this source file.  Verify that the #defines of the locking byte offsets
  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
  */
#ifdef WIN_SHM_BASE
  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif
#ifdef UNIX_SHM_BASE
  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif


  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;
  nWal = sqlite3Strlen30(zDbName) + 5;
  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal);
  if( !pRet ){
    return SQLITE_NOMEM;
  }

  pRet->pVfs = pVfs;
  pRet->pWalFd = (sqlite3_file *)&pRet[1];
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;
  sqlite3_randomness(8, &pRet->hdr.aSalt);
  pRet->zWalName = zWal = pVfs->szOsFile + (char*)pRet->pWalFd;
  sqlite3_snprintf(nWal, zWal, "%s-wal", zDbName);
  rc = sqlite3OsShmOpen(pDbFd);

  /* Open file handle on the write-ahead log file. */
  if( rc==SQLITE_OK ){
    pRet->isWIndexOpen = 1;
    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zWal, pRet->pWalFd, flags, &flags);
  }

  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{







|
|
>














|





<
<

|
















<
|








<
|
<






|







40986
40987
40988
40989
40990
40991
40992
40993
40994
40995
40996
40997
40998
40999
41000
41001
41002
41003
41004
41005
41006
41007
41008
41009
41010
41011
41012
41013
41014
41015


41016
41017
41018
41019
41020
41021
41022
41023
41024
41025
41026
41027
41028
41029
41030
41031
41032
41033

41034
41035
41036
41037
41038
41039
41040
41041
41042

41043

41044
41045
41046
41047
41048
41049
41050
41051
41052
41053
41054
41055
41056
41057
  if( pWal->isWIndexOpen ){
    sqlite3OsShmClose(pWal->pDbFd, isDelete);
    pWal->isWIndexOpen = 0;
  }
}

/* 
** Open a connection to the WAL file zWalName. The database file must 
** already be opened on connection pDbFd. The buffer that zWalName points
** to must remain valid for the lifetime of the returned Wal* handle.
**
** A SHARED lock should be held on the database file when this function
** is called. The purpose of this SHARED lock is to prevent any other
** client from unlinking the WAL or wal-index file. If another process
** were to do this just after this client opened one of these files, the
** system would be badly broken.
**
** If the log file is successfully opened, SQLITE_OK is returned and 
** *ppWal is set to point to a new WAL handle. If an error occurs,
** an SQLite error code is returned and *ppWal is left unmodified.
*/
SQLITE_PRIVATE int sqlite3WalOpen(
  sqlite3_vfs *pVfs,              /* vfs module to open wal and wal-index */
  sqlite3_file *pDbFd,            /* The open database file */
  const char *zWalName,           /* Name of the WAL file */
  Wal **ppWal                     /* OUT: Allocated Wal handle */
){
  int rc;                         /* Return Code */
  Wal *pRet;                      /* Object to allocate and return */
  int flags;                      /* Flags passed to OsOpen() */



  assert( zWalName && zWalName[0] );
  assert( pDbFd );

  /* In the amalgamation, the os_unix.c and os_win.c source files come before
  ** this source file.  Verify that the #defines of the locking byte offsets
  ** in os_unix.c and os_win.c agree with the WALINDEX_LOCK_OFFSET value.
  */
#ifdef WIN_SHM_BASE
  assert( WIN_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif
#ifdef UNIX_SHM_BASE
  assert( UNIX_SHM_BASE==WALINDEX_LOCK_OFFSET );
#endif


  /* Allocate an instance of struct Wal to return. */
  *ppWal = 0;

  pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile);
  if( !pRet ){
    return SQLITE_NOMEM;
  }

  pRet->pVfs = pVfs;
  pRet->pWalFd = (sqlite3_file *)&pRet[1];
  pRet->pDbFd = pDbFd;
  pRet->readLock = -1;

  pRet->zWalName = zWalName;

  rc = sqlite3OsShmOpen(pDbFd);

  /* Open file handle on the write-ahead log file. */
  if( rc==SQLITE_OK ){
    pRet->isWIndexOpen = 1;
    flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
    rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
  }

  if( rc!=SQLITE_OK ){
    walIndexClose(pRet, 0);
    sqlite3OsClose(pRet->pWalFd);
    sqlite3_free(pRet);
  }else{
41308
41309
41310
41311
41312
41313
41314

41315
41316
41317
41318
41319

41320


41321
41322
41323
41324
41325
41326
41327


41328
41329
41330
41331
41332
41333
41334
41335
    /* Sync the WAL to disk */
    if( sync_flags ){
      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
    }

    /* Iterate through the contents of the WAL, copying data to the db file. */
    while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){

      assert( walFramePgno(pWal, iFrame)==iDbpage );
      if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue;
      rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, 
          walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE
      );

      if( rc!=SQLITE_OK ) break;


      rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, (iDbpage-1)*szPage);
      if( rc!=SQLITE_OK ) break;
    }

    /* If work was actually accomplished... */
    if( rc==SQLITE_OK ){
      if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){


        rc = sqlite3OsTruncate(pWal->pDbFd, ((i64)pWal->hdr.nPage*(i64)szPage));
        if( rc==SQLITE_OK && sync_flags ){
          rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
        }
      }
      if( rc==SQLITE_OK ){
        pInfo->nBackfill = mxSafeFrame;
      }







>


<
|
|
>

>
>
|






>
>
|







41385
41386
41387
41388
41389
41390
41391
41392
41393
41394

41395
41396
41397
41398
41399
41400
41401
41402
41403
41404
41405
41406
41407
41408
41409
41410
41411
41412
41413
41414
41415
41416
41417
    /* Sync the WAL to disk */
    if( sync_flags ){
      rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
    }

    /* Iterate through the contents of the WAL, copying data to the db file. */
    while( rc==SQLITE_OK && 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
      i64 iOffset;
      assert( walFramePgno(pWal, iFrame)==iDbpage );
      if( iFrame<=nBackfill || iFrame>mxSafeFrame ) continue;

      iOffset = walFrameOffset(iFrame, szPage) + WAL_FRAME_HDRSIZE;
      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL file */
      rc = sqlite3OsRead(pWal->pWalFd, zBuf, szPage, iOffset);
      if( rc!=SQLITE_OK ) break;
      iOffset = (iDbpage-1)*(i64)szPage;
      testcase( IS_BIG_INT(iOffset) );
      rc = sqlite3OsWrite(pWal->pDbFd, zBuf, szPage, iOffset);
      if( rc!=SQLITE_OK ) break;
    }

    /* If work was actually accomplished... */
    if( rc==SQLITE_OK ){
      if( mxSafeFrame==walIndexHdr(pWal)->mxFrame ){
        i64 szDb = pWal->hdr.nPage*(i64)szPage;
        testcase( IS_BIG_INT(szDb) );
        rc = sqlite3OsTruncate(pWal->pDbFd, szDb);
        if( rc==SQLITE_OK && sync_flags ){
          rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
        }
      }
      if( rc==SQLITE_OK ){
        pInfo->nBackfill = mxSafeFrame;
      }
41859
41860
41861
41862
41863
41864
41865

41866
41867
41868
41869
41870
41871
41872

  /* If iRead is non-zero, then it is the log frame number that contains the
  ** required page. Read and return data from the log file.
  */
  if( iRead ){
    i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE;
    *pInWal = 1;

    return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
  }

  *pInWal = 0;
  return SQLITE_OK;
}








>







41941
41942
41943
41944
41945
41946
41947
41948
41949
41950
41951
41952
41953
41954
41955

  /* If iRead is non-zero, then it is the log frame number that contains the
  ** required page. Read and return data from the log file.
  */
  if( iRead ){
    i64 iOffset = walFrameOffset(iRead, pWal->hdr.szPage) + WAL_FRAME_HDRSIZE;
    *pInWal = 1;
    /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
    return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
  }

  *pInWal = 0;
  return SQLITE_OK;
}

42125
42126
42127
42128
42129
42130
42131

42132
42133
42134
42135
42136
42137
42138
    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
    u32 aCksum[2];                /* Checksum for wal-header */

    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
    sqlite3Put4byte(&aWalHdr[8], szPage);
    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);

    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
    
    pWal->szPage = (u16)szPage;
    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;







>







42208
42209
42210
42211
42212
42213
42214
42215
42216
42217
42218
42219
42220
42221
42222
    u8 aWalHdr[WAL_HDRSIZE];      /* Buffer to assemble wal-header in */
    u32 aCksum[2];                /* Checksum for wal-header */

    sqlite3Put4byte(&aWalHdr[0], (WAL_MAGIC | SQLITE_BIGENDIAN));
    sqlite3Put4byte(&aWalHdr[4], WAL_MAX_VERSION);
    sqlite3Put4byte(&aWalHdr[8], szPage);
    sqlite3Put4byte(&aWalHdr[12], pWal->nCkpt);
    sqlite3_randomness(8, pWal->hdr.aSalt);
    memcpy(&aWalHdr[16], pWal->hdr.aSalt, 8);
    walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum);
    sqlite3Put4byte(&aWalHdr[24], aCksum[0]);
    sqlite3Put4byte(&aWalHdr[28], aCksum[1]);
    
    pWal->szPage = (u16)szPage;
    pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN;
42149
42150
42151
42152
42153
42154
42155
42156
42157

42158
42159
42160
42161
42162
42163
42164

  /* Write the log file. */
  for(p=pList; p; p=p->pDirty){
    u32 nDbsize;                  /* Db-size field for frame header */
    i64 iOffset;                  /* Write offset in log file */
    void *pData;
   
   
    iOffset = walFrameOffset(++iFrame, szPage);

    
    /* Populate and write the frame header */
    nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0;
#if defined(SQLITE_HAS_CODEC)
    if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
#else
    pData = p->pData;







<

>







42233
42234
42235
42236
42237
42238
42239

42240
42241
42242
42243
42244
42245
42246
42247
42248

  /* Write the log file. */
  for(p=pList; p; p=p->pDirty){
    u32 nDbsize;                  /* Db-size field for frame header */
    i64 iOffset;                  /* Write offset in log file */
    void *pData;
   

    iOffset = walFrameOffset(++iFrame, szPage);
    /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
    
    /* Populate and write the frame header */
    nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0;
#if defined(SQLITE_HAS_CODEC)
    if( (pData = sqlite3PagerCodec(p))==0 ) return SQLITE_NOMEM;
#else
    pData = p->pData;
42190
42191
42192
42193
42194
42195
42196

42197
42198
42199
42200
42201
42202
42203
      void *pData;
#if defined(SQLITE_HAS_CODEC)
      if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM;
#else
      pData = pLast->pData;
#endif
      walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);

      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      iOffset += WAL_FRAME_HDRSIZE;
      rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); 
      if( rc!=SQLITE_OK ){







>







42274
42275
42276
42277
42278
42279
42280
42281
42282
42283
42284
42285
42286
42287
42288
      void *pData;
#if defined(SQLITE_HAS_CODEC)
      if( (pData = sqlite3PagerCodec(pLast))==0 ) return SQLITE_NOMEM;
#else
      pData = pLast->pData;
#endif
      walEncodeFrame(pWal, pLast->pgno, nTruncate, pData, aFrame);
      /* testcase( IS_BIG_INT(iOffset) ); // requires a 4GiB WAL */
      rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
      if( rc!=SQLITE_OK ){
        return rc;
      }
      iOffset += WAL_FRAME_HDRSIZE;
      rc = sqlite3OsWrite(pWal->pWalFd, pData, szPage, iOffset); 
      if( rc!=SQLITE_OK ){
63499
63500
63501
63502
63503
63504
63505
63506
63507
63508
63509
63510
63511
63512
63513
63514
63515
63516
63517
** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
** modes (delete, truncate, persist, off and memory), this is a simple
** operation. No IO is required.
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.
**
** If an attempt to change in to or out of WAL mode fails because another
** connection also has the same database open, then an SQLITE_BUSY error
** is raised if P5==0, or of P5!=0 the journal mode changed is skipped
** without signaling the error.
*/
case OP_JournalMode: {    /* out2-prerelease */
#if 0  /* local variables moved into u.cd */
  Btree *pBt;                     /* Btree to change journal mode of */
  Pager *pPager;                  /* Pager associated with pBt */
  int eNew;                       /* New journal mode */
  int eOld;                       /* The old journal mode */







<
<
<
<
<







63584
63585
63586
63587
63588
63589
63590





63591
63592
63593
63594
63595
63596
63597
** PAGER_JOURNALMODE_XXX values. If changing between the various rollback
** modes (delete, truncate, persist, off and memory), this is a simple
** operation. No IO is required.
**
** If changing into or out of WAL mode the procedure is more complicated.
**
** Write a string containing the final journal-mode to register P2.





*/
case OP_JournalMode: {    /* out2-prerelease */
#if 0  /* local variables moved into u.cd */
  Btree *pBt;                     /* Btree to change journal mode of */
  Pager *pPager;                  /* Pager associated with pBt */
  int eNew;                       /* New journal mode */
  int eOld;                       /* The old journal mode */
63603
63604
63605
63606
63607
63608
63609
63610
63611
63612
63613
63614
63615
63616
63617
63618
63619
63620
63621
63622
63623
63624
63625
63626
63627
63628
63629
        rc = sqlite3BtreeSetVersion(u.cd.pBt, (u.cd.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
      }
    }
  }
#endif /* ifndef SQLITE_OMIT_WAL */

  if( rc ){
    if( rc==SQLITE_BUSY && pOp->p5!=0 ) rc = SQLITE_OK;
    u.cd.eNew = u.cd.eOld;
  }
  u.cd.eNew = sqlite3PagerSetJournalMode(u.cd.pPager, u.cd.eNew);

  pOut = &aMem[pOp->p2];
  pOut->flags = MEM_Str|MEM_Static|MEM_Term;
  pOut->z = (char *)sqlite3JournalModename(u.cd.eNew);
  pOut->n = sqlite3Strlen30(pOut->z);
  pOut->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pOut, encoding);
  break;
};  
#endif /* SQLITE_OMIT_PRAGMA */

#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum * * * * *
**
** Vacuum the entire database.  This opcode will cause other virtual
** machines to be created and run.  It may not be called from within







<











|







63683
63684
63685
63686
63687
63688
63689

63690
63691
63692
63693
63694
63695
63696
63697
63698
63699
63700
63701
63702
63703
63704
63705
63706
63707
63708
        rc = sqlite3BtreeSetVersion(u.cd.pBt, (u.cd.eNew==PAGER_JOURNALMODE_WAL ? 2 : 1));
      }
    }
  }
#endif /* ifndef SQLITE_OMIT_WAL */

  if( rc ){

    u.cd.eNew = u.cd.eOld;
  }
  u.cd.eNew = sqlite3PagerSetJournalMode(u.cd.pPager, u.cd.eNew);

  pOut = &aMem[pOp->p2];
  pOut->flags = MEM_Str|MEM_Static|MEM_Term;
  pOut->z = (char *)sqlite3JournalModename(u.cd.eNew);
  pOut->n = sqlite3Strlen30(pOut->z);
  pOut->enc = SQLITE_UTF8;
  sqlite3VdbeChangeEncoding(pOut, encoding);
  break;
};
#endif /* SQLITE_OMIT_PRAGMA */

#if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
/* Opcode: Vacuum * * * * *
**
** Vacuum the entire database.  This opcode will cause other virtual
** machines to be created and run.  It may not be called from within
71828
71829
71830
71831
71832
71833
71834
71835
71836
71837
71838
71839
71840
71841
71842
71843
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
      zErrDyn = sqlite3MPrintf(db, 
        "attached databases must use the same text encoding as main database");
      rc = SQLITE_ERROR;
    }
    pPager = sqlite3BtreePager(aNew->pBt);
    sqlite3PagerLockingMode(pPager, db->dfltLockMode);
    /* journal_mode set by the OP_JournalMode opcode that will following
    ** the OP_Function opcode that invoked this function. */
    sqlite3BtreeSecureDelete(aNew->pBt,
                             sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
  }
  aNew->safety_level = 3;
  aNew->zName = sqlite3DbStrDup(db, zName);
  if( rc==SQLITE_OK && aNew->zName==0 ){
    rc = SQLITE_NOMEM;







<
<







71907
71908
71909
71910
71911
71912
71913


71914
71915
71916
71917
71918
71919
71920
    }else if( aNew->pSchema->file_format && aNew->pSchema->enc!=ENC(db) ){
      zErrDyn = sqlite3MPrintf(db, 
        "attached databases must use the same text encoding as main database");
      rc = SQLITE_ERROR;
    }
    pPager = sqlite3BtreePager(aNew->pBt);
    sqlite3PagerLockingMode(pPager, db->dfltLockMode);


    sqlite3BtreeSecureDelete(aNew->pBt,
                             sqlite3BtreeSecureDelete(db->aDb[0].pBt,-1) );
  }
  aNew->safety_level = 3;
  aNew->zName = sqlite3DbStrDup(db, zName);
  if( rc==SQLITE_OK && aNew->zName==0 ){
    rc = SQLITE_NOMEM;
72025
72026
72027
72028
72029
72030
72031
72032
72033
72034
72035
72036
72037
72038
72039
72040
72041
72042
72043
72044
72045
72046
72047
72048
72049
  assert( v || db->mallocFailed );
  if( v ){
    sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
    assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
    sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
    sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);

    if( type==SQLITE_ATTACH ){
      /* On an attach, also set the journal mode.  Note that
      ** sqlite3VdbeUsesBtree() is not call here since the iDb index
      ** will be out of range prior to the new database being attached.
      ** The OP_JournalMode opcode will all sqlite3VdbeUsesBtree() for us.
      */
      sqlite3VdbeAddOp3(v, OP_JournalMode, db->nDb, regArgs+3, 
                           db->dfltJournalMode);
      sqlite3VdbeChangeP5(v, 1);
    }

    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing
    ** statements).
    */
    sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
  }
  







<
<
<
<
<
<
<
<
<
<
<







72102
72103
72104
72105
72106
72107
72108











72109
72110
72111
72112
72113
72114
72115
  assert( v || db->mallocFailed );
  if( v ){
    sqlite3VdbeAddOp3(v, OP_Function, 0, regArgs+3-pFunc->nArg, regArgs+3);
    assert( pFunc->nArg==-1 || (pFunc->nArg&0xff)==pFunc->nArg );
    sqlite3VdbeChangeP5(v, (u8)(pFunc->nArg));
    sqlite3VdbeChangeP4(v, -1, (char *)pFunc, P4_FUNCDEF);












    /* Code an OP_Expire. For an ATTACH statement, set P1 to true (expire this
    ** statement only). For DETACH, set it to false (expire all existing
    ** statements).
    */
    sqlite3VdbeAddOp1(v, OP_Expire, (type==SQLITE_ATTACH));
  }
  
75912
75913
75914
75915
75916
75917
75918
75919
75920
75921
75922
75923
75924
75925
75926
    }
    db->aDb[1].pBt = pBt;
    assert( db->aDb[1].pSchema );
    if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
      db->mallocFailed = 1;
      return 1;
    }
    sqlite3PagerSetJournalMode(sqlite3BtreePager(pBt), db->dfltJournalMode);
  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.







<







75978
75979
75980
75981
75982
75983
75984

75985
75986
75987
75988
75989
75990
75991
    }
    db->aDb[1].pBt = pBt;
    assert( db->aDb[1].pSchema );
    if( SQLITE_NOMEM==sqlite3BtreeSetPageSize(pBt, db->nextPagesize, -1, 0) ){
      db->mallocFailed = 1;
      return 1;
    }

  }
  return 0;
}

/*
** Generate VDBE code that will verify the schema cookie and start
** a read-transaction for all named database files.
83581
83582
83583
83584
83585
83586
83587
83588







83589
83590
83591
83592
83593


83594
83595
83596
83597
83598
83599
83600
83601


83602
83603
83604
83605
83606
83607
83608
83609
83610
83611
83612
83613
83614
83615
83616
83617
83618
83619
83620
83621
83622
83623
83624
83625
83626
83627
83628
83629
83630
83631
83632
83633
83634
83635
83636
83637
83638
83639
83640
83641
83642

  /*
  **  PRAGMA [database.]journal_mode
  **  PRAGMA [database.]journal_mode =
  **                      (delete|persist|off|truncate|memory|wal|off)
  */
  if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
    int eMode;                    /* One of the PAGER_JOURNALMODE_XXX symbols */








    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);

    if( zRight==0 ){


      eMode = PAGER_JOURNALMODE_QUERY;
    }else{
      const char *zMode;
      int n = sqlite3Strlen30(zRight);
      for(eMode=0; (zMode = sqlite3JournalModename(eMode)); eMode++){
        if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
      }
      if( !zMode ){


        eMode = PAGER_JOURNALMODE_QUERY;
      }
    }
    if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
      /* Simple "PRAGMA journal_mode;" statement. This is a query for
      ** the current default journal mode (which may be different to
      ** the journal-mode of the main database).
      */
      eMode = db->dfltJournalMode;
      sqlite3VdbeAddOp2(v, OP_String8, 0, 1);
      sqlite3VdbeChangeP4(v, -1, sqlite3JournalModename(eMode), P4_STATIC);
    }else{
      int ii;

      if( pId2->n==0 ){
        /* When there is no database name before the "journal_mode" keyword
        ** in the PRAGMA, then the journal-mode will be set on
        ** all attached databases, as well as the main db file.
        **
        ** Also, the sqlite3.dfltJournalMode variable is set so that
        ** any subsequently attached databases also use the specified
        ** journal mode.
        */
        db->dfltJournalMode = (u8)eMode;
      }

      for(ii=db->nDb-1; ii>=0; ii--){
        if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
          sqlite3VdbeUsesBtree(v, ii);
          sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
        }
      }
    }

    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
  }else

  /*
  **  PRAGMA [database.]journal_size_limit
  **  PRAGMA [database.]journal_size_limit=N
  **







|
>
>
>
>
>
>
>





>
>




|



>
>



|
|
<
<
<
<
<
<
<
<
|
|
<
<
<
<
<
<
<
<
<
|
<
|
|
|
|
|
|
<
<







83646
83647
83648
83649
83650
83651
83652
83653
83654
83655
83656
83657
83658
83659
83660
83661
83662
83663
83664
83665
83666
83667
83668
83669
83670
83671
83672
83673
83674
83675
83676
83677
83678
83679
83680
83681
83682








83683
83684









83685

83686
83687
83688
83689
83690
83691


83692
83693
83694
83695
83696
83697
83698

  /*
  **  PRAGMA [database.]journal_mode
  **  PRAGMA [database.]journal_mode =
  **                      (delete|persist|off|truncate|memory|wal|off)
  */
  if( sqlite3StrICmp(zLeft,"journal_mode")==0 ){
    int eMode;        /* One of the PAGER_JOURNALMODE_XXX symbols */
    int ii;           /* Loop counter */

    /* Force the schema to be loaded on all databases.  This cases all
    ** database files to be opened and the journal_modes set. */
    if( sqlite3ReadSchema(pParse) ){
      goto pragma_out;
    }

    sqlite3VdbeSetNumCols(v, 1);
    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "journal_mode", SQLITE_STATIC);

    if( zRight==0 ){
      /* If there is no "=MODE" part of the pragma, do a query for the
      ** current mode */
      eMode = PAGER_JOURNALMODE_QUERY;
    }else{
      const char *zMode;
      int n = sqlite3Strlen30(zRight);
      for(eMode=0; (zMode = sqlite3JournalModename(eMode))!=0; eMode++){
        if( sqlite3StrNICmp(zRight, zMode, n)==0 ) break;
      }
      if( !zMode ){
        /* If the "=MODE" part does not match any known journal mode,
        ** then do a query */
        eMode = PAGER_JOURNALMODE_QUERY;
      }
    }
    if( eMode==PAGER_JOURNALMODE_QUERY && pId2->n==0 ){
      /* Convert "PRAGMA journal_mode" into "PRAGMA main.journal_mode" */








      iDb = 0;
      pId2->n = 1;









    }

    for(ii=db->nDb-1; ii>=0; ii--){
      if( db->aDb[ii].pBt && (ii==iDb || pId2->n==0) ){
        sqlite3VdbeUsesBtree(v, ii);
        sqlite3VdbeAddOp3(v, OP_JournalMode, ii, 1, eMode);
      }
    }


    sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
  }else

  /*
  **  PRAGMA [database.]journal_size_limit
  **  PRAGMA [database.]journal_size_limit=N
  **
84646
84647
84648
84649
84650
84651
84652

84653
84654
84655
84656
84657
84658


84659
84660
84661
84662
84663
84664
84665
84666
84667
84668
84669
84670
84671
84672
84673
84674
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    int rc;
    sqlite3_stmt *pStmt;


    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    db->init.orphanTrigger = 0;
    rc = sqlite3_prepare(db, argv[2], -1, &pStmt, 0);


    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          db->mallocFailed = 1;
        }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[0], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);







>





|
>
>








|







84702
84703
84704
84705
84706
84707
84708
84709
84710
84711
84712
84713
84714
84715
84716
84717
84718
84719
84720
84721
84722
84723
84724
84725
84726
84727
84728
84729
84730
84731
84732
84733
    /* Call the parser to process a CREATE TABLE, INDEX or VIEW.
    ** But because db->init.busy is set to 1, no VDBE code is generated
    ** or executed.  All the parser does is build the internal data
    ** structures that describe the table, index, or view.
    */
    int rc;
    sqlite3_stmt *pStmt;
    TESTONLY(int rcp);            /* Return code from sqlite3_prepare() */

    assert( db->init.busy );
    db->init.iDb = iDb;
    db->init.newTnum = atoi(argv[1]);
    db->init.orphanTrigger = 0;
    TESTONLY(rcp = ) sqlite3_prepare(db, argv[2], -1, &pStmt, 0);
    rc = db->errCode;
    assert( (rc&0xFF)==(rcp&0xFF) );
    db->init.iDb = 0;
    if( SQLITE_OK!=rc ){
      if( db->init.orphanTrigger ){
        assert( iDb==1 );
      }else{
        pData->rc = rc;
        if( rc==SQLITE_NOMEM ){
          db->mallocFailed = 1;
        }else if( rc!=SQLITE_INTERRUPT && (rc&0xFF)!=SQLITE_LOCKED ){
          corruptSchema(pData, argv[0], sqlite3_errmsg(db));
        }
      }
    }
    sqlite3_finalize(pStmt);
  }else if( argv[0]==0 ){
    corruptSchema(pData, 0, 0);
104121
104122
104123
104124
104125
104126
104127
104128
104129
104130
104131
104132
104133
104134
104135
104136
104137
104138
104139
104140
104141
104142
104143
104144
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */

#ifndef SQLITE_OMIT_GLOBALRECOVER
#ifndef SQLITE_OMIT_DEPRECATED
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
SQLITE_API int sqlite3_global_recover(void){
  return SQLITE_OK;
}
#endif
#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.







<








<







104180
104181
104182
104183
104184
104185
104186

104187
104188
104189
104190
104191
104192
104193
104194

104195
104196
104197
104198
104199
104200
104201
  db->xCollNeeded16 = xCollNeeded16;
  db->pCollNeededArg = pCollNeededArg;
  sqlite3_mutex_leave(db->mutex);
  return SQLITE_OK;
}
#endif /* SQLITE_OMIT_UTF16 */


#ifndef SQLITE_OMIT_DEPRECATED
/*
** This function is now an anachronism. It used to be used to recover from a
** malloc() failure, but SQLite now does this automatically.
*/
SQLITE_API int sqlite3_global_recover(void){
  return SQLITE_OK;
}

#endif

/*
** Test to see whether or not the database connection is in autocommit
** mode.  Return TRUE if it is and FALSE if not.  Autocommit mode is on
** by default.  Autocommit is disabled by a BEGIN statement and reenabled
** by the next COMMIT or ROLLBACK.

Changes to src/sqlite3.h.

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.0"
#define SQLITE_VERSION_NUMBER 3007000
#define SQLITE_SOURCE_ID      "2010-07-03 13:59:01 3b20ad03be55613d922d81aec5313327bf4098b9"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros







|







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.7.0"
#define SQLITE_VERSION_NUMBER 3007000
#define SQLITE_SOURCE_ID      "2010-07-08 17:40:38 e396184cd3bdb96e29ac33af5d1f631cac553341"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843



844




845
846
847
848
849
850
851
** SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
**
** The xRandomness(), xSleep(), and xCurrentTime() interfaces
** are not strictly a part of the filesystem, but they are
** included in the VFS structure for completeness.
** The xRandomness() function attempts to return nBytes bytes
** of good-quality randomness into zOut.  The return value is
** the actual number of bytes of randomness obtained.
** The xSleep() method causes the calling thread to sleep for at
** least the number of microseconds given.  The xCurrentTime()
** method returns a Julian Day Number for the current date and time.



**




*/
typedef struct sqlite3_vfs sqlite3_vfs;
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 2) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */







|
|






|
>
>
>
|
>
>
>
>







828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
** SQLite will always allocate at least mxPathname+1 bytes for the
** output buffer xFullPathname.  The exact size of the output buffer
** is also passed as a parameter to both  methods. If the output buffer
** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
** handled as a fatal error by SQLite, vfs implementations should endeavor
** to prevent this by setting mxPathname to a sufficiently large value.
**
** The xRandomness(), xSleep(), xCurrentTime(), and xCurrentTimeInt64()
** interfaces are not strictly a part of the filesystem, but they are
** included in the VFS structure for completeness.
** The xRandomness() function attempts to return nBytes bytes
** of good-quality randomness into zOut.  The return value is
** the actual number of bytes of randomness obtained.
** The xSleep() method causes the calling thread to sleep for at
** least the number of microseconds given.  The xCurrentTime()
** method returns a Julian Day Number for the current date and time as
** a floating point value.
** The xCurrentTimeInt64() method returns, as an integer, the Julian
** Day Number multipled by 86400000 (the number of milliseconds in 
** a 24-hour day).  
** ^SQLite will use the xCurrentTimeInt64() method to get the current
** date and time if that method is available (if iVersion is 2 or 
** greater and the function pointer is not NULL) and will fall back
** to xCurrentTime() if xCurrentTimeInt64() is unavailable.
*/
typedef struct sqlite3_vfs sqlite3_vfs;
struct sqlite3_vfs {
  int iVersion;            /* Structure version number (currently 2) */
  int szOsFile;            /* Size of subclassed sqlite3_file */
  int mxPathname;          /* Maximum file pathname length */
  sqlite3_vfs *pNext;      /* Next registered VFS */
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */
  int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};







<







871
872
873
874
875
876
877

878
879
880
881
882
883
884
  int (*xSleep)(sqlite3_vfs*, int microseconds);
  int (*xCurrentTime)(sqlite3_vfs*, double*);
  int (*xGetLastError)(sqlite3_vfs*, int, char *);
  /*
  ** The methods above are in version 1 of the sqlite_vfs object
  ** definition.  Those that follow are added in version 2 or later
  */

  int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
  /*
  ** The methods above are in versions 1 and 2 of the sqlite_vfs object.
  ** New fields may be appended in figure versions.  The iVersion
  ** value will increment whenever this happens. 
  */
};

Changes to src/stat.c.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78

79
80
81
82

83
84
85
86
87
88
89
90
















91
92
93
      b = 1;
    }
    a = t/fsize;
    @ %d(a):%d(b)
    @ </td></tr>
  }
  @ <tr><th>Number&nbsp;Of&nbsp;Check-ins:</th><td>
  n = db_int(0, "SELECT count(distinct mid) FROM mlink");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Files:</th><td>
  n = db_int(0, "SELECT count(*) FROM filename");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Wiki&nbsp;Pages:</th><td>
  n = db_int(0, "SELECT count(*) FROM tag WHERE +tagname GLOB 'wiki-*'");

  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Tickets:</th><td>
  n = db_int(0, "SELECT count(*) FROM tag WHERE +tagname GLOB 'tkt-*'");

  @ %d(n)
  @ </td></tr>
  @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
  n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event) + 0.99");

  @ %d(n) days
  @ </td></tr>
  @ <tr><th>Project&nbsp;ID:</th><td>
  @ %h(db_get("project-code",""))
  @ </td></tr>
  @ <tr><th>Server&nbsp;ID:</th><td>
  @ %h(db_get("server-code",""))
  @ </td></tr>
















  @ </table></p>
  style_footer();
}







|



|



|
>



|
>



|
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
      b = 1;
    }
    a = t/fsize;
    @ %d(a):%d(b)
    @ </td></tr>
  }
  @ <tr><th>Number&nbsp;Of&nbsp;Check-ins:</th><td>
  n = db_int(0, "SELECT count(distinct mid) FROM mlink /*scan*/");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Files:</th><td>
  n = db_int(0, "SELECT count(*) FROM filename /*scan*/");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Wiki&nbsp;Pages:</th><td>
  n = db_int(0, "SELECT count(*) FROM tag  /*scan*/"
                " WHERE +tagname GLOB 'wiki-*'");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Number&nbsp;Of&nbsp;Tickets:</th><td>
  n = db_int(0, "SELECT count(*) FROM tag  /*scan*/"
                " WHERE +tagname GLOB 'tkt-*'");
  @ %d(n)
  @ </td></tr>
  @ <tr><th>Duration&nbsp;Of&nbsp;Project:</th><td>
  n = db_int(0, "SELECT julianday('now') - (SELECT min(mtime) FROM event)"
                " + 0.99");
  @ %d(n) days
  @ </td></tr>
  @ <tr><th>Project&nbsp;ID:</th><td>
  @ %h(db_get("project-code",""))
  @ </td></tr>
  @ <tr><th>Server&nbsp;ID:</th><td>
  @ %h(db_get("server-code",""))
  @ </td></tr>

  @ <tr><th>Fossil&nbsp;Version:</th><td>
  @ %h(MANIFEST_DATE) %h(MANIFEST_VERSION)
  @ </td></tr>
  @ <tr><th>SQLite&nbsp;Version:</th><td>
  @ %h(db_text(0, "SELECT substr(sqlite_source_id(),1,30)"))
  @ (%h(SQLITE_VERSION))
  @ </td></tr>
  @ <tr><th>Database&nbsp;Stats:</th><td>
  @ %d(db_int(0, "PRAGMA %s.page_count", g.zRepoDb)) pages,
  @ %d(db_int(0, "PRAGMA %s.page_size", g.zRepoDb)) bytes/page,
  @ %d(db_int(0, "PRAGMA %s.freelist_count", g.zRepoDb)) free pages,
  @ %s(db_text(0, "PRAGMA %s.encoding", g.zRepoDb)),
  @ %s(db_text(0, "PRAGMA %s.journal_mode", g.zRepoDb)) mode
  @ </td></tr>

  @ </table></p>
  style_footer();
}

Changes to src/sync.c.

97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    zUrl = db_get("last-sync-url", 0);
    zPw = db_get("last-sync-pw", 0);
    if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];
  }
  if( zUrl==0 ){
    if( urlOptional ) exit(0);
    usage("URL");
  }
  url_parse(zUrl);
  if( !g.dontKeepUrl ){
    db_set("last-sync-url", g.urlCanonical, 0);
    if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0);
  }







|







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    zUrl = db_get("last-sync-url", 0);
    zPw = db_get("last-sync-pw", 0);
    if( db_get_boolean("auto-sync",1) ) configSync = CONFIGSET_SHUN;
  }else if( g.argc==3 ){
    zUrl = g.argv[2];
  }
  if( zUrl==0 ){
    if( urlOptional ) fossil_exit(0);
    usage("URL");
  }
  url_parse(zUrl);
  if( !g.dontKeepUrl ){
    db_set("last-sync-url", g.urlCanonical, 0);
    if( g.urlPasswd ) db_set("last-sync-pw", g.urlPasswd, 0);
  }