/ Hex Artifact Content
Login

Artifact 303e68971829ed6c7058f982e7361b967344abda:


0000: 2f 2a 0a 2a 2a 20 32 30 31 30 20 53 65 70 74 65  /*.** 2010 Septe
0010: 6d 62 65 72 20 33 31 0a 2a 2a 0a 2a 2a 20 54 68  mber 31.**.** Th
0020: 65 20 61 75 74 68 6f 72 20 64 69 73 63 6c 61 69  e author disclai
0030: 6d 73 20 63 6f 70 79 72 69 67 68 74 20 74 6f 20  ms copyright to 
0040: 74 68 69 73 20 73 6f 75 72 63 65 20 63 6f 64 65  this source code
0050: 2e 20 20 49 6e 20 70 6c 61 63 65 20 6f 66 0a 2a  .  In place of.*
0060: 2a 20 61 20 6c 65 67 61 6c 20 6e 6f 74 69 63 65  * a legal notice
0070: 2c 20 68 65 72 65 20 69 73 20 61 20 62 6c 65 73  , here is a bles
0080: 73 69 6e 67 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 4d  sing:.**.**    M
0090: 61 79 20 79 6f 75 20 64 6f 20 67 6f 6f 64 20 61  ay you do good a
00a0: 6e 64 20 6e 6f 74 20 65 76 69 6c 2e 0a 2a 2a 20  nd not evil..** 
00b0: 20 20 20 4d 61 79 20 79 6f 75 20 66 69 6e 64 20     May you find 
00c0: 66 6f 72 67 69 76 65 6e 65 73 73 20 66 6f 72 20  forgiveness for 
00d0: 79 6f 75 72 73 65 6c 66 20 61 6e 64 20 66 6f 72  yourself and for
00e0: 67 69 76 65 20 6f 74 68 65 72 73 2e 0a 2a 2a 20  give others..** 
00f0: 20 20 20 4d 61 79 20 79 6f 75 20 73 68 61 72 65     May you share
0100: 20 66 72 65 65 6c 79 2c 20 6e 65 76 65 72 20 74   freely, never t
0110: 61 6b 69 6e 67 20 6d 6f 72 65 20 74 68 61 6e 20  aking more than 
0120: 79 6f 75 20 67 69 76 65 2e 0a 2a 2a 0a 2a 2a 2a  you give..**.***
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69  ******.**.** Thi
0180: 73 20 66 69 6c 65 20 63 6f 6e 74 61 69 6e 73 20  s file contains 
0190: 61 20 56 46 53 20 22 73 68 69 6d 22 20 2d 20 61  a VFS "shim" - a
01a0: 20 6c 61 79 65 72 20 74 68 61 74 20 73 69 74 73   layer that sits
01b0: 20 69 6e 20 62 65 74 77 65 65 6e 20 74 68 65 0a   in between the.
01c0: 2a 2a 20 70 61 67 65 72 20 61 6e 64 20 74 68 65  ** pager and the
01d0: 20 72 65 61 6c 20 56 46 53 2e 0a 2a 2a 0a 2a 2a   real VFS..**.**
01e0: 20 54 68 69 73 20 70 61 72 74 69 63 75 6c 61 72   This particular
01f0: 20 73 68 69 6d 20 65 6e 66 6f 72 63 65 73 20 61   shim enforces a
0200: 20 71 75 6f 74 61 20 73 79 73 74 65 6d 20 6f 6e   quota system on
0210: 20 66 69 6c 65 73 2e 20 20 4f 6e 65 20 6f 72 20   files.  One or 
0220: 6d 6f 72 65 0a 2a 2a 20 64 61 74 61 62 61 73 65  more.** database
0230: 20 66 69 6c 65 73 20 61 72 65 20 69 6e 20 61 20   files are in a 
0240: 22 71 75 6f 74 61 20 67 72 6f 75 70 22 20 74 68  "quota group" th
0250: 61 74 20 69 73 20 64 65 66 69 6e 65 64 20 62 79  at is defined by
0260: 20 61 20 47 4c 4f 42 0a 2a 2a 20 70 61 74 74 65   a GLOB.** patte
0270: 72 6e 2e 20 20 41 20 71 75 6f 74 61 20 69 73 20  rn.  A quota is 
0280: 73 65 74 20 66 6f 72 20 74 68 65 20 63 6f 6d 62  set for the comb
0290: 69 6e 65 64 20 73 69 7a 65 20 6f 66 20 61 6c 6c  ined size of all
02a0: 20 66 69 6c 65 73 20 69 6e 20 74 68 65 0a 2a 2a   files in the.**
02b0: 20 74 68 65 20 67 72 6f 75 70 2e 20 20 41 20 71   the group.  A q
02c0: 75 6f 74 61 20 6f 66 20 7a 65 72 6f 20 6d 65 61  uota of zero mea
02d0: 6e 73 20 22 6e 6f 20 6c 69 6d 69 74 22 2e 20 20  ns "no limit".  
02e0: 49 66 20 74 68 65 20 74 6f 74 61 6c 20 73 69 7a  If the total siz
02f0: 65 0a 2a 2a 20 6f 66 20 61 6c 6c 20 66 69 6c 65  e.** of all file
0300: 73 20 69 6e 20 74 68 65 20 71 75 6f 74 61 20 67  s in the quota g
0310: 72 6f 75 70 20 69 73 20 6d 65 74 20 6f 72 20 65  roup is met or e
0320: 78 63 65 65 64 65 64 2c 20 74 68 65 6e 20 6e 65  xceeded, then ne
0330: 77 0a 2a 2a 20 77 72 69 74 65 20 72 65 71 75 65  w.** write reque
0340: 73 74 73 20 74 68 61 74 20 61 74 74 65 6d 70 74  sts that attempt
0350: 20 74 6f 20 65 6e 6c 61 72 67 65 20 61 20 66 69   to enlarge a fi
0360: 6c 65 20 66 61 69 6c 20 77 69 74 68 20 53 51 4c  le fail with SQL
0370: 49 54 45 5f 46 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20  ITE_FULL..**.** 
0380: 48 6f 77 65 76 65 72 2c 20 62 65 66 6f 72 65 20  However, before 
0390: 72 65 74 75 72 6e 69 6e 67 20 53 51 4c 49 54 45  returning SQLITE
03a0: 5f 46 55 4c 4c 2c 20 74 68 65 20 77 72 69 74 65  _FULL, the write
03b0: 20 72 65 71 75 65 73 74 73 20 69 6e 76 6f 6b 65   requests invoke
03c0: 0a 2a 2a 20 61 20 63 61 6c 6c 62 61 63 6b 20 66  .** a callback f
03d0: 75 6e 63 74 69 6f 6e 20 74 68 61 74 20 69 73 20  unction that is 
03e0: 63 6f 6e 66 69 67 75 72 61 62 6c 65 20 66 6f 72  configurable for
03f0: 20 65 61 63 68 20 71 75 6f 74 61 20 67 72 6f 75   each quota grou
0400: 70 2e 0a 2a 2a 20 54 68 69 73 20 63 61 6c 6c 62  p..** This callb
0410: 61 63 6b 20 68 61 73 20 74 68 65 20 6f 70 70 6f  ack has the oppo
0420: 72 74 75 6e 69 74 79 20 74 6f 20 65 6e 6c 61 72  rtunity to enlar
0430: 67 65 20 74 68 65 20 71 75 6f 74 61 2e 20 20 49  ge the quota.  I
0440: 66 20 74 68 65 0a 2a 2a 20 63 61 6c 6c 62 61 63  f the.** callbac
0450: 6b 20 64 6f 65 73 20 65 6e 6c 61 72 67 65 20 74  k does enlarge t
0460: 68 65 20 71 75 6f 74 61 20 73 75 63 68 20 74 68  he quota such th
0470: 61 74 20 74 68 65 20 74 6f 74 61 6c 20 73 69 7a  at the total siz
0480: 65 20 6f 66 20 61 6c 6c 0a 2a 2a 20 66 69 6c 65  e of all.** file
0490: 73 20 77 69 74 68 69 6e 20 74 68 65 20 67 72 6f  s within the gro
04a0: 75 70 20 69 73 20 6c 65 73 73 20 74 68 61 6e 20  up is less than 
04b0: 74 68 65 20 6e 65 77 20 71 75 6f 74 61 2c 20 74  the new quota, t
04c0: 68 65 6e 20 74 68 65 20 77 72 69 74 65 0a 2a 2a  hen the write.**
04d0: 20 63 6f 6e 74 69 6e 75 65 73 20 61 73 20 69 66   continues as if
04e0: 20 6e 6f 74 68 69 6e 67 20 68 61 64 20 68 61 70   nothing had hap
04f0: 70 65 6e 65 64 2e 0a 2a 2f 0a 23 69 6e 63 6c 75  pened..*/.#inclu
0500: 64 65 20 22 73 71 6c 69 74 65 33 2e 68 22 0a 23  de "sqlite3.h".#
0510: 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e  include <string.
0520: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 61 73 73  h>.#include <ass
0530: 65 72 74 2e 68 3e 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  ert.h>../*******
0540: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0550: 2a 20 4f 62 6a 65 63 74 20 44 65 66 69 6e 69 74  * Object Definit
0560: 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ions ***********
0570: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0580: 2a 2a 2a 2f 0a 0a 2f 2a 20 46 6f 72 77 61 72 64  ***/../* Forward
0590: 20 64 65 63 6c 61 72 61 74 69 6f 6e 20 6f 66 20   declaration of 
05a0: 61 6c 6c 20 6f 62 6a 65 63 74 20 74 79 70 65 73  all object types
05b0: 20 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72 75   */.typedef stru
05c0: 63 74 20 71 75 6f 74 61 47 72 6f 75 70 20 71 75  ct quotaGroup qu
05d0: 6f 74 61 47 72 6f 75 70 3b 0a 74 79 70 65 64 65  otaGroup;.typede
05e0: 66 20 73 74 72 75 63 74 20 71 75 6f 74 61 43 6f  f struct quotaCo
05f0: 6e 6e 20 71 75 6f 74 61 43 6f 6e 6e 3b 0a 74 79  nn quotaConn;.ty
0600: 70 65 64 65 66 20 73 74 72 75 63 74 20 71 75 6f  pedef struct quo
0610: 74 61 46 69 6c 65 20 71 75 6f 74 61 46 69 6c 65  taFile quotaFile
0620: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 22 71 75 6f 74  ;../*.** A "quot
0630: 61 20 67 72 6f 75 70 22 20 69 73 20 61 20 63 6f  a group" is a co
0640: 6c 6c 65 63 74 69 6f 6e 20 6f 66 20 66 69 6c 65  llection of file
0650: 73 20 77 68 6f 73 65 20 63 6f 6c 6c 65 63 74 69  s whose collecti
0660: 76 65 20 73 69 7a 65 20 77 65 20 77 61 6e 74 0a  ve size we want.
0670: 2a 2a 20 74 6f 20 6c 69 6d 69 74 2e 20 20 45 61  ** to limit.  Ea
0680: 63 68 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69  ch quota group i
0690: 73 20 64 65 66 69 6e 65 64 20 62 79 20 61 20 47  s defined by a G
06a0: 4c 4f 42 20 70 61 74 74 65 72 6e 2e 0a 2a 2a 0a  LOB pattern..**.
06b0: 2a 2a 20 54 68 65 72 65 20 69 73 20 61 6e 20 69  ** There is an i
06c0: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66  nstance of the f
06d0: 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20  ollowing object 
06e0: 66 6f 72 20 65 61 63 68 20 64 65 66 69 6e 65 64  for each defined
06f0: 20 71 75 6f 74 61 0a 2a 2a 20 67 72 6f 75 70 2e   quota.** group.
0700: 20 20 54 68 69 73 20 6f 62 6a 65 63 74 20 72 65    This object re
0710: 63 6f 72 64 73 20 74 68 65 20 47 4c 4f 42 20 70  cords the GLOB p
0720: 61 74 74 65 72 6e 20 74 68 61 74 20 64 65 66 69  attern that defi
0730: 6e 65 73 20 77 68 69 63 68 20 66 69 6c 65 73 0a  nes which files.
0740: 2a 2a 20 62 65 6c 6f 6e 67 20 74 6f 20 74 68 65  ** belong to the
0750: 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 20 20 54   quota group.  T
0760: 68 65 20 6f 62 6a 65 63 74 20 61 6c 73 6f 20 72  he object also r
0770: 65 6d 65 6d 62 65 72 73 20 74 68 65 20 73 69 7a  emembers the siz
0780: 65 20 6c 69 6d 69 74 0a 2a 2a 20 66 6f 72 20 74  e limit.** for t
0790: 68 65 20 67 72 6f 75 70 20 28 74 68 65 20 71 75  he group (the qu
07a0: 6f 74 61 29 20 61 6e 64 20 74 68 65 20 63 61 6c  ota) and the cal
07b0: 6c 62 61 63 6b 20 74 6f 20 62 65 20 69 6e 76 6f  lback to be invo
07c0: 6b 65 64 20 77 68 65 6e 20 74 68 65 0a 2a 2a 20  ked when the.** 
07d0: 73 75 6d 20 6f 66 20 74 68 65 20 73 69 7a 65 73  sum of the sizes
07e0: 20 6f 66 20 74 68 65 20 66 69 6c 65 73 20 77 69   of the files wi
07f0: 74 68 69 6e 20 74 68 65 20 67 72 6f 75 70 20 67  thin the group g
0800: 6f 65 73 20 6f 76 65 72 20 74 68 65 20 6c 69 6d  oes over the lim
0810: 69 74 2e 0a 2a 2a 0a 2a 2a 20 41 20 71 75 6f 74  it..**.** A quot
0820: 61 20 67 72 6f 75 70 20 6d 75 73 74 20 62 65 20  a group must be 
0830: 65 73 74 61 62 6c 69 73 68 65 64 20 28 75 73 69  established (usi
0840: 6e 67 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61  ng sqlite3_quota
0850: 5f 73 65 74 28 2e 2e 2e 29 29 0a 2a 2a 20 70 72  _set(...)).** pr
0860: 69 6f 72 20 74 6f 20 6f 70 65 6e 69 6e 67 20 61  ior to opening a
0870: 6e 79 20 6f 66 20 74 68 65 20 64 61 74 61 62 61  ny of the databa
0880: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 74  se connections t
0890: 68 61 74 20 61 63 63 65 73 73 20 66 69 6c 65 73  hat access files
08a0: 0a 2a 2a 20 77 69 74 68 69 6e 20 74 68 65 20 71  .** within the q
08b0: 75 6f 74 61 20 67 72 6f 75 70 2e 0a 2a 2f 0a 73  uota group..*/.s
08c0: 74 72 75 63 74 20 71 75 6f 74 61 47 72 6f 75 70  truct quotaGroup
08d0: 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20   {.  const char 
08e0: 2a 7a 50 61 74 74 65 72 6e 3b 20 20 20 20 20 20  *zPattern;      
08f0: 20 20 20 20 2f 2a 20 46 69 6c 65 6e 61 6d 65 20      /* Filename 
0900: 70 61 74 74 65 72 6e 20 74 6f 20 62 65 20 71 75  pattern to be qu
0910: 6f 74 61 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74  otaed */.  sqlit
0920: 65 33 5f 69 6e 74 36 34 20 69 4c 69 6d 69 74 3b  e3_int64 iLimit;
0930: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 55 70 70            /* Upp
0940: 65 72 20 62 6f 75 6e 64 20 6f 6e 20 74 6f 74 61  er bound on tota
0950: 6c 20 66 69 6c 65 20 73 69 7a 65 20 2a 2f 0a 20  l file size */. 
0960: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
0970: 53 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20  Size;           
0980: 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a 65 20  /* Current size 
0990: 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 2a 2f 0a  of all files */.
09a0: 20 20 76 6f 69 64 20 28 2a 78 43 61 6c 6c 62 61    void (*xCallba
09b0: 63 6b 29 28 20 20 20 20 20 20 20 20 20 20 20 20  ck)(            
09c0: 20 2f 2a 20 43 61 6c 6c 62 61 63 6b 20 69 6e 76   /* Callback inv
09d0: 6f 6b 65 64 20 77 68 65 6e 20 67 6f 69 6e 67 20  oked when going 
09e0: 6f 76 65 72 20 71 75 6f 74 61 20 2a 2f 0a 20 20  over quota */.  
09f0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
0a00: 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20 20 20  Filename,       
0a10: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c    /* Name of fil
0a20: 65 20 77 68 6f 73 65 20 73 69 7a 65 20 69 6e 63  e whose size inc
0a30: 72 65 61 73 65 73 20 2a 2f 0a 20 20 20 20 20 73  reases */.     s
0a40: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 69  qlite3_int64 *pi
0a50: 4c 69 6d 69 74 2c 20 20 20 20 20 20 20 20 2f 2a  Limit,        /*
0a60: 20 49 4e 2f 4f 55 54 3a 20 54 68 65 20 63 75 72   IN/OUT: The cur
0a70: 72 65 6e 74 20 6c 69 6d 69 74 20 2a 2f 0a 20 20  rent limit */.  
0a80: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
0a90: 20 69 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20   iSize,         
0aa0: 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20    /* Total size 
0ab0: 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20  of all files in 
0ac0: 74 68 65 20 67 72 6f 75 70 20 2a 2f 0a 20 20 20  the group */.   
0ad0: 20 20 76 6f 69 64 20 2a 70 41 72 67 20 20 20 20    void *pArg    
0ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0af0: 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61 74 61 20   /* Client data 
0b00: 2a 2f 0a 20 20 29 3b 0a 20 20 76 6f 69 64 20 2a  */.  );.  void *
0b10: 70 41 72 67 3b 20 20 20 20 20 20 20 20 20 20 20  pArg;           
0b20: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 69 72           /* Thir
0b30: 64 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 74 68  d argument to th
0b40: 65 20 78 43 61 6c 6c 62 61 63 6b 28 29 20 2a 2f  e xCallback() */
0b50: 0a 20 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72  .  void (*xDestr
0b60: 6f 79 29 28 76 6f 69 64 2a 29 3b 20 20 20 20 20  oy)(void*);     
0b70: 20 20 2f 2a 20 4f 70 74 69 6f 6e 61 6c 20 64 65    /* Optional de
0b80: 73 74 72 75 63 74 6f 72 20 66 6f 72 20 70 41 72  structor for pAr
0b90: 67 20 2a 2f 0a 20 20 71 75 6f 74 61 47 72 6f 75  g */.  quotaGrou
0ba0: 70 20 2a 70 4e 65 78 74 2c 20 2a 2a 70 70 50 72  p *pNext, **ppPr
0bb0: 65 76 3b 20 20 20 2f 2a 20 44 6f 75 62 6c 79 20  ev;   /* Doubly 
0bc0: 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 61  linked list of a
0bd0: 6c 6c 20 71 75 6f 74 61 20 6f 62 6a 65 63 74 73  ll quota objects
0be0: 20 2a 2f 0a 20 20 71 75 6f 74 61 46 69 6c 65 20   */.  quotaFile 
0bf0: 2a 70 46 69 6c 65 73 3b 20 20 20 20 20 20 20 20  *pFiles;        
0c00: 20 20 20 20 20 2f 2a 20 46 69 6c 65 73 20 77 69       /* Files wi
0c10: 74 68 69 6e 20 74 68 69 73 20 67 72 6f 75 70 20  thin this group 
0c20: 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20  */.};../*.** An 
0c30: 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 69 73  instance of this
0c40: 20 73 74 72 75 63 74 75 72 65 20 72 65 70 72 65   structure repre
0c50: 73 65 6e 74 73 20 61 20 73 69 6e 67 6c 65 20 66  sents a single f
0c60: 69 6c 65 20 74 68 61 74 20 69 73 20 70 61 72 74  ile that is part
0c70: 0a 2a 2a 20 6f 66 20 61 20 71 75 6f 74 61 20 67  .** of a quota g
0c80: 72 6f 75 70 2e 20 20 41 20 73 69 6e 67 6c 65 20  roup.  A single 
0c90: 66 69 6c 65 20 63 61 6e 20 62 65 20 6f 70 65 6e  file can be open
0ca0: 65 64 20 6d 75 6c 74 69 70 6c 65 20 74 69 6d 65  ed multiple time
0cb0: 73 2e 20 20 49 6e 0a 2a 2a 20 6f 72 64 65 72 20  s.  In.** order 
0cc0: 6b 65 65 70 20 6d 75 6c 74 69 70 6c 65 20 6f 70  keep multiple op
0cd0: 65 6e 69 6e 67 73 20 6f 66 20 74 68 65 20 73 61  enings of the sa
0ce0: 6d 65 20 66 69 6c 65 20 66 72 6f 6d 20 63 61 75  me file from cau
0cf0: 73 69 6e 67 20 74 68 65 20 73 69 7a 65 0a 2a 2a  sing the size.**
0d00: 20 6f 66 20 74 68 65 20 66 69 6c 65 20 74 6f 20   of the file to 
0d10: 63 6f 75 6e 74 20 61 67 61 69 6e 73 74 20 74 68  count against th
0d20: 65 20 71 75 6f 74 61 20 6d 75 6c 74 69 70 6c 65  e quota multiple
0d30: 20 74 69 6d 65 73 2c 20 65 61 63 68 20 66 69 6c   times, each fil
0d40: 65 0a 2a 2a 20 68 61 73 20 61 20 75 6e 69 71 75  e.** has a uniqu
0d50: 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  e instance of th
0d60: 69 73 20 6f 62 6a 65 63 74 20 61 6e 64 20 6d 75  is object and mu
0d70: 6c 74 69 70 6c 65 20 6f 70 65 6e 20 63 6f 6e 6e  ltiple open conn
0d80: 65 63 74 69 6f 6e 73 0a 2a 2a 20 74 6f 20 74 68  ections.** to th
0d90: 65 20 73 61 6d 65 20 66 69 6c 65 20 65 61 63 68  e same file each
0da0: 20 70 6f 69 6e 74 20 74 6f 20 61 20 73 69 6e 67   point to a sing
0db0: 6c 65 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  le instance of t
0dc0: 68 69 73 20 6f 62 6a 65 63 74 2e 0a 2a 2f 0a 73  his object..*/.s
0dd0: 74 72 75 63 74 20 71 75 6f 74 61 46 69 6c 65 20  truct quotaFile 
0de0: 7b 0a 20 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e  {.  char *zFilen
0df0: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
0e00: 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74      /* Name of t
0e10: 68 69 73 20 66 69 6c 65 20 2a 2f 0a 20 20 71 75  his file */.  qu
0e20: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
0e30: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ;             /*
0e40: 20 51 75 6f 74 61 20 67 72 6f 75 70 20 74 6f 20   Quota group to 
0e50: 77 68 69 63 68 20 74 68 69 73 20 66 69 6c 65 20  which this file 
0e60: 62 65 6c 6f 6e 67 73 20 2a 2f 0a 20 20 73 71 6c  belongs */.  sql
0e70: 69 74 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65  ite3_int64 iSize
0e80: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
0e90: 43 75 72 72 65 6e 74 20 73 69 7a 65 20 6f 66 20  Current size of 
0ea0: 74 68 69 73 20 66 69 6c 65 20 2a 2f 0a 20 20 69  this file */.  i
0eb0: 6e 74 20 6e 52 65 66 3b 20 20 20 20 20 20 20 20  nt nRef;        
0ec0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
0ed0: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 74 69 6d 65  * Number of time
0ee0: 73 20 74 68 69 73 20 66 69 6c 65 20 69 73 20 6f  s this file is o
0ef0: 70 65 6e 20 2a 2f 0a 20 20 71 75 6f 74 61 46 69  pen */.  quotaFi
0f00: 6c 65 20 2a 70 4e 65 78 74 2c 20 2a 2a 70 70 50  le *pNext, **ppP
0f10: 72 65 76 3b 20 20 20 20 20 2f 2a 20 4c 69 6e 6b  rev;     /* Link
0f20: 65 64 20 6c 69 73 74 20 6f 66 20 66 69 6c 65 73  ed list of files
0f30: 20 69 6e 20 74 68 65 20 73 61 6d 65 20 67 72 6f   in the same gro
0f40: 75 70 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  up */.};../*.** 
0f50: 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  An instance of t
0f60: 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a  he following obj
0f70: 65 63 74 20 72 65 70 72 65 73 65 6e 74 73 20 65  ect represents e
0f80: 61 63 68 20 6f 70 65 6e 20 63 6f 6e 6e 65 63 74  ach open connect
0f90: 69 6f 6e 0a 2a 2a 20 74 6f 20 61 20 66 69 6c 65  ion.** to a file
0fa0: 20 74 68 61 74 20 70 61 72 74 69 63 69 70 61 74   that participat
0fb0: 65 73 20 69 6e 20 71 75 6f 74 61 20 74 72 61 63  es in quota trac
0fc0: 6b 69 6e 67 2e 20 20 54 68 69 73 20 6f 62 6a 65  king.  This obje
0fd0: 63 74 20 69 73 20 61 20 0a 2a 2a 20 73 75 62 63  ct is a .** subc
0fe0: 6c 61 73 73 20 6f 66 20 73 71 6c 69 74 65 33 5f  lass of sqlite3_
0ff0: 66 69 6c 65 2e 20 20 54 68 65 20 73 71 6c 69 74  file.  The sqlit
1000: 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74 20 66  e3_file object f
1010: 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e  or the underlyin
1020: 67 0a 2a 2a 20 56 46 53 20 69 73 20 61 70 70 65  g.** VFS is appe
1030: 6e 64 65 64 20 74 6f 20 74 68 69 73 20 73 74 72  nded to this str
1040: 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 72 75 63  ucture..*/.struc
1050: 74 20 71 75 6f 74 61 43 6f 6e 6e 20 7b 0a 20 20  t quotaConn {.  
1060: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 62 61 73  sqlite3_file bas
1070: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
1080: 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20  /* Base class - 
1090: 6d 75 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f  must be first */
10a0: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46  .  quotaFile *pF
10b0: 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ile;            
10c0: 20 20 20 2f 2a 20 54 68 65 20 75 6e 64 65 72 6c     /* The underl
10d0: 79 69 6e 67 20 66 69 6c 65 20 2a 2f 0a 20 20 2f  ying file */.  /
10e0: 2a 20 54 68 65 20 75 6e 64 65 72 6c 79 69 6e 67  * The underlying
10f0: 20 56 46 53 20 73 71 6c 69 74 65 33 5f 66 69 6c   VFS sqlite3_fil
1100: 65 20 69 73 20 61 70 70 65 6e 64 65 64 20 74 6f  e is appended to
1110: 20 74 68 69 73 20 6f 62 6a 65 63 74 20 2a 2f 0a   this object */.
1120: 7d 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  };../***********
1130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 47  ************** G
1140: 6c 6f 62 61 6c 20 56 61 72 69 61 62 6c 65 73 20  lobal Variables 
1150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1170: 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 41 6c 6c 20 67 6c  **/./*.** All gl
1180: 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 75  obal variables u
1190: 73 65 64 20 62 79 20 74 68 69 73 20 66 69 6c 65  sed by this file
11a0: 20 61 72 65 20 63 6f 6e 74 61 69 6e 69 6e 67 20   are containing 
11b0: 77 69 74 68 69 6e 20 74 68 65 20 66 6f 6c 6c 6f  within the follo
11c0: 77 69 6e 67 0a 2a 2a 20 67 51 75 6f 74 61 20 73  wing.** gQuota s
11d0: 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 61  tructure..*/.sta
11e0: 74 69 63 20 73 74 72 75 63 74 20 7b 0a 20 20 2f  tic struct {.  /
11f0: 2a 20 54 68 65 20 70 4f 72 69 67 56 66 73 20 69  * The pOrigVfs i
1200: 73 20 74 68 65 20 72 65 61 6c 2c 20 6f 72 69 67  s the real, orig
1210: 69 6e 61 6c 20 75 6e 64 65 72 6c 79 69 6e 67 20  inal underlying 
1220: 56 46 53 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69  VFS implementati
1230: 6f 6e 2e 0a 20 20 2a 2a 20 4d 6f 73 74 20 6f 70  on..  ** Most op
1240: 65 72 61 74 69 6f 6e 73 20 70 61 73 73 2d 74 68  erations pass-th
1250: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 72 65 61  rough to the rea
1260: 6c 20 56 46 53 2e 20 20 54 68 69 73 20 76 61 6c  l VFS.  This val
1270: 75 65 20 69 73 20 72 65 61 64 2d 6f 6e 6c 79 0a  ue is read-only.
1280: 20 20 2a 2a 20 64 75 72 69 6e 67 20 6f 70 65 72    ** during oper
1290: 61 74 69 6f 6e 2e 20 20 49 74 20 69 73 20 6f 6e  ation.  It is on
12a0: 6c 79 20 6d 6f 64 69 66 69 65 64 20 61 74 20 73  ly modified at s
12b0: 74 61 72 74 2d 74 69 6d 65 20 61 6e 64 20 74 68  tart-time and th
12c0: 75 73 20 64 6f 65 73 20 6e 6f 74 0a 20 20 2a 2a  us does not.  **
12d0: 20 72 65 71 75 69 72 65 20 61 20 6d 75 74 65 78   require a mutex
12e0: 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ..  */.  sqlite3
12f0: 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73 3b 0a  _vfs *pOrigVfs;.
1300: 0a 20 20 2f 2a 20 54 68 65 20 73 54 68 69 73 56  .  /* The sThisV
1310: 66 73 20 69 73 20 74 68 65 20 56 46 53 20 73 74  fs is the VFS st
1320: 72 75 63 74 75 72 65 20 75 73 65 64 20 62 79 20  ructure used by 
1330: 74 68 69 73 20 73 68 69 6d 2e 20 20 49 74 20 69  this shim.  It i
1340: 73 20 69 6e 69 74 69 61 6c 69 7a 65 64 0a 20 20  s initialized.  
1350: 2a 2a 20 61 74 20 73 74 61 72 74 2d 74 69 6d 65  ** at start-time
1360: 20 61 6e 64 20 74 68 75 73 20 64 6f 65 73 20 6e   and thus does n
1370: 6f 74 20 72 65 71 75 69 72 65 20 61 20 6d 75 74  ot require a mut
1380: 65 78 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ex.  */.  sqlite
1390: 33 5f 76 66 73 20 73 54 68 69 73 56 66 73 3b 0a  3_vfs sThisVfs;.
13a0: 0a 20 20 2f 2a 20 54 68 65 20 73 49 6f 4d 65 74  .  /* The sIoMet
13b0: 68 6f 64 73 20 64 65 66 69 6e 65 73 20 74 68 65  hods defines the
13c0: 20 6d 65 74 68 6f 64 73 20 75 73 65 64 20 62 79   methods used by
13d0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 6f 62   sqlite3_file ob
13e0: 6a 65 63 74 73 20 0a 20 20 2a 2a 20 61 73 73 6f  jects .  ** asso
13f0: 63 69 61 74 65 64 20 77 69 74 68 20 74 68 69 73  ciated with this
1400: 20 73 68 69 6d 2e 20 20 49 74 20 69 73 20 69 6e   shim.  It is in
1410: 69 74 69 61 6c 69 7a 65 64 20 61 74 20 73 74 61  itialized at sta
1420: 72 74 2d 74 69 6d 65 20 61 6e 64 20 64 6f 65 73  rt-time and does
1430: 0a 20 20 2a 2a 20 6e 6f 74 20 72 65 71 75 69 72  .  ** not requir
1440: 65 20 61 20 6d 75 74 65 78 2e 0a 20 20 2a 2a 0a  e a mutex..  **.
1450: 20 20 2a 2a 20 57 68 65 6e 20 74 68 65 20 75 6e    ** When the un
1460: 64 65 72 6c 79 69 6e 67 20 56 46 53 20 69 73 20  derlying VFS is 
1470: 63 61 6c 6c 65 64 20 74 6f 20 6f 70 65 6e 20 61  called to open a
1480: 20 66 69 6c 65 2c 20 69 74 20 6d 69 67 68 74 20   file, it might 
1490: 72 65 74 75 72 6e 20 0a 20 20 2a 2a 20 65 69 74  return .  ** eit
14a0: 68 65 72 20 61 20 76 65 72 73 69 6f 6e 20 31 20  her a version 1 
14b0: 6f 72 20 61 20 76 65 72 73 69 6f 6e 20 32 20 73  or a version 2 s
14c0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 6f 62 6a 65  qlite3_file obje
14d0: 63 74 2e 20 20 54 68 69 73 20 73 68 69 6d 0a 20  ct.  This shim. 
14e0: 20 2a 2a 20 68 61 73 20 74 6f 20 63 72 65 61 74   ** has to creat
14f0: 65 20 61 20 77 72 61 70 70 65 72 20 73 71 6c 69  e a wrapper sqli
1500: 74 65 33 5f 66 69 6c 65 20 6f 66 20 74 68 65 20  te3_file of the 
1510: 73 61 6d 65 20 76 65 72 73 69 6f 6e 2e 20 20 48  same version.  H
1520: 65 6e 63 65 0a 20 20 2a 2a 20 74 68 65 72 65 20  ence.  ** there 
1530: 61 72 65 20 74 77 6f 20 49 2f 4f 20 6d 65 74 68  are two I/O meth
1540: 6f 64 20 73 74 72 75 63 74 75 72 65 73 2c 20 6f  od structures, o
1550: 6e 65 20 66 6f 72 20 76 65 72 73 69 6f 6e 20 31  ne for version 1
1560: 20 61 6e 64 20 74 68 65 20 6f 74 68 65 72 0a 20   and the other. 
1570: 20 2a 2a 20 66 6f 72 20 76 65 72 73 69 6f 6e 20   ** for version 
1580: 32 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65  2..  */.  sqlite
1590: 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20 73 49 6f  3_io_methods sIo
15a0: 4d 65 74 68 6f 64 73 56 31 3b 0a 20 20 73 71 6c  MethodsV1;.  sql
15b0: 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64 73 20  ite3_io_methods 
15c0: 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b 0a 0a 20  sIoMethodsV2;.. 
15d0: 20 2f 2a 20 54 72 75 65 20 77 68 65 6e 20 74 68   /* True when th
15e0: 69 73 20 73 68 69 6d 20 61 73 20 62 65 65 6e 20  is shim as been 
15f0: 69 6e 69 74 69 61 6c 69 7a 65 64 2e 0a 20 20 2a  initialized..  *
1600: 2f 0a 20 20 69 6e 74 20 69 73 49 6e 69 74 69 61  /.  int isInitia
1610: 6c 69 7a 65 64 3b 0a 0a 20 20 2f 2a 20 46 6f 72  lized;..  /* For
1620: 20 72 75 6e 2d 74 69 6d 65 20 61 63 63 65 73 73   run-time access
1630: 20 61 6e 79 20 6f 66 20 74 68 65 20 6f 74 68 65   any of the othe
1640: 72 20 67 6c 6f 62 61 6c 20 64 61 74 61 20 73 74  r global data st
1650: 72 75 63 74 75 72 65 73 20 69 6e 20 74 68 69 73  ructures in this
1660: 0a 20 20 2a 2a 20 73 68 69 6d 2c 20 74 68 65 20  .  ** shim, the 
1670: 66 6f 6c 6c 6f 77 69 6e 67 20 6d 75 74 65 78 20  following mutex 
1680: 6d 75 73 74 20 62 65 20 68 65 6c 64 2e 0a 20 20  must be held..  
1690: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75 74  */.  sqlite3_mut
16a0: 65 78 20 2a 70 4d 75 74 65 78 3b 0a 0a 20 20 2f  ex *pMutex;..  /
16b0: 2a 20 4c 69 73 74 20 6f 66 20 71 75 6f 74 61 47  * List of quotaG
16c0: 72 6f 75 70 20 6f 62 6a 65 63 74 73 2e 0a 20 20  roup objects..  
16d0: 2a 2f 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20  */.  quotaGroup 
16e0: 2a 70 47 72 6f 75 70 3b 0a 0a 7d 20 67 51 75 6f  *pGroup;..} gQuo
16f0: 74 61 3b 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ta;../**********
1700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20  *************** 
1710: 55 74 69 6c 69 74 79 20 52 6f 75 74 69 6e 65 73  Utility Routines
1720: 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a   ***************
1730: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1740: 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 41 63 71 75 69 72  **/./*.** Acquir
1750: 65 20 61 6e 64 20 72 65 6c 65 61 73 65 20 74 68  e and release th
1760: 65 20 6d 75 74 65 78 20 75 73 65 64 20 74 6f 20  e mutex used to 
1770: 73 65 72 69 61 6c 69 7a 65 20 61 63 63 65 73 73  serialize access
1780: 20 74 6f 20 74 68 65 0a 2a 2a 20 6c 69 73 74 20   to the.** list 
1790: 6f 66 20 71 75 6f 74 61 47 72 6f 75 70 73 2e 0a  of quotaGroups..
17a0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71  */.static void q
17b0: 75 6f 74 61 45 6e 74 65 72 28 76 6f 69 64 29 7b  uotaEnter(void){
17c0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65   sqlite3_mutex_e
17d0: 6e 74 65 72 28 67 51 75 6f 74 61 2e 70 4d 75 74  nter(gQuota.pMut
17e0: 65 78 29 3b 20 7d 0a 73 74 61 74 69 63 20 76 6f  ex); }.static vo
17f0: 69 64 20 71 75 6f 74 61 4c 65 61 76 65 28 76 6f  id quotaLeave(vo
1800: 69 64 29 7b 20 73 71 6c 69 74 65 33 5f 6d 75 74  id){ sqlite3_mut
1810: 65 78 5f 6c 65 61 76 65 28 67 51 75 6f 74 61 2e  ex_leave(gQuota.
1820: 70 4d 75 74 65 78 29 3b 20 7d 0a 0a 0a 2f 2a 20  pMutex); }.../* 
1830: 49 66 20 74 68 65 20 72 65 66 65 72 65 6e 63 65  If the reference
1840: 20 63 6f 75 6e 74 20 61 6e 64 20 74 68 72 65 73   count and thres
1850: 68 6f 6c 64 20 66 6f 72 20 61 20 71 75 6f 74 61  hold for a quota
1860: 47 72 6f 75 70 20 61 72 65 20 62 6f 74 68 0a 2a  Group are both.*
1870: 2a 20 7a 65 72 6f 2c 20 74 68 65 6e 20 64 65 73  * zero, then des
1880: 74 72 6f 79 20 74 68 65 20 71 75 6f 74 61 47 72  troy the quotaGr
1890: 6f 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  oup..*/.static v
18a0: 6f 69 64 20 71 75 6f 74 61 47 72 6f 75 70 44 65  oid quotaGroupDe
18b0: 72 65 66 28 71 75 6f 74 61 47 72 6f 75 70 20 2a  ref(quotaGroup *
18c0: 70 47 72 6f 75 70 29 7b 0a 20 20 69 66 28 20 70  pGroup){.  if( p
18d0: 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3d 3d 30  Group->pFiles==0
18e0: 20 26 26 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d   && pGroup->iLim
18f0: 69 74 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  it==0 ){.    if(
1900: 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 20 29   pGroup->pNext )
1910: 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 2d 3e   pGroup->pNext->
1920: 70 70 50 72 65 76 20 3d 20 70 47 72 6f 75 70 2d  ppPrev = pGroup-
1930: 3e 70 70 50 72 65 76 3b 0a 20 20 20 20 69 66 28  >ppPrev;.    if(
1940: 20 70 47 72 6f 75 70 2d 3e 70 70 50 72 65 76 20   pGroup->ppPrev 
1950: 29 20 2a 70 47 72 6f 75 70 2d 3e 70 70 50 72 65  ) *pGroup->ppPre
1960: 76 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78  v = pGroup->pNex
1970: 74 3b 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75  t;.    if( pGrou
1980: 70 2d 3e 78 44 65 73 74 72 6f 79 20 29 20 70 47  p->xDestroy ) pG
1990: 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79 28 70  roup->xDestroy(p
19a0: 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a 20 20  Group->pArg);.  
19b0: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
19c0: 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  Group);.  }.}../
19d0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45  *.** Return TRUE
19e0: 20 69 66 20 73 74 72 69 6e 67 20 7a 20 6d 61 74   if string z mat
19f0: 63 68 65 73 20 67 6c 6f 62 20 70 61 74 74 65 72  ches glob patter
1a00: 6e 20 7a 47 6c 6f 62 2e 0a 2a 2a 0a 2a 2a 20 47  n zGlob..**.** G
1a10: 6c 6f 62 62 69 6e 67 20 72 75 6c 65 73 3a 0a 2a  lobbing rules:.*
1a20: 2a 0a 2a 2a 20 20 20 20 20 20 27 2a 27 20 20 20  *.**      '*'   
1a30: 20 20 20 20 4d 61 74 63 68 65 73 20 61 6e 79 20      Matches any 
1a40: 73 65 71 75 65 6e 63 65 20 6f 66 20 7a 65 72 6f  sequence of zero
1a50: 20 6f 72 20 6d 6f 72 65 20 63 68 61 72 61 63 74   or more charact
1a60: 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  ers..**.**      
1a70: 27 3f 27 20 20 20 20 20 20 20 4d 61 74 63 68 65  '?'       Matche
1a80: 73 20 65 78 61 63 74 6c 79 20 6f 6e 65 20 63 68  s exactly one ch
1a90: 61 72 61 63 74 65 72 2e 0a 2a 2a 0a 2a 2a 20 20  aracter..**.**  
1aa0: 20 20 20 5b 2e 2e 2e 5d 20 20 20 20 20 20 4d 61     [...]      Ma
1ab0: 74 63 68 65 73 20 6f 6e 65 20 63 68 61 72 61 63  tches one charac
1ac0: 74 65 72 20 66 72 6f 6d 20 74 68 65 20 65 6e 63  ter from the enc
1ad0: 6c 6f 73 65 64 20 6c 69 73 74 20 6f 66 0a 2a 2a  losed list of.**
1ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1af0: 63 68 61 72 61 63 74 65 72 73 2e 0a 2a 2a 0a 2a  characters..**.*
1b00: 2a 20 20 20 20 20 5b 5e 2e 2e 2e 5d 20 20 20 20  *     [^...]    
1b10: 20 4d 61 74 63 68 65 73 20 6f 6e 65 20 63 68 61   Matches one cha
1b20: 72 61 63 74 65 72 20 6e 6f 74 20 69 6e 20 74 68  racter not in th
1b30: 65 20 65 6e 63 6c 6f 73 65 64 20 6c 69 73 74 2e  e enclosed list.
1b40: 0a 2a 2a 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  .**.*/.static in
1b50: 74 20 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 63  t quotaStrglob(c
1b60: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 47 6c 6f 62  onst char *zGlob
1b70: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 29  , const char *z)
1b80: 7b 0a 20 20 69 6e 74 20 63 2c 20 63 32 3b 0a 20  {.  int c, c2;. 
1b90: 20 69 6e 74 20 69 6e 76 65 72 74 3b 0a 20 20 69   int invert;.  i
1ba0: 6e 74 20 73 65 65 6e 3b 0a 0a 20 20 77 68 69 6c  nt seen;..  whil
1bb0: 65 28 20 28 63 20 3d 20 28 2a 28 7a 47 6c 6f 62  e( (c = (*(zGlob
1bc0: 2b 2b 29 29 29 21 3d 30 20 29 7b 0a 20 20 20 20  ++)))!=0 ){.    
1bd0: 69 66 28 20 63 3d 3d 27 2a 27 20 29 7b 0a 20 20  if( c=='*' ){.  
1be0: 20 20 20 20 77 68 69 6c 65 28 20 28 63 3d 28 2a      while( (c=(*
1bf0: 28 7a 47 6c 6f 62 2b 2b 29 29 29 20 3d 3d 20 27  (zGlob++))) == '
1c00: 2a 27 20 7c 7c 20 63 3d 3d 27 3f 27 20 29 7b 0a  *' || c=='?' ){.
1c10: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27          if( c=='
1c20: 3f 27 20 26 26 20 28 2a 28 7a 2b 2b 29 29 3d 3d  ?' && (*(z++))==
1c30: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  0 ) return 0;.  
1c40: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
1c50: 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  c==0 ){.        
1c60: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20  return 1;.      
1c70: 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 5b 27  }else if( c=='['
1c80: 20 29 7b 0a 20 20 20 20 20 20 20 20 77 68 69 6c   ){.        whil
1c90: 65 28 20 2a 7a 20 26 26 20 71 75 6f 74 61 53 74  e( *z && quotaSt
1ca0: 72 67 6c 6f 62 28 7a 47 6c 6f 62 2d 31 2c 7a 29  rglob(zGlob-1,z)
1cb0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
1cc0: 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a   z++;.        }.
1cd0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 28          return (
1ce0: 2a 7a 29 21 3d 30 3b 0a 20 20 20 20 20 20 7d 0a  *z)!=0;.      }.
1cf0: 20 20 20 20 20 20 77 68 69 6c 65 28 20 28 63 32        while( (c2
1d00: 20 3d 20 28 2a 28 7a 2b 2b 29 29 29 21 3d 30 20   = (*(z++)))!=0 
1d10: 29 7b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65  ){.        while
1d20: 28 20 63 32 21 3d 63 20 29 7b 0a 20 20 20 20 20  ( c2!=c ){.     
1d30: 20 20 20 20 20 63 32 20 3d 20 2a 28 7a 2b 2b 29       c2 = *(z++)
1d40: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
1d50: 63 32 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  c2==0 ) return 0
1d60: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
1d70: 20 20 20 20 69 66 28 20 71 75 6f 74 61 53 74 72      if( quotaStr
1d80: 67 6c 6f 62 28 7a 47 6c 6f 62 2c 7a 29 20 29 20  glob(zGlob,z) ) 
1d90: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20  return 1;.      
1da0: 7d 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 30  }.      return 0
1db0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
1dc0: 63 3d 3d 27 3f 27 20 29 7b 0a 20 20 20 20 20 20  c=='?' ){.      
1dd0: 69 66 28 20 28 2a 28 7a 2b 2b 29 29 3d 3d 30 20  if( (*(z++))==0 
1de0: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20  ) return 0;.    
1df0: 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 5b 27  }else if( c=='['
1e00: 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 70 72   ){.      int pr
1e10: 69 6f 72 5f 63 20 3d 20 30 3b 0a 20 20 20 20 20  ior_c = 0;.     
1e20: 20 73 65 65 6e 20 3d 20 30 3b 0a 20 20 20 20 20   seen = 0;.     
1e30: 20 69 6e 76 65 72 74 20 3d 20 30 3b 0a 20 20 20   invert = 0;.   
1e40: 20 20 20 63 20 3d 20 2a 28 7a 2b 2b 29 3b 0a 20     c = *(z++);. 
1e50: 20 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29 20       if( c==0 ) 
1e60: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20  return 0;.      
1e70: 63 32 20 3d 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b  c2 = *(zGlob++);
1e80: 0a 20 20 20 20 20 20 69 66 28 20 63 32 3d 3d 27  .      if( c2=='
1e90: 5e 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  ^' ){.        in
1ea0: 76 65 72 74 20 3d 20 31 3b 0a 20 20 20 20 20 20  vert = 1;.      
1eb0: 20 20 63 32 20 3d 20 2a 28 7a 47 6c 6f 62 2b 2b    c2 = *(zGlob++
1ec0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
1ed0: 20 69 66 28 20 63 32 3d 3d 27 5d 27 20 29 7b 0a   if( c2==']' ){.
1ee0: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27          if( c=='
1ef0: 5d 27 20 29 20 73 65 65 6e 20 3d 20 31 3b 0a 20  ]' ) seen = 1;. 
1f00: 20 20 20 20 20 20 20 63 32 20 3d 20 2a 28 7a 47         c2 = *(zG
1f10: 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20 20 7d 0a  lob++);.      }.
1f20: 20 20 20 20 20 20 77 68 69 6c 65 28 20 63 32 20        while( c2 
1f30: 26 26 20 63 32 21 3d 27 5d 27 20 29 7b 0a 20 20  && c2!=']' ){.  
1f40: 20 20 20 20 20 20 69 66 28 20 63 32 3d 3d 27 2d        if( c2=='-
1f50: 27 20 26 26 20 7a 47 6c 6f 62 5b 30 5d 21 3d 27  ' && zGlob[0]!='
1f60: 5d 27 20 26 26 20 7a 47 6c 6f 62 5b 30 5d 21 3d  ]' && zGlob[0]!=
1f70: 30 20 26 26 20 70 72 69 6f 72 5f 63 3e 30 20 29  0 && prior_c>0 )
1f80: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 32 20 3d  {.          c2 =
1f90: 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20   *(zGlob++);.   
1fa0: 20 20 20 20 20 20 20 69 66 28 20 63 3e 3d 70 72         if( c>=pr
1fb0: 69 6f 72 5f 63 20 26 26 20 63 3c 3d 63 32 20 29  ior_c && c<=c2 )
1fc0: 20 73 65 65 6e 20 3d 20 31 3b 0a 20 20 20 20 20   seen = 1;.     
1fd0: 20 20 20 20 20 70 72 69 6f 72 5f 63 20 3d 20 30       prior_c = 0
1fe0: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b  ;.        }else{
1ff0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 63  .          if( c
2000: 3d 3d 63 32 20 29 7b 0a 20 20 20 20 20 20 20 20  ==c2 ){.        
2010: 20 20 20 20 73 65 65 6e 20 3d 20 31 3b 0a 20 20      seen = 1;.  
2020: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
2030: 20 20 20 20 70 72 69 6f 72 5f 63 20 3d 20 63 32      prior_c = c2
2040: 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20  ;.        }.    
2050: 20 20 20 20 63 32 20 3d 20 2a 28 7a 47 6c 6f 62      c2 = *(zGlob
2060: 2b 2b 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ++);.      }.   
2070: 20 20 20 69 66 28 20 63 32 3d 3d 30 20 7c 7c 20     if( c2==0 || 
2080: 28 73 65 65 6e 20 5e 20 69 6e 76 65 72 74 29 3d  (seen ^ invert)=
2090: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  =0 ) return 0;. 
20a0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
20b0: 69 66 28 20 63 21 3d 28 2a 28 7a 2b 2b 29 29 20  if( c!=(*(z++)) 
20c0: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20  ) return 0;.    
20d0: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 2a  }.  }.  return *
20e0: 7a 3d 3d 30 3b 0a 7d 0a 0a 0a 2f 2a 20 46 69 6e  z==0;.}.../* Fin
20f0: 64 20 61 20 71 75 6f 74 61 47 72 6f 75 70 20 67  d a quotaGroup g
2100: 69 76 65 6e 20 74 68 65 20 66 69 6c 65 6e 61 6d  iven the filenam
2110: 65 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  e..**.** Return 
2120: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65  a pointer to the
2130: 20 71 75 6f 74 61 47 72 6f 75 70 20 6f 62 6a 65   quotaGroup obje
2140: 63 74 2e 20 52 65 74 75 72 6e 20 4e 55 4c 4c 20  ct. Return NULL 
2150: 69 66 20 6e 6f 74 20 66 6f 75 6e 64 2e 0a 2a 2f  if not found..*/
2160: 0a 73 74 61 74 69 63 20 71 75 6f 74 61 47 72 6f  .static quotaGro
2170: 75 70 20 2a 71 75 6f 74 61 47 72 6f 75 70 46 69  up *quotaGroupFi
2180: 6e 64 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  nd(const char *z
2190: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 71 75 6f  Filename){.  quo
21a0: 74 61 47 72 6f 75 70 20 2a 70 3b 0a 20 20 66 6f  taGroup *p;.  fo
21b0: 72 28 70 3d 67 51 75 6f 74 61 2e 70 47 72 6f 75  r(p=gQuota.pGrou
21c0: 70 3b 20 70 20 26 26 20 71 75 6f 74 61 53 74 72  p; p && quotaStr
21d0: 67 6c 6f 62 28 70 2d 3e 7a 50 61 74 74 65 72 6e  glob(p->zPattern
21e0: 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3d 3d 30 3b  , zFilename)==0;
21f0: 0a 20 20 20 20 20 20 70 3d 70 2d 3e 70 4e 65 78  .      p=p->pNex
2200: 74 29 7b 7d 0a 20 20 72 65 74 75 72 6e 20 70 3b  t){}.  return p;
2210: 0a 7d 0a 0a 2f 2a 20 54 72 61 6e 73 6c 61 74 65  .}../* Translate
2220: 20 61 6e 20 73 71 6c 69 74 65 33 5f 66 69 6c 65   an sqlite3_file
2230: 2a 20 74 68 61 74 20 69 73 20 72 65 61 6c 6c 79  * that is really
2240: 20 61 20 71 75 6f 74 61 43 6f 6e 6e 2a 20 69 6e   a quotaConn* in
2250: 74 6f 0a 2a 2a 20 74 68 65 20 73 71 6c 69 74 65  to.** the sqlite
2260: 33 5f 66 69 6c 65 2a 20 66 6f 72 20 74 68 65 20  3_file* for the 
2270: 75 6e 64 65 72 6c 79 69 6e 67 20 6f 72 69 67 69  underlying origi
2280: 6e 61 6c 20 56 46 53 2e 0a 2a 2f 0a 73 74 61 74  nal VFS..*/.stat
2290: 69 63 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ic sqlite3_file 
22a0: 2a 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 73 71  *quotaSubOpen(sq
22b0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e  lite3_file *pCon
22c0: 6e 29 7b 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20  n){.  quotaConn 
22d0: 2a 70 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a  *p = (quotaConn*
22e0: 29 70 43 6f 6e 6e 3b 0a 20 20 72 65 74 75 72 6e  )pConn;.  return
22f0: 20 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29   (sqlite3_file*)
2300: 26 70 5b 31 5d 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a  &p[1];.}../*****
2310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2320: 2a 2a 2a 2a 20 56 46 53 20 4d 65 74 68 6f 64 20  **** VFS Method 
2330: 57 72 61 70 70 65 72 73 20 2a 2a 2a 2a 2a 2a 2a  Wrappers *******
2340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2350: 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 54 68  ******/./*.** Th
2360: 69 73 20 69 73 20 74 68 65 20 78 4f 70 65 6e 20  is is the xOpen 
2370: 6d 65 74 68 6f 64 20 75 73 65 64 20 66 6f 72 20  method used for 
2380: 74 68 65 20 22 71 75 6f 74 61 22 20 56 46 53 2e  the "quota" VFS.
2390: 0a 2a 2a 0a 2a 2a 20 4d 6f 73 74 20 6f 66 20 74  .**.** Most of t
23a0: 68 65 20 77 6f 72 6b 20 69 73 20 64 6f 6e 65 20  he work is done 
23b0: 62 79 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e  by the underlyin
23c0: 67 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 20  g original VFS. 
23d0: 20 54 68 69 73 20 6d 65 74 68 6f 64 0a 2a 2a 20   This method.** 
23e0: 73 69 6d 70 6c 79 20 6c 69 6e 6b 73 20 74 68 65  simply links the
23f0: 20 6e 65 77 20 66 69 6c 65 20 69 6e 74 6f 20 74   new file into t
2400: 68 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 71  he appropriate q
2410: 75 6f 74 61 20 67 72 6f 75 70 20 69 66 20 69 74  uota group if it
2420: 20 69 73 20 61 0a 2a 2a 20 66 69 6c 65 20 74 68   is a.** file th
2430: 61 74 20 6e 65 65 64 73 20 74 6f 20 62 65 20 74  at needs to be t
2440: 72 61 63 6b 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  racked..*/.stati
2450: 63 20 69 6e 74 20 71 75 6f 74 61 4f 70 65 6e 28  c int quotaOpen(
2460: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
2470: 70 56 66 73 2c 20 20 20 20 20 20 20 20 20 20 2f  pVfs,          /
2480: 2a 20 54 68 65 20 71 75 6f 74 61 20 56 46 53 20  * The quota VFS 
2490: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
24a0: 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20  *zName,         
24b0: 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c 65   /* Name of file
24c0: 20 74 6f 20 62 65 20 6f 70 65 6e 65 64 20 2a 2f   to be opened */
24d0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
24e0: 2a 70 43 6f 6e 6e 2c 20 20 20 20 20 20 20 20 2f  *pConn,        /
24f0: 2a 20 46 69 6c 6c 20 69 6e 20 74 68 69 73 20 66  * Fill in this f
2500: 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 2a  ile descriptor *
2510: 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c 20 20  /.  int flags,  
2520: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2530: 2f 2a 20 46 6c 61 67 73 20 74 6f 20 63 6f 6e 74  /* Flags to cont
2540: 72 6f 6c 20 74 68 65 20 6f 70 65 6e 69 6e 67 20  rol the opening 
2550: 2a 2f 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c  */.  int *pOutFl
2560: 61 67 73 20 20 20 20 20 20 20 20 20 20 20 20 20  ags             
2570: 20 2f 2a 20 46 6c 61 67 73 20 73 68 6f 77 69 6e   /* Flags showin
2580: 67 20 72 65 73 75 6c 74 73 20 6f 66 20 6f 70 65  g results of ope
2590: 6e 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74  ning */.){.  int
25a0: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
25b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
25c0: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c          /* Resul
25d0: 74 20 63 6f 64 65 20 2a 2f 20 20 20 20 20 20 20  t code */       
25e0: 20 20 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20 2a    .  quotaConn *
25f0: 70 51 75 6f 74 61 4f 70 65 6e 3b 20 20 20 20 20  pQuotaOpen;     
2600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2610: 2f 2a 20 54 68 65 20 6e 65 77 20 71 75 6f 74 61  /* The new quota
2620: 20 66 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72   file descriptor
2630: 20 2a 2f 0a 20 20 71 75 6f 74 61 46 69 6c 65 20   */.  quotaFile 
2640: 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20  *pFile;         
2650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2660: 20 2f 2a 20 43 6f 72 72 65 73 70 6f 6e 64 69 6e   /* Correspondin
2670: 67 20 71 75 6f 74 61 46 69 6c 65 20 6f 62 6a 20  g quotaFile obj 
2680: 2a 2f 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20  */.  quotaGroup 
2690: 2a 70 47 72 6f 75 70 3b 20 20 20 20 20 20 20 20  *pGroup;        
26a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
26b0: 2f 2a 20 54 68 65 20 67 72 6f 75 70 20 66 69 6c  /* The group fil
26c0: 65 20 62 65 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a  e belongs to */.
26d0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
26e0: 70 53 75 62 4f 70 65 6e 3b 20 20 20 20 20 20 20  pSubOpen;       
26f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2700: 52 65 61 6c 20 66 69 6c 65 20 64 65 73 63 72 69  Real file descri
2710: 70 74 6f 72 20 2a 2f 0a 20 20 73 71 6c 69 74 65  ptor */.  sqlite
2720: 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73 20  3_vfs *pOrigVfs 
2730: 3d 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66  = gQuota.pOrigVf
2740: 73 3b 20 20 20 2f 2a 20 52 65 61 6c 20 56 46 53  s;   /* Real VFS
2750: 20 2a 2f 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65   */..  /* If the
2760: 20 66 69 6c 65 20 69 73 20 6e 6f 74 20 61 20 6d   file is not a m
2770: 61 69 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c  ain database fil
2780: 65 20 6f 72 20 61 20 57 41 4c 2c 20 74 68 65 6e  e or a WAL, then
2790: 20 75 73 65 20 74 68 65 0a 20 20 2a 2a 20 6e 6f   use the.  ** no
27a0: 72 6d 61 6c 20 78 4f 70 65 6e 20 6d 65 74 68 6f  rmal xOpen metho
27b0: 64 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 28 66  d..  */.  if( (f
27c0: 6c 61 67 73 20 26 20 28 53 51 4c 49 54 45 5f 4f  lags & (SQLITE_O
27d0: 50 45 4e 5f 4d 41 49 4e 5f 44 42 7c 53 51 4c 49  PEN_MAIN_DB|SQLI
27e0: 54 45 5f 4f 50 45 4e 5f 57 41 4c 29 29 3d 3d 30  TE_OPEN_WAL))==0
27f0: 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 70   ){.    return p
2800: 4f 72 69 67 56 66 73 2d 3e 78 4f 70 65 6e 28 70  OrigVfs->xOpen(p
2810: 4f 72 69 67 56 66 73 2c 20 7a 4e 61 6d 65 2c 20  OrigVfs, zName, 
2820: 70 43 6f 6e 6e 2c 20 66 6c 61 67 73 2c 20 70 4f  pConn, flags, pO
2830: 75 74 46 6c 61 67 73 29 3b 0a 20 20 7d 0a 0a 20  utFlags);.  }.. 
2840: 20 2f 2a 20 49 66 20 74 68 65 20 6e 61 6d 65 20   /* If the name 
2850: 6f 66 20 74 68 65 20 66 69 6c 65 20 64 6f 65 73  of the file does
2860: 20 6e 6f 74 20 6d 61 74 63 68 20 61 6e 79 20 71   not match any q
2870: 75 6f 74 61 20 67 72 6f 75 70 2c 20 74 68 65 6e  uota group, then
2880: 0a 20 20 2a 2a 20 75 73 65 20 74 68 65 20 6e 6f  .  ** use the no
2890: 72 6d 61 6c 20 78 4f 70 65 6e 20 6d 65 74 68 6f  rmal xOpen metho
28a0: 64 2e 0a 20 20 2a 2f 0a 20 20 71 75 6f 74 61 45  d..  */.  quotaE
28b0: 6e 74 65 72 28 29 3b 0a 20 20 70 47 72 6f 75 70  nter();.  pGroup
28c0: 20 3d 20 71 75 6f 74 61 47 72 6f 75 70 46 69 6e   = quotaGroupFin
28d0: 64 28 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20  d(zName);.  if( 
28e0: 70 47 72 6f 75 70 3d 3d 30 20 29 7b 0a 20 20 20  pGroup==0 ){.   
28f0: 20 72 63 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e   rc = pOrigVfs->
2900: 78 4f 70 65 6e 28 70 4f 72 69 67 56 66 73 2c 20  xOpen(pOrigVfs, 
2910: 7a 4e 61 6d 65 2c 20 70 43 6f 6e 6e 2c 20 66 6c  zName, pConn, fl
2920: 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b  ags, pOutFlags);
2930: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 2f 2a  .  }else{.    /*
2940: 20 49 66 20 77 65 20 67 65 74 20 74 6f 20 74 68   If we get to th
2950: 69 73 20 70 6f 69 6e 74 2c 20 69 74 20 6d 65 61  is point, it mea
2960: 6e 73 20 74 68 65 20 66 69 6c 65 20 6e 65 65 64  ns the file need
2970: 73 20 74 6f 20 62 65 20 71 75 6f 74 61 20 74 72  s to be quota tr
2980: 61 63 6b 65 64 2e 0a 20 20 20 20 2a 2f 0a 20 20  acked..    */.  
2990: 20 20 70 51 75 6f 74 61 4f 70 65 6e 20 3d 20 28    pQuotaOpen = (
29a0: 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e  quotaConn*)pConn
29b0: 3b 0a 20 20 20 20 70 53 75 62 4f 70 65 6e 20 3d  ;.    pSubOpen =
29c0: 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43   quotaSubOpen(pC
29d0: 6f 6e 6e 29 3b 0a 20 20 20 20 72 63 20 3d 20 70  onn);.    rc = p
29e0: 4f 72 69 67 56 66 73 2d 3e 78 4f 70 65 6e 28 70  OrigVfs->xOpen(p
29f0: 4f 72 69 67 56 66 73 2c 20 7a 4e 61 6d 65 2c 20  OrigVfs, zName, 
2a00: 70 53 75 62 4f 70 65 6e 2c 20 66 6c 61 67 73 2c  pSubOpen, flags,
2a10: 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 20   pOutFlags);.   
2a20: 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f   if( rc==SQLITE_
2a30: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 66 6f 72 28  OK ){.      for(
2a40: 70 46 69 6c 65 3d 70 47 72 6f 75 70 2d 3e 70 46  pFile=pGroup->pF
2a50: 69 6c 65 73 3b 20 70 46 69 6c 65 20 26 26 20 73  iles; pFile && s
2a60: 74 72 63 6d 70 28 70 46 69 6c 65 2d 3e 7a 46 69  trcmp(pFile->zFi
2a70: 6c 65 6e 61 6d 65 2c 20 7a 4e 61 6d 65 29 3b 0a  lename, zName);.
2a80: 20 20 20 20 20 20 20 20 20 20 70 46 69 6c 65 3d            pFile=
2a90: 70 46 69 6c 65 2d 3e 70 4e 65 78 74 29 7b 7d 0a  pFile->pNext){}.
2aa0: 20 20 20 20 20 20 69 66 28 20 70 46 69 6c 65 3d        if( pFile=
2ab0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 6e  =0 ){.        in
2ac0: 74 20 6e 4e 61 6d 65 20 3d 20 73 74 72 6c 65 6e  t nName = strlen
2ad0: 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 20  (zName);.       
2ae0: 20 70 46 69 6c 65 20 3d 20 73 71 6c 69 74 65 33   pFile = sqlite3
2af0: 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28  _malloc( sizeof(
2b00: 2a 70 46 69 6c 65 29 20 2b 20 6e 4e 61 6d 65 20  *pFile) + nName 
2b10: 2b 20 31 20 29 3b 0a 20 20 20 20 20 20 20 20 69  + 1 );.        i
2b20: 66 28 20 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  f( pFile==0 ){. 
2b30: 20 20 20 20 20 20 20 20 20 71 75 6f 74 61 4c 65           quotaLe
2b40: 61 76 65 28 29 3b 0a 20 20 20 20 20 20 20 20 20  ave();.         
2b50: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
2b60: 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 53 75 62  ods->xClose(pSub
2b70: 4f 70 65 6e 29 3b 0a 20 20 20 20 20 20 20 20 20  Open);.         
2b80: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
2b90: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20 20 7d 0a  OMEM;.        }.
2ba0: 20 20 20 20 20 20 20 20 6d 65 6d 73 65 74 28 70          memset(p
2bb0: 46 69 6c 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28  File, 0, sizeof(
2bc0: 2a 70 46 69 6c 65 29 29 3b 0a 20 20 20 20 20 20  *pFile));.      
2bd0: 20 20 70 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61    pFile->zFilena
2be0: 6d 65 20 3d 20 28 63 68 61 72 2a 29 26 70 46 69  me = (char*)&pFi
2bf0: 6c 65 5b 31 5d 3b 0a 20 20 20 20 20 20 20 20 6d  le[1];.        m
2c00: 65 6d 63 70 79 28 70 46 69 6c 65 2d 3e 7a 46 69  emcpy(pFile->zFi
2c10: 6c 65 6e 61 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e  lename, zName, n
2c20: 4e 61 6d 65 2b 31 29 3b 0a 20 20 20 20 20 20 20  Name+1);.       
2c30: 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 20 3d 20   pFile->pNext = 
2c40: 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3b 0a  pGroup->pFiles;.
2c50: 20 20 20 20 20 20 20 20 69 66 28 20 70 47 72 6f          if( pGro
2c60: 75 70 2d 3e 70 46 69 6c 65 73 20 29 20 70 47 72  up->pFiles ) pGr
2c70: 6f 75 70 2d 3e 70 46 69 6c 65 73 2d 3e 70 70 50  oup->pFiles->ppP
2c80: 72 65 76 20 3d 20 26 70 46 69 6c 65 2d 3e 70 4e  rev = &pFile->pN
2c90: 65 78 74 3b 0a 20 20 20 20 20 20 20 20 70 46 69  ext;.        pFi
2ca0: 6c 65 2d 3e 70 70 50 72 65 76 20 3d 20 26 70 47  le->ppPrev = &pG
2cb0: 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3b 0a 20 20  roup->pFiles;.  
2cc0: 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 46        pGroup->pF
2cd0: 69 6c 65 73 20 3d 20 70 46 69 6c 65 3b 0a 20 20  iles = pFile;.  
2ce0: 20 20 20 20 20 20 70 46 69 6c 65 2d 3e 70 47 72        pFile->pGr
2cf0: 6f 75 70 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20  oup = pGroup;.  
2d00: 20 20 20 20 7d 0a 20 20 20 20 20 20 70 46 69 6c      }.      pFil
2d10: 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20 20  e->nRef++;.     
2d20: 20 70 51 75 6f 74 61 4f 70 65 6e 2d 3e 70 46 69   pQuotaOpen->pFi
2d30: 6c 65 20 3d 20 70 46 69 6c 65 3b 0a 20 20 20 20  le = pFile;.    
2d40: 20 20 69 66 28 20 70 53 75 62 4f 70 65 6e 2d 3e    if( pSubOpen->
2d50: 70 4d 65 74 68 6f 64 73 2d 3e 69 56 65 72 73 69  pMethods->iVersi
2d60: 6f 6e 3d 3d 31 20 29 7b 0a 20 20 20 20 20 20 20  on==1 ){.       
2d70: 20 70 51 75 6f 74 61 4f 70 65 6e 2d 3e 62 61 73   pQuotaOpen->bas
2d80: 65 2e 70 4d 65 74 68 6f 64 73 20 3d 20 26 67 51  e.pMethods = &gQ
2d90: 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56  uota.sIoMethodsV
2da0: 31 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a  1;.      }else{.
2db0: 20 20 20 20 20 20 20 20 70 51 75 6f 74 61 4f 70          pQuotaOp
2dc0: 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f 64  en->base.pMethod
2dd0: 73 20 3d 20 26 67 51 75 6f 74 61 2e 73 49 6f 4d  s = &gQuota.sIoM
2de0: 65 74 68 6f 64 73 56 32 3b 0a 20 20 20 20 20 20  ethodsV2;.      
2df0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 71 75  }.    }.  }.  qu
2e00: 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 72 65  otaLeave();.  re
2e10: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a  turn rc;.}../***
2e20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e30: 2a 2a 2a 2a 2a 20 49 2f 4f 20 4d 65 74 68 6f 64  ***** I/O Method
2e40: 20 57 72 61 70 70 65 72 73 20 2a 2a 2a 2a 2a 2a   Wrappers ******
2e50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
2e60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 78  *********/../* x
2e70: 43 6c 6f 73 65 20 72 65 71 75 65 73 74 73 20 67  Close requests g
2e80: 65 74 20 70 61 73 73 65 64 20 74 68 72 6f 75 67  et passed throug
2e90: 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61  h to the origina
2ea0: 6c 20 56 46 53 2e 20 20 42 75 74 20 77 65 0a 2a  l VFS.  But we.*
2eb0: 2a 20 61 6c 73 6f 20 68 61 76 65 20 74 6f 20 75  * also have to u
2ec0: 6e 6c 69 6e 6b 20 74 68 65 20 71 75 6f 74 61 43  nlink the quotaC
2ed0: 6f 6e 6e 20 66 72 6f 6d 20 74 68 65 20 71 75 6f  onn from the quo
2ee0: 74 61 46 69 6c 65 20 61 6e 64 20 71 75 6f 74 61  taFile and quota
2ef0: 47 72 6f 75 70 2e 0a 2a 2a 20 54 68 65 20 71 75  Group..** The qu
2f00: 6f 74 61 46 69 6c 65 20 61 6e 64 2f 6f 72 20 71  otaFile and/or q
2f10: 75 6f 74 61 47 72 6f 75 70 20 61 72 65 20 66 72  uotaGroup are fr
2f20: 65 65 64 20 69 66 20 74 68 65 79 20 61 72 65 20  eed if they are 
2f30: 6e 6f 20 6c 6f 6e 67 65 72 20 69 6e 20 75 73 65  no longer in use
2f40: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2f50: 71 75 6f 74 61 43 6c 6f 73 65 28 73 71 6c 69 74  quotaClose(sqlit
2f60: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b  e3_file *pConn){
2f70: 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20  .  quotaConn *p 
2f80: 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43  = (quotaConn*)pC
2f90: 6f 6e 6e 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65  onn;.  quotaFile
2fa0: 20 2a 70 46 69 6c 65 20 3d 20 70 2d 3e 70 46 69   *pFile = p->pFi
2fb0: 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  le;.  sqlite3_fi
2fc0: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71  le *pSubOpen = q
2fd0: 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e  uotaSubOpen(pCon
2fe0: 6e 29 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  n);.  int rc;.  
2ff0: 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d 3e 70  rc = pSubOpen->p
3000: 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28  Methods->xClose(
3010: 70 53 75 62 4f 70 65 6e 29 3b 0a 20 20 71 75 6f  pSubOpen);.  quo
3020: 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70 46 69  taEnter();.  pFi
3030: 6c 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20 20 69 66  le->nRef--;.  if
3040: 28 20 70 46 69 6c 65 2d 3e 6e 52 65 66 3d 3d 30  ( pFile->nRef==0
3050: 20 29 7b 0a 20 20 20 20 71 75 6f 74 61 47 72 6f   ){.    quotaGro
3060: 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 46 69  up *pGroup = pFi
3070: 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20  le->pGroup;.    
3080: 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2d 3d  pGroup->iSize -=
3090: 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20   pFile->iSize;. 
30a0: 20 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4e     if( pFile->pN
30b0: 65 78 74 20 29 20 70 46 69 6c 65 2d 3e 70 4e 65  ext ) pFile->pNe
30c0: 78 74 2d 3e 70 70 50 72 65 76 20 3d 20 70 46 69  xt->ppPrev = pFi
30d0: 6c 65 2d 3e 70 70 50 72 65 76 3b 0a 20 20 20 20  le->ppPrev;.    
30e0: 2a 70 46 69 6c 65 2d 3e 70 70 50 72 65 76 20 3d  *pFile->ppPrev =
30f0: 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 3b 0a 20   pFile->pNext;. 
3100: 20 20 20 71 75 6f 74 61 47 72 6f 75 70 44 65 72     quotaGroupDer
3110: 65 66 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20  ef(pGroup);.    
3120: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 46 69  sqlite3_free(pFi
3130: 6c 65 29 3b 0a 20 20 7d 0a 20 20 71 75 6f 74 61  le);.  }.  quota
3140: 4c 65 61 76 65 28 29 3b 0a 20 20 72 65 74 75 72  Leave();.  retur
3150: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  n rc;.}../* Pass
3160: 20 78 52 65 61 64 20 72 65 71 75 65 73 74 73 20   xRead requests 
3170: 64 69 72 65 63 74 6f 72 79 20 74 68 72 75 20 74  directory thru t
3180: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
3190: 46 53 20 77 69 74 68 6f 75 74 0a 2a 2a 20 66 75  FS without.** fu
31a0: 72 74 68 65 72 20 70 72 6f 63 65 73 73 69 6e 67  rther processing
31b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
31c0: 71 75 6f 74 61 52 65 61 64 28 0a 20 20 73 71 6c  quotaRead(.  sql
31d0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e  ite3_file *pConn
31e0: 2c 0a 20 20 76 6f 69 64 20 2a 70 42 75 66 2c 0a  ,.  void *pBuf,.
31f0: 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20 20 73 71    int iAmt,.  sq
3200: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66 73  lite3_int64 iOfs
3210: 74 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  t.){.  sqlite3_f
3220: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
3230: 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f  quotaSubOpen(pCo
3240: 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 53  nn);.  return pS
3250: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
3260: 2d 3e 78 52 65 61 64 28 70 53 75 62 4f 70 65 6e  ->xRead(pSubOpen
3270: 2c 20 70 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f  , pBuf, iAmt, iO
3280: 66 73 74 29 3b 0a 7d 0a 0a 2f 2a 20 43 68 65 63  fst);.}../* Chec
3290: 6b 20 78 57 72 69 74 65 20 72 65 71 75 65 73 74  k xWrite request
32a0: 73 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 79  s to see if they
32b0: 20 65 78 70 61 6e 64 20 74 68 65 20 66 69 6c 65   expand the file
32c0: 2e 20 20 49 66 20 74 68 65 79 20 64 6f 2c 0a 2a  .  If they do,.*
32d0: 2a 20 74 68 65 20 70 65 72 66 6f 72 6d 20 61 20  * the perform a 
32e0: 71 75 6f 74 61 20 63 68 65 63 6b 20 62 65 66 6f  quota check befo
32f0: 72 65 20 70 61 73 73 69 6e 67 20 74 68 65 6d 20  re passing them 
3300: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 0a 2a  through to the.*
3310: 2a 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 0a  * original VFS..
3320: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75  */.static int qu
3330: 6f 74 61 57 72 69 74 65 28 0a 20 20 73 71 6c 69  otaWrite(.  sqli
3340: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
3350: 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 70  .  const void *p
3360: 42 75 66 2c 0a 20 20 69 6e 74 20 69 41 6d 74 2c  Buf,.  int iAmt,
3370: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
3380: 20 69 4f 66 73 74 0a 29 7b 0a 20 20 71 75 6f 74   iOfst.){.  quot
3390: 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f 74  aConn *p = (quot
33a0: 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20  aConn*)pConn;.  
33b0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53  sqlite3_file *pS
33c0: 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75  ubOpen = quotaSu
33d0: 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20  bOpen(pConn);.  
33e0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 45  sqlite3_int64 iE
33f0: 6e 64 20 3d 20 69 4f 66 73 74 2b 69 41 6d 74 3b  nd = iOfst+iAmt;
3400: 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70  .  quotaGroup *p
3410: 47 72 6f 75 70 3b 0a 20 20 71 75 6f 74 61 46 69  Group;.  quotaFi
3420: 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70 2d 3e 70  le *pFile = p->p
3430: 46 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33 5f  File;.  sqlite3_
3440: 69 6e 74 36 34 20 73 7a 4e 65 77 3b 0a 0a 20 20  int64 szNew;..  
3450: 69 66 28 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65  if( pFile->iSize
3460: 3c 69 45 6e 64 20 29 7b 0a 20 20 20 20 70 47 72  <iEnd ){.    pGr
3470: 6f 75 70 20 3d 20 70 46 69 6c 65 2d 3e 70 47 72  oup = pFile->pGr
3480: 6f 75 70 3b 0a 20 20 20 20 71 75 6f 74 61 45 6e  oup;.    quotaEn
3490: 74 65 72 28 29 3b 0a 20 20 20 20 73 7a 4e 65 77  ter();.    szNew
34a0: 20 3d 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65   = pGroup->iSize
34b0: 20 2d 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 20   - pFile->iSize 
34c0: 2b 20 69 45 6e 64 3b 0a 20 20 20 20 69 66 28 20  + iEnd;.    if( 
34d0: 73 7a 4e 65 77 3e 70 47 72 6f 75 70 2d 3e 69 4c  szNew>pGroup->iL
34e0: 69 6d 69 74 20 26 26 20 70 47 72 6f 75 70 2d 3e  imit && pGroup->
34f0: 69 4c 69 6d 69 74 3e 30 20 29 7b 0a 20 20 20 20  iLimit>0 ){.    
3500: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 78 43    if( pGroup->xC
3510: 61 6c 6c 62 61 63 6b 20 29 7b 0a 20 20 20 20 20  allback ){.     
3520: 20 20 20 70 47 72 6f 75 70 2d 3e 78 43 61 6c 6c     pGroup->xCall
3530: 62 61 63 6b 28 70 46 69 6c 65 2d 3e 7a 46 69 6c  back(pFile->zFil
3540: 65 6e 61 6d 65 2c 20 26 70 47 72 6f 75 70 2d 3e  ename, &pGroup->
3550: 69 4c 69 6d 69 74 2c 20 73 7a 4e 65 77 2c 20 0a  iLimit, szNew, .
3560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3570: 20 20 20 20 20 20 20 20 20 20 70 47 72 6f 75 70            pGroup
3580: 2d 3e 70 41 72 67 29 3b 0a 20 20 20 20 20 20 7d  ->pArg);.      }
3590: 0a 20 20 20 20 20 20 69 66 28 20 73 7a 4e 65 77  .      if( szNew
35a0: 3e 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 20  >pGroup->iLimit 
35b0: 26 26 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69  && pGroup->iLimi
35c0: 74 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 71  t>0 ){.        q
35d0: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 20  uotaLeave();.   
35e0: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
35f0: 54 45 5f 46 55 4c 4c 3b 0a 20 20 20 20 20 20 7d  TE_FULL;.      }
3600: 0a 20 20 20 20 7d 0a 20 20 20 20 70 47 72 6f 75  .    }.    pGrou
3610: 70 2d 3e 69 53 69 7a 65 20 3d 20 73 7a 4e 65 77  p->iSize = szNew
3620: 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e 69 53 69  ;.    pFile->iSi
3630: 7a 65 20 3d 20 69 45 6e 64 3b 0a 20 20 20 20 71  ze = iEnd;.    q
3640: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 7d  uotaLeave();.  }
3650: 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70  .  return pSubOp
3660: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57  en->pMethods->xW
3670: 72 69 74 65 28 70 53 75 62 4f 70 65 6e 2c 20 70  rite(pSubOpen, p
3680: 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74  Buf, iAmt, iOfst
3690: 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 54  );.}../* Pass xT
36a0: 72 75 6e 63 61 74 65 20 72 65 71 75 65 73 74 73  runcate requests
36b0: 20 74 68 72 75 20 74 6f 20 74 68 65 20 6f 72 69   thru to the ori
36c0: 67 69 6e 61 6c 20 56 46 53 2e 20 20 49 66 20 74  ginal VFS.  If t
36d0: 68 65 0a 2a 2a 20 73 75 63 63 65 73 73 2c 20 75  he.** success, u
36e0: 70 64 61 74 65 20 74 68 65 20 66 69 6c 65 20 73  pdate the file s
36f0: 69 7a 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ize..*/.static i
3700: 6e 74 20 71 75 6f 74 61 54 72 75 6e 63 61 74 65  nt quotaTruncate
3710: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
3720: 43 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f 69 6e  Conn, sqlite3_in
3730: 74 36 34 20 73 69 7a 65 29 7b 0a 20 20 71 75 6f  t64 size){.  quo
3740: 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f  taConn *p = (quo
3750: 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  taConn*)pConn;. 
3760: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
3770: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
3780: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
3790: 20 69 6e 74 20 72 63 20 3d 20 70 53 75 62 4f 70   int rc = pSubOp
37a0: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 54  en->pMethods->xT
37b0: 72 75 6e 63 61 74 65 28 70 53 75 62 4f 70 65 6e  runcate(pSubOpen
37c0: 2c 20 73 69 7a 65 29 3b 0a 20 20 71 75 6f 74 61  , size);.  quota
37d0: 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70 2d  File *pFile = p-
37e0: 3e 70 46 69 6c 65 3b 0a 20 20 71 75 6f 74 61 47  >pFile;.  quotaG
37f0: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20  roup *pGroup;.  
3800: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
3810: 4b 20 29 7b 0a 20 20 20 20 71 75 6f 74 61 45 6e  K ){.    quotaEn
3820: 74 65 72 28 29 3b 0a 20 20 20 20 70 47 72 6f 75  ter();.    pGrou
3830: 70 20 3d 20 70 46 69 6c 65 2d 3e 70 47 72 6f 75  p = pFile->pGrou
3840: 70 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 69  p;.    pGroup->i
3850: 53 69 7a 65 20 2d 3d 20 70 46 69 6c 65 2d 3e 69  Size -= pFile->i
3860: 53 69 7a 65 3b 0a 20 20 20 20 70 46 69 6c 65 2d  Size;.    pFile-
3870: 3e 69 53 69 7a 65 20 3d 20 73 69 7a 65 3b 0a 20  >iSize = size;. 
3880: 20 20 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65     pGroup->iSize
3890: 20 2b 3d 20 73 69 7a 65 3b 0a 20 20 20 20 71 75   += size;.    qu
38a0: 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 7d 0a  otaLeave();.  }.
38b0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
38c0: 2f 2a 20 50 61 73 73 20 78 53 79 6e 63 20 72 65  /* Pass xSync re
38d0: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
38e0: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
38f0: 46 53 20 77 69 74 68 6f 75 74 20 63 68 61 6e 67  FS without chang
3900: 65 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  e.*/.static int 
3910: 71 75 6f 74 61 53 79 6e 63 28 73 71 6c 69 74 65  quotaSync(sqlite
3920: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
3930: 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20 73 71 6c  nt flags){.  sql
3940: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
3950: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
3960: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74  en(pConn);.  ret
3970: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
3980: 65 74 68 6f 64 73 2d 3e 78 53 79 6e 63 28 70 53  ethods->xSync(pS
3990: 75 62 4f 70 65 6e 2c 20 66 6c 61 67 73 29 3b 0a  ubOpen, flags);.
39a0: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 46 69 6c 65  }../* Pass xFile
39b0: 53 69 7a 65 20 72 65 71 75 65 73 74 73 20 74 68  Size requests th
39c0: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69  rough to the ori
39d0: 67 69 6e 61 6c 20 56 46 53 20 62 75 74 20 74 68  ginal VFS but th
39e0: 65 6e 0a 2a 2a 20 75 70 64 61 74 65 20 74 68 65  en.** update the
39f0: 20 71 75 6f 74 61 47 72 6f 75 70 20 77 69 74 68   quotaGroup with
3a00: 20 74 68 65 20 6e 65 77 20 73 69 7a 65 20 62 65   the new size be
3a10: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
3a20: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75  */.static int qu
3a30: 6f 74 61 46 69 6c 65 53 69 7a 65 28 73 71 6c 69  otaFileSize(sqli
3a40: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
3a50: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a   sqlite3_int64 *
3a60: 70 53 69 7a 65 29 7b 0a 20 20 71 75 6f 74 61 43  pSize){.  quotaC
3a70: 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f 74 61 43  onn *p = (quotaC
3a80: 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 73 71  onn*)pConn;.  sq
3a90: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
3aa0: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
3ab0: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 71 75  pen(pConn);.  qu
3ac0: 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d  otaFile *pFile =
3ad0: 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20 71 75 6f   p->pFile;.  quo
3ae0: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b  taGroup *pGroup;
3af0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
3b00: 20 73 7a 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a   sz;.  int rc;..
3b10: 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d    rc = pSubOpen-
3b20: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65  >pMethods->xFile
3b30: 53 69 7a 65 28 70 53 75 62 4f 70 65 6e 2c 20 26  Size(pSubOpen, &
3b40: 73 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  sz);.  if( rc==S
3b50: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
3b60: 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20  quotaEnter();.  
3b70: 20 20 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65    pGroup = pFile
3b80: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47  ->pGroup;.    pG
3b90: 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2d 3d 20 70  roup->iSize -= p
3ba0: 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20 20  File->iSize;.   
3bb0: 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 20 3d 20   pFile->iSize = 
3bc0: 73 7a 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  sz;.    pGroup->
3bd0: 69 53 69 7a 65 20 2b 3d 20 73 7a 3b 0a 20 20 20  iSize += sz;.   
3be0: 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20   quotaLeave();. 
3bf0: 20 20 20 2a 70 53 69 7a 65 20 3d 20 73 7a 3b 0a     *pSize = sz;.
3c00: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
3c10: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 4c 6f 63  .}../* Pass xLoc
3c20: 6b 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75  k requests throu
3c30: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
3c40: 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64  al VFS unchanged
3c50: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
3c60: 71 75 6f 74 61 4c 6f 63 6b 28 73 71 6c 69 74 65  quotaLock(sqlite
3c70: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
3c80: 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 73 71 6c 69  nt lock){.  sqli
3c90: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
3ca0: 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65  en = quotaSubOpe
3cb0: 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75  n(pConn);.  retu
3cc0: 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65  rn pSubOpen->pMe
3cd0: 74 68 6f 64 73 2d 3e 78 4c 6f 63 6b 28 70 53 75  thods->xLock(pSu
3ce0: 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29 3b 0a 7d 0a  bOpen, lock);.}.
3cf0: 0a 2f 2a 20 50 61 73 73 20 78 55 6e 6c 6f 63 6b  ./* Pass xUnlock
3d00: 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67   requests throug
3d10: 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61  h to the origina
3d20: 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e  l VFS unchanged.
3d30: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71  .*/.static int q
3d40: 75 6f 74 61 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  uotaUnlock(sqlit
3d50: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20  e3_file *pConn, 
3d60: 69 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 73 71 6c  int lock){.  sql
3d70: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
3d80: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
3d90: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74  en(pConn);.  ret
3da0: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
3db0: 65 74 68 6f 64 73 2d 3e 78 55 6e 6c 6f 63 6b 28  ethods->xUnlock(
3dc0: 70 53 75 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29 3b  pSubOpen, lock);
3dd0: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 43 68 65  .}../* Pass xChe
3de0: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 20 72  ckReservedLock r
3df0: 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20  equests through 
3e00: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
3e10: 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a  VFS unchanged..*
3e20: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f  /.static int quo
3e30: 74 61 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c  taCheckReservedL
3e40: 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ock(sqlite3_file
3e50: 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 2a 70 52   *pConn, int *pR
3e60: 65 73 4f 75 74 29 7b 0a 20 20 73 71 6c 69 74 65  esOut){.  sqlite
3e70: 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e  3_file *pSubOpen
3e80: 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28   = quotaSubOpen(
3e90: 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e  pConn);.  return
3ea0: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
3eb0: 6f 64 73 2d 3e 78 43 68 65 63 6b 52 65 73 65 72  ods->xCheckReser
3ec0: 76 65 64 4c 6f 63 6b 28 70 53 75 62 4f 70 65 6e  vedLock(pSubOpen
3ed0: 2c 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f  , pResOut);.}../
3ee0: 2a 20 50 61 73 73 20 78 46 69 6c 65 43 6f 6e 74  * Pass xFileCont
3ef0: 72 6f 6c 20 72 65 71 75 65 73 74 73 20 74 68 72  rol requests thr
3f00: 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67  ough to the orig
3f10: 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67  inal VFS unchang
3f20: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
3f30: 74 20 71 75 6f 74 61 46 69 6c 65 43 6f 6e 74 72  t quotaFileContr
3f40: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ol(sqlite3_file 
3f50: 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 6f 70 2c 20  *pConn, int op, 
3f60: 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20 20 73  void *pArg){.  s
3f70: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
3f80: 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62  bOpen = quotaSub
3f90: 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72  Open(pConn);.  r
3fa0: 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e  eturn pSubOpen->
3fb0: 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 43  pMethods->xFileC
3fc0: 6f 6e 74 72 6f 6c 28 70 53 75 62 4f 70 65 6e 2c  ontrol(pSubOpen,
3fd0: 20 6f 70 2c 20 70 41 72 67 29 3b 0a 7d 0a 0a 2f   op, pArg);.}../
3fe0: 2a 20 50 61 73 73 20 78 53 65 63 74 6f 72 53 69  * Pass xSectorSi
3ff0: 7a 65 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  ze requests thro
4000: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
4010: 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65  nal VFS unchange
4020: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
4030: 20 71 75 6f 74 61 53 65 63 74 6f 72 53 69 7a 65   quotaSectorSize
4040: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
4050: 43 6f 6e 6e 29 7b 0a 20 20 73 71 6c 69 74 65 33  Conn){.  sqlite3
4060: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
4070: 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70  = quotaSubOpen(p
4080: 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20  Conn);.  return 
4090: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
40a0: 64 73 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65 28  ds->xSectorSize(
40b0: 70 53 75 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a  pSubOpen);.}../*
40c0: 20 50 61 73 73 20 78 44 65 76 69 63 65 43 68 61   Pass xDeviceCha
40d0: 72 61 63 74 65 72 69 73 74 69 63 73 20 72 65 71  racteristics req
40e0: 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f  uests through to
40f0: 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46   the original VF
4100: 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a  S unchanged..*/.
4110: 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61  static int quota
4120: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
4130: 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69  stics(sqlite3_fi
4140: 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71  le *pConn){.  sq
4150: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
4160: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
4170: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65  pen(pConn);.  re
4180: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
4190: 4d 65 74 68 6f 64 73 2d 3e 78 44 65 76 69 63 65  Methods->xDevice
41a0: 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28  Characteristics(
41b0: 70 53 75 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a  pSubOpen);.}../*
41c0: 20 50 61 73 73 20 78 53 68 6d 4d 61 70 20 72 65   Pass xShmMap re
41d0: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
41e0: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
41f0: 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f  FS unchanged..*/
4200: 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74  .static int quot
4210: 61 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74  aShmMap(.  sqlit
4220: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20  e3_file *pConn, 
4230: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61             /* Ha
4240: 6e 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74  ndle open on dat
4250: 61 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20  abase file */.  
4260: 69 6e 74 20 69 52 65 67 69 6f 6e 2c 20 20 20 20  int iRegion,    
4270: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4280: 2f 2a 20 52 65 67 69 6f 6e 20 74 6f 20 72 65 74  /* Region to ret
4290: 72 69 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20 73  rieve */.  int s
42a0: 7a 52 65 67 69 6f 6e 2c 20 20 20 20 20 20 20 20  zRegion,        
42b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69             /* Si
42c0: 7a 65 20 6f 66 20 72 65 67 69 6f 6e 73 20 2a 2f  ze of regions */
42d0: 0a 20 20 69 6e 74 20 62 45 78 74 65 6e 64 2c 20  .  int bExtend, 
42e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
42f0: 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 65 78     /* True to ex
4300: 74 65 6e 64 20 66 69 6c 65 20 69 66 20 6e 65 63  tend file if nec
4310: 65 73 73 61 72 79 20 2a 2f 0a 20 20 76 6f 69 64  essary */.  void
4320: 20 76 6f 6c 61 74 69 6c 65 20 2a 2a 70 70 20 20   volatile **pp  
4330: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f              /* O
4340: 55 54 3a 20 4d 61 70 70 65 64 20 6d 65 6d 6f 72  UT: Mapped memor
4350: 79 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65  y */.){.  sqlite
4360: 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e  3_file *pSubOpen
4370: 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28   = quotaSubOpen(
4380: 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e  pConn);.  return
4390: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
43a0: 6f 64 73 2d 3e 78 53 68 6d 4d 61 70 28 70 53 75  ods->xShmMap(pSu
43b0: 62 4f 70 65 6e 2c 20 69 52 65 67 69 6f 6e 2c 20  bOpen, iRegion, 
43c0: 73 7a 52 65 67 69 6f 6e 2c 20 62 45 78 74 65 6e  szRegion, bExten
43d0: 64 2c 20 70 70 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  d, pp);.}../* Pa
43e0: 73 73 20 78 53 68 6d 4c 6f 63 6b 20 72 65 71 75  ss xShmLock requ
43f0: 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20  ests through to 
4400: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  the original VFS
4410: 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73   unchanged..*/.s
4420: 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 53  tatic int quotaS
4430: 68 6d 4c 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65  hmLock(.  sqlite
4440: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20  3_file *pConn,  
4450: 20 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65       /* Database
4460: 20 66 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68   file holding th
4470: 65 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20  e shared memory 
4480: 2a 2f 0a 20 20 69 6e 74 20 6f 66 73 74 2c 20 20  */.  int ofst,  
4490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44a0: 2f 2a 20 46 69 72 73 74 20 6c 6f 63 6b 20 74 6f  /* First lock to
44b0: 20 61 63 71 75 69 72 65 20 6f 72 20 72 65 6c 65   acquire or rele
44c0: 61 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 2c 20  ase */.  int n, 
44d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
44e0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
44f0: 20 6c 6f 63 6b 73 20 74 6f 20 61 63 71 75 69 72   locks to acquir
4500: 65 20 6f 72 20 72 65 6c 65 61 73 65 20 2a 2f 0a  e or release */.
4510: 20 20 69 6e 74 20 66 6c 61 67 73 20 20 20 20 20    int flags     
4520: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4530: 57 68 61 74 20 74 6f 20 64 6f 20 77 69 74 68 20  What to do with 
4540: 74 68 65 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20  the lock */.){. 
4550: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
4560: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
4570: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
4580: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
4590: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d  ->pMethods->xShm
45a0: 4c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6f  Lock(pSubOpen, o
45b0: 66 73 74 2c 20 6e 2c 20 66 6c 61 67 73 29 3b 0a  fst, n, flags);.
45c0: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 42  }../* Pass xShmB
45d0: 61 72 72 69 65 72 20 72 65 71 75 65 73 74 73 20  arrier requests 
45e0: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f  through to the o
45f0: 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68  riginal VFS unch
4600: 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  anged..*/.static
4610: 20 76 6f 69 64 20 71 75 6f 74 61 53 68 6d 42 61   void quotaShmBa
4620: 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69  rrier(sqlite3_fi
4630: 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71  le *pConn){.  sq
4640: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
4650: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
4660: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 70 53  pen(pConn);.  pS
4670: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
4680: 2d 3e 78 53 68 6d 42 61 72 72 69 65 72 28 70 53  ->xShmBarrier(pS
4690: 75 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20 50  ubOpen);.}../* P
46a0: 61 73 73 20 78 53 68 6d 55 6e 6d 61 70 20 72 65  ass xShmUnmap re
46b0: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
46c0: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
46d0: 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f  FS unchanged..*/
46e0: 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74  .static int quot
46f0: 61 53 68 6d 55 6e 6d 61 70 28 73 71 6c 69 74 65  aShmUnmap(sqlite
4700: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
4710: 6e 74 20 64 65 6c 65 74 65 46 6c 61 67 29 7b 0a  nt deleteFlag){.
4720: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
4730: 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61  pSubOpen = quota
4740: 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a  SubOpen(pConn);.
4750: 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65    return pSubOpe
4760: 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68  n->pMethods->xSh
4770: 6d 55 6e 6d 61 70 28 70 53 75 62 4f 70 65 6e 2c  mUnmap(pSubOpen,
4780: 20 64 65 6c 65 74 65 46 6c 61 67 29 3b 0a 7d 0a   deleteFlag);.}.
4790: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
47a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 50 75 62  ************ Pub
47b0: 6c 69 63 20 49 6e 74 65 72 66 61 63 65 73 20 2a  lic Interfaces *
47c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
47d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
47e0: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74  .** Initialize t
47f0: 68 65 20 71 75 6f 74 61 20 56 46 53 20 73 68 69  he quota VFS shi
4800: 6d 2e 20 20 55 73 65 20 74 68 65 20 56 46 53 20  m.  Use the VFS 
4810: 6e 61 6d 65 64 20 7a 4f 72 69 67 56 66 73 4e 61  named zOrigVfsNa
4820: 6d 65 0a 2a 2a 20 61 73 20 74 68 65 20 56 46 53  me.** as the VFS
4830: 20 74 68 61 74 20 64 6f 65 73 20 74 68 65 20 61   that does the a
4840: 63 74 75 61 6c 20 77 6f 72 6b 2e 20 20 55 73 65  ctual work.  Use
4850: 20 74 68 65 20 64 65 66 61 75 6c 74 20 69 66 0a   the default if.
4860: 2a 2a 20 7a 4f 72 69 67 56 66 73 4e 61 6d 65 3d  ** zOrigVfsName=
4870: 3d 4e 55 4c 4c 2e 20 20 0a 2a 2a 0a 2a 2a 20 54  =NULL.  .**.** T
4880: 68 65 20 71 75 6f 74 61 20 56 46 53 20 73 68 69  he quota VFS shi
4890: 6d 20 69 73 20 6e 61 6d 65 64 20 22 71 75 6f 74  m is named "quot
48a0: 61 22 2e 20 20 49 74 20 77 69 6c 6c 20 62 65 63  a".  It will bec
48b0: 6f 6d 65 20 74 68 65 20 64 65 66 61 75 6c 74 0a  ome the default.
48c0: 2a 2a 20 56 46 53 20 69 66 20 6d 61 6b 65 44 65  ** VFS if makeDe
48d0: 66 61 75 6c 74 20 69 73 20 6e 6f 6e 2d 7a 65 72  fault is non-zer
48e0: 6f 2e 0a 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f  o..**.** THIS RO
48f0: 55 54 49 4e 45 20 49 53 20 4e 4f 54 20 54 48 52  UTINE IS NOT THR
4900: 45 41 44 53 41 46 45 2e 20 20 43 61 6c 6c 20 74  EADSAFE.  Call t
4910: 68 69 73 20 72 6f 75 74 69 6e 65 20 65 78 61 63  his routine exac
4920: 74 6c 79 20 6f 6e 63 65 0a 2a 2a 20 64 75 72 69  tly once.** duri
4930: 6e 67 20 73 74 61 72 74 2d 75 70 2e 0a 2a 2f 0a  ng start-up..*/.
4940: 69 6e 74 20 73 71 6c 69 74 65 33 5f 71 75 6f 74  int sqlite3_quot
4950: 61 5f 69 6e 69 74 69 61 6c 69 7a 65 28 63 6f 6e  a_initialize(con
4960: 73 74 20 63 68 61 72 20 2a 7a 4f 72 69 67 56 66  st char *zOrigVf
4970: 73 4e 61 6d 65 2c 20 69 6e 74 20 6d 61 6b 65 44  sName, int makeD
4980: 65 66 61 75 6c 74 29 7b 0a 20 20 73 71 6c 69 74  efault){.  sqlit
4990: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73  e3_vfs *pOrigVfs
49a0: 3b 0a 20 20 69 66 28 20 67 51 75 6f 74 61 2e 69  ;.  if( gQuota.i
49b0: 73 49 6e 69 74 69 61 6c 69 7a 65 64 20 29 20 72  sInitialized ) r
49c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53  eturn SQLITE_MIS
49d0: 55 53 45 3b 0a 20 20 70 4f 72 69 67 56 66 73 20  USE;.  pOrigVfs 
49e0: 3d 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 66 69  = sqlite3_vfs_fi
49f0: 6e 64 28 7a 4f 72 69 67 56 66 73 4e 61 6d 65 29  nd(zOrigVfsName)
4a00: 3b 0a 20 20 69 66 28 20 70 4f 72 69 67 56 66 73  ;.  if( pOrigVfs
4a10: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
4a20: 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 61 73 73  ITE_ERROR;.  ass
4a30: 65 72 74 28 20 70 4f 72 69 67 56 66 73 21 3d 26  ert( pOrigVfs!=&
4a40: 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 20  gQuota.sThisVfs 
4a50: 29 3b 0a 20 20 67 51 75 6f 74 61 2e 70 4d 75 74  );.  gQuota.pMut
4a60: 65 78 20 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74  ex = sqlite3_mut
4a70: 65 78 5f 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f  ex_alloc(SQLITE_
4a80: 4d 55 54 45 58 5f 46 41 53 54 29 3b 0a 20 20 69  MUTEX_FAST);.  i
4a90: 66 28 20 21 67 51 75 6f 74 61 2e 70 4d 75 74 65  f( !gQuota.pMute
4aa0: 78 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  x ){.    return 
4ab0: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
4ac0: 7d 0a 20 20 67 51 75 6f 74 61 2e 69 73 49 6e 69  }.  gQuota.isIni
4ad0: 74 69 61 6c 69 7a 65 64 20 3d 20 31 3b 0a 20 20  tialized = 1;.  
4ae0: 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73 20  gQuota.pOrigVfs 
4af0: 3d 20 70 4f 72 69 67 56 66 73 3b 0a 20 20 67 51  = pOrigVfs;.  gQ
4b00: 75 6f 74 61 2e 73 54 68 69 73 56 66 73 20 3d 20  uota.sThisVfs = 
4b10: 2a 70 4f 72 69 67 56 66 73 3b 0a 20 20 67 51 75  *pOrigVfs;.  gQu
4b20: 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 78 4f 70  ota.sThisVfs.xOp
4b30: 65 6e 20 3d 20 71 75 6f 74 61 4f 70 65 6e 3b 0a  en = quotaOpen;.
4b40: 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66    gQuota.sThisVf
4b50: 73 2e 73 7a 4f 73 46 69 6c 65 20 2b 3d 20 73 69  s.szOsFile += si
4b60: 7a 65 6f 66 28 71 75 6f 74 61 43 6f 6e 6e 29 3b  zeof(quotaConn);
4b70: 0a 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56  .  gQuota.sThisV
4b80: 66 73 2e 7a 4e 61 6d 65 20 3d 20 22 71 75 6f 74  fs.zName = "quot
4b90: 61 22 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f  a";.  gQuota.sIo
4ba0: 4d 65 74 68 6f 64 73 56 31 2e 69 56 65 72 73 69  MethodsV1.iVersi
4bb0: 6f 6e 20 3d 20 31 3b 0a 20 20 67 51 75 6f 74 61  on = 1;.  gQuota
4bc0: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 43  .sIoMethodsV1.xC
4bd0: 6c 6f 73 65 20 3d 20 71 75 6f 74 61 43 6c 6f 73  lose = quotaClos
4be0: 65 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d  e;.  gQuota.sIoM
4bf0: 65 74 68 6f 64 73 56 31 2e 78 52 65 61 64 20 3d  ethodsV1.xRead =
4c00: 20 71 75 6f 74 61 52 65 61 64 3b 0a 20 20 67 51   quotaRead;.  gQ
4c10: 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56  uota.sIoMethodsV
4c20: 31 2e 78 57 72 69 74 65 20 3d 20 71 75 6f 74 61  1.xWrite = quota
4c30: 57 72 69 74 65 3b 0a 20 20 67 51 75 6f 74 61 2e  Write;.  gQuota.
4c40: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 54 72  sIoMethodsV1.xTr
4c50: 75 6e 63 61 74 65 20 3d 20 71 75 6f 74 61 54 72  uncate = quotaTr
4c60: 75 6e 63 61 74 65 3b 0a 20 20 67 51 75 6f 74 61  uncate;.  gQuota
4c70: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 53  .sIoMethodsV1.xS
4c80: 79 6e 63 20 3d 20 71 75 6f 74 61 53 79 6e 63 3b  ync = quotaSync;
4c90: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
4ca0: 68 6f 64 73 56 31 2e 78 46 69 6c 65 53 69 7a 65  hodsV1.xFileSize
4cb0: 20 3d 20 71 75 6f 74 61 46 69 6c 65 53 69 7a 65   = quotaFileSize
4cc0: 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65  ;.  gQuota.sIoMe
4cd0: 74 68 6f 64 73 56 31 2e 78 4c 6f 63 6b 20 3d 20  thodsV1.xLock = 
4ce0: 71 75 6f 74 61 4c 6f 63 6b 3b 0a 20 20 67 51 75  quotaLock;.  gQu
4cf0: 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31  ota.sIoMethodsV1
4d00: 2e 78 55 6e 6c 6f 63 6b 20 3d 20 71 75 6f 74 61  .xUnlock = quota
4d10: 55 6e 6c 6f 63 6b 3b 0a 20 20 67 51 75 6f 74 61  Unlock;.  gQuota
4d20: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 43  .sIoMethodsV1.xC
4d30: 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b  heckReservedLock
4d40: 20 3d 20 71 75 6f 74 61 43 68 65 63 6b 52 65 73   = quotaCheckRes
4d50: 65 72 76 65 64 4c 6f 63 6b 3b 0a 20 20 67 51 75  ervedLock;.  gQu
4d60: 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31  ota.sIoMethodsV1
4d70: 2e 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 20 3d 20  .xFileControl = 
4d80: 71 75 6f 74 61 46 69 6c 65 43 6f 6e 74 72 6f 6c  quotaFileControl
4d90: 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65  ;.  gQuota.sIoMe
4da0: 74 68 6f 64 73 56 31 2e 78 53 65 63 74 6f 72 53  thodsV1.xSectorS
4db0: 69 7a 65 20 3d 20 71 75 6f 74 61 53 65 63 74 6f  ize = quotaSecto
4dc0: 72 53 69 7a 65 3b 0a 20 20 67 51 75 6f 74 61 2e  rSize;.  gQuota.
4dd0: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 44 65  sIoMethodsV1.xDe
4de0: 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74  viceCharacterist
4df0: 69 63 73 20 3d 20 71 75 6f 74 61 44 65 76 69 63  ics = quotaDevic
4e00: 65 43 68 61 72 61 63 74 65 72 69 73 74 69 63 73  eCharacteristics
4e10: 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65  ;.  gQuota.sIoMe
4e20: 74 68 6f 64 73 56 32 20 3d 20 67 51 75 6f 74 61  thodsV2 = gQuota
4e30: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 3b 0a 20  .sIoMethodsV1;. 
4e40: 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f   gQuota.sIoMetho
4e50: 64 73 56 32 2e 69 56 65 72 73 69 6f 6e 20 3d 20  dsV2.iVersion = 
4e60: 32 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d  2;.  gQuota.sIoM
4e70: 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 4d 61 70  ethodsV2.xShmMap
4e80: 20 3d 20 71 75 6f 74 61 53 68 6d 4d 61 70 3b 0a   = quotaShmMap;.
4e90: 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68    gQuota.sIoMeth
4ea0: 6f 64 73 56 32 2e 78 53 68 6d 4c 6f 63 6b 20 3d  odsV2.xShmLock =
4eb0: 20 71 75 6f 74 61 53 68 6d 4c 6f 63 6b 3b 0a 20   quotaShmLock;. 
4ec0: 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f   gQuota.sIoMetho
4ed0: 64 73 56 32 2e 78 53 68 6d 42 61 72 72 69 65 72  dsV2.xShmBarrier
4ee0: 20 3d 20 71 75 6f 74 61 53 68 6d 42 61 72 72 69   = quotaShmBarri
4ef0: 65 72 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f  er;.  gQuota.sIo
4f00: 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 55 6e  MethodsV2.xShmUn
4f10: 6d 61 70 20 3d 20 71 75 6f 74 61 53 68 6d 55 6e  map = quotaShmUn
4f20: 6d 61 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 76  map;.  sqlite3_v
4f30: 66 73 5f 72 65 67 69 73 74 65 72 28 26 67 51 75  fs_register(&gQu
4f40: 6f 74 61 2e 73 54 68 69 73 56 66 73 2c 20 6d 61  ota.sThisVfs, ma
4f50: 6b 65 44 65 66 61 75 6c 74 29 3b 0a 20 20 72 65  keDefault);.  re
4f60: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
4f70: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 68 75 74 64 6f 77  }../*.** Shutdow
4f80: 6e 20 74 68 65 20 71 75 6f 74 61 20 73 79 73 74  n the quota syst
4f90: 65 6d 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 53 51  em..**.** All SQ
4fa0: 4c 69 74 65 20 64 61 74 61 62 61 73 65 20 63 6f  Lite database co
4fb0: 6e 6e 65 63 74 69 6f 6e 73 20 6d 75 73 74 20 62  nnections must b
4fc0: 65 20 63 6c 6f 73 65 64 20 62 65 66 6f 72 65 20  e closed before 
4fd0: 63 61 6c 6c 69 6e 67 20 74 68 69 73 0a 2a 2a 20  calling this.** 
4fe0: 72 6f 75 74 69 6e 65 2e 0a 2a 2a 0a 2a 2a 20 54  routine..**.** T
4ff0: 48 49 53 20 52 4f 55 54 49 4e 45 20 49 53 20 4e  HIS ROUTINE IS N
5000: 4f 54 20 54 48 52 45 41 44 53 41 46 45 2e 20 20  OT THREADSAFE.  
5010: 43 61 6c 6c 20 74 68 69 73 20 72 6f 75 74 69 6e  Call this routin
5020: 65 20 65 78 61 63 74 6c 79 20 6f 6e 65 20 77 68  e exactly one wh
5030: 69 6c 65 0a 2a 2a 20 73 68 75 74 74 69 6e 67 20  ile.** shutting 
5040: 64 6f 77 6e 20 69 6e 20 6f 72 64 65 72 20 74 6f  down in order to
5050: 20 66 72 65 65 20 61 6c 6c 20 72 65 6d 61 69 6e   free all remain
5060: 69 6e 67 20 71 75 6f 74 61 20 67 72 6f 75 70 73  ing quota groups
5070: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
5080: 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28  _quota_shutdown(
5090: 76 6f 69 64 29 7b 0a 20 20 71 75 6f 74 61 47 72  void){.  quotaGr
50a0: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 69  oup *pGroup;.  i
50b0: 66 28 20 67 51 75 6f 74 61 2e 69 73 49 6e 69 74  f( gQuota.isInit
50c0: 69 61 6c 69 7a 65 64 3d 3d 30 20 29 20 72 65 74  ialized==0 ) ret
50d0: 75 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53  urn SQLITE_MISUS
50e0: 45 3b 0a 20 20 66 6f 72 28 70 47 72 6f 75 70 3d  E;.  for(pGroup=
50f0: 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 20 70  gQuota.pGroup; p
5100: 47 72 6f 75 70 3b 20 70 47 72 6f 75 70 3d 70 47  Group; pGroup=pG
5110: 72 6f 75 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20  roup->pNext){.  
5120: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 70 46    if( pGroup->pF
5130: 69 6c 65 73 20 29 20 72 65 74 75 72 6e 20 53 51  iles ) return SQ
5140: 4c 49 54 45 5f 4d 49 53 55 53 45 3b 0a 20 20 7d  LITE_MISUSE;.  }
5150: 0a 20 20 77 68 69 6c 65 28 20 67 51 75 6f 74 61  .  while( gQuota
5160: 2e 70 47 72 6f 75 70 20 29 7b 0a 20 20 20 20 70  .pGroup ){.    p
5170: 47 72 6f 75 70 20 3d 20 67 51 75 6f 74 61 2e 70  Group = gQuota.p
5180: 47 72 6f 75 70 3b 0a 20 20 20 20 67 51 75 6f 74  Group;.    gQuot
5190: 61 2e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75  a.pGroup = pGrou
51a0: 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 73 71  p->pNext;.    sq
51b0: 6c 69 74 65 33 5f 66 72 65 65 28 70 47 72 6f 75  lite3_free(pGrou
51c0: 70 29 3b 0a 20 20 7d 0a 20 20 67 51 75 6f 74 61  p);.  }.  gQuota
51d0: 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 20 3d  .isInitialized =
51e0: 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75   0;.  sqlite3_mu
51f0: 74 65 78 5f 66 72 65 65 28 67 51 75 6f 74 61 2e  tex_free(gQuota.
5200: 70 4d 75 74 65 78 29 3b 0a 20 20 73 71 6c 69 74  pMutex);.  sqlit
5210: 65 33 5f 76 66 73 5f 75 6e 72 65 67 69 73 74 65  e3_vfs_unregiste
5220: 72 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73 56  r(&gQuota.sThisV
5230: 66 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 67  fs);.  memset(&g
5240: 51 75 6f 74 61 2c 20 30 2c 20 73 69 7a 65 6f 66  Quota, 0, sizeof
5250: 28 67 51 75 6f 74 61 29 29 3b 0a 20 20 72 65 74  (gQuota));.  ret
5260: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5270: 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 6f  ../*.** Create o
5280: 72 20 64 65 73 74 72 6f 79 20 61 20 71 75 6f 74  r destroy a quot
5290: 61 20 67 72 6f 75 70 2e 0a 2a 2a 0a 2a 2a 20 54  a group..**.** T
52a0: 68 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69  he quota group i
52b0: 73 20 64 65 66 69 6e 65 64 20 62 79 20 74 68 65  s defined by the
52c0: 20 7a 50 61 74 74 65 72 6e 2e 20 20 57 68 65 6e   zPattern.  When
52d0: 20 63 61 6c 6c 69 6e 67 20 74 68 69 73 20 72 6f   calling this ro
52e0: 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20  utine.** with a 
52f0: 7a 50 61 74 74 65 72 6e 20 66 6f 72 20 61 20 71  zPattern for a q
5300: 75 6f 74 61 20 67 72 6f 75 70 20 74 68 61 74 20  uota group that 
5310: 61 6c 72 65 61 64 79 20 65 78 69 73 74 73 2c 20  already exists, 
5320: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
5330: 6d 65 72 65 6c 79 20 75 70 64 61 74 65 73 20 74  merely updates t
5340: 68 65 20 69 4c 69 6d 69 74 2c 20 78 43 61 6c 6c  he iLimit, xCall
5350: 62 61 63 6b 2c 20 61 6e 64 20 70 41 72 67 20 76  back, and pArg v
5360: 61 6c 75 65 73 20 66 6f 72 20 74 68 61 74 20 71  alues for that q
5370: 75 6f 74 61 0a 2a 2a 20 67 72 6f 75 70 2e 20 20  uota.** group.  
5380: 49 66 20 7a 50 61 74 74 65 72 6e 20 69 73 20 6e  If zPattern is n
5390: 65 77 2c 20 74 68 65 6e 20 61 20 6e 65 77 20 71  ew, then a new q
53a0: 75 6f 74 61 20 67 72 6f 75 70 20 69 73 20 63 72  uota group is cr
53b0: 65 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  eated..**.** If 
53c0: 74 68 65 20 69 4c 69 6d 69 74 20 66 6f 72 20 61  the iLimit for a
53d0: 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69 73 20   quota group is 
53e0: 73 65 74 20 74 6f 20 7a 65 72 6f 2c 20 74 68 65  set to zero, the
53f0: 6e 20 74 68 65 20 71 75 6f 74 61 20 67 72 6f 75  n the quota grou
5400: 70 0a 2a 2a 20 69 73 20 64 69 73 61 62 6c 65 64  p.** is disabled
5410: 20 61 6e 64 20 77 69 6c 6c 20 62 65 20 64 65 6c   and will be del
5420: 65 74 65 64 20 77 68 65 6e 20 74 68 65 20 6c 61  eted when the la
5430: 73 74 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  st database conn
5440: 65 63 74 69 6f 6e 20 75 73 69 6e 67 0a 2a 2a 20  ection using.** 
5450: 74 68 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20  the quota group 
5460: 69 73 20 63 6c 6f 73 65 64 2e 0a 2a 2a 0a 2a 2a  is closed..**.**
5470: 20 43 61 6c 6c 69 6e 67 20 74 68 69 73 20 72 6f   Calling this ro
5480: 75 74 69 6e 65 20 6f 6e 20 61 20 7a 50 61 74 74  utine on a zPatt
5490: 65 72 6e 20 74 68 61 74 20 64 6f 65 73 20 6e 6f  ern that does no
54a0: 74 20 65 78 69 73 74 20 61 6e 64 20 77 69 74 68  t exist and with
54b0: 20 61 0a 2a 2a 20 7a 65 72 6f 20 69 4c 69 6d 69   a.** zero iLimi
54c0: 74 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a  t is a no-op..**
54d0: 0a 2a 2a 20 41 20 71 75 6f 74 61 20 67 72 6f 75  .** A quota grou
54e0: 70 20 6d 75 73 74 20 65 78 69 73 74 20 77 69 74  p must exist wit
54f0: 68 20 61 20 6e 6f 6e 2d 7a 65 72 6f 20 69 4c 69  h a non-zero iLi
5500: 6d 69 74 20 70 72 69 6f 72 20 74 6f 20 6f 70 65  mit prior to ope
5510: 6e 69 6e 67 0a 2a 2a 20 64 61 74 61 62 61 73 65  ning.** database
5520: 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 69 66 20   connections if 
5530: 74 68 6f 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  those connection
5540: 73 20 61 72 65 20 74 6f 20 70 61 72 74 69 63 69  s are to partici
5550: 70 61 74 65 20 69 6e 20 74 68 65 0a 2a 2a 20 71  pate in the.** q
5560: 75 6f 74 61 20 67 72 6f 75 70 2e 20 20 43 72 65  uota group.  Cre
5570: 61 74 69 6e 67 20 61 20 71 75 6f 74 61 20 67 72  ating a quota gr
5580: 6f 75 70 20 64 6f 65 73 20 6e 6f 74 20 61 66 66  oup does not aff
5590: 65 63 74 20 64 61 74 61 62 61 73 65 20 63 6f 6e  ect database con
55a0: 6e 65 63 74 69 6f 6e 73 0a 2a 2a 20 74 68 61 74  nections.** that
55b0: 20 61 72 65 20 61 6c 72 65 61 64 79 20 6f 70 65   are already ope
55c0: 6e 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  n..*/.int sqlite
55d0: 33 5f 71 75 6f 74 61 5f 73 65 74 28 0a 20 20 63  3_quota_set(.  c
55e0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 74  onst char *zPatt
55f0: 65 72 6e 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ern,           /
5600: 2a 20 54 68 65 20 66 69 6c 65 6e 61 6d 65 20 70  * The filename p
5610: 61 74 74 65 72 6e 20 2a 2f 0a 20 20 73 71 6c 69  attern */.  sqli
5620: 74 65 33 5f 69 6e 74 36 34 20 69 4c 69 6d 69 74  te3_int64 iLimit
5630: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ,           /* N
5640: 65 77 20 71 75 6f 74 61 20 74 6f 20 73 65 74 20  ew quota to set 
5650: 66 6f 72 20 74 68 69 73 20 71 75 6f 74 61 20 67  for this quota g
5660: 72 6f 75 70 20 2a 2f 0a 20 20 76 6f 69 64 20 28  roup */.  void (
5670: 2a 78 43 61 6c 6c 62 61 63 6b 29 28 20 20 20 20  *xCallback)(    
5680: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c            /* Cal
5690: 6c 62 61 63 6b 20 69 6e 76 6f 6b 65 64 20 77 68  lback invoked wh
56a0: 65 6e 20 67 6f 69 6e 67 20 6f 76 65 72 20 71 75  en going over qu
56b0: 6f 74 61 20 2a 2f 0a 20 20 20 20 20 63 6f 6e 73  ota */.     cons
56c0: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
56d0: 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  e,         /* Na
56e0: 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f 73 65  me of file whose
56f0: 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65 73 20   size increases 
5700: 2a 2f 0a 20 20 20 20 20 73 71 6c 69 74 65 33 5f  */.     sqlite3_
5710: 69 6e 74 36 34 20 2a 70 69 4c 69 6d 69 74 2c 20  int64 *piLimit, 
5720: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
5730: 3a 20 54 68 65 20 63 75 72 72 65 6e 74 20 6c 69  : The current li
5740: 6d 69 74 20 2a 2f 0a 20 20 20 20 20 73 71 6c 69  mit */.     sqli
5750: 74 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65 2c  te3_int64 iSize,
5760: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
5770: 74 61 6c 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20  tal size of all 
5780: 66 69 6c 65 73 20 69 6e 20 74 68 65 20 67 72 6f  files in the gro
5790: 75 70 20 2a 2f 0a 20 20 20 20 20 76 6f 69 64 20  up */.     void 
57a0: 2a 70 41 72 67 20 20 20 20 20 20 20 20 20 20 20  *pArg           
57b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6c 69            /* Cli
57c0: 65 6e 74 20 64 61 74 61 20 2a 2f 0a 20 20 29 2c  ent data */.  ),
57d0: 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 2c 20 20  .  void *pArg,  
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
57f0: 20 20 20 2f 2a 20 63 6c 69 65 6e 74 20 64 61 74     /* client dat
5800: 61 20 70 61 73 73 65 64 20 74 68 72 75 20 74 6f  a passed thru to
5810: 20 63 61 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 76   callback */.  v
5820: 6f 69 64 20 28 2a 78 44 65 73 74 72 6f 79 29 28  oid (*xDestroy)(
5830: 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20 2f  void*)         /
5840: 2a 20 4f 70 74 69 6f 6e 61 6c 20 64 65 73 74 72  * Optional destr
5850: 75 63 74 6f 72 20 66 6f 72 20 70 41 72 67 20 2a  uctor for pArg *
5860: 2f 0a 29 7b 0a 20 20 71 75 6f 74 61 47 72 6f 75  /.){.  quotaGrou
5870: 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 71 75 6f  p *pGroup;.  quo
5880: 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70 47 72  taEnter();.  pGr
5890: 6f 75 70 20 3d 20 67 51 75 6f 74 61 2e 70 47 72  oup = gQuota.pGr
58a0: 6f 75 70 3b 0a 20 20 77 68 69 6c 65 28 20 70 47  oup;.  while( pG
58b0: 72 6f 75 70 20 26 26 20 73 74 72 63 6d 70 28 70  roup && strcmp(p
58c0: 47 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72 6e 2c  Group->zPattern,
58d0: 20 7a 50 61 74 74 65 72 6e 29 21 3d 30 20 29 7b   zPattern)!=0 ){
58e0: 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20 70 47  .    pGroup = pG
58f0: 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d  roup->pNext;.  }
5900: 0a 20 20 69 66 28 20 70 47 72 6f 75 70 3d 3d 30  .  if( pGroup==0
5910: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 50 61 74   ){.    int nPat
5920: 74 65 72 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 50  tern = strlen(zP
5930: 61 74 74 65 72 6e 29 3b 0a 20 20 20 20 69 66 28  attern);.    if(
5940: 20 69 4c 69 6d 69 74 3c 3d 30 20 29 7b 0a 20 20   iLimit<=0 ){.  
5950: 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29      quotaLeave()
5960: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
5970: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a  QLITE_OK;.    }.
5980: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 73 71 6c      pGroup = sql
5990: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a  ite3_malloc( siz
59a0: 65 6f 66 28 2a 70 47 72 6f 75 70 29 20 2b 20 6e  eof(*pGroup) + n
59b0: 50 61 74 74 65 72 6e 20 2b 20 31 20 29 3b 0a 20  Pattern + 1 );. 
59c0: 20 20 20 69 66 28 20 70 47 72 6f 75 70 3d 3d 30     if( pGroup==0
59d0: 20 29 7b 0a 20 20 20 20 20 20 71 75 6f 74 61 4c   ){.      quotaL
59e0: 65 61 76 65 28 29 3b 0a 20 20 20 20 20 20 72 65  eave();.      re
59f0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
5a00: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  M;.    }.    mem
5a10: 73 65 74 28 70 47 72 6f 75 70 2c 20 30 2c 20 73  set(pGroup, 0, s
5a20: 69 7a 65 6f 66 28 2a 70 47 72 6f 75 70 29 29 3b  izeof(*pGroup));
5a30: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 7a 50 61  .    pGroup->zPa
5a40: 74 74 65 72 6e 20 3d 20 28 63 68 61 72 2a 29 26  ttern = (char*)&
5a50: 70 47 72 6f 75 70 5b 31 5d 3b 0a 20 20 20 20 6d  pGroup[1];.    m
5a60: 65 6d 63 70 79 28 28 63 68 61 72 20 2a 29 70 47  emcpy((char *)pG
5a70: 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72 6e 2c 20  roup->zPattern, 
5a80: 7a 50 61 74 74 65 72 6e 2c 20 6e 50 61 74 74 65  zPattern, nPatte
5a90: 72 6e 2b 31 29 3b 0a 20 20 20 20 69 66 28 20 67  rn+1);.    if( g
5aa0: 51 75 6f 74 61 2e 70 47 72 6f 75 70 20 29 20 67  Quota.pGroup ) g
5ab0: 51 75 6f 74 61 2e 70 47 72 6f 75 70 2d 3e 70 70  Quota.pGroup->pp
5ac0: 50 72 65 76 20 3d 20 26 70 47 72 6f 75 70 2d 3e  Prev = &pGroup->
5ad0: 70 4e 65 78 74 3b 0a 20 20 20 20 70 47 72 6f 75  pNext;.    pGrou
5ae0: 70 2d 3e 70 4e 65 78 74 20 3d 20 67 51 75 6f 74  p->pNext = gQuot
5af0: 61 2e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47  a.pGroup;.    pG
5b00: 72 6f 75 70 2d 3e 70 70 50 72 65 76 20 3d 20 26  roup->ppPrev = &
5b10: 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20  gQuota.pGroup;. 
5b20: 20 20 20 67 51 75 6f 74 61 2e 70 47 72 6f 75 70     gQuota.pGroup
5b30: 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20 7d 0a 20   = pGroup;.  }. 
5b40: 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 20   pGroup->iLimit 
5b50: 3d 20 69 4c 69 6d 69 74 3b 0a 20 20 70 47 72 6f  = iLimit;.  pGro
5b60: 75 70 2d 3e 78 43 61 6c 6c 62 61 63 6b 20 3d 20  up->xCallback = 
5b70: 78 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 69 66 28  xCallback;.  if(
5b80: 20 70 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f   pGroup->xDestro
5b90: 79 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 41 72  y && pGroup->pAr
5ba0: 67 21 3d 70 41 72 67 20 29 7b 0a 20 20 20 20 70  g!=pArg ){.    p
5bb0: 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79 28  Group->xDestroy(
5bc0: 70 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a 20  pGroup->pArg);. 
5bd0: 20 7d 0a 20 20 70 47 72 6f 75 70 2d 3e 70 41 72   }.  pGroup->pAr
5be0: 67 20 3d 20 70 41 72 67 3b 0a 20 20 70 47 72 6f  g = pArg;.  pGro
5bf0: 75 70 2d 3e 78 44 65 73 74 72 6f 79 20 3d 20 78  up->xDestroy = x
5c00: 44 65 73 74 72 6f 79 3b 0a 20 20 71 75 6f 74 61  Destroy;.  quota
5c10: 47 72 6f 75 70 44 65 72 65 66 28 70 47 72 6f 75  GroupDeref(pGrou
5c20: 70 29 3b 0a 20 20 71 75 6f 74 61 4c 65 61 76 65  p);.  quotaLeave
5c30: 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  ();.  return SQL
5c40: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 20 20 0a 2f 2a  ITE_OK;.}..  ./*
5c50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5c60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 54 65 73  ************ Tes
5c70: 74 20 43 6f 64 65 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  t Code *********
5c80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5c90: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 69 66 64  **********/.#ifd
5ca0: 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 23  ef SQLITE_TEST.#
5cb0: 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a  include <tcl.h>.
5cc0: 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20  ./*.** Argument 
5cd0: 70 61 73 73 65 64 20 74 6f 20 61 20 54 43 4c 20  passed to a TCL 
5ce0: 71 75 6f 74 61 2d 6f 76 65 72 2d 6c 69 6d 69 74  quota-over-limit
5cf0: 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a 74 79   callback..*/.ty
5d00: 70 65 64 65 66 20 73 74 72 75 63 74 20 54 63 6c  pedef struct Tcl
5d10: 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 54 63  QuotaCallback Tc
5d20: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 3b 0a  lQuotaCallback;.
5d30: 73 74 72 75 63 74 20 54 63 6c 51 75 6f 74 61 43  struct TclQuotaC
5d40: 61 6c 6c 62 61 63 6b 20 7b 0a 20 20 54 63 6c 5f  allback {.  Tcl_
5d50: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 20  Interp *interp; 
5d60: 20 20 20 2f 2a 20 49 6e 74 65 72 70 72 65 74 65     /* Interprete
5d70: 72 20 69 6e 20 77 68 69 63 68 20 74 6f 20 72 75  r in which to ru
5d80: 6e 20 74 68 65 20 73 63 72 69 70 74 20 2a 2f 0a  n the script */.
5d90: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72 69    Tcl_Obj *pScri
5da0: 70 74 3b 20 20 20 20 20 20 2f 2a 20 53 63 72 69  pt;      /* Scri
5db0: 70 74 20 74 6f 20 62 65 20 72 75 6e 20 2a 2f 0a  pt to be run */.
5dc0: 7d 3b 0a 0a 65 78 74 65 72 6e 20 63 6f 6e 73 74  };..extern const
5dd0: 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33 54 65   char *sqlite3Te
5de0: 73 74 45 72 72 6f 72 4e 61 6d 65 28 69 6e 74 29  stErrorName(int)
5df0: 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  ;.../*.** This i
5e00: 73 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66  s the callback f
5e10: 72 6f 6d 20 61 20 71 75 6f 74 61 2d 6f 76 65 72  rom a quota-over
5e20: 2d 6c 69 6d 69 74 2e 0a 2a 2f 0a 73 74 61 74 69  -limit..*/.stati
5e30: 63 20 76 6f 69 64 20 74 63 6c 51 75 6f 74 61 43  c void tclQuotaC
5e40: 61 6c 6c 62 61 63 6b 28 0a 20 20 63 6f 6e 73 74  allback(.  const
5e50: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
5e60: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  ,          /* Na
5e70: 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f 73 65  me of file whose
5e80: 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65 73 20   size increases 
5e90: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
5ea0: 36 34 20 2a 70 69 4c 69 6d 69 74 2c 20 20 20 20  64 *piLimit,    
5eb0: 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
5ec0: 54 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6d 69  The current limi
5ed0: 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  t */.  sqlite3_i
5ee0: 6e 74 36 34 20 69 53 69 7a 65 2c 20 20 20 20 20  nt64 iSize,     
5ef0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20         /* Total 
5f00: 73 69 7a 65 20 6f 66 20 61 6c 6c 20 66 69 6c 65  size of all file
5f10: 73 20 69 6e 20 74 68 65 20 67 72 6f 75 70 20 2a  s in the group *
5f20: 2f 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 20 20  /.  void *pArg  
5f30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5f40: 20 20 20 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61      /* Client da
5f50: 74 61 20 2a 2f 0a 29 7b 0a 20 20 54 63 6c 51 75  ta */.){.  TclQu
5f60: 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70 3b 20  otaCallback *p; 
5f70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
5f80: 6c 6c 62 61 63 6b 20 73 63 72 69 70 74 20 6f 62  llback script ob
5f90: 6a 65 63 74 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  ject */.  Tcl_Ob
5fa0: 6a 20 2a 70 45 76 61 6c 3b 20 20 20 20 20 20 20  j *pEval;       
5fb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 63 72            /* Scr
5fc0: 69 70 74 20 74 6f 20 65 76 61 6c 75 61 74 65 20  ipt to evaluate 
5fd0: 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 56  */.  Tcl_Obj *pV
5fe0: 61 72 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  arname;         
5ff0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
6000: 76 61 72 69 61 62 6c 65 20 74 6f 20 70 61 73 73  variable to pass
6010: 20 61 73 20 32 6e 64 20 61 72 67 20 2a 2f 0a 20   as 2nd arg */. 
6020: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 6e   unsigned int rn
6030: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
6040: 20 2f 2a 20 52 61 6e 64 6f 6d 20 70 61 72 74 20   /* Random part 
6050: 6f 66 20 70 56 61 72 6e 61 6d 65 20 2a 2f 0a 20  of pVarname */. 
6060: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
6070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6080: 20 2f 2a 20 54 63 6c 20 65 72 72 6f 72 20 63 6f   /* Tcl error co
6090: 64 65 20 2a 2f 0a 0a 20 20 70 20 3d 20 28 54 63  de */..  p = (Tc
60a0: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a  lQuotaCallback *
60b0: 29 70 41 72 67 3b 0a 0a 20 20 70 56 61 72 6e 61  )pArg;..  pVarna
60c0: 6d 65 20 3d 20 54 63 6c 5f 4e 65 77 53 74 72 69  me = Tcl_NewStri
60d0: 6e 67 4f 62 6a 28 22 3a 3a 70 69 4c 69 6d 69 74  ngObj("::piLimit
60e0: 5f 22 2c 20 2d 31 29 3b 0a 20 20 54 63 6c 5f 49  _", -1);.  Tcl_I
60f0: 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 56 61 72  ncrRefCount(pVar
6100: 6e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74 65 33  name);.  sqlite3
6110: 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 73 69 7a 65  _randomness(size
6120: 6f 66 28 72 6e 64 29 2c 20 28 76 6f 69 64 20 2a  of(rnd), (void *
6130: 29 26 72 6e 64 29 3b 0a 20 20 54 63 6c 5f 41 70  )&rnd);.  Tcl_Ap
6140: 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28 70 56 61  pendObjToObj(pVa
6150: 72 6e 61 6d 65 2c 20 54 63 6c 5f 4e 65 77 49 6e  rname, Tcl_NewIn
6160: 74 4f 62 6a 28 28 69 6e 74 29 28 72 6e 64 26 30  tObj((int)(rnd&0
6170: 78 37 46 46 46 46 46 46 46 29 29 29 3b 0a 20 20  x7FFFFFFF)));.  
6180: 54 63 6c 5f 4f 62 6a 53 65 74 56 61 72 32 28 70  Tcl_ObjSetVar2(p
6190: 2d 3e 69 6e 74 65 72 70 2c 20 70 56 61 72 6e 61  ->interp, pVarna
61a0: 6d 65 2c 20 30 2c 20 54 63 6c 5f 4e 65 77 57 69  me, 0, Tcl_NewWi
61b0: 64 65 49 6e 74 4f 62 6a 28 2a 70 69 4c 69 6d 69  deIntObj(*piLimi
61c0: 74 29 2c 20 30 29 3b 0a 0a 20 20 70 45 76 61 6c  t), 0);..  pEval
61d0: 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61 74 65   = Tcl_Duplicate
61e0: 4f 62 6a 28 70 2d 3e 70 53 63 72 69 70 74 29 3b  Obj(p->pScript);
61f0: 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f  .  Tcl_IncrRefCo
6200: 75 6e 74 28 70 45 76 61 6c 29 3b 0a 20 20 54 63  unt(pEval);.  Tc
6210: 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45  l_ListObjAppendE
6220: 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c  lement(0, pEval,
6230: 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62   Tcl_NewStringOb
6240: 6a 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d 31 29  j(zFilename, -1)
6250: 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  );.  Tcl_ListObj
6260: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
6270: 20 70 45 76 61 6c 2c 20 70 56 61 72 6e 61 6d 65   pEval, pVarname
6280: 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  );.  Tcl_ListObj
6290: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
62a0: 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77 57   pEval, Tcl_NewW
62b0: 69 64 65 49 6e 74 4f 62 6a 28 69 53 69 7a 65 29  ideIntObj(iSize)
62c0: 29 3b 0a 20 20 72 63 20 3d 20 54 63 6c 5f 45 76  );.  rc = Tcl_Ev
62d0: 61 6c 4f 62 6a 45 78 28 70 2d 3e 69 6e 74 65 72  alObjEx(p->inter
62e0: 70 2c 20 70 45 76 61 6c 2c 20 54 43 4c 5f 45 56  p, pEval, TCL_EV
62f0: 41 4c 5f 47 4c 4f 42 41 4c 29 3b 0a 0a 20 20 69  AL_GLOBAL);..  i
6300: 66 28 20 72 63 3d 3d 54 43 4c 5f 4f 4b 20 29 7b  f( rc==TCL_OK ){
6310: 0a 20 20 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 4c  .    Tcl_Obj *pL
6320: 69 6d 69 74 20 3d 20 54 63 6c 5f 4f 62 6a 47 65  imit = Tcl_ObjGe
6330: 74 56 61 72 32 28 70 2d 3e 69 6e 74 65 72 70 2c  tVar2(p->interp,
6340: 20 70 56 61 72 6e 61 6d 65 2c 20 30 2c 20 30 29   pVarname, 0, 0)
6350: 3b 0a 20 20 20 20 72 63 20 3d 20 54 63 6c 5f 47  ;.    rc = Tcl_G
6360: 65 74 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a  etWideIntFromObj
6370: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 4c 69 6d  (p->interp, pLim
6380: 69 74 2c 20 70 69 4c 69 6d 69 74 29 3b 0a 20 20  it, piLimit);.  
6390: 20 20 54 63 6c 5f 55 6e 73 65 74 56 61 72 28 70    Tcl_UnsetVar(p
63a0: 2d 3e 69 6e 74 65 72 70 2c 20 54 63 6c 5f 47 65  ->interp, Tcl_Ge
63b0: 74 53 74 72 69 6e 67 28 70 56 61 72 6e 61 6d 65  tString(pVarname
63c0: 29 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 54 63  ), 0);.  }..  Tc
63d0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
63e0: 45 76 61 6c 29 3b 0a 20 20 54 63 6c 5f 44 65 63  Eval);.  Tcl_Dec
63f0: 72 52 65 66 43 6f 75 6e 74 28 70 56 61 72 6e 61  rRefCount(pVarna
6400: 6d 65 29 3b 0a 20 20 69 66 28 20 72 63 21 3d 54  me);.  if( rc!=T
6410: 43 4c 5f 4f 4b 20 29 20 54 63 6c 5f 42 61 63 6b  CL_OK ) Tcl_Back
6420: 67 72 6f 75 6e 64 45 72 72 6f 72 28 70 2d 3e 69  groundError(p->i
6430: 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  nterp);.}../*.**
6440: 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20   Destructor for 
6450: 61 20 54 43 4c 20 71 75 6f 74 61 2d 6f 76 65 72  a TCL quota-over
6460: 2d 6c 69 6d 69 74 20 63 61 6c 6c 62 61 63 6b 2e  -limit callback.
6470: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
6480: 74 63 6c 43 61 6c 6c 62 61 63 6b 44 65 73 74 72  tclCallbackDestr
6490: 75 63 74 6f 72 28 76 6f 69 64 20 2a 70 4f 62 6a  uctor(void *pObj
64a0: 29 7b 0a 20 20 54 63 6c 51 75 6f 74 61 43 61 6c  ){.  TclQuotaCal
64b0: 6c 62 61 63 6b 20 2a 70 20 3d 20 28 54 63 6c 51  lback *p = (TclQ
64c0: 75 6f 74 61 43 61 6c 6c 62 61 63 6b 2a 29 70 4f  uotaCallback*)pO
64d0: 62 6a 3b 0a 20 20 69 66 28 20 70 20 29 7b 0a 20  bj;.  if( p ){. 
64e0: 20 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f     Tcl_DecrRefCo
64f0: 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74 29 3b  unt(p->pScript);
6500: 0a 20 20 20 20 63 6b 66 72 65 65 28 28 63 68 61  .    ckfree((cha
6510: 72 20 2a 29 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  r *)p);.  }.}../
6520: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
6530: 69 74 65 33 5f 71 75 6f 74 61 5f 69 6e 69 74 69  ite3_quota_initi
6540: 61 6c 69 7a 65 20 4e 41 4d 45 20 4d 41 4b 45 44  alize NAME MAKED
6550: 45 46 41 55 4c 54 0a 2a 2f 0a 73 74 61 74 69 63  EFAULT.*/.static
6560: 20 69 6e 74 20 74 65 73 74 5f 71 75 6f 74 61 5f   int test_quota_
6570: 69 6e 69 74 69 61 6c 69 7a 65 28 0a 20 20 76 6f  initialize(.  vo
6580: 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c  id * clientData,
6590: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
65a0: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
65b0: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
65c0: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
65d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
65e0: 65 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  e;              
65f0: 2f 2a 20 4e 61 6d 65 20 6f 66 20 6e 65 77 20 71  /* Name of new q
6600: 75 6f 74 61 20 56 46 53 20 2a 2f 0a 20 20 69 6e  uota VFS */.  in
6610: 74 20 6d 61 6b 65 44 65 66 61 75 6c 74 3b 20 20  t makeDefault;  
6620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
6630: 20 54 72 75 65 20 74 6f 20 6d 61 6b 65 20 74 68   True to make th
6640: 65 20 6e 65 77 20 56 46 53 20 74 68 65 20 64 65  e new VFS the de
6650: 66 61 75 6c 74 20 2a 2f 0a 20 20 69 6e 74 20 72  fault */.  int r
6660: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
6670: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
6680: 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  lue returned by 
6690: 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65  quota_initialize
66a0: 28 29 20 2a 2f 0a 0a 20 20 2f 2a 20 50 72 6f 63  () */..  /* Proc
66b0: 65 73 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ess arguments */
66c0: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20 29  .  if( objc!=3 )
66d0: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
66e0: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
66f0: 2c 20 6f 62 6a 76 2c 20 22 4e 41 4d 45 20 4d 41  , objv, "NAME MA
6700: 4b 45 44 45 46 41 55 4c 54 22 29 3b 0a 20 20 20  KEDEFAULT");.   
6710: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
6720: 52 3b 0a 20 20 7d 0a 20 20 7a 4e 61 6d 65 20 3d  R;.  }.  zName =
6730: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
6740: 62 6a 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 54  bjv[1]);.  if( T
6750: 63 6c 5f 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f  cl_GetBooleanFro
6760: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
6770: 76 5b 32 5d 2c 20 26 6d 61 6b 65 44 65 66 61 75  v[2], &makeDefau
6780: 6c 74 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  lt) ) return TCL
6790: 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 7a 4e  _ERROR;.  if( zN
67a0: 61 6d 65 5b 30 5d 3d 3d 27 5c 30 27 20 29 20 7a  ame[0]=='\0' ) z
67b0: 4e 61 6d 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20  Name = 0;..  /* 
67c0: 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 71 75 6f  Call sqlite3_quo
67d0: 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  ta_initialize() 
67e0: 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65  */.  rc = sqlite
67f0: 33 5f 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69  3_quota_initiali
6800: 7a 65 28 7a 4e 61 6d 65 2c 20 6d 61 6b 65 44 65  ze(zName, makeDe
6810: 66 61 75 6c 74 29 3b 0a 20 20 54 63 6c 5f 53 65  fault);.  Tcl_Se
6820: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  tResult(interp, 
6830: 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 54  (char *)sqlite3T
6840: 65 73 74 45 72 72 6f 72 4e 61 6d 65 28 72 63 29  estErrorName(rc)
6850: 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a  , TCL_STATIC);..
6860: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
6870: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64  .}../*.** tclcmd
6880: 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  : sqlite3_quota_
6890: 73 68 75 74 64 6f 77 6e 0a 2a 2f 0a 73 74 61 74  shutdown.*/.stat
68a0: 69 63 20 69 6e 74 20 74 65 73 74 5f 71 75 6f 74  ic int test_quot
68b0: 61 5f 73 68 75 74 64 6f 77 6e 28 0a 20 20 76 6f  a_shutdown(.  vo
68c0: 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c  id * clientData,
68d0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
68e0: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
68f0: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
6900: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
6910: 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20  int rc;         
6920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6930: 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65  /* Value returne
6940: 64 20 62 79 20 71 75 6f 74 61 5f 73 68 75 74 64  d by quota_shutd
6950: 6f 77 6e 28 29 20 2a 2f 0a 0a 20 20 69 66 28 20  own() */..  if( 
6960: 6f 62 6a 63 21 3d 31 20 29 7b 0a 20 20 20 20 54  objc!=1 ){.    T
6970: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
6980: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
6990: 20 22 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e   "");.    return
69a0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
69b0: 0a 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74  .  /* Call sqlit
69c0: 65 33 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77  e3_quota_shutdow
69d0: 6e 28 29 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71  n() */.  rc = sq
69e0: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68 75 74  lite3_quota_shut
69f0: 64 6f 77 6e 28 29 3b 0a 20 20 54 63 6c 5f 53 65  down();.  Tcl_Se
6a00: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  tResult(interp, 
6a10: 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 54  (char *)sqlite3T
6a20: 65 73 74 45 72 72 6f 72 4e 61 6d 65 28 72 63 29  estErrorName(rc)
6a30: 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a  , TCL_STATIC);..
6a40: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
6a50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64  .}../*.** tclcmd
6a60: 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  : sqlite3_quota_
6a70: 73 65 74 20 50 41 54 54 45 52 4e 20 4c 49 4d 49  set PATTERN LIMI
6a80: 54 20 53 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74  T SCRIPT.*/.stat
6a90: 69 63 20 69 6e 74 20 74 65 73 74 5f 71 75 6f 74  ic int test_quot
6aa0: 61 5f 73 65 74 28 0a 20 20 76 6f 69 64 20 2a 20  a_set(.  void * 
6ab0: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
6ac0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6ad0: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
6ae0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
6af0: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74  bjv[].){.  const
6b00: 20 63 68 61 72 20 2a 7a 50 61 74 74 65 72 6e 3b   char *zPattern;
6b10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46 69             /* Fi
6b20: 6c 65 20 70 61 74 74 65 72 6e 20 74 6f 20 63 6f  le pattern to co
6b30: 6e 66 69 67 75 72 65 20 2a 2f 0a 20 20 73 71 6c  nfigure */.  sql
6b40: 69 74 65 33 5f 69 6e 74 36 34 20 69 4c 69 6d 69  ite3_int64 iLimi
6b50: 74 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  t;           /* 
6b60: 49 6e 69 74 69 61 6c 20 71 75 6f 74 61 20 69 6e  Initial quota in
6b70: 20 62 79 74 65 73 20 2a 2f 0a 20 20 54 63 6c 5f   bytes */.  Tcl_
6b80: 4f 62 6a 20 2a 70 53 63 72 69 70 74 3b 20 20 20  Obj *pScript;   
6b90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
6ba0: 63 6c 20 73 63 72 69 70 74 20 74 6f 20 69 6e 76  cl script to inv
6bb0: 6f 6b 65 20 74 6f 20 69 6e 63 72 65 61 73 65 20  oke to increase 
6bc0: 71 75 6f 74 61 20 2a 2f 0a 20 20 69 6e 74 20 72  quota */.  int r
6bd0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
6be0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
6bf0: 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  lue returned by 
6c00: 71 75 6f 74 61 5f 73 65 74 28 29 20 2a 2f 0a 20  quota_set() */. 
6c10: 20 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63   TclQuotaCallbac
6c20: 6b 20 2a 70 3b 20 20 20 20 20 20 20 20 20 20 20  k *p;           
6c30: 20 2f 2a 20 43 61 6c 6c 62 61 63 6b 20 6f 62 6a   /* Callback obj
6c40: 65 63 74 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63  ect */.  int nSc
6c50: 72 69 70 74 3b 20 20 20 20 20 20 20 20 20 20 20  ript;           
6c60: 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67           /* Leng
6c70: 74 68 20 6f 66 20 63 61 6c 6c 62 61 63 6b 20 73  th of callback s
6c80: 63 72 69 70 74 20 2a 2f 0a 0a 20 20 2f 2a 20 50  cript */..  /* P
6c90: 72 6f 63 65 73 73 20 61 72 67 75 6d 65 6e 74 73  rocess arguments
6ca0: 20 2a 2f 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d   */.  if( objc!=
6cb0: 34 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f  4 ){.    Tcl_Wro
6cc0: 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70  ngNumArgs(interp
6cd0: 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 50 41 54 54  , 1, objv, "PATT
6ce0: 45 52 4e 20 4c 49 4d 49 54 20 53 43 52 49 50 54  ERN LIMIT SCRIPT
6cf0: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
6d00: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20  CL_ERROR;.  }.  
6d10: 7a 50 61 74 74 65 72 6e 20 3d 20 54 63 6c 5f 47  zPattern = Tcl_G
6d20: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d  etString(objv[1]
6d30: 29 3b 0a 20 20 69 66 28 20 54 63 6c 5f 47 65 74  );.  if( Tcl_Get
6d40: 57 69 64 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  WideIntFromObj(i
6d50: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20  nterp, objv[2], 
6d60: 26 69 4c 69 6d 69 74 29 20 29 20 72 65 74 75 72  &iLimit) ) retur
6d70: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70  n TCL_ERROR;.  p
6d80: 53 63 72 69 70 74 20 3d 20 6f 62 6a 76 5b 33 5d  Script = objv[3]
6d90: 3b 0a 20 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  ;.  Tcl_GetStrin
6da0: 67 46 72 6f 6d 4f 62 6a 28 70 53 63 72 69 70 74  gFromObj(pScript
6db0: 2c 20 26 6e 53 63 72 69 70 74 29 3b 0a 0a 20 20  , &nScript);..  
6dc0: 69 66 28 20 6e 53 63 72 69 70 74 3e 30 20 29 7b  if( nScript>0 ){
6dd0: 0a 20 20 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65  .    /* Allocate
6de0: 20 61 20 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62   a TclQuotaCallb
6df0: 61 63 6b 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20  ack object */.  
6e00: 20 20 70 20 3d 20 28 54 63 6c 51 75 6f 74 61 43    p = (TclQuotaC
6e10: 61 6c 6c 62 61 63 6b 20 2a 29 63 6b 61 6c 6c 6f  allback *)ckallo
6e20: 63 28 73 69 7a 65 6f 66 28 54 63 6c 51 75 6f 74  c(sizeof(TclQuot
6e30: 61 43 61 6c 6c 62 61 63 6b 29 29 3b 0a 20 20 20  aCallback));.   
6e40: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69   memset(p, 0, si
6e50: 7a 65 6f 66 28 54 63 6c 51 75 6f 74 61 43 61 6c  zeof(TclQuotaCal
6e60: 6c 62 61 63 6b 29 29 3b 0a 20 20 20 20 70 2d 3e  lback));.    p->
6e70: 69 6e 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b  interp = interp;
6e80: 0a 20 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  .    Tcl_IncrRef
6e90: 43 6f 75 6e 74 28 70 53 63 72 69 70 74 29 3b 0a  Count(pScript);.
6ea0: 20 20 20 20 70 2d 3e 70 53 63 72 69 70 74 20 3d      p->pScript =
6eb0: 20 70 53 63 72 69 70 74 3b 0a 20 20 7d 65 6c 73   pScript;.  }els
6ec0: 65 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20 20  e{.    p = 0;.  
6ed0: 7d 0a 20 20 2f 2a 20 49 6e 76 6f 6b 65 20 73 71  }.  /* Invoke sq
6ee0: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 65 74 28  lite3_quota_set(
6ef0: 29 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69  ) */.  rc = sqli
6f00: 74 65 33 5f 71 75 6f 74 61 5f 73 65 74 28 7a 50  te3_quota_set(zP
6f10: 61 74 74 65 72 6e 2c 20 69 4c 69 6d 69 74 2c 20  attern, iLimit, 
6f20: 74 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b  tclQuotaCallback
6f30: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,.              
6f40: 20 20 20 20 20 20 20 20 20 20 20 28 76 6f 69 64             (void
6f50: 2a 29 70 2c 20 74 63 6c 43 61 6c 6c 62 61 63 6b  *)p, tclCallback
6f60: 44 65 73 74 72 75 63 74 6f 72 29 3b 0a 0a 20 20  Destructor);..  
6f70: 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e  Tcl_SetResult(in
6f80: 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71  terp, (char *)sq
6f90: 6c 69 74 65 33 54 65 73 74 45 72 72 6f 72 4e 61  lite3TestErrorNa
6fa0: 6d 65 28 72 63 29 2c 20 54 43 4c 5f 53 54 41 54  me(rc), TCL_STAT
6fb0: 49 43 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43  IC);.  return TC
6fc0: 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74  L_OK;.}../*.** t
6fd0: 63 6c 63 6d 64 3a 20 20 73 71 6c 69 74 65 33 5f  clcmd:  sqlite3_
6fe0: 71 75 6f 74 61 5f 64 75 6d 70 0a 2a 2f 0a 73 74  quota_dump.*/.st
6ff0: 61 74 69 63 20 69 6e 74 20 74 65 73 74 5f 71 75  atic int test_qu
7000: 6f 74 61 5f 64 75 6d 70 28 0a 20 20 76 6f 69 64  ota_dump(.  void
7010: 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20   * clientData,. 
7020: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
7030: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
7040: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
7050: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 54 63  T objv[].){.  Tc
7060: 6c 5f 4f 62 6a 20 2a 70 52 65 73 75 6c 74 3b 0a  l_Obj *pResult;.
7070: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 47 72 6f 75    Tcl_Obj *pGrou
7080: 70 54 65 72 6d 3b 0a 20 20 54 63 6c 5f 4f 62 6a  pTerm;.  Tcl_Obj
7090: 20 2a 70 46 69 6c 65 54 65 72 6d 3b 0a 20 20 71   *pFileTerm;.  q
70a0: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
70b0: 70 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a  p;.  quotaFile *
70c0: 70 46 69 6c 65 3b 0a 0a 20 20 70 52 65 73 75 6c  pFile;..  pResul
70d0: 74 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29  t = Tcl_NewObj()
70e0: 3b 0a 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29  ;.  quotaEnter()
70f0: 3b 0a 20 20 66 6f 72 28 70 47 72 6f 75 70 3d 67  ;.  for(pGroup=g
7100: 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 20 70 47  Quota.pGroup; pG
7110: 72 6f 75 70 3b 20 70 47 72 6f 75 70 3d 70 47 72  roup; pGroup=pGr
7120: 6f 75 70 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20  oup->pNext){.   
7130: 20 70 47 72 6f 75 70 54 65 72 6d 20 3d 20 54 63   pGroupTerm = Tc
7140: 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20  l_NewObj();.    
7150: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
7160: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
7170: 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20 20 20   pGroupTerm,.   
7180: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74         Tcl_NewSt
7190: 72 69 6e 67 4f 62 6a 28 70 47 72 6f 75 70 2d 3e  ringObj(pGroup->
71a0: 7a 50 61 74 74 65 72 6e 2c 20 2d 31 29 29 3b 0a  zPattern, -1));.
71b0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
71c0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
71d0: 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c  erp, pGroupTerm,
71e0: 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e  .          Tcl_N
71f0: 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 70 47 72  ewWideIntObj(pGr
7200: 6f 75 70 2d 3e 69 4c 69 6d 69 74 29 29 3b 0a 20  oup->iLimit));. 
7210: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
7220: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
7230: 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a  rp, pGroupTerm,.
7240: 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65            Tcl_Ne
7250: 77 57 69 64 65 49 6e 74 4f 62 6a 28 70 47 72 6f  wWideIntObj(pGro
7260: 75 70 2d 3e 69 53 69 7a 65 29 29 3b 0a 20 20 20  up->iSize));.   
7270: 20 66 6f 72 28 70 46 69 6c 65 3d 70 47 72 6f 75   for(pFile=pGrou
7280: 70 2d 3e 70 46 69 6c 65 73 3b 20 70 46 69 6c 65  p->pFiles; pFile
7290: 3b 20 70 46 69 6c 65 3d 70 46 69 6c 65 2d 3e 70  ; pFile=pFile->p
72a0: 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 70 46 69  Next){.      pFi
72b0: 6c 65 54 65 72 6d 20 3d 20 54 63 6c 5f 4e 65 77  leTerm = Tcl_New
72c0: 4f 62 6a 28 29 3b 0a 20 20 20 20 20 20 54 63 6c  Obj();.      Tcl
72d0: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
72e0: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46  ement(interp, pF
72f0: 69 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20  ileTerm,.       
7300: 20 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69       Tcl_NewStri
7310: 6e 67 4f 62 6a 28 70 46 69 6c 65 2d 3e 7a 46 69  ngObj(pFile->zFi
7320: 6c 65 6e 61 6d 65 2c 20 2d 31 29 29 3b 0a 20 20  lename, -1));.  
7330: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
7340: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
7350: 65 72 70 2c 20 70 46 69 6c 65 54 65 72 6d 2c 0a  erp, pFileTerm,.
7360: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
7370: 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 70 46  NewWideIntObj(pF
7380: 69 6c 65 2d 3e 69 53 69 7a 65 29 29 3b 0a 20 20  ile->iSize));.  
7390: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
73a0: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
73b0: 65 72 70 2c 20 70 46 69 6c 65 54 65 72 6d 2c 0a  erp, pFileTerm,.
73c0: 20 20 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f              Tcl_
73d0: 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 70 46  NewWideIntObj(pF
73e0: 69 6c 65 2d 3e 6e 52 65 66 29 29 3b 0a 20 20 20  ile->nRef));.   
73f0: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
7400: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
7410: 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 20  rp, pGroupTerm, 
7420: 70 46 69 6c 65 54 65 72 6d 29 3b 0a 20 20 20 20  pFileTerm);.    
7430: 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  }.    Tcl_ListOb
7440: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
7450: 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74 2c 20  nterp, pResult, 
7460: 70 47 72 6f 75 70 54 65 72 6d 29 3b 0a 20 20 7d  pGroupTerm);.  }
7470: 0a 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b  .  quotaLeave();
7480: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
7490: 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 52 65 73  ult(interp, pRes
74a0: 75 6c 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  ult);.  return T
74b0: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  CL_OK;.}../*.** 
74c0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 67  This routine reg
74d0: 69 73 74 65 72 73 20 74 68 65 20 63 75 73 74 6f  isters the custo
74e0: 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 73 20 64  m TCL commands d
74f0: 65 66 69 6e 65 64 20 69 6e 20 74 68 69 73 0a 2a  efined in this.*
7500: 2a 20 6d 6f 64 75 6c 65 2e 20 20 54 68 69 73 20  * module.  This 
7510: 73 68 6f 75 6c 64 20 62 65 20 74 68 65 20 6f 6e  should be the on
7520: 6c 79 20 70 72 6f 63 65 64 75 72 65 20 76 69 73  ly procedure vis
7530: 69 62 6c 65 20 66 72 6f 6d 20 6f 75 74 73 69 64  ible from outsid
7540: 65 0a 2a 2a 20 6f 66 20 74 68 69 73 20 6d 6f 64  e.** of this mod
7550: 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69  ule..*/.int Sqli
7560: 74 65 71 75 6f 74 61 5f 49 6e 69 74 28 54 63 6c  tequota_Init(Tcl
7570: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29  _Interp *interp)
7580: 7b 0a 20 20 73 74 61 74 69 63 20 73 74 72 75 63  {.  static struc
7590: 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a 7a  t {.     char *z
75a0: 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f  Name;.     Tcl_O
75b0: 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63  bjCmdProc *xProc
75c0: 3b 0a 20 20 7d 20 61 43 6d 64 5b 5d 20 3d 20 7b  ;.  } aCmd[] = {
75d0: 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f  .    { "sqlite3_
75e0: 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65  quota_initialize
75f0: 22 2c 20 74 65 73 74 5f 71 75 6f 74 61 5f 69 6e  ", test_quota_in
7600: 69 74 69 61 6c 69 7a 65 20 7d 2c 0a 20 20 20 20  itialize },.    
7610: 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61  { "sqlite3_quota
7620: 5f 73 68 75 74 64 6f 77 6e 22 2c 20 74 65 73 74  _shutdown", test
7630: 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 20  _quota_shutdown 
7640: 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65  },.    { "sqlite
7650: 33 5f 71 75 6f 74 61 5f 73 65 74 22 2c 20 74 65  3_quota_set", te
7660: 73 74 5f 71 75 6f 74 61 5f 73 65 74 20 7d 2c 0a  st_quota_set },.
7670: 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71      { "sqlite3_q
7680: 75 6f 74 61 5f 64 75 6d 70 22 2c 20 74 65 73 74  uota_dump", test
7690: 5f 71 75 6f 74 61 5f 64 75 6d 70 20 7d 2c 0a 20  _quota_dump },. 
76a0: 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20   };.  int i;..  
76b0: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f  for(i=0; i<sizeo
76c0: 66 28 61 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  f(aCmd)/sizeof(a
76d0: 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  Cmd[0]); i++){. 
76e0: 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a     Tcl_CreateObj
76f0: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
7700: 61 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 61  aCmd[i].zName, a
7710: 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 30 2c  Cmd[i].xProc, 0,
7720: 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75   0);.  }..  retu
7730: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 23 65 6e  rn TCL_OK;.}.#en
7740: 64 69 66 0a                                      dif.