enlargedb.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. /*
  2. ** Try to enlarge an SQLite database by appending many unused pages.
  3. ** The resulting database will fail PRAGMA integrity_check due to the
  4. ** appended unused pages, but it should work otherwise.
  5. **
  6. ** Usage:
  7. **
  8. ** enlargedb DATABASE N
  9. **
  10. ** Adds N blank pages onto the end of DATABASE. N can be decimal
  11. ** or hex. The total number of pages after adding must be no greater
  12. ** than 4294967297
  13. */
  14. #include <stdio.h>
  15. #include <string.h>
  16. #include <stdlib.h>
  17. int main(int argc, char **argv){
  18. char *zEnd;
  19. long long int toAppend;
  20. long long int currentSz;
  21. long long int newSz;
  22. FILE *f;
  23. size_t got;
  24. int pgsz;
  25. char zero = 0;
  26. unsigned char buf[100];
  27. if( argc!=3 ) goto usage_error;
  28. toAppend = strtoll(argv[2], &zEnd, 0);
  29. if( zEnd==argv[2] || zEnd[0] ) goto usage_error;
  30. if( toAppend<1 ){
  31. fprintf(stderr, "N must be at least 1\n");
  32. exit(1);
  33. }
  34. f = fopen(argv[1], "r+b");
  35. if( f==0 ){
  36. fprintf(stderr, "cannot open \"%s\" for reading and writing\n", argv[1]);
  37. exit(1);
  38. }
  39. got = fread(buf, 1, sizeof(buf), f);
  40. if( got!=sizeof(buf) ) goto not_valid_db;
  41. if( strcmp((char*)buf,"SQLite format 3")!=0 ) goto not_valid_db;
  42. pgsz = (buf[16]<<8) + buf[17];
  43. if( pgsz==1 ) pgsz = 65536;
  44. if( pgsz<512 || pgsz>65536 || (pgsz&(pgsz-1))!=0 ) goto not_valid_db;
  45. currentSz = (buf[28]<<24) + (buf[29]<<16) + (buf[30]<<8) + buf[31];
  46. newSz = currentSz + toAppend;
  47. if( newSz > 0xffffffff ) newSz = 0xffffffff;
  48. buf[28] = (newSz>>24) & 0xff;
  49. buf[29] = (newSz>>16) & 0xff;
  50. buf[30] = (newSz>>8) & 0xff;
  51. buf[31] = newSz & 0xff;
  52. fseek(f, 28, SEEK_SET);
  53. fwrite(&buf[28],4,1,f);
  54. fseek(f, (long)(newSz*pgsz - 1), SEEK_SET);
  55. fwrite(&zero,1,1,f);
  56. fclose(f);
  57. return 0;
  58. not_valid_db:
  59. fprintf(stderr,"not a valid database: %s\n", argv[1]);
  60. exit(1);
  61. usage_error:
  62. fprintf(stderr,"Usage: %s DATABASE N\n", argv[0]);
  63. exit(1);
  64. }