/ Hex Artifact Content
Login

Artifact b5576f17d701af461effd7ca1e71f0d100071192:


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 67 72 65 61 74 65 72 20  roup is greater 
0320: 74 68 61 6e 20 74 68 65 20 6c 69 6d 69 74 2c 20  than the limit, 
0330: 74 68 65 6e 0a 2a 2a 20 77 72 69 74 65 20 72 65  then.** write re
0340: 71 75 65 73 74 73 20 74 68 61 74 20 61 74 74 65  quests that atte
0350: 6d 70 74 20 74 6f 20 65 6e 6c 61 72 67 65 20 61  mpt to enlarge a
0360: 20 66 69 6c 65 20 66 61 69 6c 20 77 69 74 68 20   file fail with 
0370: 53 51 4c 49 54 45 5f 46 55 4c 4c 2e 0a 2a 2a 0a  SQLITE_FULL..**.
0380: 2a 2a 20 48 6f 77 65 76 65 72 2c 20 62 65 66 6f  ** However, befo
0390: 72 65 20 72 65 74 75 72 6e 69 6e 67 20 53 51 4c  re returning SQL
03a0: 49 54 45 5f 46 55 4c 4c 2c 20 74 68 65 20 77 72  ITE_FULL, the wr
03b0: 69 74 65 20 72 65 71 75 65 73 74 73 20 69 6e 76  ite requests inv
03c0: 6f 6b 65 0a 2a 2a 20 61 20 63 61 6c 6c 62 61 63  oke.** a callbac
03d0: 6b 20 66 75 6e 63 74 69 6f 6e 20 74 68 61 74 20  k function that 
03e0: 69 73 20 63 6f 6e 66 69 67 75 72 61 62 6c 65 20  is configurable 
03f0: 66 6f 72 20 65 61 63 68 20 71 75 6f 74 61 20 67  for each quota g
0400: 72 6f 75 70 2e 0a 2a 2a 20 54 68 69 73 20 63 61  roup..** This ca
0410: 6c 6c 62 61 63 6b 20 68 61 73 20 74 68 65 20 6f  llback has the o
0420: 70 70 6f 72 74 75 6e 69 74 79 20 74 6f 20 65 6e  pportunity to en
0430: 6c 61 72 67 65 20 74 68 65 20 71 75 6f 74 61 2e  large the quota.
0440: 20 20 49 66 20 74 68 65 0a 2a 2a 20 63 61 6c 6c    If the.** call
0450: 62 61 63 6b 20 64 6f 65 73 20 65 6e 6c 61 72 67  back does enlarg
0460: 65 20 74 68 65 20 71 75 6f 74 61 20 73 75 63 68  e the quota such
0470: 20 74 68 61 74 20 74 68 65 20 74 6f 74 61 6c 20   that the total 
0480: 73 69 7a 65 20 6f 66 20 61 6c 6c 0a 2a 2a 20 66  size of all.** f
0490: 69 6c 65 73 20 77 69 74 68 69 6e 20 74 68 65 20  iles within the 
04a0: 67 72 6f 75 70 20 69 73 20 6c 65 73 73 20 74 68  group is less th
04b0: 61 6e 20 74 68 65 20 6e 65 77 20 71 75 6f 74 61  an the new quota
04c0: 2c 20 74 68 65 6e 20 74 68 65 20 77 72 69 74 65  , then the write
04d0: 0a 2a 2a 20 63 6f 6e 74 69 6e 75 65 73 20 61 73  .** continues as
04e0: 20 69 66 20 6e 6f 74 68 69 6e 67 20 68 61 64 20   if nothing had 
04f0: 68 61 70 70 65 6e 65 64 2e 0a 2a 2f 0a 23 69 6e  happened..*/.#in
0500: 63 6c 75 64 65 20 22 73 71 6c 69 74 65 33 2e 68  clude "sqlite3.h
0510: 22 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69  ".#include <stri
0520: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  ng.h>.#include <
0530: 61 73 73 65 72 74 2e 68 3e 0a 0a 2f 2a 0a 2a 2a  assert.h>../*.**
0540: 20 46 6f 72 20 61 6e 20 62 75 69 6c 64 20 77 69   For an build wi
0550: 74 68 6f 75 74 20 6d 75 74 65 78 65 73 2c 20 6e  thout mutexes, n
0560: 6f 2d 6f 70 20 74 68 65 20 6d 75 74 65 78 20 63  o-op the mutex c
0570: 61 6c 6c 73 2e 0a 2a 2f 0a 23 69 66 20 64 65 66  alls..*/.#if def
0580: 69 6e 65 64 28 53 51 4c 49 54 45 5f 54 48 52 45  ined(SQLITE_THRE
0590: 41 44 53 41 46 45 29 20 26 26 20 53 51 4c 49 54  ADSAFE) && SQLIT
05a0: 45 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30 0a  E_THREADSAFE==0.
05b0: 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f  #define sqlite3_
05c0: 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 58 29 20 20  mutex_alloc(X)  
05d0: 20 20 28 28 73 71 6c 69 74 65 33 5f 6d 75 74 65    ((sqlite3_mute
05e0: 78 2a 29 38 29 0a 23 64 65 66 69 6e 65 20 73 71  x*)8).#define sq
05f0: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 66 72 65 65  lite3_mutex_free
0600: 28 58 29 0a 23 64 65 66 69 6e 65 20 73 71 6c 69  (X).#define sqli
0610: 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28  te3_mutex_enter(
0620: 58 29 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74  X).#define sqlit
0630: 65 33 5f 6d 75 74 65 78 5f 74 72 79 28 58 29 20  e3_mutex_try(X) 
0640: 20 20 20 20 20 53 51 4c 49 54 45 5f 4f 4b 0a 23       SQLITE_OK.#
0650: 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f 6d  define sqlite3_m
0660: 75 74 65 78 5f 6c 65 61 76 65 28 58 29 0a 23 64  utex_leave(X).#d
0670: 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f 6d 75  efine sqlite3_mu
0680: 74 65 78 5f 68 65 6c 64 28 58 29 20 20 20 20 20  tex_held(X)     
0690: 28 28 76 6f 69 64 29 28 58 29 2c 31 29 0a 23 64  ((void)(X),1).#d
06a0: 65 66 69 6e 65 20 73 71 6c 69 74 65 33 5f 6d 75  efine sqlite3_mu
06b0: 74 65 78 5f 6e 6f 74 68 65 6c 64 28 58 29 20 20  tex_notheld(X)  
06c0: 28 28 76 6f 69 64 29 28 58 29 2c 31 29 0a 23 65  ((void)(X),1).#e
06d0: 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54 45 5f 54  ndif /* SQLITE_T
06e0: 48 52 45 41 44 53 41 46 45 3d 3d 30 20 2a 2f 0a  HREADSAFE==0 */.
06f0: 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ../*************
0700: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 4f 62 6a 65  *********** Obje
0710: 63 74 20 44 65 66 69 6e 69 74 69 6f 6e 73 20 2a  ct Definitions *
0720: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0730: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a  *************/..
0740: 2f 2a 20 46 6f 72 77 61 72 64 20 64 65 63 6c 61  /* Forward decla
0750: 72 61 74 69 6f 6e 20 6f 66 20 61 6c 6c 20 6f 62  ration of all ob
0760: 6a 65 63 74 20 74 79 70 65 73 20 2a 2f 0a 74 79  ject types */.ty
0770: 70 65 64 65 66 20 73 74 72 75 63 74 20 71 75 6f  pedef struct quo
0780: 74 61 47 72 6f 75 70 20 71 75 6f 74 61 47 72 6f  taGroup quotaGro
0790: 75 70 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  up;.typedef stru
07a0: 63 74 20 71 75 6f 74 61 43 6f 6e 6e 20 71 75 6f  ct quotaConn quo
07b0: 74 61 43 6f 6e 6e 3b 0a 74 79 70 65 64 65 66 20  taConn;.typedef 
07c0: 73 74 72 75 63 74 20 71 75 6f 74 61 46 69 6c 65  struct quotaFile
07d0: 20 71 75 6f 74 61 46 69 6c 65 3b 0a 0a 2f 2a 0a   quotaFile;../*.
07e0: 2a 2a 20 41 20 22 71 75 6f 74 61 20 67 72 6f 75  ** A "quota grou
07f0: 70 22 20 69 73 20 61 20 63 6f 6c 6c 65 63 74 69  p" is a collecti
0800: 6f 6e 20 6f 66 20 66 69 6c 65 73 20 77 68 6f 73  on of files whos
0810: 65 20 63 6f 6c 6c 65 63 74 69 76 65 20 73 69 7a  e collective siz
0820: 65 20 77 65 20 77 61 6e 74 0a 2a 2a 20 74 6f 20  e we want.** to 
0830: 6c 69 6d 69 74 2e 20 20 45 61 63 68 20 71 75 6f  limit.  Each quo
0840: 74 61 20 67 72 6f 75 70 20 69 73 20 64 65 66 69  ta group is defi
0850: 6e 65 64 20 62 79 20 61 20 47 4c 4f 42 20 70 61  ned by a GLOB pa
0860: 74 74 65 72 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 65  ttern..**.** The
0870: 72 65 20 69 73 20 61 6e 20 69 6e 73 74 61 6e 63  re is an instanc
0880: 65 20 6f 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69  e of the followi
0890: 6e 67 20 6f 62 6a 65 63 74 20 66 6f 72 20 65 61  ng object for ea
08a0: 63 68 20 64 65 66 69 6e 65 64 20 71 75 6f 74 61  ch defined quota
08b0: 0a 2a 2a 20 67 72 6f 75 70 2e 20 20 54 68 69 73  .** group.  This
08c0: 20 6f 62 6a 65 63 74 20 72 65 63 6f 72 64 73 20   object records 
08d0: 74 68 65 20 47 4c 4f 42 20 70 61 74 74 65 72 6e  the GLOB pattern
08e0: 20 74 68 61 74 20 64 65 66 69 6e 65 73 20 77 68   that defines wh
08f0: 69 63 68 20 66 69 6c 65 73 0a 2a 2a 20 62 65 6c  ich files.** bel
0900: 6f 6e 67 20 74 6f 20 74 68 65 20 71 75 6f 74 61  ong to the quota
0910: 20 67 72 6f 75 70 2e 20 20 54 68 65 20 6f 62 6a   group.  The obj
0920: 65 63 74 20 61 6c 73 6f 20 72 65 6d 65 6d 62 65  ect also remembe
0930: 72 73 20 74 68 65 20 73 69 7a 65 20 6c 69 6d 69  rs the size limi
0940: 74 0a 2a 2a 20 66 6f 72 20 74 68 65 20 67 72 6f  t.** for the gro
0950: 75 70 20 28 74 68 65 20 71 75 6f 74 61 29 20 61  up (the quota) a
0960: 6e 64 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20  nd the callback 
0970: 74 6f 20 62 65 20 69 6e 76 6f 6b 65 64 20 77 68  to be invoked wh
0980: 65 6e 20 74 68 65 0a 2a 2a 20 73 75 6d 20 6f 66  en the.** sum of
0990: 20 74 68 65 20 73 69 7a 65 73 20 6f 66 20 74 68   the sizes of th
09a0: 65 20 66 69 6c 65 73 20 77 69 74 68 69 6e 20 74  e files within t
09b0: 68 65 20 67 72 6f 75 70 20 67 6f 65 73 20 6f 76  he group goes ov
09c0: 65 72 20 74 68 65 20 6c 69 6d 69 74 2e 0a 2a 2a  er the limit..**
09d0: 0a 2a 2a 20 41 20 71 75 6f 74 61 20 67 72 6f 75  .** A quota grou
09e0: 70 20 6d 75 73 74 20 62 65 20 65 73 74 61 62 6c  p must be establ
09f0: 69 73 68 65 64 20 28 75 73 69 6e 67 20 73 71 6c  ished (using sql
0a00: 69 74 65 33 5f 71 75 6f 74 61 5f 73 65 74 28 2e  ite3_quota_set(.
0a10: 2e 2e 29 29 0a 2a 2a 20 70 72 69 6f 72 20 74 6f  ..)).** prior to
0a20: 20 6f 70 65 6e 69 6e 67 20 61 6e 79 20 6f 66 20   opening any of 
0a30: 74 68 65 20 64 61 74 61 62 61 73 65 20 63 6f 6e  the database con
0a40: 6e 65 63 74 69 6f 6e 73 20 74 68 61 74 20 61 63  nections that ac
0a50: 63 65 73 73 20 66 69 6c 65 73 0a 2a 2a 20 77 69  cess files.** wi
0a60: 74 68 69 6e 20 74 68 65 20 71 75 6f 74 61 20 67  thin the quota g
0a70: 72 6f 75 70 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  roup..*/.struct 
0a80: 71 75 6f 74 61 47 72 6f 75 70 20 7b 0a 20 20 63  quotaGroup {.  c
0a90: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 74  onst char *zPatt
0aa0: 65 72 6e 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  ern;          /*
0ab0: 20 46 69 6c 65 6e 61 6d 65 20 70 61 74 74 65 72   Filename patter
0ac0: 6e 20 74 6f 20 62 65 20 71 75 6f 74 61 65 64 20  n to be quotaed 
0ad0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
0ae0: 36 34 20 69 4c 69 6d 69 74 3b 20 20 20 20 20 20  64 iLimit;      
0af0: 20 20 20 20 2f 2a 20 55 70 70 65 72 20 62 6f 75      /* Upper bou
0b00: 6e 64 20 6f 6e 20 74 6f 74 61 6c 20 66 69 6c 65  nd on total file
0b10: 20 73 69 7a 65 20 2a 2f 0a 20 20 73 71 6c 69 74   size */.  sqlit
0b20: 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65 3b 20  e3_int64 iSize; 
0b30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 75 72            /* Cur
0b40: 72 65 6e 74 20 73 69 7a 65 20 6f 66 20 61 6c 6c  rent size of all
0b50: 20 66 69 6c 65 73 20 2a 2f 0a 20 20 76 6f 69 64   files */.  void
0b60: 20 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 20 20   (*xCallback)(  
0b70: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
0b80: 6c 6c 62 61 63 6b 20 69 6e 76 6f 6b 65 64 20 77  llback invoked w
0b90: 68 65 6e 20 67 6f 69 6e 67 20 6f 76 65 72 20 71  hen going over q
0ba0: 75 6f 74 61 20 2a 2f 0a 20 20 20 20 20 63 6f 6e  uota */.     con
0bb0: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61  st char *zFilena
0bc0: 6d 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  me,         /* N
0bd0: 61 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f 73  ame of file whos
0be0: 65 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65 73  e size increases
0bf0: 20 2a 2f 0a 20 20 20 20 20 73 71 6c 69 74 65 33   */.     sqlite3
0c00: 5f 69 6e 74 36 34 20 2a 70 69 4c 69 6d 69 74 2c  _int64 *piLimit,
0c10: 20 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55          /* IN/OU
0c20: 54 3a 20 54 68 65 20 63 75 72 72 65 6e 74 20 6c  T: The current l
0c30: 69 6d 69 74 20 2a 2f 0a 20 20 20 20 20 73 71 6c  imit */.     sql
0c40: 69 74 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65  ite3_int64 iSize
0c50: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  ,           /* T
0c60: 6f 74 61 6c 20 73 69 7a 65 20 6f 66 20 61 6c 6c  otal size of all
0c70: 20 66 69 6c 65 73 20 69 6e 20 74 68 65 20 67 72   files in the gr
0c80: 6f 75 70 20 2a 2f 0a 20 20 20 20 20 76 6f 69 64  oup */.     void
0c90: 20 2a 70 41 72 67 20 20 20 20 20 20 20 20 20 20   *pArg          
0ca0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6c             /* Cl
0cb0: 69 65 6e 74 20 64 61 74 61 20 2a 2f 0a 20 20 29  ient data */.  )
0cc0: 3b 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 3b 20  ;.  void *pArg; 
0cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0ce0: 20 20 20 2f 2a 20 54 68 69 72 64 20 61 72 67 75     /* Third argu
0cf0: 6d 65 6e 74 20 74 6f 20 74 68 65 20 78 43 61 6c  ment to the xCal
0d00: 6c 62 61 63 6b 28 29 20 2a 2f 0a 20 20 76 6f 69  lback() */.  voi
0d10: 64 20 28 2a 78 44 65 73 74 72 6f 79 29 28 76 6f  d (*xDestroy)(vo
0d20: 69 64 2a 29 3b 20 20 20 20 20 20 20 2f 2a 20 4f  id*);       /* O
0d30: 70 74 69 6f 6e 61 6c 20 64 65 73 74 72 75 63 74  ptional destruct
0d40: 6f 72 20 66 6f 72 20 70 41 72 67 20 2a 2f 0a 20  or for pArg */. 
0d50: 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 4e 65   quotaGroup *pNe
0d60: 78 74 2c 20 2a 2a 70 70 50 72 65 76 3b 20 20 20  xt, **ppPrev;   
0d70: 2f 2a 20 44 6f 75 62 6c 79 20 6c 69 6e 6b 65 64  /* Doubly linked
0d80: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 20 71 75 6f   list of all quo
0d90: 74 61 20 6f 62 6a 65 63 74 73 20 2a 2f 0a 20 20  ta objects */.  
0da0: 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65  quotaFile *pFile
0db0: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  s;             /
0dc0: 2a 20 46 69 6c 65 73 20 77 69 74 68 69 6e 20 74  * Files within t
0dd0: 68 69 73 20 67 72 6f 75 70 20 2a 2f 0a 7d 3b 0a  his group */.};.
0de0: 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73 74 61 6e  ./*.** An instan
0df0: 63 65 20 6f 66 20 74 68 69 73 20 73 74 72 75 63  ce of this struc
0e00: 74 75 72 65 20 72 65 70 72 65 73 65 6e 74 73 20  ture represents 
0e10: 61 20 73 69 6e 67 6c 65 20 66 69 6c 65 20 74 68  a single file th
0e20: 61 74 20 69 73 20 70 61 72 74 0a 2a 2a 20 6f 66  at is part.** of
0e30: 20 61 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 20   a quota group. 
0e40: 20 41 20 73 69 6e 67 6c 65 20 66 69 6c 65 20 63   A single file c
0e50: 61 6e 20 62 65 20 6f 70 65 6e 65 64 20 6d 75 6c  an be opened mul
0e60: 74 69 70 6c 65 20 74 69 6d 65 73 2e 20 20 49 6e  tiple times.  In
0e70: 0a 2a 2a 20 6f 72 64 65 72 20 6b 65 65 70 20 6d  .** order keep m
0e80: 75 6c 74 69 70 6c 65 20 6f 70 65 6e 69 6e 67 73  ultiple openings
0e90: 20 6f 66 20 74 68 65 20 73 61 6d 65 20 66 69 6c   of the same fil
0ea0: 65 20 66 72 6f 6d 20 63 61 75 73 69 6e 67 20 74  e from causing t
0eb0: 68 65 20 73 69 7a 65 0a 2a 2a 20 6f 66 20 74 68  he size.** of th
0ec0: 65 20 66 69 6c 65 20 74 6f 20 63 6f 75 6e 74 20  e file to count 
0ed0: 61 67 61 69 6e 73 74 20 74 68 65 20 71 75 6f 74  against the quot
0ee0: 61 20 6d 75 6c 74 69 70 6c 65 20 74 69 6d 65 73  a multiple times
0ef0: 2c 20 65 61 63 68 20 66 69 6c 65 0a 2a 2a 20 68  , each file.** h
0f00: 61 73 20 61 20 75 6e 69 71 75 65 20 69 6e 73 74  as a unique inst
0f10: 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62 6a  ance of this obj
0f20: 65 63 74 20 61 6e 64 20 6d 75 6c 74 69 70 6c 65  ect and multiple
0f30: 20 6f 70 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e   open connection
0f40: 73 0a 2a 2a 20 74 6f 20 74 68 65 20 73 61 6d 65  s.** to the same
0f50: 20 66 69 6c 65 20 65 61 63 68 20 70 6f 69 6e 74   file each point
0f60: 20 74 6f 20 61 20 73 69 6e 67 6c 65 20 69 6e 73   to a single ins
0f70: 74 61 6e 63 65 20 6f 66 20 74 68 69 73 20 6f 62  tance of this ob
0f80: 6a 65 63 74 2e 0a 2a 2f 0a 73 74 72 75 63 74 20  ject..*/.struct 
0f90: 71 75 6f 74 61 46 69 6c 65 20 7b 0a 20 20 63 68  quotaFile {.  ch
0fa0: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20  ar *zFilename;  
0fb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0fc0: 20 4e 61 6d 65 20 6f 66 20 74 68 69 73 20 66 69   Name of this fi
0fd0: 6c 65 20 2a 2f 0a 20 20 71 75 6f 74 61 47 72 6f  le */.  quotaGro
0fe0: 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20 20  up *pGroup;     
0ff0: 20 20 20 20 20 20 20 20 2f 2a 20 51 75 6f 74 61          /* Quota
1000: 20 67 72 6f 75 70 20 74 6f 20 77 68 69 63 68 20   group to which 
1010: 74 68 69 73 20 66 69 6c 65 20 62 65 6c 6f 6e 67  this file belong
1020: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  s */.  sqlite3_i
1030: 6e 74 36 34 20 69 53 69 7a 65 3b 20 20 20 20 20  nt64 iSize;     
1040: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
1050: 74 20 73 69 7a 65 20 6f 66 20 74 68 69 73 20 66  t size of this f
1060: 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 52 65  ile */.  int nRe
1070: 66 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f;              
1080: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
1090: 65 72 20 6f 66 20 74 69 6d 65 73 20 74 68 69 73  er of times this
10a0: 20 66 69 6c 65 20 69 73 20 6f 70 65 6e 20 2a 2f   file is open */
10b0: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 4e  .  quotaFile *pN
10c0: 65 78 74 2c 20 2a 2a 70 70 50 72 65 76 3b 20 20  ext, **ppPrev;  
10d0: 20 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69 73     /* Linked lis
10e0: 74 20 6f 66 20 66 69 6c 65 73 20 69 6e 20 74 68  t of files in th
10f0: 65 20 73 61 6d 65 20 67 72 6f 75 70 20 2a 2f 0a  e same group */.
1100: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73  };../*.** An ins
1110: 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c  tance of the fol
1120: 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 72 65  lowing object re
1130: 70 72 65 73 65 6e 74 73 20 65 61 63 68 20 6f 70  presents each op
1140: 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a 2a 2a  en connection.**
1150: 20 74 6f 20 61 20 66 69 6c 65 20 74 68 61 74 20   to a file that 
1160: 70 61 72 74 69 63 69 70 61 74 65 73 20 69 6e 20  participates in 
1170: 71 75 6f 74 61 20 74 72 61 63 6b 69 6e 67 2e 20  quota tracking. 
1180: 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69 73 20   This object is 
1190: 61 20 0a 2a 2a 20 73 75 62 63 6c 61 73 73 20 6f  a .** subclass o
11a0: 66 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2e 20  f sqlite3_file. 
11b0: 20 54 68 65 20 73 71 6c 69 74 65 33 5f 66 69 6c   The sqlite3_fil
11c0: 65 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65  e object for the
11d0: 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 56   underlying.** V
11e0: 46 53 20 69 73 20 61 70 70 65 6e 64 65 64 20 74  FS is appended t
11f0: 6f 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  o this structure
1200: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 71 75 6f 74  ..*/.struct quot
1210: 61 43 6f 6e 6e 20 7b 0a 20 20 73 71 6c 69 74 65  aConn {.  sqlite
1220: 33 5f 66 69 6c 65 20 62 61 73 65 3b 20 20 20 20  3_file base;    
1230: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 61 73            /* Bas
1240: 65 20 63 6c 61 73 73 20 2d 20 6d 75 73 74 20 62  e class - must b
1250: 65 20 66 69 72 73 74 20 2a 2f 0a 20 20 71 75 6f  e first */.  quo
1260: 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  taFile *pFile;  
1270: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1280: 54 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66  The underlying f
1290: 69 6c 65 20 2a 2f 0a 20 20 2f 2a 20 54 68 65 20  ile */.  /* The 
12a0: 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20 73  underlying VFS s
12b0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 69 73 20 61  qlite3_file is a
12c0: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 69 73 20  ppended to this 
12d0: 6f 62 6a 65 63 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  object */.};../*
12e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
12f0: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 6c 6f 62 61 6c 20  ******** Global 
1300: 56 61 72 69 61 62 6c 65 73 20 2a 2a 2a 2a 2a 2a  Variables ******
1310: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1330: 0a 2a 2a 20 41 6c 6c 20 67 6c 6f 62 61 6c 20 76  .** All global v
1340: 61 72 69 61 62 6c 65 73 20 75 73 65 64 20 62 79  ariables used by
1350: 20 74 68 69 73 20 66 69 6c 65 20 61 72 65 20 63   this file are c
1360: 6f 6e 74 61 69 6e 69 6e 67 20 77 69 74 68 69 6e  ontaining within
1370: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a   the following.*
1380: 2a 20 67 51 75 6f 74 61 20 73 74 72 75 63 74 75  * gQuota structu
1390: 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74  re..*/.static st
13a0: 72 75 63 74 20 7b 0a 20 20 2f 2a 20 54 68 65 20  ruct {.  /* The 
13b0: 70 4f 72 69 67 56 66 73 20 69 73 20 74 68 65 20  pOrigVfs is the 
13c0: 72 65 61 6c 2c 20 6f 72 69 67 69 6e 61 6c 20 75  real, original u
13d0: 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20 69 6d  nderlying VFS im
13e0: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 20 20  plementation..  
13f0: 2a 2a 20 4d 6f 73 74 20 6f 70 65 72 61 74 69 6f  ** Most operatio
1400: 6e 73 20 70 61 73 73 2d 74 68 72 6f 75 67 68 20  ns pass-through 
1410: 74 6f 20 74 68 65 20 72 65 61 6c 20 56 46 53 2e  to the real VFS.
1420: 20 20 54 68 69 73 20 76 61 6c 75 65 20 69 73 20    This value is 
1430: 72 65 61 64 2d 6f 6e 6c 79 0a 20 20 2a 2a 20 64  read-only.  ** d
1440: 75 72 69 6e 67 20 6f 70 65 72 61 74 69 6f 6e 2e  uring operation.
1450: 20 20 49 74 20 69 73 20 6f 6e 6c 79 20 6d 6f 64    It is only mod
1460: 69 66 69 65 64 20 61 74 20 73 74 61 72 74 2d 74  ified at start-t
1470: 69 6d 65 20 61 6e 64 20 74 68 75 73 20 64 6f 65  ime and thus doe
1480: 73 20 6e 6f 74 0a 20 20 2a 2a 20 72 65 71 75 69  s not.  ** requi
1490: 72 65 20 61 20 6d 75 74 65 78 2e 0a 20 20 2a 2f  re a mutex..  */
14a0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
14b0: 70 4f 72 69 67 56 66 73 3b 0a 0a 20 20 2f 2a 20  pOrigVfs;..  /* 
14c0: 54 68 65 20 73 54 68 69 73 56 66 73 20 69 73 20  The sThisVfs is 
14d0: 74 68 65 20 56 46 53 20 73 74 72 75 63 74 75 72  the VFS structur
14e0: 65 20 75 73 65 64 20 62 79 20 74 68 69 73 20 73  e used by this s
14f0: 68 69 6d 2e 20 20 49 74 20 69 73 20 69 6e 69 74  him.  It is init
1500: 69 61 6c 69 7a 65 64 0a 20 20 2a 2a 20 61 74 20  ialized.  ** at 
1510: 73 74 61 72 74 2d 74 69 6d 65 20 61 6e 64 20 74  start-time and t
1520: 68 75 73 20 64 6f 65 73 20 6e 6f 74 20 72 65 71  hus does not req
1530: 75 69 72 65 20 61 20 6d 75 74 65 78 0a 20 20 2a  uire a mutex.  *
1540: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  /.  sqlite3_vfs 
1550: 73 54 68 69 73 56 66 73 3b 0a 0a 20 20 2f 2a 20  sThisVfs;..  /* 
1560: 54 68 65 20 73 49 6f 4d 65 74 68 6f 64 73 20 64  The sIoMethods d
1570: 65 66 69 6e 65 73 20 74 68 65 20 6d 65 74 68 6f  efines the metho
1580: 64 73 20 75 73 65 64 20 62 79 20 73 71 6c 69 74  ds used by sqlit
1590: 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74 73 20  e3_file objects 
15a0: 0a 20 20 2a 2a 20 61 73 73 6f 63 69 61 74 65 64  .  ** associated
15b0: 20 77 69 74 68 20 74 68 69 73 20 73 68 69 6d 2e   with this shim.
15c0: 20 20 49 74 20 69 73 20 69 6e 69 74 69 61 6c 69    It is initiali
15d0: 7a 65 64 20 61 74 20 73 74 61 72 74 2d 74 69 6d  zed at start-tim
15e0: 65 20 61 6e 64 20 64 6f 65 73 0a 20 20 2a 2a 20  e and does.  ** 
15f0: 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20 6d 75  not require a mu
1600: 74 65 78 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 57  tex..  **.  ** W
1610: 68 65 6e 20 74 68 65 20 75 6e 64 65 72 6c 79 69  hen the underlyi
1620: 6e 67 20 56 46 53 20 69 73 20 63 61 6c 6c 65 64  ng VFS is called
1630: 20 74 6f 20 6f 70 65 6e 20 61 20 66 69 6c 65 2c   to open a file,
1640: 20 69 74 20 6d 69 67 68 74 20 72 65 74 75 72 6e   it might return
1650: 20 0a 20 20 2a 2a 20 65 69 74 68 65 72 20 61 20   .  ** either a 
1660: 76 65 72 73 69 6f 6e 20 31 20 6f 72 20 61 20 76  version 1 or a v
1670: 65 72 73 69 6f 6e 20 32 20 73 71 6c 69 74 65 33  ersion 2 sqlite3
1680: 5f 66 69 6c 65 20 6f 62 6a 65 63 74 2e 20 20 54  _file object.  T
1690: 68 69 73 20 73 68 69 6d 0a 20 20 2a 2a 20 68 61  his shim.  ** ha
16a0: 73 20 74 6f 20 63 72 65 61 74 65 20 61 20 77 72  s to create a wr
16b0: 61 70 70 65 72 20 73 71 6c 69 74 65 33 5f 66 69  apper sqlite3_fi
16c0: 6c 65 20 6f 66 20 74 68 65 20 73 61 6d 65 20 76  le of the same v
16d0: 65 72 73 69 6f 6e 2e 20 20 48 65 6e 63 65 0a 20  ersion.  Hence. 
16e0: 20 2a 2a 20 74 68 65 72 65 20 61 72 65 20 74 77   ** there are tw
16f0: 6f 20 49 2f 4f 20 6d 65 74 68 6f 64 20 73 74 72  o I/O method str
1700: 75 63 74 75 72 65 73 2c 20 6f 6e 65 20 66 6f 72  uctures, one for
1710: 20 76 65 72 73 69 6f 6e 20 31 20 61 6e 64 20 74   version 1 and t
1720: 68 65 20 6f 74 68 65 72 0a 20 20 2a 2a 20 66 6f  he other.  ** fo
1730: 72 20 76 65 72 73 69 6f 6e 20 32 2e 0a 20 20 2a  r version 2..  *
1740: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  /.  sqlite3_io_m
1750: 65 74 68 6f 64 73 20 73 49 6f 4d 65 74 68 6f 64  ethods sIoMethod
1760: 73 56 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69  sV1;.  sqlite3_i
1770: 6f 5f 6d 65 74 68 6f 64 73 20 73 49 6f 4d 65 74  o_methods sIoMet
1780: 68 6f 64 73 56 32 3b 0a 0a 20 20 2f 2a 20 54 72  hodsV2;..  /* Tr
1790: 75 65 20 77 68 65 6e 20 74 68 69 73 20 73 68 69  ue when this shi
17a0: 6d 20 61 73 20 62 65 65 6e 20 69 6e 69 74 69 61  m as been initia
17b0: 6c 69 7a 65 64 2e 0a 20 20 2a 2f 0a 20 20 69 6e  lized..  */.  in
17c0: 74 20 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 3b  t isInitialized;
17d0: 0a 0a 20 20 2f 2a 20 46 6f 72 20 72 75 6e 2d 74  ..  /* For run-t
17e0: 69 6d 65 20 61 63 63 65 73 73 20 61 6e 79 20 6f  ime access any o
17f0: 66 20 74 68 65 20 6f 74 68 65 72 20 67 6c 6f 62  f the other glob
1800: 61 6c 20 64 61 74 61 20 73 74 72 75 63 74 75 72  al data structur
1810: 65 73 20 69 6e 20 74 68 69 73 0a 20 20 2a 2a 20  es in this.  ** 
1820: 73 68 69 6d 2c 20 74 68 65 20 66 6f 6c 6c 6f 77  shim, the follow
1830: 69 6e 67 20 6d 75 74 65 78 20 6d 75 73 74 20 62  ing mutex must b
1840: 65 20 68 65 6c 64 2e 0a 20 20 2a 2f 0a 20 20 73  e held..  */.  s
1850: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 70 4d  qlite3_mutex *pM
1860: 75 74 65 78 3b 0a 0a 20 20 2f 2a 20 4c 69 73 74  utex;..  /* List
1870: 20 6f 66 20 71 75 6f 74 61 47 72 6f 75 70 20 6f   of quotaGroup o
1880: 62 6a 65 63 74 73 2e 0a 20 20 2a 2f 0a 20 20 71  bjects..  */.  q
1890: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
18a0: 70 3b 0a 0a 7d 20 67 51 75 6f 74 61 3b 0a 0a 2f  p;..} gQuota;../
18b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
18c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 55 74 69 6c 69 74  ********* Utilit
18d0: 79 20 52 6f 75 74 69 6e 65 73 20 2a 2a 2a 2a 2a  y Routines *****
18e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
18f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1900: 0a 2a 2a 20 41 63 71 75 69 72 65 20 61 6e 64 20  .** Acquire and 
1910: 72 65 6c 65 61 73 65 20 74 68 65 20 6d 75 74 65  release the mute
1920: 78 20 75 73 65 64 20 74 6f 20 73 65 72 69 61 6c  x used to serial
1930: 69 7a 65 20 61 63 63 65 73 73 20 74 6f 20 74 68  ize access to th
1940: 65 0a 2a 2a 20 6c 69 73 74 20 6f 66 20 71 75 6f  e.** list of quo
1950: 74 61 47 72 6f 75 70 73 2e 0a 2a 2f 0a 73 74 61  taGroups..*/.sta
1960: 74 69 63 20 76 6f 69 64 20 71 75 6f 74 61 45 6e  tic void quotaEn
1970: 74 65 72 28 76 6f 69 64 29 7b 20 73 71 6c 69 74  ter(void){ sqlit
1980: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 67  e3_mutex_enter(g
1990: 51 75 6f 74 61 2e 70 4d 75 74 65 78 29 3b 20 7d  Quota.pMutex); }
19a0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71 75 6f  .static void quo
19b0: 74 61 4c 65 61 76 65 28 76 6f 69 64 29 7b 20 73  taLeave(void){ s
19c0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
19d0: 76 65 28 67 51 75 6f 74 61 2e 70 4d 75 74 65 78  ve(gQuota.pMutex
19e0: 29 3b 20 7d 0a 0a 0a 2f 2a 20 49 66 20 74 68 65  ); }.../* If the
19f0: 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e 74   reference count
1a00: 20 61 6e 64 20 74 68 72 65 73 68 6f 6c 64 20 66   and threshold f
1a10: 6f 72 20 61 20 71 75 6f 74 61 47 72 6f 75 70 20  or a quotaGroup 
1a20: 61 72 65 20 62 6f 74 68 0a 2a 2a 20 7a 65 72 6f  are both.** zero
1a30: 2c 20 74 68 65 6e 20 64 65 73 74 72 6f 79 20 74  , then destroy t
1a40: 68 65 20 71 75 6f 74 61 47 72 6f 75 70 2e 0a 2a  he quotaGroup..*
1a50: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71 75  /.static void qu
1a60: 6f 74 61 47 72 6f 75 70 44 65 72 65 66 28 71 75  otaGroupDeref(qu
1a70: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
1a80: 29 7b 0a 20 20 69 66 28 20 70 47 72 6f 75 70 2d  ){.  if( pGroup-
1a90: 3e 70 46 69 6c 65 73 3d 3d 30 20 26 26 20 70 47  >pFiles==0 && pG
1aa0: 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 3d 3d 30 20  roup->iLimit==0 
1ab0: 29 7b 0a 20 20 20 20 2a 70 47 72 6f 75 70 2d 3e  ){.    *pGroup->
1ac0: 70 70 50 72 65 76 20 3d 20 70 47 72 6f 75 70 2d  ppPrev = pGroup-
1ad0: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 69 66 28 20  >pNext;.    if( 
1ae0: 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 20 29 20  pGroup->pNext ) 
1af0: 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 2d 3e 70  pGroup->pNext->p
1b00: 70 50 72 65 76 20 3d 20 70 47 72 6f 75 70 2d 3e  pPrev = pGroup->
1b10: 70 70 50 72 65 76 3b 0a 20 20 20 20 69 66 28 20  ppPrev;.    if( 
1b20: 70 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79  pGroup->xDestroy
1b30: 20 29 20 70 47 72 6f 75 70 2d 3e 78 44 65 73 74   ) pGroup->xDest
1b40: 72 6f 79 28 70 47 72 6f 75 70 2d 3e 70 41 72 67  roy(pGroup->pArg
1b50: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
1b60: 72 65 65 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d  ree(pGroup);.  }
1b70: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
1b80: 20 54 52 55 45 20 69 66 20 73 74 72 69 6e 67 20   TRUE if string 
1b90: 7a 20 6d 61 74 63 68 65 73 20 67 6c 6f 62 20 70  z matches glob p
1ba0: 61 74 74 65 72 6e 20 7a 47 6c 6f 62 2e 0a 2a 2a  attern zGlob..**
1bb0: 0a 2a 2a 20 47 6c 6f 62 62 69 6e 67 20 72 75 6c  .** Globbing rul
1bc0: 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 27  es:.**.**      '
1bd0: 2a 27 20 20 20 20 20 20 20 4d 61 74 63 68 65 73  *'       Matches
1be0: 20 61 6e 79 20 73 65 71 75 65 6e 63 65 20 6f 66   any sequence of
1bf0: 20 7a 65 72 6f 20 6f 72 20 6d 6f 72 65 20 63 68   zero or more ch
1c00: 61 72 61 63 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20  aracters..**.** 
1c10: 20 20 20 20 20 27 3f 27 20 20 20 20 20 20 20 4d       '?'       M
1c20: 61 74 63 68 65 73 20 65 78 61 63 74 6c 79 20 6f  atches exactly o
1c30: 6e 65 20 63 68 61 72 61 63 74 65 72 2e 0a 2a 2a  ne character..**
1c40: 0a 2a 2a 20 20 20 20 20 5b 2e 2e 2e 5d 20 20 20  .**     [...]   
1c50: 20 20 20 4d 61 74 63 68 65 73 20 6f 6e 65 20 63     Matches one c
1c60: 68 61 72 61 63 74 65 72 20 66 72 6f 6d 20 74 68  haracter from th
1c70: 65 20 65 6e 63 6c 6f 73 65 64 20 6c 69 73 74 20  e enclosed list 
1c80: 6f 66 0a 2a 2a 20 20 20 20 20 20 20 20 20 20 20  of.**           
1c90: 20 20 20 20 20 63 68 61 72 61 63 74 65 72 73 2e       characters.
1ca0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 5b 5e 2e 2e 2e  .**.**     [^...
1cb0: 5d 20 20 20 20 20 4d 61 74 63 68 65 73 20 6f 6e  ]     Matches on
1cc0: 65 20 63 68 61 72 61 63 74 65 72 20 6e 6f 74 20  e character not 
1cd0: 69 6e 20 74 68 65 20 65 6e 63 6c 6f 73 65 64 20  in the enclosed 
1ce0: 6c 69 73 74 2e 0a 2a 2a 0a 2a 2f 0a 73 74 61 74  list..**.*/.stat
1cf0: 69 63 20 69 6e 74 20 71 75 6f 74 61 53 74 72 67  ic int quotaStrg
1d00: 6c 6f 62 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  lob(const char *
1d10: 7a 47 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68 61  zGlob, const cha
1d20: 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20 63 2c 20  r *z){.  int c, 
1d30: 63 32 3b 0a 20 20 69 6e 74 20 69 6e 76 65 72 74  c2;.  int invert
1d40: 3b 0a 20 20 69 6e 74 20 73 65 65 6e 3b 0a 0a 20  ;.  int seen;.. 
1d50: 20 77 68 69 6c 65 28 20 28 63 20 3d 20 28 2a 28   while( (c = (*(
1d60: 7a 47 6c 6f 62 2b 2b 29 29 29 21 3d 30 20 29 7b  zGlob++)))!=0 ){
1d70: 0a 20 20 20 20 69 66 28 20 63 3d 3d 27 2a 27 20  .    if( c=='*' 
1d80: 29 7b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20  ){.      while( 
1d90: 28 63 3d 28 2a 28 7a 47 6c 6f 62 2b 2b 29 29 29  (c=(*(zGlob++)))
1da0: 20 3d 3d 20 27 2a 27 20 7c 7c 20 63 3d 3d 27 3f   == '*' || c=='?
1db0: 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  ' ){.        if(
1dc0: 20 63 3d 3d 27 3f 27 20 26 26 20 28 2a 28 7a 2b   c=='?' && (*(z+
1dd0: 2b 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  +))==0 ) return 
1de0: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  0;.      }.     
1df0: 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20   if( c==0 ){.   
1e00: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
1e10: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63       }else if( c
1e20: 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20 20 20 20  =='[' ){.       
1e30: 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 71 75   while( *z && qu
1e40: 6f 74 61 53 74 72 67 6c 6f 62 28 7a 47 6c 6f 62  otaStrglob(zGlob
1e50: 2d 31 2c 7a 29 3d 3d 30 20 29 7b 0a 20 20 20 20  -1,z)==0 ){.    
1e60: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20        z++;.     
1e70: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 72 65 74     }.        ret
1e80: 75 72 6e 20 28 2a 7a 29 21 3d 30 3b 0a 20 20 20  urn (*z)!=0;.   
1e90: 20 20 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65     }.      while
1ea0: 28 20 28 63 32 20 3d 20 28 2a 28 7a 2b 2b 29 29  ( (c2 = (*(z++))
1eb0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )!=0 ){.        
1ec0: 77 68 69 6c 65 28 20 63 32 21 3d 63 20 29 7b 0a  while( c2!=c ){.
1ed0: 20 20 20 20 20 20 20 20 20 20 63 32 20 3d 20 2a            c2 = *
1ee0: 28 7a 2b 2b 29 3b 0a 20 20 20 20 20 20 20 20 20  (z++);.         
1ef0: 20 69 66 28 20 63 32 3d 3d 30 20 29 20 72 65 74   if( c2==0 ) ret
1f00: 75 72 6e 20 30 3b 0a 20 20 20 20 20 20 20 20 7d  urn 0;.        }
1f10: 0a 20 20 20 20 20 20 20 20 69 66 28 20 71 75 6f  .        if( quo
1f20: 74 61 53 74 72 67 6c 6f 62 28 7a 47 6c 6f 62 2c  taStrglob(zGlob,
1f30: 7a 29 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  z) ) return 1;. 
1f40: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65 74       }.      ret
1f50: 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65  urn 0;.    }else
1f60: 20 69 66 28 20 63 3d 3d 27 3f 27 20 29 7b 0a 20   if( c=='?' ){. 
1f70: 20 20 20 20 20 69 66 28 20 28 2a 28 7a 2b 2b 29       if( (*(z++)
1f80: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  )==0 ) return 0;
1f90: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63  .    }else if( c
1fa0: 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20 20 20 69  =='[' ){.      i
1fb0: 6e 74 20 70 72 69 6f 72 5f 63 20 3d 20 30 3b 0a  nt prior_c = 0;.
1fc0: 20 20 20 20 20 20 73 65 65 6e 20 3d 20 30 3b 0a        seen = 0;.
1fd0: 20 20 20 20 20 20 69 6e 76 65 72 74 20 3d 20 30        invert = 0
1fe0: 3b 0a 20 20 20 20 20 20 63 20 3d 20 2a 28 7a 2b  ;.      c = *(z+
1ff0: 2b 29 3b 0a 20 20 20 20 20 20 69 66 28 20 63 3d  +);.      if( c=
2000: 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20  =0 ) return 0;. 
2010: 20 20 20 20 20 63 32 20 3d 20 2a 28 7a 47 6c 6f       c2 = *(zGlo
2020: 62 2b 2b 29 3b 0a 20 20 20 20 20 20 69 66 28 20  b++);.      if( 
2030: 63 32 3d 3d 27 5e 27 20 29 7b 0a 20 20 20 20 20  c2=='^' ){.     
2040: 20 20 20 69 6e 76 65 72 74 20 3d 20 31 3b 0a 20     invert = 1;. 
2050: 20 20 20 20 20 20 20 63 32 20 3d 20 2a 28 7a 47         c2 = *(zG
2060: 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20 20 7d 0a  lob++);.      }.
2070: 20 20 20 20 20 20 69 66 28 20 63 32 3d 3d 27 5d        if( c2==']
2080: 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28  ' ){.        if(
2090: 20 63 3d 3d 27 5d 27 20 29 20 73 65 65 6e 20 3d   c==']' ) seen =
20a0: 20 31 3b 0a 20 20 20 20 20 20 20 20 63 32 20 3d   1;.        c2 =
20b0: 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20   *(zGlob++);.   
20c0: 20 20 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65     }.      while
20d0: 28 20 63 32 20 26 26 20 63 32 21 3d 27 5d 27 20  ( c2 && c2!=']' 
20e0: 29 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63  ){.        if( c
20f0: 32 3d 3d 27 2d 27 20 26 26 20 7a 47 6c 6f 62 5b  2=='-' && zGlob[
2100: 30 5d 21 3d 27 5d 27 20 26 26 20 7a 47 6c 6f 62  0]!=']' && zGlob
2110: 5b 30 5d 21 3d 30 20 26 26 20 70 72 69 6f 72 5f  [0]!=0 && prior_
2120: 63 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  c>0 ){.         
2130: 20 63 32 20 3d 20 2a 28 7a 47 6c 6f 62 2b 2b 29   c2 = *(zGlob++)
2140: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
2150: 63 3e 3d 70 72 69 6f 72 5f 63 20 26 26 20 63 3c  c>=prior_c && c<
2160: 3d 63 32 20 29 20 73 65 65 6e 20 3d 20 31 3b 0a  =c2 ) seen = 1;.
2170: 20 20 20 20 20 20 20 20 20 20 70 72 69 6f 72 5f            prior_
2180: 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d  c = 0;.        }
2190: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
21a0: 69 66 28 20 63 3d 3d 63 32 20 29 7b 0a 20 20 20  if( c==c2 ){.   
21b0: 20 20 20 20 20 20 20 20 20 73 65 65 6e 20 3d 20           seen = 
21c0: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20  1;.          }. 
21d0: 20 20 20 20 20 20 20 20 20 70 72 69 6f 72 5f 63           prior_c
21e0: 20 3d 20 63 32 3b 0a 20 20 20 20 20 20 20 20 7d   = c2;.        }
21f0: 0a 20 20 20 20 20 20 20 20 63 32 20 3d 20 2a 28  .        c2 = *(
2200: 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20 20  zGlob++);.      
2210: 7d 0a 20 20 20 20 20 20 69 66 28 20 63 32 3d 3d  }.      if( c2==
2220: 30 20 7c 7c 20 28 73 65 65 6e 20 5e 20 69 6e 76  0 || (seen ^ inv
2230: 65 72 74 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  ert)==0 ) return
2240: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   0;.    }else{. 
2250: 20 20 20 20 20 69 66 28 20 63 21 3d 28 2a 28 7a       if( c!=(*(z
2260: 2b 2b 29 29 20 29 20 72 65 74 75 72 6e 20 30 3b  ++)) ) return 0;
2270: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
2280: 75 72 6e 20 2a 7a 3d 3d 30 3b 0a 7d 0a 0a 0a 2f  urn *z==0;.}.../
2290: 2a 20 46 69 6e 64 20 61 20 71 75 6f 74 61 47 72  * Find a quotaGr
22a0: 6f 75 70 20 67 69 76 65 6e 20 74 68 65 20 66 69  oup given the fi
22b0: 6c 65 6e 61 6d 65 2e 0a 2a 2a 0a 2a 2a 20 52 65  lename..**.** Re
22c0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
22d0: 6f 20 74 68 65 20 71 75 6f 74 61 47 72 6f 75 70  o the quotaGroup
22e0: 20 6f 62 6a 65 63 74 2e 20 52 65 74 75 72 6e 20   object. Return 
22f0: 4e 55 4c 4c 20 69 66 20 6e 6f 74 20 66 6f 75 6e  NULL if not foun
2300: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 71 75 6f  d..*/.static quo
2310: 74 61 47 72 6f 75 70 20 2a 71 75 6f 74 61 47 72  taGroup *quotaGr
2320: 6f 75 70 46 69 6e 64 28 63 6f 6e 73 74 20 63 68  oupFind(const ch
2330: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a  ar *zFilename){.
2340: 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 3b    quotaGroup *p;
2350: 0a 20 20 66 6f 72 28 70 3d 67 51 75 6f 74 61 2e  .  for(p=gQuota.
2360: 70 47 72 6f 75 70 3b 20 70 20 26 26 20 71 75 6f  pGroup; p && quo
2370: 74 61 53 74 72 67 6c 6f 62 28 70 2d 3e 7a 50 61  taStrglob(p->zPa
2380: 74 74 65 72 6e 2c 20 7a 46 69 6c 65 6e 61 6d 65  ttern, zFilename
2390: 29 3d 3d 30 3b 0a 20 20 20 20 20 20 70 3d 70 2d  )==0;.      p=p-
23a0: 3e 70 4e 65 78 74 29 7b 7d 0a 20 20 72 65 74 75  >pNext){}.  retu
23b0: 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 20 54 72 61 6e  rn p;.}../* Tran
23c0: 73 6c 61 74 65 20 61 6e 20 73 71 6c 69 74 65 33  slate an sqlite3
23d0: 5f 66 69 6c 65 2a 20 74 68 61 74 20 69 73 20 72  _file* that is r
23e0: 65 61 6c 6c 79 20 61 20 71 75 6f 74 61 43 6f 6e  eally a quotaCon
23f0: 6e 2a 20 69 6e 74 6f 0a 2a 2a 20 74 68 65 20 73  n* into.** the s
2400: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 20 66 6f 72  qlite3_file* for
2410: 20 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20   the underlying 
2420: 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 0a 2a 2f  original VFS..*/
2430: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
2440: 66 69 6c 65 20 2a 71 75 6f 74 61 53 75 62 4f 70  file *quotaSubOp
2450: 65 6e 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  en(sqlite3_file 
2460: 2a 70 43 6f 6e 6e 29 7b 0a 20 20 71 75 6f 74 61  *pConn){.  quota
2470: 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f 74 61  Conn *p = (quota
2480: 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 72  Conn*)pConn;.  r
2490: 65 74 75 72 6e 20 28 73 71 6c 69 74 65 33 5f 66  eturn (sqlite3_f
24a0: 69 6c 65 2a 29 26 70 5b 31 5d 3b 0a 7d 0a 0a 2f  ile*)&p[1];.}../
24b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
24c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 56 46 53 20 4d 65  ********* VFS Me
24d0: 74 68 6f 64 20 57 72 61 70 70 65 72 73 20 2a 2a  thod Wrappers **
24e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
24f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a  ***********/./*.
2500: 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78  ** This is the x
2510: 4f 70 65 6e 20 6d 65 74 68 6f 64 20 75 73 65 64  Open method used
2520: 20 66 6f 72 20 74 68 65 20 22 71 75 6f 74 61 22   for the "quota"
2530: 20 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 73 74   VFS..**.** Most
2540: 20 6f 66 20 74 68 65 20 77 6f 72 6b 20 69 73 20   of the work is 
2550: 64 6f 6e 65 20 62 79 20 74 68 65 20 75 6e 64 65  done by the unde
2560: 72 6c 79 69 6e 67 20 6f 72 69 67 69 6e 61 6c 20  rlying original 
2570: 56 46 53 2e 20 20 54 68 69 73 20 6d 65 74 68 6f  VFS.  This metho
2580: 64 0a 2a 2a 20 73 69 6d 70 6c 79 20 6c 69 6e 6b  d.** simply link
2590: 73 20 74 68 65 20 6e 65 77 20 66 69 6c 65 20 69  s the new file i
25a0: 6e 74 6f 20 74 68 65 20 61 70 70 72 6f 70 72 69  nto the appropri
25b0: 61 74 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20  ate quota group 
25c0: 69 66 20 69 74 20 69 73 20 61 0a 2a 2a 20 66 69  if it is a.** fi
25d0: 6c 65 20 74 68 61 74 20 6e 65 65 64 73 20 74 6f  le that needs to
25e0: 20 62 65 20 74 72 61 63 6b 65 64 2e 0a 2a 2f 0a   be tracked..*/.
25f0: 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61  static int quota
2600: 4f 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f  Open(.  sqlite3_
2610: 76 66 73 20 2a 70 56 66 73 2c 20 20 20 20 20 20  vfs *pVfs,      
2620: 20 20 20 20 2f 2a 20 54 68 65 20 71 75 6f 74 61      /* The quota
2630: 20 56 46 53 20 2a 2f 0a 20 20 63 6f 6e 73 74 20   VFS */.  const 
2640: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20  char *zName,    
2650: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
2660: 20 66 69 6c 65 20 74 6f 20 62 65 20 6f 70 65 6e   file to be open
2670: 65 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  ed */.  sqlite3_
2680: 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20  file *pConn,    
2690: 20 20 20 20 2f 2a 20 46 69 6c 6c 20 69 6e 20 74      /* Fill in t
26a0: 68 69 73 20 66 69 6c 65 20 64 65 73 63 72 69 70  his file descrip
26b0: 74 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61  tor */.  int fla
26c0: 67 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  gs,             
26d0: 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f       /* Flags to
26e0: 20 63 6f 6e 74 72 6f 6c 20 74 68 65 20 6f 70 65   control the ope
26f0: 6e 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  ning */.  int *p
2700: 4f 75 74 46 6c 61 67 73 20 20 20 20 20 20 20 20  OutFlags        
2710: 20 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 73        /* Flags s
2720: 68 6f 77 69 6e 67 20 72 65 73 75 6c 74 73 20 6f  howing results o
2730: 66 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a 29 7b 0a  f opening */.){.
2740: 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20    int rc;       
2750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2760: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2770: 52 65 73 75 6c 74 20 63 6f 64 65 20 2a 2f 20 20  Result code */  
2780: 20 20 20 20 20 20 20 0a 20 20 71 75 6f 74 61 43         .  quotaC
2790: 6f 6e 6e 20 2a 70 51 75 6f 74 61 4f 70 65 6e 3b  onn *pQuotaOpen;
27a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
27b0: 20 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20       /* The new 
27c0: 71 75 6f 74 61 20 66 69 6c 65 20 64 65 73 63 72  quota file descr
27d0: 69 70 74 6f 72 20 2a 2f 0a 20 20 71 75 6f 74 61  iptor */.  quota
27e0: 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20  File *pFile;    
27f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2800: 20 20 20 20 20 20 2f 2a 20 43 6f 72 72 65 73 70        /* Corresp
2810: 6f 6e 64 69 6e 67 20 71 75 6f 74 61 46 69 6c 65  onding quotaFile
2820: 20 6f 62 6a 20 2a 2f 0a 20 20 71 75 6f 74 61 47   obj */.  quotaG
2830: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20  roup *pGroup;   
2840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2850: 20 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75       /* The grou
2860: 70 20 66 69 6c 65 20 62 65 6c 6f 6e 67 73 20 74  p file belongs t
2870: 6f 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  o */.  sqlite3_f
2880: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 3b 20 20  ile *pSubOpen;  
2890: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
28a0: 20 20 2f 2a 20 52 65 61 6c 20 66 69 6c 65 20 64    /* Real file d
28b0: 65 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20 20 73  escriptor */.  s
28c0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69  qlite3_vfs *pOri
28d0: 67 56 66 73 20 3d 20 67 51 75 6f 74 61 2e 70 4f  gVfs = gQuota.pO
28e0: 72 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61  rigVfs;   /* Rea
28f0: 6c 20 56 46 53 20 2a 2f 0a 0a 20 20 2f 2a 20 49  l VFS */..  /* I
2900: 66 20 74 68 65 20 66 69 6c 65 20 69 73 20 6e 6f  f the file is no
2910: 74 20 61 20 6d 61 69 6e 20 64 61 74 61 62 61 73  t a main databas
2920: 65 20 66 69 6c 65 20 6f 72 20 61 20 57 41 4c 2c  e file or a WAL,
2930: 20 74 68 65 6e 20 75 73 65 20 74 68 65 0a 20 20   then use the.  
2940: 2a 2a 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20  ** normal xOpen 
2950: 6d 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 69  method..  */.  i
2960: 66 28 20 28 66 6c 61 67 73 20 26 20 28 53 51 4c  f( (flags & (SQL
2970: 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42  ITE_OPEN_MAIN_DB
2980: 7c 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c  |SQLITE_OPEN_WAL
2990: 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  ))==0 ){.    ret
29a0: 75 72 6e 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f  urn pOrigVfs->xO
29b0: 70 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e  pen(pOrigVfs, zN
29c0: 61 6d 65 2c 20 70 43 6f 6e 6e 2c 20 66 6c 61 67  ame, pConn, flag
29d0: 73 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20  s, pOutFlags);. 
29e0: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20   }..  /* If the 
29f0: 6e 61 6d 65 20 6f 66 20 74 68 65 20 66 69 6c 65  name of the file
2a00: 20 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20   does not match 
2a10: 61 6e 79 20 71 75 6f 74 61 20 67 72 6f 75 70 2c  any quota group,
2a20: 20 74 68 65 6e 0a 20 20 2a 2a 20 75 73 65 20 74   then.  ** use t
2a30: 68 65 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20  he normal xOpen 
2a40: 6d 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 71  method..  */.  q
2a50: 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70  uotaEnter();.  p
2a60: 47 72 6f 75 70 20 3d 20 71 75 6f 74 61 47 72 6f  Group = quotaGro
2a70: 75 70 46 69 6e 64 28 7a 4e 61 6d 65 29 3b 0a 20  upFind(zName);. 
2a80: 20 69 66 28 20 70 47 72 6f 75 70 3d 3d 30 20 29   if( pGroup==0 )
2a90: 7b 0a 20 20 20 20 72 63 20 3d 20 70 4f 72 69 67  {.    rc = pOrig
2aa0: 56 66 73 2d 3e 78 4f 70 65 6e 28 70 4f 72 69 67  Vfs->xOpen(pOrig
2ab0: 56 66 73 2c 20 7a 4e 61 6d 65 2c 20 70 43 6f 6e  Vfs, zName, pCon
2ac0: 6e 2c 20 66 6c 61 67 73 2c 20 70 4f 75 74 46 6c  n, flags, pOutFl
2ad0: 61 67 73 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ags);.  }else{. 
2ae0: 20 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20     /* If we get 
2af0: 74 6f 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 69  to this point, i
2b00: 74 20 6d 65 61 6e 73 20 74 68 65 20 66 69 6c 65  t means the file
2b10: 20 6e 65 65 64 73 20 74 6f 20 62 65 20 71 75 6f   needs to be quo
2b20: 74 61 20 74 72 61 63 6b 65 64 2e 0a 20 20 20 20  ta tracked..    
2b30: 2a 2f 0a 20 20 20 20 70 51 75 6f 74 61 4f 70 65  */.    pQuotaOpe
2b40: 6e 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29  n = (quotaConn*)
2b50: 70 43 6f 6e 6e 3b 0a 20 20 20 20 70 53 75 62 4f  pConn;.    pSubO
2b60: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
2b70: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 20 20 72  en(pConn);.    r
2b80: 63 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f  c = pOrigVfs->xO
2b90: 70 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e  pen(pOrigVfs, zN
2ba0: 61 6d 65 2c 20 70 53 75 62 4f 70 65 6e 2c 20 66  ame, pSubOpen, f
2bb0: 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29  lags, pOutFlags)
2bc0: 3b 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51  ;.    if( rc==SQ
2bd0: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20  LITE_OK ){.     
2be0: 20 66 6f 72 28 70 46 69 6c 65 3d 70 47 72 6f 75   for(pFile=pGrou
2bf0: 70 2d 3e 70 46 69 6c 65 73 3b 20 70 46 69 6c 65  p->pFiles; pFile
2c00: 20 26 26 20 73 74 72 63 6d 70 28 70 46 69 6c 65   && strcmp(pFile
2c10: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 7a 4e 61  ->zFilename, zNa
2c20: 6d 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 70  me);.          p
2c30: 46 69 6c 65 3d 70 46 69 6c 65 2d 3e 70 4e 65 78  File=pFile->pNex
2c40: 74 29 7b 7d 0a 20 20 20 20 20 20 69 66 28 20 70  t){}.      if( p
2c50: 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20  File==0 ){.     
2c60: 20 20 20 69 6e 74 20 6e 4e 61 6d 65 20 3d 20 73     int nName = s
2c70: 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 3b 0a 20 20  trlen(zName);.  
2c80: 20 20 20 20 20 20 70 46 69 6c 65 20 3d 20 73 71        pFile = sq
2c90: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69  lite3_malloc( si
2ca0: 7a 65 6f 66 28 2a 70 46 69 6c 65 29 20 2b 20 6e  zeof(*pFile) + n
2cb0: 4e 61 6d 65 20 2b 20 31 20 29 3b 0a 20 20 20 20  Name + 1 );.    
2cc0: 20 20 20 20 69 66 28 20 70 46 69 6c 65 3d 3d 30      if( pFile==0
2cd0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 71 75   ){.          qu
2ce0: 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 20 20  otaLeave();.    
2cf0: 20 20 20 20 20 20 70 53 75 62 4f 70 65 6e 2d 3e        pSubOpen->
2d00: 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65  pMethods->xClose
2d10: 28 70 53 75 62 4f 70 65 6e 29 3b 0a 20 20 20 20  (pSubOpen);.    
2d20: 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c        return SQL
2d30: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
2d40: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 6d 65 6d     }.        mem
2d50: 73 65 74 28 70 46 69 6c 65 2c 20 30 2c 20 73 69  set(pFile, 0, si
2d60: 7a 65 6f 66 28 2a 70 46 69 6c 65 29 29 3b 0a 20  zeof(*pFile));. 
2d70: 20 20 20 20 20 20 20 70 46 69 6c 65 2d 3e 7a 46         pFile->zF
2d80: 69 6c 65 6e 61 6d 65 20 3d 20 28 63 68 61 72 2a  ilename = (char*
2d90: 29 26 70 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20  )&pFile[1];.    
2da0: 20 20 20 20 6d 65 6d 63 70 79 28 70 46 69 6c 65      memcpy(pFile
2db0: 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 7a 4e 61  ->zFilename, zNa
2dc0: 6d 65 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20  me, nName+1);.  
2dd0: 20 20 20 20 20 20 70 46 69 6c 65 2d 3e 70 4e 65        pFile->pNe
2de0: 78 74 20 3d 20 70 47 72 6f 75 70 2d 3e 70 46 69  xt = pGroup->pFi
2df0: 6c 65 73 3b 0a 20 20 20 20 20 20 20 20 69 66 28  les;.        if(
2e00: 20 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 20   pGroup->pFiles 
2e10: 29 20 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73  ) pGroup->pFiles
2e20: 2d 3e 70 70 50 72 65 76 20 3d 20 26 70 46 69 6c  ->ppPrev = &pFil
2e30: 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20  e->pNext;.      
2e40: 20 20 70 46 69 6c 65 2d 3e 70 70 50 72 65 76 20    pFile->ppPrev 
2e50: 3d 20 26 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65  = &pGroup->pFile
2e60: 73 3b 0a 20 20 20 20 20 20 20 20 70 47 72 6f 75  s;.        pGrou
2e70: 70 2d 3e 70 46 69 6c 65 73 20 3d 20 70 46 69 6c  p->pFiles = pFil
2e80: 65 3b 0a 20 20 20 20 20 20 20 20 70 46 69 6c 65  e;.        pFile
2e90: 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75  ->pGroup = pGrou
2ea0: 70 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  p;.      }.     
2eb0: 20 70 46 69 6c 65 2d 3e 6e 52 65 66 2b 2b 3b 0a   pFile->nRef++;.
2ec0: 20 20 20 20 20 20 70 51 75 6f 74 61 4f 70 65 6e        pQuotaOpen
2ed0: 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 3b  ->pFile = pFile;
2ee0: 0a 20 20 20 20 20 20 69 66 28 20 70 53 75 62 4f  .      if( pSubO
2ef0: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 69  pen->pMethods->i
2f00: 56 65 72 73 69 6f 6e 3d 3d 31 20 29 7b 0a 20 20  Version==1 ){.  
2f10: 20 20 20 20 20 20 70 51 75 6f 74 61 4f 70 65 6e        pQuotaOpen
2f20: 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f 64 73 20  ->base.pMethods 
2f30: 3d 20 26 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  = &gQuota.sIoMet
2f40: 68 6f 64 73 56 31 3b 0a 20 20 20 20 20 20 7d 65  hodsV1;.      }e
2f50: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 51 75  lse{.        pQu
2f60: 6f 74 61 4f 70 65 6e 2d 3e 62 61 73 65 2e 70 4d  otaOpen->base.pM
2f70: 65 74 68 6f 64 73 20 3d 20 26 67 51 75 6f 74 61  ethods = &gQuota
2f80: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b 0a 20  .sIoMethodsV2;. 
2f90: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
2fa0: 0a 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b  .  quotaLeave();
2fb0: 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a  .  return rc;.}.
2fc0: 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ./**************
2fd0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 49 2f 4f 20 4d  ********** I/O M
2fe0: 65 74 68 6f 64 20 57 72 61 70 70 65 72 73 20 2a  ethod Wrappers *
2ff0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3000: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a  **************/.
3010: 0a 2f 2a 20 78 43 6c 6f 73 65 20 72 65 71 75 65  ./* xClose reque
3020: 73 74 73 20 67 65 74 20 70 61 73 73 65 64 20 74  sts get passed t
3030: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
3040: 69 67 69 6e 61 6c 20 56 46 53 2e 20 20 42 75 74  iginal VFS.  But
3050: 20 77 65 0a 2a 2a 20 61 6c 73 6f 20 68 61 76 65   we.** also have
3060: 20 74 6f 20 75 6e 6c 69 6e 6b 20 74 68 65 20 71   to unlink the q
3070: 75 6f 74 61 43 6f 6e 6e 20 66 72 6f 6d 20 74 68  uotaConn from th
3080: 65 20 71 75 6f 74 61 46 69 6c 65 20 61 6e 64 20  e quotaFile and 
3090: 71 75 6f 74 61 47 72 6f 75 70 2e 0a 2a 2a 20 54  quotaGroup..** T
30a0: 68 65 20 71 75 6f 74 61 46 69 6c 65 20 61 6e 64  he quotaFile and
30b0: 2f 6f 72 20 71 75 6f 74 61 47 72 6f 75 70 20 61  /or quotaGroup a
30c0: 72 65 20 66 72 65 65 64 20 69 66 20 74 68 65 79  re freed if they
30d0: 20 61 72 65 20 6e 6f 20 6c 6f 6e 67 65 72 20 69   are no longer i
30e0: 6e 20 75 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  n use..*/.static
30f0: 20 69 6e 74 20 71 75 6f 74 61 43 6c 6f 73 65 28   int quotaClose(
3100: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
3110: 6f 6e 6e 29 7b 0a 20 20 71 75 6f 74 61 43 6f 6e  onn){.  quotaCon
3120: 6e 20 2a 70 20 3d 20 28 71 75 6f 74 61 43 6f 6e  n *p = (quotaCon
3130: 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 71 75 6f 74  n*)pConn;.  quot
3140: 61 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70  aFile *pFile = p
3150: 2d 3e 70 46 69 6c 65 3b 0a 20 20 73 71 6c 69 74  ->pFile;.  sqlit
3160: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
3170: 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e  n = quotaSubOpen
3180: 28 70 43 6f 6e 6e 29 3b 0a 20 20 69 6e 74 20 72  (pConn);.  int r
3190: 63 3b 0a 20 20 72 63 20 3d 20 70 53 75 62 4f 70  c;.  rc = pSubOp
31a0: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43  en->pMethods->xC
31b0: 6c 6f 73 65 28 70 53 75 62 4f 70 65 6e 29 3b 0a  lose(pSubOpen);.
31c0: 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a    quotaEnter();.
31d0: 20 20 70 46 69 6c 65 2d 3e 6e 52 65 66 2d 2d 3b    pFile->nRef--;
31e0: 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 6e 52  .  if( pFile->nR
31f0: 65 66 3d 3d 30 20 29 7b 0a 20 20 20 20 71 75 6f  ef==0 ){.    quo
3200: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20  taGroup *pGroup 
3210: 3d 20 70 46 69 6c 65 2d 3e 70 47 72 6f 75 70 3b  = pFile->pGroup;
3220: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 69 53 69  .    pGroup->iSi
3230: 7a 65 20 2d 3d 20 70 46 69 6c 65 2d 3e 69 53 69  ze -= pFile->iSi
3240: 7a 65 3b 0a 20 20 20 20 69 66 28 20 70 46 69 6c  ze;.    if( pFil
3250: 65 2d 3e 70 4e 65 78 74 20 29 20 70 46 69 6c 65  e->pNext ) pFile
3260: 2d 3e 70 4e 65 78 74 2d 3e 70 70 50 72 65 76 20  ->pNext->ppPrev 
3270: 3d 20 70 46 69 6c 65 2d 3e 70 70 50 72 65 76 3b  = pFile->ppPrev;
3280: 0a 20 20 20 20 2a 70 46 69 6c 65 2d 3e 70 70 50  .    *pFile->ppP
3290: 72 65 76 20 3d 20 70 46 69 6c 65 2d 3e 70 4e 65  rev = pFile->pNe
32a0: 78 74 3b 0a 20 20 20 20 71 75 6f 74 61 47 72 6f  xt;.    quotaGro
32b0: 75 70 44 65 72 65 66 28 70 47 72 6f 75 70 29 3b  upDeref(pGroup);
32c0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
32d0: 65 28 70 46 69 6c 65 29 3b 0a 20 20 7d 0a 20 20  e(pFile);.  }.  
32e0: 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20  quotaLeave();.  
32f0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
3300: 20 50 61 73 73 20 78 52 65 61 64 20 72 65 71 75   Pass xRead requ
3310: 65 73 74 73 20 64 69 72 65 63 74 6f 72 79 20 74  ests directory t
3320: 68 72 75 20 74 6f 20 74 68 65 20 6f 72 69 67 69  hru to the origi
3330: 6e 61 6c 20 56 46 53 20 77 69 74 68 6f 75 74 0a  nal VFS without.
3340: 2a 2a 20 66 75 72 74 68 65 72 20 70 72 6f 63 65  ** further proce
3350: 73 73 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  ssing..*/.static
3360: 20 69 6e 74 20 71 75 6f 74 61 52 65 61 64 28 0a   int quotaRead(.
3370: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3380: 70 43 6f 6e 6e 2c 0a 20 20 76 6f 69 64 20 2a 70  pConn,.  void *p
3390: 42 75 66 2c 0a 20 20 69 6e 74 20 69 41 6d 74 2c  Buf,.  int iAmt,
33a0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
33b0: 20 69 4f 66 73 74 0a 29 7b 0a 20 20 73 71 6c 69   iOfst.){.  sqli
33c0: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
33d0: 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65  en = quotaSubOpe
33e0: 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75  n(pConn);.  retu
33f0: 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65  rn pSubOpen->pMe
3400: 74 68 6f 64 73 2d 3e 78 52 65 61 64 28 70 53 75  thods->xRead(pSu
3410: 62 4f 70 65 6e 2c 20 70 42 75 66 2c 20 69 41 6d  bOpen, pBuf, iAm
3420: 74 2c 20 69 4f 66 73 74 29 3b 0a 7d 0a 0a 2f 2a  t, iOfst);.}../*
3430: 20 43 68 65 63 6b 20 78 57 72 69 74 65 20 72 65   Check xWrite re
3440: 71 75 65 73 74 73 20 74 6f 20 73 65 65 20 69 66  quests to see if
3450: 20 74 68 65 79 20 65 78 70 61 6e 64 20 74 68 65   they expand the
3460: 20 66 69 6c 65 2e 20 20 49 66 20 74 68 65 79 20   file.  If they 
3470: 64 6f 2c 0a 2a 2a 20 74 68 65 20 70 65 72 66 6f  do,.** the perfo
3480: 72 6d 20 61 20 71 75 6f 74 61 20 63 68 65 63 6b  rm a quota check
3490: 20 62 65 66 6f 72 65 20 70 61 73 73 69 6e 67 20   before passing 
34a0: 74 68 65 6d 20 74 68 72 6f 75 67 68 20 74 6f 20  them through to 
34b0: 74 68 65 0a 2a 2a 20 6f 72 69 67 69 6e 61 6c 20  the.** original 
34c0: 56 46 53 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  VFS..*/.static i
34d0: 6e 74 20 71 75 6f 74 61 57 72 69 74 65 28 0a 20  nt quotaWrite(. 
34e0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
34f0: 43 6f 6e 6e 2c 0a 20 20 63 6f 6e 73 74 20 76 6f  Conn,.  const vo
3500: 69 64 20 2a 70 42 75 66 2c 0a 20 20 69 6e 74 20  id *pBuf,.  int 
3510: 69 41 6d 74 2c 0a 20 20 73 71 6c 69 74 65 33 5f  iAmt,.  sqlite3_
3520: 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a 20  int64 iOfst.){. 
3530: 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20   quotaConn *p = 
3540: 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e  (quotaConn*)pCon
3550: 6e 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  n;.  sqlite3_fil
3560: 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75  e *pSubOpen = qu
3570: 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e  otaSubOpen(pConn
3580: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  );.  sqlite3_int
3590: 36 34 20 69 45 6e 64 20 3d 20 69 4f 66 73 74 2b  64 iEnd = iOfst+
35a0: 69 41 6d 74 3b 0a 20 20 71 75 6f 74 61 47 72 6f  iAmt;.  quotaGro
35b0: 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 71 75  up *pGroup;.  qu
35c0: 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d  otaFile *pFile =
35d0: 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20 73 71 6c   p->pFile;.  sql
35e0: 69 74 65 33 5f 69 6e 74 36 34 20 73 7a 4e 65 77  ite3_int64 szNew
35f0: 3b 0a 0a 20 20 69 66 28 20 70 46 69 6c 65 2d 3e  ;..  if( pFile->
3600: 69 53 69 7a 65 3c 69 45 6e 64 20 29 7b 0a 20 20  iSize<iEnd ){.  
3610: 20 20 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65    pGroup = pFile
3620: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 71 75  ->pGroup;.    qu
3630: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 20 20  otaEnter();.    
3640: 73 7a 4e 65 77 20 3d 20 70 47 72 6f 75 70 2d 3e  szNew = pGroup->
3650: 69 53 69 7a 65 20 2d 20 70 46 69 6c 65 2d 3e 69  iSize - pFile->i
3660: 53 69 7a 65 20 2b 20 69 45 6e 64 3b 0a 20 20 20  Size + iEnd;.   
3670: 20 69 66 28 20 73 7a 4e 65 77 3e 70 47 72 6f 75   if( szNew>pGrou
3680: 70 2d 3e 69 4c 69 6d 69 74 20 26 26 20 70 47 72  p->iLimit && pGr
3690: 6f 75 70 2d 3e 69 4c 69 6d 69 74 3e 30 20 29 7b  oup->iLimit>0 ){
36a0: 0a 20 20 20 20 20 20 69 66 28 20 70 47 72 6f 75  .      if( pGrou
36b0: 70 2d 3e 78 43 61 6c 6c 62 61 63 6b 20 29 7b 0a  p->xCallback ){.
36c0: 20 20 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e          pGroup->
36d0: 78 43 61 6c 6c 62 61 63 6b 28 70 46 69 6c 65 2d  xCallback(pFile-
36e0: 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 26 70 47 72  >zFilename, &pGr
36f0: 6f 75 70 2d 3e 69 4c 69 6d 69 74 2c 20 73 7a 4e  oup->iLimit, szN
3700: 65 77 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20  ew, .           
3710: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70                 p
3720: 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a 20 20  Group->pArg);.  
3730: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
3740: 73 7a 4e 65 77 3e 70 47 72 6f 75 70 2d 3e 69 4c  szNew>pGroup->iL
3750: 69 6d 69 74 20 26 26 20 70 47 72 6f 75 70 2d 3e  imit && pGroup->
3760: 69 4c 69 6d 69 74 3e 30 20 29 7b 0a 20 20 20 20  iLimit>0 ){.    
3770: 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29      quotaLeave()
3780: 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72 6e  ;.        return
3790: 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3b 0a 20 20   SQLITE_FULL;.  
37a0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20      }.    }.    
37b0: 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20 3d 20  pGroup->iSize = 
37c0: 73 7a 4e 65 77 3b 0a 20 20 20 20 70 46 69 6c 65  szNew;.    pFile
37d0: 2d 3e 69 53 69 7a 65 20 3d 20 69 45 6e 64 3b 0a  ->iSize = iEnd;.
37e0: 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29      quotaLeave()
37f0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 70  ;.  }.  return p
3800: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
3810: 73 2d 3e 78 57 72 69 74 65 28 70 53 75 62 4f 70  s->xWrite(pSubOp
3820: 65 6e 2c 20 70 42 75 66 2c 20 69 41 6d 74 2c 20  en, pBuf, iAmt, 
3830: 69 4f 66 73 74 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  iOfst);.}../* Pa
3840: 73 73 20 78 54 72 75 6e 63 61 74 65 20 72 65 71  ss xTruncate req
3850: 75 65 73 74 73 20 74 68 72 75 20 74 6f 20 74 68  uests thru to th
3860: 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e 20  e original VFS. 
3870: 20 49 66 20 74 68 65 0a 2a 2a 20 73 75 63 63 65   If the.** succe
3880: 73 73 2c 20 75 70 64 61 74 65 20 74 68 65 20 66  ss, update the f
3890: 69 6c 65 20 73 69 7a 65 2e 0a 2a 2f 0a 73 74 61  ile size..*/.sta
38a0: 74 69 63 20 69 6e 74 20 71 75 6f 74 61 54 72 75  tic int quotaTru
38b0: 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69  ncate(sqlite3_fi
38c0: 6c 65 20 2a 70 43 6f 6e 6e 2c 20 73 71 6c 69 74  le *pConn, sqlit
38d0: 65 33 5f 69 6e 74 36 34 20 73 69 7a 65 29 7b 0a  e3_int64 size){.
38e0: 20 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d    quotaConn *p =
38f0: 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f   (quotaConn*)pCo
3900: 6e 6e 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  nn;.  sqlite3_fi
3910: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71  le *pSubOpen = q
3920: 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e  uotaSubOpen(pCon
3930: 6e 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 70  n);.  int rc = p
3940: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
3950: 73 2d 3e 78 54 72 75 6e 63 61 74 65 28 70 53 75  s->xTruncate(pSu
3960: 62 4f 70 65 6e 2c 20 73 69 7a 65 29 3b 0a 20 20  bOpen, size);.  
3970: 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65  quotaFile *pFile
3980: 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20 71   = p->pFile;.  q
3990: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
39a0: 70 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  p;.  if( rc==SQL
39b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 71 75  ITE_OK ){.    qu
39c0: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 20 20  otaEnter();.    
39d0: 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65 2d 3e  pGroup = pFile->
39e0: 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47 72 6f  pGroup;.    pGro
39f0: 75 70 2d 3e 69 53 69 7a 65 20 2d 3d 20 70 46 69  up->iSize -= pFi
3a00: 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20 20 20 70  le->iSize;.    p
3a10: 46 69 6c 65 2d 3e 69 53 69 7a 65 20 3d 20 73 69  File->iSize = si
3a20: 7a 65 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  ze;.    pGroup->
3a30: 69 53 69 7a 65 20 2b 3d 20 73 69 7a 65 3b 0a 20  iSize += size;. 
3a40: 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b     quotaLeave();
3a50: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63  .  }.  return rc
3a60: 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 79  ;.}../* Pass xSy
3a70: 6e 63 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  nc requests thro
3a80: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
3a90: 6e 61 6c 20 56 46 53 20 77 69 74 68 6f 75 74 20  nal VFS without 
3aa0: 63 68 61 6e 67 65 0a 2a 2f 0a 73 74 61 74 69 63  change.*/.static
3ab0: 20 69 6e 74 20 71 75 6f 74 61 53 79 6e 63 28 73   int quotaSync(s
3ac0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
3ad0: 6e 6e 2c 20 69 6e 74 20 66 6c 61 67 73 29 7b 0a  nn, int flags){.
3ae0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3af0: 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61  pSubOpen = quota
3b00: 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a  SubOpen(pConn);.
3b10: 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65    return pSubOpe
3b20: 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 79  n->pMethods->xSy
3b30: 6e 63 28 70 53 75 62 4f 70 65 6e 2c 20 66 6c 61  nc(pSubOpen, fla
3b40: 67 73 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20  gs);.}../* Pass 
3b50: 78 46 69 6c 65 53 69 7a 65 20 72 65 71 75 65 73  xFileSize reques
3b60: 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68  ts through to th
3b70: 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 62  e original VFS b
3b80: 75 74 20 74 68 65 6e 0a 2a 2a 20 75 70 64 61 74  ut then.** updat
3b90: 65 20 74 68 65 20 71 75 6f 74 61 47 72 6f 75 70  e the quotaGroup
3ba0: 20 77 69 74 68 20 74 68 65 20 6e 65 77 20 73 69   with the new si
3bb0: 7a 65 20 62 65 66 6f 72 65 20 72 65 74 75 72 6e  ze before return
3bc0: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ing..*/.static i
3bd0: 6e 74 20 71 75 6f 74 61 46 69 6c 65 53 69 7a 65  nt quotaFileSize
3be0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
3bf0: 43 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f 69 6e  Conn, sqlite3_in
3c00: 74 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20 71  t64 *pSize){.  q
3c10: 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71  uotaConn *p = (q
3c20: 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b  uotaConn*)pConn;
3c30: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
3c40: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74  *pSubOpen = quot
3c50: 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b  aSubOpen(pConn);
3c60: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46  .  quotaFile *pF
3c70: 69 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a  ile = p->pFile;.
3c80: 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47    quotaGroup *pG
3c90: 72 6f 75 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f  roup;.  sqlite3_
3ca0: 69 6e 74 36 34 20 73 7a 3b 0a 20 20 69 6e 74 20  int64 sz;.  int 
3cb0: 72 63 3b 0a 0a 20 20 72 63 20 3d 20 70 53 75 62  rc;..  rc = pSub
3cc0: 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e  Open->pMethods->
3cd0: 78 46 69 6c 65 53 69 7a 65 28 70 53 75 62 4f 70  xFileSize(pSubOp
3ce0: 65 6e 2c 20 26 73 7a 29 3b 0a 20 20 69 66 28 20  en, &sz);.  if( 
3cf0: 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b  rc==SQLITE_OK ){
3d00: 0a 20 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28  .    quotaEnter(
3d10: 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20  );.    pGroup = 
3d20: 70 46 69 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  pFile->pGroup;. 
3d30: 20 20 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65     pGroup->iSize
3d40: 20 2d 3d 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65   -= pFile->iSize
3d50: 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e 69 53 69  ;.    pFile->iSi
3d60: 7a 65 20 3d 20 73 7a 3b 0a 20 20 20 20 70 47 72  ze = sz;.    pGr
3d70: 6f 75 70 2d 3e 69 53 69 7a 65 20 2b 3d 20 73 7a  oup->iSize += sz
3d80: 3b 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65  ;.    quotaLeave
3d90: 28 29 3b 0a 20 20 20 20 2a 70 53 69 7a 65 20 3d  ();.    *pSize =
3da0: 20 73 7a 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72   sz;.  }.  retur
3db0: 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  n rc;.}../* Pass
3dc0: 20 78 4c 6f 63 6b 20 72 65 71 75 65 73 74 73 20   xLock requests 
3dd0: 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f  through to the o
3de0: 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68  riginal VFS unch
3df0: 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63  anged..*/.static
3e00: 20 69 6e 74 20 71 75 6f 74 61 4c 6f 63 6b 28 73   int quotaLock(s
3e10: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
3e20: 6e 6e 2c 20 69 6e 74 20 6c 6f 63 6b 29 7b 0a 20  nn, int lock){. 
3e30: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
3e40: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
3e50: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
3e60: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
3e70: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 4c 6f 63  ->pMethods->xLoc
3e80: 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6c 6f 63 6b  k(pSubOpen, lock
3e90: 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 55  );.}../* Pass xU
3ea0: 6e 6c 6f 63 6b 20 72 65 71 75 65 73 74 73 20 74  nlock requests t
3eb0: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
3ec0: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
3ed0: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
3ee0: 69 6e 74 20 71 75 6f 74 61 55 6e 6c 6f 63 6b 28  int quotaUnlock(
3ef0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
3f00: 6f 6e 6e 2c 20 69 6e 74 20 6c 6f 63 6b 29 7b 0a  onn, int lock){.
3f10: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3f20: 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61  pSubOpen = quota
3f30: 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a  SubOpen(pConn);.
3f40: 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65    return pSubOpe
3f50: 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 55 6e  n->pMethods->xUn
3f60: 6c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6c  lock(pSubOpen, l
3f70: 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  ock);.}../* Pass
3f80: 20 78 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c   xCheckReservedL
3f90: 6f 63 6b 20 72 65 71 75 65 73 74 73 20 74 68 72  ock requests thr
3fa0: 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67  ough to the orig
3fb0: 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67  inal VFS unchang
3fc0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
3fd0: 74 20 71 75 6f 74 61 43 68 65 63 6b 52 65 73 65  t quotaCheckRese
3fe0: 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74 65 33  rvedLock(sqlite3
3ff0: 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e  _file *pConn, in
4000: 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20 20 73  t *pResOut){.  s
4010: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
4020: 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62  bOpen = quotaSub
4030: 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72  Open(pConn);.  r
4040: 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e  eturn pSubOpen->
4050: 70 4d 65 74 68 6f 64 73 2d 3e 78 43 68 65 63 6b  pMethods->xCheck
4060: 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 70 53 75  ReservedLock(pSu
4070: 62 4f 70 65 6e 2c 20 70 52 65 73 4f 75 74 29 3b  bOpen, pResOut);
4080: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 46 69 6c  .}../* Pass xFil
4090: 65 43 6f 6e 74 72 6f 6c 20 72 65 71 75 65 73 74  eControl request
40a0: 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65  s through to the
40b0: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e   original VFS un
40c0: 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74  changed..*/.stat
40d0: 69 63 20 69 6e 74 20 71 75 6f 74 61 46 69 6c 65  ic int quotaFile
40e0: 43 6f 6e 74 72 6f 6c 28 73 71 6c 69 74 65 33 5f  Control(sqlite3_
40f0: 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74  file *pConn, int
4100: 20 6f 70 2c 20 76 6f 69 64 20 2a 70 41 72 67 29   op, void *pArg)
4110: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  {.  sqlite3_file
4120: 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f   *pSubOpen = quo
4130: 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29  taSubOpen(pConn)
4140: 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f  ;.  return pSubO
4150: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
4160: 46 69 6c 65 43 6f 6e 74 72 6f 6c 28 70 53 75 62  FileControl(pSub
4170: 4f 70 65 6e 2c 20 6f 70 2c 20 70 41 72 67 29 3b  Open, op, pArg);
4180: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 65 63  .}../* Pass xSec
4190: 74 6f 72 53 69 7a 65 20 72 65 71 75 65 73 74 73  torSize requests
41a0: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20   through to the 
41b0: 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63  original VFS unc
41c0: 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  hanged..*/.stati
41d0: 63 20 69 6e 74 20 71 75 6f 74 61 53 65 63 74 6f  c int quotaSecto
41e0: 72 53 69 7a 65 28 73 71 6c 69 74 65 33 5f 66 69  rSize(sqlite3_fi
41f0: 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71  le *pConn){.  sq
4200: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
4210: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
4220: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65  pen(pConn);.  re
4230: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
4240: 4d 65 74 68 6f 64 73 2d 3e 78 53 65 63 74 6f 72  Methods->xSector
4250: 53 69 7a 65 28 70 53 75 62 4f 70 65 6e 29 3b 0a  Size(pSubOpen);.
4260: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 44 65 76 69  }../* Pass xDevi
4270: 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69 63  ceCharacteristic
4280: 73 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75  s requests throu
4290: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
42a0: 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64  al VFS unchanged
42b0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
42c0: 71 75 6f 74 61 44 65 76 69 63 65 43 68 61 72 61  quotaDeviceChara
42d0: 63 74 65 72 69 73 74 69 63 73 28 73 71 6c 69 74  cteristics(sqlit
42e0: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b  e3_file *pConn){
42f0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
4300: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74  *pSubOpen = quot
4310: 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b  aSubOpen(pConn);
4320: 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70  .  return pSubOp
4330: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 44  en->pMethods->xD
4340: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
4350: 74 69 63 73 28 70 53 75 62 4f 70 65 6e 29 3b 0a  tics(pSubOpen);.
4360: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 4d  }../* Pass xShmM
4370: 61 70 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  ap requests thro
4380: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
4390: 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65  nal VFS unchange
43a0: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
43b0: 20 71 75 6f 74 61 53 68 6d 4d 61 70 28 0a 20 20   quotaShmMap(.  
43c0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
43d0: 6f 6e 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  onn,            
43e0: 2f 2a 20 48 61 6e 64 6c 65 20 6f 70 65 6e 20 6f  /* Handle open o
43f0: 6e 20 64 61 74 61 62 61 73 65 20 66 69 6c 65 20  n database file 
4400: 2a 2f 0a 20 20 69 6e 74 20 69 52 65 67 69 6f 6e  */.  int iRegion
4410: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
4420: 20 20 20 20 20 2f 2a 20 52 65 67 69 6f 6e 20 74       /* Region t
4430: 6f 20 72 65 74 72 69 65 76 65 20 2a 2f 0a 20 20  o retrieve */.  
4440: 69 6e 74 20 73 7a 52 65 67 69 6f 6e 2c 20 20 20  int szRegion,   
4450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4460: 2f 2a 20 53 69 7a 65 20 6f 66 20 72 65 67 69 6f  /* Size of regio
4470: 6e 73 20 2a 2f 0a 20 20 69 6e 74 20 62 45 78 74  ns */.  int bExt
4480: 65 6e 64 2c 20 20 20 20 20 20 20 20 20 20 20 20  end,            
4490: 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20          /* True 
44a0: 74 6f 20 65 78 74 65 6e 64 20 66 69 6c 65 20 69  to extend file i
44b0: 66 20 6e 65 63 65 73 73 61 72 79 20 2a 2f 0a 20  f necessary */. 
44c0: 20 76 6f 69 64 20 76 6f 6c 61 74 69 6c 65 20 2a   void volatile *
44d0: 2a 70 70 20 20 20 20 20 20 20 20 20 20 20 20 20  *pp             
44e0: 20 2f 2a 20 4f 55 54 3a 20 4d 61 70 70 65 64 20   /* OUT: Mapped 
44f0: 6d 65 6d 6f 72 79 20 2a 2f 0a 29 7b 0a 20 20 73  memory */.){.  s
4500: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
4510: 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62  bOpen = quotaSub
4520: 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72  Open(pConn);.  r
4530: 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e  eturn pSubOpen->
4540: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4d 61  pMethods->xShmMa
4550: 70 28 70 53 75 62 4f 70 65 6e 2c 20 69 52 65 67  p(pSubOpen, iReg
4560: 69 6f 6e 2c 20 73 7a 52 65 67 69 6f 6e 2c 20 62  ion, szRegion, b
4570: 45 78 74 65 6e 64 2c 20 70 70 29 3b 0a 7d 0a 0a  Extend, pp);.}..
4580: 2f 2a 20 50 61 73 73 20 78 53 68 6d 4c 6f 63 6b  /* Pass xShmLock
4590: 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67   requests throug
45a0: 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61  h to the origina
45b0: 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e  l VFS unchanged.
45c0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71  .*/.static int q
45d0: 75 6f 74 61 53 68 6d 4c 6f 63 6b 28 0a 20 20 73  uotaShmLock(.  s
45e0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
45f0: 6e 6e 2c 20 20 20 20 20 20 20 2f 2a 20 44 61 74  nn,       /* Dat
4600: 61 62 61 73 65 20 66 69 6c 65 20 68 6f 6c 64 69  abase file holdi
4610: 6e 67 20 74 68 65 20 73 68 61 72 65 64 20 6d 65  ng the shared me
4620: 6d 6f 72 79 20 2a 2f 0a 20 20 69 6e 74 20 6f 66  mory */.  int of
4630: 73 74 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  st,             
4640: 20 20 20 20 20 2f 2a 20 46 69 72 73 74 20 6c 6f       /* First lo
4650: 63 6b 20 74 6f 20 61 63 71 75 69 72 65 20 6f 72  ck to acquire or
4660: 20 72 65 6c 65 61 73 65 20 2a 2f 0a 20 20 69 6e   release */.  in
4670: 74 20 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20  t n,            
4680: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
4690: 65 72 20 6f 66 20 6c 6f 63 6b 73 20 74 6f 20 61  er of locks to a
46a0: 63 71 75 69 72 65 20 6f 72 20 72 65 6c 65 61 73  cquire or releas
46b0: 65 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67 73  e */.  int flags
46c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
46d0: 20 20 2f 2a 20 57 68 61 74 20 74 6f 20 64 6f 20    /* What to do 
46e0: 77 69 74 68 20 74 68 65 20 6c 6f 63 6b 20 2a 2f  with the lock */
46f0: 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  .){.  sqlite3_fi
4700: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71  le *pSubOpen = q
4710: 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e  uotaSubOpen(pCon
4720: 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 75  n);.  return pSu
4730: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
4740: 3e 78 53 68 6d 4c 6f 63 6b 28 70 53 75 62 4f 70  >xShmLock(pSubOp
4750: 65 6e 2c 20 6f 66 73 74 2c 20 6e 2c 20 66 6c 61  en, ofst, n, fla
4760: 67 73 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20  gs);.}../* Pass 
4770: 78 53 68 6d 42 61 72 72 69 65 72 20 72 65 71 75  xShmBarrier requ
4780: 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20  ests through to 
4790: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  the original VFS
47a0: 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73   unchanged..*/.s
47b0: 74 61 74 69 63 20 76 6f 69 64 20 71 75 6f 74 61  tatic void quota
47c0: 53 68 6d 42 61 72 72 69 65 72 28 73 71 6c 69 74  ShmBarrier(sqlit
47d0: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b  e3_file *pConn){
47e0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
47f0: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74  *pSubOpen = quot
4800: 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b  aSubOpen(pConn);
4810: 0a 20 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65  .  pSubOpen->pMe
4820: 74 68 6f 64 73 2d 3e 78 53 68 6d 42 61 72 72 69  thods->xShmBarri
4830: 65 72 28 70 53 75 62 4f 70 65 6e 29 3b 0a 7d 0a  er(pSubOpen);.}.
4840: 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 55 6e 6d  ./* Pass xShmUnm
4850: 61 70 20 72 65 71 75 65 73 74 73 20 74 68 72 6f  ap requests thro
4860: 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69  ugh to the origi
4870: 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65  nal VFS unchange
4880: 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  d..*/.static int
4890: 20 71 75 6f 74 61 53 68 6d 55 6e 6d 61 70 28 73   quotaShmUnmap(s
48a0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f  qlite3_file *pCo
48b0: 6e 6e 2c 20 69 6e 74 20 64 65 6c 65 74 65 46 6c  nn, int deleteFl
48c0: 61 67 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  ag){.  sqlite3_f
48d0: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
48e0: 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f  quotaSubOpen(pCo
48f0: 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 53  nn);.  return pS
4900: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
4910: 2d 3e 78 53 68 6d 55 6e 6d 61 70 28 70 53 75 62  ->xShmUnmap(pSub
4920: 4f 70 65 6e 2c 20 64 65 6c 65 74 65 46 6c 61 67  Open, deleteFlag
4930: 29 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a  );.}../*********
4940: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4950: 2a 20 50 75 62 6c 69 63 20 49 6e 74 65 72 66 61  * Public Interfa
4960: 63 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ces ************
4970: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4980: 2a 2f 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  */./*.** Initial
4990: 69 7a 65 20 74 68 65 20 71 75 6f 74 61 20 56 46  ize the quota VF
49a0: 53 20 73 68 69 6d 2e 20 20 55 73 65 20 74 68 65  S shim.  Use the
49b0: 20 56 46 53 20 6e 61 6d 65 64 20 7a 4f 72 69 67   VFS named zOrig
49c0: 56 66 73 4e 61 6d 65 0a 2a 2a 20 61 73 20 74 68  VfsName.** as th
49d0: 65 20 56 46 53 20 74 68 61 74 20 64 6f 65 73 20  e VFS that does 
49e0: 74 68 65 20 61 63 74 75 61 6c 20 77 6f 72 6b 2e  the actual work.
49f0: 20 20 55 73 65 20 74 68 65 20 64 65 66 61 75 6c    Use the defaul
4a00: 74 20 69 66 0a 2a 2a 20 7a 4f 72 69 67 56 66 73  t if.** zOrigVfs
4a10: 4e 61 6d 65 3d 3d 4e 55 4c 4c 2e 20 20 0a 2a 2a  Name==NULL.  .**
4a20: 0a 2a 2a 20 54 68 65 20 71 75 6f 74 61 20 56 46  .** The quota VF
4a30: 53 20 73 68 69 6d 20 69 73 20 6e 61 6d 65 64 20  S shim is named 
4a40: 22 71 75 6f 74 61 22 2e 20 20 49 74 20 77 69 6c  "quota".  It wil
4a50: 6c 20 62 65 63 6f 6d 65 20 74 68 65 20 64 65 66  l become the def
4a60: 61 75 6c 74 0a 2a 2a 20 56 46 53 20 69 66 20 6d  ault.** VFS if m
4a70: 61 6b 65 44 65 66 61 75 6c 74 20 69 73 20 6e 6f  akeDefault is no
4a80: 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 54 48  n-zero..**.** TH
4a90: 49 53 20 52 4f 55 54 49 4e 45 20 49 53 20 4e 4f  IS ROUTINE IS NO
4aa0: 54 20 54 48 52 45 41 44 53 41 46 45 2e 20 20 43  T THREADSAFE.  C
4ab0: 61 6c 6c 20 74 68 69 73 20 72 6f 75 74 69 6e 65  all this routine
4ac0: 20 65 78 61 63 74 6c 79 20 6f 6e 63 65 0a 2a 2a   exactly once.**
4ad0: 20 64 75 72 69 6e 67 20 73 74 61 72 74 2d 75 70   during start-up
4ae0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
4af0: 5f 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a  _quota_initializ
4b00: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4f  e(const char *zO
4b10: 72 69 67 56 66 73 4e 61 6d 65 2c 20 69 6e 74 20  rigVfsName, int 
4b20: 6d 61 6b 65 44 65 66 61 75 6c 74 29 7b 0a 20 20  makeDefault){.  
4b30: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72  sqlite3_vfs *pOr
4b40: 69 67 56 66 73 3b 0a 20 20 69 66 28 20 67 51 75  igVfs;.  if( gQu
4b50: 6f 74 61 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65  ota.isInitialize
4b60: 64 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  d ) return SQLIT
4b70: 45 5f 4d 49 53 55 53 45 3b 0a 20 20 70 4f 72 69  E_MISUSE;.  pOri
4b80: 67 56 66 73 20 3d 20 73 71 6c 69 74 65 33 5f 76  gVfs = sqlite3_v
4b90: 66 73 5f 66 69 6e 64 28 7a 4f 72 69 67 56 66 73  fs_find(zOrigVfs
4ba0: 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 70 4f 72  Name);.  if( pOr
4bb0: 69 67 56 66 73 3d 3d 30 20 29 20 72 65 74 75 72  igVfs==0 ) retur
4bc0: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
4bd0: 20 20 61 73 73 65 72 74 28 20 70 4f 72 69 67 56    assert( pOrigV
4be0: 66 73 21 3d 26 67 51 75 6f 74 61 2e 73 54 68 69  fs!=&gQuota.sThi
4bf0: 73 56 66 73 20 29 3b 0a 20 20 67 51 75 6f 74 61  sVfs );.  gQuota
4c00: 2e 70 4d 75 74 65 78 20 3d 20 73 71 6c 69 74 65  .pMutex = sqlite
4c10: 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 53 51  3_mutex_alloc(SQ
4c20: 4c 49 54 45 5f 4d 55 54 45 58 5f 46 41 53 54 29  LITE_MUTEX_FAST)
4c30: 3b 0a 20 20 69 66 28 20 21 67 51 75 6f 74 61 2e  ;.  if( !gQuota.
4c40: 70 4d 75 74 65 78 20 29 7b 0a 20 20 20 20 72 65  pMutex ){.    re
4c50: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
4c60: 4d 3b 0a 20 20 7d 0a 20 20 67 51 75 6f 74 61 2e  M;.  }.  gQuota.
4c70: 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 20 3d 20  isInitialized = 
4c80: 31 3b 0a 20 20 67 51 75 6f 74 61 2e 70 4f 72 69  1;.  gQuota.pOri
4c90: 67 56 66 73 20 3d 20 70 4f 72 69 67 56 66 73 3b  gVfs = pOrigVfs;
4ca0: 0a 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56  .  gQuota.sThisV
4cb0: 66 73 20 3d 20 2a 70 4f 72 69 67 56 66 73 3b 0a  fs = *pOrigVfs;.
4cc0: 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66    gQuota.sThisVf
4cd0: 73 2e 78 4f 70 65 6e 20 3d 20 71 75 6f 74 61 4f  s.xOpen = quotaO
4ce0: 70 65 6e 3b 0a 20 20 67 51 75 6f 74 61 2e 73 54  pen;.  gQuota.sT
4cf0: 68 69 73 56 66 73 2e 73 7a 4f 73 46 69 6c 65 20  hisVfs.szOsFile 
4d00: 2b 3d 20 73 69 7a 65 6f 66 28 71 75 6f 74 61 43  += sizeof(quotaC
4d10: 6f 6e 6e 29 3b 0a 20 20 67 51 75 6f 74 61 2e 73  onn);.  gQuota.s
4d20: 54 68 69 73 56 66 73 2e 7a 4e 61 6d 65 20 3d 20  ThisVfs.zName = 
4d30: 22 71 75 6f 74 61 22 3b 0a 20 20 67 51 75 6f 74  "quota";.  gQuot
4d40: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 69  a.sIoMethodsV1.i
4d50: 56 65 72 73 69 6f 6e 20 3d 20 31 3b 0a 20 20 67  Version = 1;.  g
4d60: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
4d70: 56 31 2e 78 43 6c 6f 73 65 20 3d 20 71 75 6f 74  V1.xClose = quot
4d80: 61 43 6c 6f 73 65 3b 0a 20 20 67 51 75 6f 74 61  aClose;.  gQuota
4d90: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 52  .sIoMethodsV1.xR
4da0: 65 61 64 20 3d 20 71 75 6f 74 61 52 65 61 64 3b  ead = quotaRead;
4db0: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
4dc0: 68 6f 64 73 56 31 2e 78 57 72 69 74 65 20 3d 20  hodsV1.xWrite = 
4dd0: 71 75 6f 74 61 57 72 69 74 65 3b 0a 20 20 67 51  quotaWrite;.  gQ
4de0: 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56  uota.sIoMethodsV
4df0: 31 2e 78 54 72 75 6e 63 61 74 65 20 3d 20 71 75  1.xTruncate = qu
4e00: 6f 74 61 54 72 75 6e 63 61 74 65 3b 0a 20 20 67  otaTruncate;.  g
4e10: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
4e20: 56 31 2e 78 53 79 6e 63 20 3d 20 71 75 6f 74 61  V1.xSync = quota
4e30: 53 79 6e 63 3b 0a 20 20 67 51 75 6f 74 61 2e 73  Sync;.  gQuota.s
4e40: 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 46 69 6c  IoMethodsV1.xFil
4e50: 65 53 69 7a 65 20 3d 20 71 75 6f 74 61 46 69 6c  eSize = quotaFil
4e60: 65 53 69 7a 65 3b 0a 20 20 67 51 75 6f 74 61 2e  eSize;.  gQuota.
4e70: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 4c 6f  sIoMethodsV1.xLo
4e80: 63 6b 20 3d 20 71 75 6f 74 61 4c 6f 63 6b 3b 0a  ck = quotaLock;.
4e90: 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68    gQuota.sIoMeth
4ea0: 6f 64 73 56 31 2e 78 55 6e 6c 6f 63 6b 20 3d 20  odsV1.xUnlock = 
4eb0: 71 75 6f 74 61 55 6e 6c 6f 63 6b 3b 0a 20 20 67  quotaUnlock;.  g
4ec0: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
4ed0: 56 31 2e 78 43 68 65 63 6b 52 65 73 65 72 76 65  V1.xCheckReserve
4ee0: 64 4c 6f 63 6b 20 3d 20 71 75 6f 74 61 43 68 65  dLock = quotaChe
4ef0: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 3b 0a  ckReservedLock;.
4f00: 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68    gQuota.sIoMeth
4f10: 6f 64 73 56 31 2e 78 46 69 6c 65 43 6f 6e 74 72  odsV1.xFileContr
4f20: 6f 6c 20 3d 20 71 75 6f 74 61 46 69 6c 65 43 6f  ol = quotaFileCo
4f30: 6e 74 72 6f 6c 3b 0a 20 20 67 51 75 6f 74 61 2e  ntrol;.  gQuota.
4f40: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 53 65  sIoMethodsV1.xSe
4f50: 63 74 6f 72 53 69 7a 65 20 3d 20 71 75 6f 74 61  ctorSize = quota
4f60: 53 65 63 74 6f 72 53 69 7a 65 3b 0a 20 20 67 51  SectorSize;.  gQ
4f70: 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56  uota.sIoMethodsV
4f80: 31 2e 78 44 65 76 69 63 65 43 68 61 72 61 63 74  1.xDeviceCharact
4f90: 65 72 69 73 74 69 63 73 20 3d 20 71 75 6f 74 61  eristics = quota
4fa0: 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69  DeviceCharacteri
4fb0: 73 74 69 63 73 3b 0a 20 20 67 51 75 6f 74 61 2e  stics;.  gQuota.
4fc0: 73 49 6f 4d 65 74 68 6f 64 73 56 32 20 3d 20 67  sIoMethodsV2 = g
4fd0: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
4fe0: 56 31 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f  V1;.  gQuota.sIo
4ff0: 4d 65 74 68 6f 64 73 56 32 2e 69 56 65 72 73 69  MethodsV2.iVersi
5000: 6f 6e 20 3d 20 32 3b 0a 20 20 67 51 75 6f 74 61  on = 2;.  gQuota
5010: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53  .sIoMethodsV2.xS
5020: 68 6d 4d 61 70 20 3d 20 71 75 6f 74 61 53 68 6d  hmMap = quotaShm
5030: 4d 61 70 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49  Map;.  gQuota.sI
5040: 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 4c  oMethodsV2.xShmL
5050: 6f 63 6b 20 3d 20 71 75 6f 74 61 53 68 6d 4c 6f  ock = quotaShmLo
5060: 63 6b 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f  ck;.  gQuota.sIo
5070: 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 42 61  MethodsV2.xShmBa
5080: 72 72 69 65 72 20 3d 20 71 75 6f 74 61 53 68 6d  rrier = quotaShm
5090: 42 61 72 72 69 65 72 3b 0a 20 20 67 51 75 6f 74  Barrier;.  gQuot
50a0: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78  a.sIoMethodsV2.x
50b0: 53 68 6d 55 6e 6d 61 70 20 3d 20 71 75 6f 74 61  ShmUnmap = quota
50c0: 53 68 6d 55 6e 6d 61 70 3b 0a 20 20 73 71 6c 69  ShmUnmap;.  sqli
50d0: 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74 65 72  te3_vfs_register
50e0: 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66  (&gQuota.sThisVf
50f0: 73 2c 20 6d 61 6b 65 44 65 66 61 75 6c 74 29 3b  s, makeDefault);
5100: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
5110: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 68  _OK;.}../*.** Sh
5120: 75 74 64 6f 77 6e 20 74 68 65 20 71 75 6f 74 61  utdown the quota
5130: 20 73 79 73 74 65 6d 2e 0a 2a 2a 0a 2a 2a 20 41   system..**.** A
5140: 6c 6c 20 53 51 4c 69 74 65 20 64 61 74 61 62 61  ll SQLite databa
5150: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 6d  se connections m
5160: 75 73 74 20 62 65 20 63 6c 6f 73 65 64 20 62 65  ust be closed be
5170: 66 6f 72 65 20 63 61 6c 6c 69 6e 67 20 74 68 69  fore calling thi
5180: 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 2e 0a 2a 2a  s.** routine..**
5190: 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54 49 4e 45  .** THIS ROUTINE
51a0: 20 49 53 20 4e 4f 54 20 54 48 52 45 41 44 53 41   IS NOT THREADSA
51b0: 46 45 2e 20 20 43 61 6c 6c 20 74 68 69 73 20 72  FE.  Call this r
51c0: 6f 75 74 69 6e 65 20 65 78 61 63 74 6c 79 20 6f  outine exactly o
51d0: 6e 65 20 77 68 69 6c 65 0a 2a 2a 20 73 68 75 74  ne while.** shut
51e0: 74 69 6e 67 20 64 6f 77 6e 20 69 6e 20 6f 72 64  ting down in ord
51f0: 65 72 20 74 6f 20 66 72 65 65 20 61 6c 6c 20 72  er to free all r
5200: 65 6d 61 69 6e 69 6e 67 20 71 75 6f 74 61 20 67  emaining quota g
5210: 72 6f 75 70 73 2e 0a 2a 2f 0a 69 6e 74 20 73 71  roups..*/.int sq
5220: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68 75 74  lite3_quota_shut
5230: 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20 71 75  down(void){.  qu
5240: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
5250: 3b 0a 20 20 69 66 28 20 67 51 75 6f 74 61 2e 69  ;.  if( gQuota.i
5260: 73 49 6e 69 74 69 61 6c 69 7a 65 64 3d 3d 30 20  sInitialized==0 
5270: 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f  ) return SQLITE_
5280: 4d 49 53 55 53 45 3b 0a 20 20 66 6f 72 28 70 47  MISUSE;.  for(pG
5290: 72 6f 75 70 3d 67 51 75 6f 74 61 2e 70 47 72 6f  roup=gQuota.pGro
52a0: 75 70 3b 20 70 47 72 6f 75 70 3b 20 70 47 72 6f  up; pGroup; pGro
52b0: 75 70 3d 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74  up=pGroup->pNext
52c0: 29 7b 0a 20 20 20 20 69 66 28 20 70 47 72 6f 75  ){.    if( pGrou
52d0: 70 2d 3e 70 46 69 6c 65 73 20 29 20 72 65 74 75  p->pFiles ) retu
52e0: 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45  rn SQLITE_MISUSE
52f0: 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 67  ;.  }.  while( g
5300: 51 75 6f 74 61 2e 70 47 72 6f 75 70 20 29 7b 0a  Quota.pGroup ){.
5310: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 67 51 75      pGroup = gQu
5320: 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20 20 20 20  ota.pGroup;.    
5330: 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 20 3d 20  gQuota.pGroup = 
5340: 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20  pGroup->pNext;. 
5350: 20 20 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69     pGroup->iLimi
5360: 74 20 3d 20 30 3b 0a 20 20 20 20 71 75 6f 74 61  t = 0;.    quota
5370: 47 72 6f 75 70 44 65 72 65 66 28 70 47 72 6f 75  GroupDeref(pGrou
5380: 70 29 3b 0a 20 20 7d 0a 20 20 67 51 75 6f 74 61  p);.  }.  gQuota
5390: 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 20 3d  .isInitialized =
53a0: 20 30 3b 0a 20 20 73 71 6c 69 74 65 33 5f 6d 75   0;.  sqlite3_mu
53b0: 74 65 78 5f 66 72 65 65 28 67 51 75 6f 74 61 2e  tex_free(gQuota.
53c0: 70 4d 75 74 65 78 29 3b 0a 20 20 73 71 6c 69 74  pMutex);.  sqlit
53d0: 65 33 5f 76 66 73 5f 75 6e 72 65 67 69 73 74 65  e3_vfs_unregiste
53e0: 72 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73 56  r(&gQuota.sThisV
53f0: 66 73 29 3b 0a 20 20 6d 65 6d 73 65 74 28 26 67  fs);.  memset(&g
5400: 51 75 6f 74 61 2c 20 30 2c 20 73 69 7a 65 6f 66  Quota, 0, sizeof
5410: 28 67 51 75 6f 74 61 29 29 3b 0a 20 20 72 65 74  (gQuota));.  ret
5420: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5430: 0a 0a 2f 2a 0a 2a 2a 20 43 72 65 61 74 65 20 6f  ../*.** Create o
5440: 72 20 64 65 73 74 72 6f 79 20 61 20 71 75 6f 74  r destroy a quot
5450: 61 20 67 72 6f 75 70 2e 0a 2a 2a 0a 2a 2a 20 54  a group..**.** T
5460: 68 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69  he quota group i
5470: 73 20 64 65 66 69 6e 65 64 20 62 79 20 74 68 65  s defined by the
5480: 20 7a 50 61 74 74 65 72 6e 2e 20 20 57 68 65 6e   zPattern.  When
5490: 20 63 61 6c 6c 69 6e 67 20 74 68 69 73 20 72 6f   calling this ro
54a0: 75 74 69 6e 65 0a 2a 2a 20 77 69 74 68 20 61 20  utine.** with a 
54b0: 7a 50 61 74 74 65 72 6e 20 66 6f 72 20 61 20 71  zPattern for a q
54c0: 75 6f 74 61 20 67 72 6f 75 70 20 74 68 61 74 20  uota group that 
54d0: 61 6c 72 65 61 64 79 20 65 78 69 73 74 73 2c 20  already exists, 
54e0: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
54f0: 6d 65 72 65 6c 79 20 75 70 64 61 74 65 73 20 74  merely updates t
5500: 68 65 20 69 4c 69 6d 69 74 2c 20 78 43 61 6c 6c  he iLimit, xCall
5510: 62 61 63 6b 2c 20 61 6e 64 20 70 41 72 67 20 76  back, and pArg v
5520: 61 6c 75 65 73 20 66 6f 72 20 74 68 61 74 20 71  alues for that q
5530: 75 6f 74 61 0a 2a 2a 20 67 72 6f 75 70 2e 20 20  uota.** group.  
5540: 49 66 20 7a 50 61 74 74 65 72 6e 20 69 73 20 6e  If zPattern is n
5550: 65 77 2c 20 74 68 65 6e 20 61 20 6e 65 77 20 71  ew, then a new q
5560: 75 6f 74 61 20 67 72 6f 75 70 20 69 73 20 63 72  uota group is cr
5570: 65 61 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  eated..**.** If 
5580: 74 68 65 20 69 4c 69 6d 69 74 20 66 6f 72 20 61  the iLimit for a
5590: 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69 73 20   quota group is 
55a0: 73 65 74 20 74 6f 20 7a 65 72 6f 2c 20 74 68 65  set to zero, the
55b0: 6e 20 74 68 65 20 71 75 6f 74 61 20 67 72 6f 75  n the quota grou
55c0: 70 0a 2a 2a 20 69 73 20 64 69 73 61 62 6c 65 64  p.** is disabled
55d0: 20 61 6e 64 20 77 69 6c 6c 20 62 65 20 64 65 6c   and will be del
55e0: 65 74 65 64 20 77 68 65 6e 20 74 68 65 20 6c 61  eted when the la
55f0: 73 74 20 64 61 74 61 62 61 73 65 20 63 6f 6e 6e  st database conn
5600: 65 63 74 69 6f 6e 20 75 73 69 6e 67 0a 2a 2a 20  ection using.** 
5610: 74 68 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20  the quota group 
5620: 69 73 20 63 6c 6f 73 65 64 2e 0a 2a 2a 0a 2a 2a  is closed..**.**
5630: 20 43 61 6c 6c 69 6e 67 20 74 68 69 73 20 72 6f   Calling this ro
5640: 75 74 69 6e 65 20 6f 6e 20 61 20 7a 50 61 74 74  utine on a zPatt
5650: 65 72 6e 20 74 68 61 74 20 64 6f 65 73 20 6e 6f  ern that does no
5660: 74 20 65 78 69 73 74 20 61 6e 64 20 77 69 74 68  t exist and with
5670: 20 61 0a 2a 2a 20 7a 65 72 6f 20 69 4c 69 6d 69   a.** zero iLimi
5680: 74 20 69 73 20 61 20 6e 6f 2d 6f 70 2e 0a 2a 2a  t is a no-op..**
5690: 0a 2a 2a 20 41 20 71 75 6f 74 61 20 67 72 6f 75  .** A quota grou
56a0: 70 20 6d 75 73 74 20 65 78 69 73 74 20 77 69 74  p must exist wit
56b0: 68 20 61 20 6e 6f 6e 2d 7a 65 72 6f 20 69 4c 69  h a non-zero iLi
56c0: 6d 69 74 20 70 72 69 6f 72 20 74 6f 20 6f 70 65  mit prior to ope
56d0: 6e 69 6e 67 0a 2a 2a 20 64 61 74 61 62 61 73 65  ning.** database
56e0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 69 66 20   connections if 
56f0: 74 68 6f 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  those connection
5700: 73 20 61 72 65 20 74 6f 20 70 61 72 74 69 63 69  s are to partici
5710: 70 61 74 65 20 69 6e 20 74 68 65 0a 2a 2a 20 71  pate in the.** q
5720: 75 6f 74 61 20 67 72 6f 75 70 2e 20 20 43 72 65  uota group.  Cre
5730: 61 74 69 6e 67 20 61 20 71 75 6f 74 61 20 67 72  ating a quota gr
5740: 6f 75 70 20 64 6f 65 73 20 6e 6f 74 20 61 66 66  oup does not aff
5750: 65 63 74 20 64 61 74 61 62 61 73 65 20 63 6f 6e  ect database con
5760: 6e 65 63 74 69 6f 6e 73 0a 2a 2a 20 74 68 61 74  nections.** that
5770: 20 61 72 65 20 61 6c 72 65 61 64 79 20 6f 70 65   are already ope
5780: 6e 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65  n..*/.int sqlite
5790: 33 5f 71 75 6f 74 61 5f 73 65 74 28 0a 20 20 63  3_quota_set(.  c
57a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 74  onst char *zPatt
57b0: 65 72 6e 2c 20 20 20 20 20 20 20 20 20 20 20 2f  ern,           /
57c0: 2a 20 54 68 65 20 66 69 6c 65 6e 61 6d 65 20 70  * The filename p
57d0: 61 74 74 65 72 6e 20 2a 2f 0a 20 20 73 71 6c 69  attern */.  sqli
57e0: 74 65 33 5f 69 6e 74 36 34 20 69 4c 69 6d 69 74  te3_int64 iLimit
57f0: 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ,           /* N
5800: 65 77 20 71 75 6f 74 61 20 74 6f 20 73 65 74 20  ew quota to set 
5810: 66 6f 72 20 74 68 69 73 20 71 75 6f 74 61 20 67  for this quota g
5820: 72 6f 75 70 20 2a 2f 0a 20 20 76 6f 69 64 20 28  roup */.  void (
5830: 2a 78 43 61 6c 6c 62 61 63 6b 29 28 20 20 20 20  *xCallback)(    
5840: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c            /* Cal
5850: 6c 62 61 63 6b 20 69 6e 76 6f 6b 65 64 20 77 68  lback invoked wh
5860: 65 6e 20 67 6f 69 6e 67 20 6f 76 65 72 20 71 75  en going over qu
5870: 6f 74 61 20 2a 2f 0a 20 20 20 20 20 63 6f 6e 73  ota */.     cons
5880: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
5890: 65 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  e,         /* Na
58a0: 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f 73 65  me of file whose
58b0: 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65 73 20   size increases 
58c0: 2a 2f 0a 20 20 20 20 20 73 71 6c 69 74 65 33 5f  */.     sqlite3_
58d0: 69 6e 74 36 34 20 2a 70 69 4c 69 6d 69 74 2c 20  int64 *piLimit, 
58e0: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
58f0: 3a 20 54 68 65 20 63 75 72 72 65 6e 74 20 6c 69  : The current li
5900: 6d 69 74 20 2a 2f 0a 20 20 20 20 20 73 71 6c 69  mit */.     sqli
5910: 74 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65 2c  te3_int64 iSize,
5920: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f             /* To
5930: 74 61 6c 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20  tal size of all 
5940: 66 69 6c 65 73 20 69 6e 20 74 68 65 20 67 72 6f  files in the gro
5950: 75 70 20 2a 2f 0a 20 20 20 20 20 76 6f 69 64 20  up */.     void 
5960: 2a 70 41 72 67 20 20 20 20 20 20 20 20 20 20 20  *pArg           
5970: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6c 69            /* Cli
5980: 65 6e 74 20 64 61 74 61 20 2a 2f 0a 20 20 29 2c  ent data */.  ),
5990: 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 2c 20 20  .  void *pArg,  
59a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59b0: 20 20 20 2f 2a 20 63 6c 69 65 6e 74 20 64 61 74     /* client dat
59c0: 61 20 70 61 73 73 65 64 20 74 68 72 75 20 74 6f  a passed thru to
59d0: 20 63 61 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 76   callback */.  v
59e0: 6f 69 64 20 28 2a 78 44 65 73 74 72 6f 79 29 28  oid (*xDestroy)(
59f0: 76 6f 69 64 2a 29 20 20 20 20 20 20 20 20 20 2f  void*)         /
5a00: 2a 20 4f 70 74 69 6f 6e 61 6c 20 64 65 73 74 72  * Optional destr
5a10: 75 63 74 6f 72 20 66 6f 72 20 70 41 72 67 20 2a  uctor for pArg *
5a20: 2f 0a 29 7b 0a 20 20 71 75 6f 74 61 47 72 6f 75  /.){.  quotaGrou
5a30: 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 71 75 6f  p *pGroup;.  quo
5a40: 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70 47 72  taEnter();.  pGr
5a50: 6f 75 70 20 3d 20 67 51 75 6f 74 61 2e 70 47 72  oup = gQuota.pGr
5a60: 6f 75 70 3b 0a 20 20 77 68 69 6c 65 28 20 70 47  oup;.  while( pG
5a70: 72 6f 75 70 20 26 26 20 73 74 72 63 6d 70 28 70  roup && strcmp(p
5a80: 47 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72 6e 2c  Group->zPattern,
5a90: 20 7a 50 61 74 74 65 72 6e 29 21 3d 30 20 29 7b   zPattern)!=0 ){
5aa0: 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20 70 47  .    pGroup = pG
5ab0: 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d  roup->pNext;.  }
5ac0: 0a 20 20 69 66 28 20 70 47 72 6f 75 70 3d 3d 30  .  if( pGroup==0
5ad0: 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 50 61 74   ){.    int nPat
5ae0: 74 65 72 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 50  tern = strlen(zP
5af0: 61 74 74 65 72 6e 29 3b 0a 20 20 20 20 69 66 28  attern);.    if(
5b00: 20 69 4c 69 6d 69 74 3c 3d 30 20 29 7b 0a 20 20   iLimit<=0 ){.  
5b10: 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29      quotaLeave()
5b20: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53  ;.      return S
5b30: 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 20 20 7d 0a  QLITE_OK;.    }.
5b40: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 73 71 6c      pGroup = sql
5b50: 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a  ite3_malloc( siz
5b60: 65 6f 66 28 2a 70 47 72 6f 75 70 29 20 2b 20 6e  eof(*pGroup) + n
5b70: 50 61 74 74 65 72 6e 20 2b 20 31 20 29 3b 0a 20  Pattern + 1 );. 
5b80: 20 20 20 69 66 28 20 70 47 72 6f 75 70 3d 3d 30     if( pGroup==0
5b90: 20 29 7b 0a 20 20 20 20 20 20 71 75 6f 74 61 4c   ){.      quotaL
5ba0: 65 61 76 65 28 29 3b 0a 20 20 20 20 20 20 72 65  eave();.      re
5bb0: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  turn SQLITE_NOME
5bc0: 4d 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  M;.    }.    mem
5bd0: 73 65 74 28 70 47 72 6f 75 70 2c 20 30 2c 20 73  set(pGroup, 0, s
5be0: 69 7a 65 6f 66 28 2a 70 47 72 6f 75 70 29 29 3b  izeof(*pGroup));
5bf0: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 7a 50 61  .    pGroup->zPa
5c00: 74 74 65 72 6e 20 3d 20 28 63 68 61 72 2a 29 26  ttern = (char*)&
5c10: 70 47 72 6f 75 70 5b 31 5d 3b 0a 20 20 20 20 6d  pGroup[1];.    m
5c20: 65 6d 63 70 79 28 28 63 68 61 72 20 2a 29 70 47  emcpy((char *)pG
5c30: 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72 6e 2c 20  roup->zPattern, 
5c40: 7a 50 61 74 74 65 72 6e 2c 20 6e 50 61 74 74 65  zPattern, nPatte
5c50: 72 6e 2b 31 29 3b 0a 20 20 20 20 69 66 28 20 67  rn+1);.    if( g
5c60: 51 75 6f 74 61 2e 70 47 72 6f 75 70 20 29 20 67  Quota.pGroup ) g
5c70: 51 75 6f 74 61 2e 70 47 72 6f 75 70 2d 3e 70 70  Quota.pGroup->pp
5c80: 50 72 65 76 20 3d 20 26 70 47 72 6f 75 70 2d 3e  Prev = &pGroup->
5c90: 70 4e 65 78 74 3b 0a 20 20 20 20 70 47 72 6f 75  pNext;.    pGrou
5ca0: 70 2d 3e 70 4e 65 78 74 20 3d 20 67 51 75 6f 74  p->pNext = gQuot
5cb0: 61 2e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47  a.pGroup;.    pG
5cc0: 72 6f 75 70 2d 3e 70 70 50 72 65 76 20 3d 20 26  roup->ppPrev = &
5cd0: 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20  gQuota.pGroup;. 
5ce0: 20 20 20 67 51 75 6f 74 61 2e 70 47 72 6f 75 70     gQuota.pGroup
5cf0: 20 3d 20 70 47 72 6f 75 70 3b 0a 20 20 7d 0a 20   = pGroup;.  }. 
5d00: 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 20   pGroup->iLimit 
5d10: 3d 20 69 4c 69 6d 69 74 3b 0a 20 20 70 47 72 6f  = iLimit;.  pGro
5d20: 75 70 2d 3e 78 43 61 6c 6c 62 61 63 6b 20 3d 20  up->xCallback = 
5d30: 78 43 61 6c 6c 62 61 63 6b 3b 0a 20 20 69 66 28  xCallback;.  if(
5d40: 20 70 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f   pGroup->xDestro
5d50: 79 20 26 26 20 70 47 72 6f 75 70 2d 3e 70 41 72  y && pGroup->pAr
5d60: 67 21 3d 70 41 72 67 20 29 7b 0a 20 20 20 20 70  g!=pArg ){.    p
5d70: 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79 28  Group->xDestroy(
5d80: 70 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a 20  pGroup->pArg);. 
5d90: 20 7d 0a 20 20 70 47 72 6f 75 70 2d 3e 70 41 72   }.  pGroup->pAr
5da0: 67 20 3d 20 70 41 72 67 3b 0a 20 20 70 47 72 6f  g = pArg;.  pGro
5db0: 75 70 2d 3e 78 44 65 73 74 72 6f 79 20 3d 20 78  up->xDestroy = x
5dc0: 44 65 73 74 72 6f 79 3b 0a 20 20 71 75 6f 74 61  Destroy;.  quota
5dd0: 47 72 6f 75 70 44 65 72 65 66 28 70 47 72 6f 75  GroupDeref(pGrou
5de0: 70 29 3b 0a 20 20 71 75 6f 74 61 4c 65 61 76 65  p);.  quotaLeave
5df0: 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  ();.  return SQL
5e00: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 20 20 0a 2f 2a  ITE_OK;.}..  ./*
5e10: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 54 65 73  ************ Tes
5e30: 74 20 43 6f 64 65 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  t Code *********
5e40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5e50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 69 66 64  **********/.#ifd
5e60: 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54 0a 23  ef SQLITE_TEST.#
5e70: 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68 3e 0a  include <tcl.h>.
5e80: 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20  ./*.** Argument 
5e90: 70 61 73 73 65 64 20 74 6f 20 61 20 54 43 4c 20  passed to a TCL 
5ea0: 71 75 6f 74 61 2d 6f 76 65 72 2d 6c 69 6d 69 74  quota-over-limit
5eb0: 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a 74 79   callback..*/.ty
5ec0: 70 65 64 65 66 20 73 74 72 75 63 74 20 54 63 6c  pedef struct Tcl
5ed0: 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 54 63  QuotaCallback Tc
5ee0: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 3b 0a  lQuotaCallback;.
5ef0: 73 74 72 75 63 74 20 54 63 6c 51 75 6f 74 61 43  struct TclQuotaC
5f00: 61 6c 6c 62 61 63 6b 20 7b 0a 20 20 54 63 6c 5f  allback {.  Tcl_
5f10: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 3b 20  Interp *interp; 
5f20: 20 20 20 2f 2a 20 49 6e 74 65 72 70 72 65 74 65     /* Interprete
5f30: 72 20 69 6e 20 77 68 69 63 68 20 74 6f 20 72 75  r in which to ru
5f40: 6e 20 74 68 65 20 73 63 72 69 70 74 20 2a 2f 0a  n the script */.
5f50: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72 69    Tcl_Obj *pScri
5f60: 70 74 3b 20 20 20 20 20 20 2f 2a 20 53 63 72 69  pt;      /* Scri
5f70: 70 74 20 74 6f 20 62 65 20 72 75 6e 20 2a 2f 0a  pt to be run */.
5f80: 7d 3b 0a 0a 65 78 74 65 72 6e 20 63 6f 6e 73 74  };..extern const
5f90: 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33 54 65   char *sqlite3Te
5fa0: 73 74 45 72 72 6f 72 4e 61 6d 65 28 69 6e 74 29  stErrorName(int)
5fb0: 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69  ;.../*.** This i
5fc0: 73 20 74 68 65 20 63 61 6c 6c 62 61 63 6b 20 66  s the callback f
5fd0: 72 6f 6d 20 61 20 71 75 6f 74 61 2d 6f 76 65 72  rom a quota-over
5fe0: 2d 6c 69 6d 69 74 2e 0a 2a 2f 0a 73 74 61 74 69  -limit..*/.stati
5ff0: 63 20 76 6f 69 64 20 74 63 6c 51 75 6f 74 61 43  c void tclQuotaC
6000: 61 6c 6c 62 61 63 6b 28 0a 20 20 63 6f 6e 73 74  allback(.  const
6010: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
6020: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61  ,          /* Na
6030: 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f 73 65  me of file whose
6040: 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65 73 20   size increases 
6050: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
6060: 36 34 20 2a 70 69 4c 69 6d 69 74 2c 20 20 20 20  64 *piLimit,    
6070: 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20       /* IN/OUT: 
6080: 54 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6d 69  The current limi
6090: 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  t */.  sqlite3_i
60a0: 6e 74 36 34 20 69 53 69 7a 65 2c 20 20 20 20 20  nt64 iSize,     
60b0: 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20         /* Total 
60c0: 73 69 7a 65 20 6f 66 20 61 6c 6c 20 66 69 6c 65  size of all file
60d0: 73 20 69 6e 20 74 68 65 20 67 72 6f 75 70 20 2a  s in the group *
60e0: 2f 0a 20 20 76 6f 69 64 20 2a 70 41 72 67 20 20  /.  void *pArg  
60f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6100: 20 20 20 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61      /* Client da
6110: 74 61 20 2a 2f 0a 29 7b 0a 20 20 54 63 6c 51 75  ta */.){.  TclQu
6120: 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70 3b 20  otaCallback *p; 
6130: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43 61             /* Ca
6140: 6c 6c 62 61 63 6b 20 73 63 72 69 70 74 20 6f 62  llback script ob
6150: 6a 65 63 74 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62  ject */.  Tcl_Ob
6160: 6a 20 2a 70 45 76 61 6c 3b 20 20 20 20 20 20 20  j *pEval;       
6170: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 63 72            /* Scr
6180: 69 70 74 20 74 6f 20 65 76 61 6c 75 61 74 65 20  ipt to evaluate 
6190: 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 56  */.  Tcl_Obj *pV
61a0: 61 72 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  arname;         
61b0: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
61c0: 76 61 72 69 61 62 6c 65 20 74 6f 20 70 61 73 73  variable to pass
61d0: 20 61 73 20 32 6e 64 20 61 72 67 20 2a 2f 0a 20   as 2nd arg */. 
61e0: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 6e   unsigned int rn
61f0: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  d;              
6200: 20 2f 2a 20 52 61 6e 64 6f 6d 20 70 61 72 74 20   /* Random part 
6210: 6f 66 20 70 56 61 72 6e 61 6d 65 20 2a 2f 0a 20  of pVarname */. 
6220: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
6230: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6240: 20 2f 2a 20 54 63 6c 20 65 72 72 6f 72 20 63 6f   /* Tcl error co
6250: 64 65 20 2a 2f 0a 0a 20 20 70 20 3d 20 28 54 63  de */..  p = (Tc
6260: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a  lQuotaCallback *
6270: 29 70 41 72 67 3b 0a 20 20 69 66 28 20 70 3d 3d  )pArg;.  if( p==
6280: 30 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20 20 70  0 ) return;..  p
6290: 56 61 72 6e 61 6d 65 20 3d 20 54 63 6c 5f 4e 65  Varname = Tcl_Ne
62a0: 77 53 74 72 69 6e 67 4f 62 6a 28 22 3a 3a 70 69  wStringObj("::pi
62b0: 4c 69 6d 69 74 5f 22 2c 20 2d 31 29 3b 0a 20 20  Limit_", -1);.  
62c0: 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74  Tcl_IncrRefCount
62d0: 28 70 56 61 72 6e 61 6d 65 29 3b 0a 20 20 73 71  (pVarname);.  sq
62e0: 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73  lite3_randomness
62f0: 28 73 69 7a 65 6f 66 28 72 6e 64 29 2c 20 28 76  (sizeof(rnd), (v
6300: 6f 69 64 20 2a 29 26 72 6e 64 29 3b 0a 20 20 54  oid *)&rnd);.  T
6310: 63 6c 5f 41 70 70 65 6e 64 4f 62 6a 54 6f 4f 62  cl_AppendObjToOb
6320: 6a 28 70 56 61 72 6e 61 6d 65 2c 20 54 63 6c 5f  j(pVarname, Tcl_
6330: 4e 65 77 49 6e 74 4f 62 6a 28 28 69 6e 74 29 28  NewIntObj((int)(
6340: 72 6e 64 26 30 78 37 46 46 46 46 46 46 46 29 29  rnd&0x7FFFFFFF))
6350: 29 3b 0a 20 20 54 63 6c 5f 4f 62 6a 53 65 74 56  );.  Tcl_ObjSetV
6360: 61 72 32 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70  ar2(p->interp, p
6370: 56 61 72 6e 61 6d 65 2c 20 30 2c 20 54 63 6c 5f  Varname, 0, Tcl_
6380: 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 2a 70  NewWideIntObj(*p
6390: 69 4c 69 6d 69 74 29 2c 20 30 29 3b 0a 0a 20 20  iLimit), 0);..  
63a0: 70 45 76 61 6c 20 3d 20 54 63 6c 5f 44 75 70 6c  pEval = Tcl_Dupl
63b0: 69 63 61 74 65 4f 62 6a 28 70 2d 3e 70 53 63 72  icateObj(p->pScr
63c0: 69 70 74 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72  ipt);.  Tcl_Incr
63d0: 52 65 66 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b  RefCount(pEval);
63e0: 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70  .  Tcl_ListObjAp
63f0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70  pendElement(0, p
6400: 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77 53 74 72  Eval, Tcl_NewStr
6410: 69 6e 67 4f 62 6a 28 7a 46 69 6c 65 6e 61 6d 65  ingObj(zFilename
6420: 2c 20 2d 31 29 29 3b 0a 20 20 54 63 6c 5f 4c 69  , -1));.  Tcl_Li
6430: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
6440: 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 70 56 61  nt(0, pEval, pVa
6450: 72 6e 61 6d 65 29 3b 0a 20 20 54 63 6c 5f 4c 69  rname);.  Tcl_Li
6460: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
6470: 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 54 63 6c  nt(0, pEval, Tcl
6480: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 69  _NewWideIntObj(i
6490: 53 69 7a 65 29 29 3b 0a 20 20 72 63 20 3d 20 54  Size));.  rc = T
64a0: 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 70 2d 3e  cl_EvalObjEx(p->
64b0: 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c 20 54  interp, pEval, T
64c0: 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 3b  CL_EVAL_GLOBAL);
64d0: 0a 0a 20 20 69 66 28 20 72 63 3d 3d 54 43 4c 5f  ..  if( rc==TCL_
64e0: 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f 4f 62  OK ){.    Tcl_Ob
64f0: 6a 20 2a 70 4c 69 6d 69 74 20 3d 20 54 63 6c 5f  j *pLimit = Tcl_
6500: 4f 62 6a 47 65 74 56 61 72 32 28 70 2d 3e 69 6e  ObjGetVar2(p->in
6510: 74 65 72 70 2c 20 70 56 61 72 6e 61 6d 65 2c 20  terp, pVarname, 
6520: 30 2c 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20  0, 0);.    rc = 
6530: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
6540: 6f 6d 4f 62 6a 28 70 2d 3e 69 6e 74 65 72 70 2c  omObj(p->interp,
6550: 20 70 4c 69 6d 69 74 2c 20 70 69 4c 69 6d 69 74   pLimit, piLimit
6560: 29 3b 0a 20 20 20 20 54 63 6c 5f 55 6e 73 65 74  );.    Tcl_Unset
6570: 56 61 72 28 70 2d 3e 69 6e 74 65 72 70 2c 20 54  Var(p->interp, T
6580: 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 70 56 61  cl_GetString(pVa
6590: 72 6e 61 6d 65 29 2c 20 30 29 3b 0a 20 20 7d 0a  rname), 0);.  }.
65a0: 0a 20 20 54 63 6c 5f 44 65 63 72 52 65 66 43 6f  .  Tcl_DecrRefCo
65b0: 75 6e 74 28 70 45 76 61 6c 29 3b 0a 20 20 54 63  unt(pEval);.  Tc
65c0: 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74 28 70  l_DecrRefCount(p
65d0: 56 61 72 6e 61 6d 65 29 3b 0a 20 20 69 66 28 20  Varname);.  if( 
65e0: 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 54 63 6c  rc!=TCL_OK ) Tcl
65f0: 5f 42 61 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72  _BackgroundError
6600: 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a  (p->interp);.}..
6610: 2f 2a 0a 2a 2a 20 44 65 73 74 72 75 63 74 6f 72  /*.** Destructor
6620: 20 66 6f 72 20 61 20 54 43 4c 20 71 75 6f 74 61   for a TCL quota
6630: 2d 6f 76 65 72 2d 6c 69 6d 69 74 20 63 61 6c 6c  -over-limit call
6640: 62 61 63 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  back..*/.static 
6650: 76 6f 69 64 20 74 63 6c 43 61 6c 6c 62 61 63 6b  void tclCallback
6660: 44 65 73 74 72 75 63 74 6f 72 28 76 6f 69 64 20  Destructor(void 
6670: 2a 70 4f 62 6a 29 7b 0a 20 20 54 63 6c 51 75 6f  *pObj){.  TclQuo
6680: 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70 20 3d 20  taCallback *p = 
6690: 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63  (TclQuotaCallbac
66a0: 6b 2a 29 70 4f 62 6a 3b 0a 20 20 69 66 28 20 70  k*)pObj;.  if( p
66b0: 20 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65 63 72   ){.    Tcl_Decr
66c0: 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72  RefCount(p->pScr
66d0: 69 70 74 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  ipt);.    sqlite
66e0: 33 5f 66 72 65 65 28 28 63 68 61 72 20 2a 29 70  3_free((char *)p
66f0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  );.  }.}../*.** 
6700: 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f  tclcmd: sqlite3_
6710: 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65  quota_initialize
6720: 20 4e 41 4d 45 20 4d 41 4b 45 44 45 46 41 55 4c   NAME MAKEDEFAUL
6730: 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  T.*/.static int 
6740: 74 65 73 74 5f 71 75 6f 74 61 5f 69 6e 69 74 69  test_quota_initi
6750: 61 6c 69 7a 65 28 0a 20 20 76 6f 69 64 20 2a 20  alize(.  void * 
6760: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
6770: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6780: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
6790: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
67a0: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74  bjv[].){.  const
67b0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20   char *zName;   
67c0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61             /* Na
67d0: 6d 65 20 6f 66 20 6e 65 77 20 71 75 6f 74 61 20  me of new quota 
67e0: 56 46 53 20 2a 2f 0a 20 20 69 6e 74 20 6d 61 6b  VFS */.  int mak
67f0: 65 44 65 66 61 75 6c 74 3b 20 20 20 20 20 20 20  eDefault;       
6800: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72 75 65           /* True
6810: 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 6e 65 77   to make the new
6820: 20 56 46 53 20 74 68 65 20 64 65 66 61 75 6c 74   VFS the default
6830: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20   */.  int rc;   
6840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6850: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 72        /* Value r
6860: 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f 74 61  eturned by quota
6870: 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 2a 2f  _initialize() */
6880: 0a 0a 20 20 2f 2a 20 50 72 6f 63 65 73 73 20 61  ..  /* Process a
6890: 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 69 66  rguments */.  if
68a0: 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20 20 20  ( objc!=3 ){.   
68b0: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
68c0: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
68d0: 76 2c 20 22 4e 41 4d 45 20 4d 41 4b 45 44 45 46  v, "NAME MAKEDEF
68e0: 41 55 4c 54 22 29 3b 0a 20 20 20 20 72 65 74 75  AULT");.    retu
68f0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
6900: 7d 0a 20 20 7a 4e 61 6d 65 20 3d 20 54 63 6c 5f  }.  zName = Tcl_
6910: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
6920: 5d 29 3b 0a 20 20 69 66 28 20 54 63 6c 5f 47 65  ]);.  if( Tcl_Ge
6930: 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62 6a 28  tBooleanFromObj(
6940: 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c  interp, objv[2],
6950: 20 26 6d 61 6b 65 44 65 66 61 75 6c 74 29 20 29   &makeDefault) )
6960: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
6970: 52 3b 0a 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30  R;.  if( zName[0
6980: 5d 3d 3d 27 5c 30 27 20 29 20 7a 4e 61 6d 65 20  ]=='\0' ) zName 
6990: 3d 20 30 3b 0a 0a 20 20 2f 2a 20 43 61 6c 6c 20  = 0;..  /* Call 
69a0: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 69 6e  sqlite3_quota_in
69b0: 69 74 69 61 6c 69 7a 65 28 29 20 2a 2f 0a 20 20  itialize() */.  
69c0: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 71 75 6f  rc = sqlite3_quo
69d0: 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 28 7a 4e  ta_initialize(zN
69e0: 61 6d 65 2c 20 6d 61 6b 65 44 65 66 61 75 6c 74  ame, makeDefault
69f0: 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52 65 73 75  );.  Tcl_SetResu
6a00: 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68 61 72  lt(interp, (char
6a10: 20 2a 29 73 71 6c 69 74 65 33 54 65 73 74 45 72   *)sqlite3TestEr
6a20: 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c  rorName(rc), TCL
6a30: 5f 53 54 41 54 49 43 29 3b 0a 0a 20 20 72 65 74  _STATIC);..  ret
6a40: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
6a50: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
6a60: 69 74 65 33 5f 71 75 6f 74 61 5f 73 68 75 74 64  ite3_quota_shutd
6a70: 6f 77 6e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  own.*/.static in
6a80: 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 73 68 75  t test_quota_shu
6a90: 74 64 6f 77 6e 28 0a 20 20 76 6f 69 64 20 2a 20  tdown(.  void * 
6aa0: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
6ab0: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6ac0: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
6ad0: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
6ae0: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e 74 20 72  bjv[].){.  int r
6af0: 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  c;              
6b00: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 56 61             /* Va
6b10: 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62 79 20  lue returned by 
6b20: 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28 29  quota_shutdown()
6b30: 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21   */..  if( objc!
6b40: 3d 31 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =1 ){.    Tcl_Wr
6b50: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
6b60: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 22 29 3b  p, 1, objv, "");
6b70: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
6b80: 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  ERROR;.  }..  /*
6b90: 20 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f 71 75   Call sqlite3_qu
6ba0: 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28 29 20 2a  ota_shutdown() *
6bb0: 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  /.  rc = sqlite3
6bc0: 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28  _quota_shutdown(
6bd0: 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52 65 73 75  );.  Tcl_SetResu
6be0: 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68 61 72  lt(interp, (char
6bf0: 20 2a 29 73 71 6c 69 74 65 33 54 65 73 74 45 72   *)sqlite3TestEr
6c00: 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c  rorName(rc), TCL
6c10: 5f 53 54 41 54 49 43 29 3b 0a 0a 20 20 72 65 74  _STATIC);..  ret
6c20: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
6c30: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
6c40: 69 74 65 33 5f 71 75 6f 74 61 5f 73 65 74 20 50  ite3_quota_set P
6c50: 41 54 54 45 52 4e 20 4c 49 4d 49 54 20 53 43 52  ATTERN LIMIT SCR
6c60: 49 50 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  IPT.*/.static in
6c70: 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 73 65 74  t test_quota_set
6c80: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
6c90: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
6ca0: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
6cb0: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
6cc0: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
6cd0: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
6ce0: 20 2a 7a 50 61 74 74 65 72 6e 3b 20 20 20 20 20   *zPattern;     
6cf0: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 70 61        /* File pa
6d00: 74 74 65 72 6e 20 74 6f 20 63 6f 6e 66 69 67 75  ttern to configu
6d10: 72 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f  re */.  sqlite3_
6d20: 69 6e 74 36 34 20 69 4c 69 6d 69 74 3b 20 20 20  int64 iLimit;   
6d30: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 69 74 69          /* Initi
6d40: 61 6c 20 71 75 6f 74 61 20 69 6e 20 62 79 74 65  al quota in byte
6d50: 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  s */.  Tcl_Obj *
6d60: 70 53 63 72 69 70 74 3b 20 20 20 20 20 20 20 20  pScript;        
6d70: 20 20 20 20 20 20 20 2f 2a 20 54 63 6c 20 73 63         /* Tcl sc
6d80: 72 69 70 74 20 74 6f 20 69 6e 76 6f 6b 65 20 74  ript to invoke t
6d90: 6f 20 69 6e 63 72 65 61 73 65 20 71 75 6f 74 61  o increase quota
6da0: 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20 20   */.  int rc;   
6db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dc0: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 72        /* Value r
6dd0: 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f 74 61  eturned by quota
6de0: 5f 73 65 74 28 29 20 2a 2f 0a 20 20 54 63 6c 51  _set() */.  TclQ
6df0: 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70 3b  uotaCallback *p;
6e00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 43              /* C
6e10: 61 6c 6c 62 61 63 6b 20 6f 62 6a 65 63 74 20 2a  allback object *
6e20: 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70 74 3b  /.  int nScript;
6e30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e40: 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66      /* Length of
6e50: 20 63 61 6c 6c 62 61 63 6b 20 73 63 72 69 70 74   callback script
6e60: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 44 65   */.  void (*xDe
6e70: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b 20 20  stroy)(void*);  
6e80: 20 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f 6e 61        /* Optiona
6e90: 6c 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72  l destructor for
6ea0: 20 70 41 72 67 20 2a 2f 0a 20 20 76 6f 69 64 20   pArg */.  void 
6eb0: 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 63 6f 6e  (*xCallback)(con
6ec0: 73 74 20 63 68 61 72 20 2a 2c 20 73 71 6c 69 74  st char *, sqlit
6ed0: 65 33 5f 69 6e 74 36 34 20 2a 2c 20 73 71 6c 69  e3_int64 *, sqli
6ee0: 74 65 33 5f 69 6e 74 36 34 2c 20 76 6f 69 64 20  te3_int64, void 
6ef0: 2a 29 3b 0a 0a 20 20 2f 2a 20 50 72 6f 63 65 73  *);..  /* Proces
6f00: 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20  s arguments */. 
6f10: 20 69 66 28 20 6f 62 6a 63 21 3d 34 20 29 7b 0a   if( objc!=4 ){.
6f20: 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d      Tcl_WrongNum
6f30: 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20  Args(interp, 1, 
6f40: 6f 62 6a 76 2c 20 22 50 41 54 54 45 52 4e 20 4c  objv, "PATTERN L
6f50: 49 4d 49 54 20 53 43 52 49 50 54 22 29 3b 0a 20  IMIT SCRIPT");. 
6f60: 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52     return TCL_ER
6f70: 52 4f 52 3b 0a 20 20 7d 0a 20 20 7a 50 61 74 74  ROR;.  }.  zPatt
6f80: 65 72 6e 20 3d 20 54 63 6c 5f 47 65 74 53 74 72  ern = Tcl_GetStr
6f90: 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20 20  ing(objv[1]);.  
6fa0: 69 66 28 20 54 63 6c 5f 47 65 74 57 69 64 65 49  if( Tcl_GetWideI
6fb0: 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  ntFromObj(interp
6fc0: 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 4c 69 6d  , objv[2], &iLim
6fd0: 69 74 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  it) ) return TCL
6fe0: 5f 45 52 52 4f 52 3b 0a 20 20 70 53 63 72 69 70  _ERROR;.  pScrip
6ff0: 74 20 3d 20 6f 62 6a 76 5b 33 5d 3b 0a 20 20 54  t = objv[3];.  T
7000: 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72 6f 6d  cl_GetStringFrom
7010: 4f 62 6a 28 70 53 63 72 69 70 74 2c 20 26 6e 53  Obj(pScript, &nS
7020: 63 72 69 70 74 29 3b 0a 0a 20 20 69 66 28 20 6e  cript);..  if( n
7030: 53 63 72 69 70 74 3e 30 20 29 7b 0a 20 20 20 20  Script>0 ){.    
7040: 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20 54 63  /* Allocate a Tc
7050: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 6f  lQuotaCallback o
7060: 62 6a 65 63 74 20 2a 2f 0a 20 20 20 20 70 20 3d  bject */.    p =
7070: 20 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61   (TclQuotaCallba
7080: 63 6b 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c  ck *)sqlite3_mal
7090: 6c 6f 63 28 73 69 7a 65 6f 66 28 54 63 6c 51 75  loc(sizeof(TclQu
70a0: 6f 74 61 43 61 6c 6c 62 61 63 6b 29 29 3b 0a 20  otaCallback));. 
70b0: 20 20 20 69 66 28 20 21 70 20 29 7b 0a 20 20 20     if( !p ){.   
70c0: 20 20 20 54 63 6c 5f 53 65 74 52 65 73 75 6c 74     Tcl_SetResult
70d0: 28 69 6e 74 65 72 70 2c 20 28 63 68 61 72 20 2a  (interp, (char *
70e0: 29 22 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 22 2c  )"SQLITE_NOMEM",
70f0: 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 20 20   TCL_STATIC);.  
7100: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f      return TCL_O
7110: 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d 65 6d  K;.    }.    mem
7120: 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66  set(p, 0, sizeof
7130: 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63  (TclQuotaCallbac
7140: 6b 29 29 3b 0a 20 20 20 20 70 2d 3e 69 6e 74 65  k));.    p->inte
7150: 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20 20 20  rp = interp;.   
7160: 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75 6e   Tcl_IncrRefCoun
7170: 74 28 70 53 63 72 69 70 74 29 3b 0a 20 20 20 20  t(pScript);.    
7180: 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 70 53 63  p->pScript = pSc
7190: 72 69 70 74 3b 0a 20 20 20 20 78 44 65 73 74 72  ript;.    xDestr
71a0: 6f 79 20 3d 20 74 63 6c 43 61 6c 6c 62 61 63 6b  oy = tclCallback
71b0: 44 65 73 74 72 75 63 74 6f 72 3b 0a 20 20 20 20  Destructor;.    
71c0: 78 43 61 6c 6c 62 61 63 6b 20 3d 20 74 63 6c 51  xCallback = tclQ
71d0: 75 6f 74 61 43 61 6c 6c 62 61 63 6b 3b 0a 20 20  uotaCallback;.  
71e0: 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d 20 30  }else{.    p = 0
71f0: 3b 0a 20 20 20 20 78 44 65 73 74 72 6f 79 20 3d  ;.    xDestroy =
7200: 20 30 3b 0a 20 20 20 20 78 43 61 6c 6c 62 61 63   0;.    xCallbac
7210: 6b 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  k = 0;.  }..  /*
7220: 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f   Invoke sqlite3_
7230: 71 75 6f 74 61 5f 73 65 74 28 29 20 2a 2f 0a 20  quota_set() */. 
7240: 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 71 75   rc = sqlite3_qu
7250: 6f 74 61 5f 73 65 74 28 7a 50 61 74 74 65 72 6e  ota_set(zPattern
7260: 2c 20 69 4c 69 6d 69 74 2c 20 78 43 61 6c 6c 62  , iLimit, xCallb
7270: 61 63 6b 2c 20 28 76 6f 69 64 2a 29 70 2c 20 78  ack, (void*)p, x
7280: 44 65 73 74 72 6f 79 29 3b 0a 0a 20 20 54 63 6c  Destroy);..  Tcl
7290: 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65 72  _SetResult(inter
72a0: 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c 69 74  p, (char *)sqlit
72b0: 65 33 54 65 73 74 45 72 72 6f 72 4e 61 6d 65 28  e3TestErrorName(
72c0: 72 63 29 2c 20 54 43 4c 5f 53 54 41 54 49 43 29  rc), TCL_STATIC)
72d0: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
72e0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63  K;.}../*.** tclc
72f0: 6d 64 3a 20 20 73 71 6c 69 74 65 33 5f 71 75 6f  md:  sqlite3_quo
7300: 74 61 5f 64 75 6d 70 0a 2a 2f 0a 73 74 61 74 69  ta_dump.*/.stati
7310: 63 20 69 6e 74 20 74 65 73 74 5f 71 75 6f 74 61  c int test_quota
7320: 5f 64 75 6d 70 28 0a 20 20 76 6f 69 64 20 2a 20  _dump(.  void * 
7330: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
7340: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
7350: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
7360: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
7370: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 54 63 6c 5f 4f  bjv[].){.  Tcl_O
7380: 62 6a 20 2a 70 52 65 73 75 6c 74 3b 0a 20 20 54  bj *pResult;.  T
7390: 63 6c 5f 4f 62 6a 20 2a 70 47 72 6f 75 70 54 65  cl_Obj *pGroupTe
73a0: 72 6d 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70  rm;.  Tcl_Obj *p
73b0: 46 69 6c 65 54 65 72 6d 3b 0a 20 20 71 75 6f 74  FileTerm;.  quot
73c0: 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a  aGroup *pGroup;.
73d0: 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69    quotaFile *pFi
73e0: 6c 65 3b 0a 0a 20 20 70 52 65 73 75 6c 74 20 3d  le;..  pResult =
73f0: 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20   Tcl_NewObj();. 
7400: 20 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20   quotaEnter();. 
7410: 20 66 6f 72 28 70 47 72 6f 75 70 3d 67 51 75 6f   for(pGroup=gQuo
7420: 74 61 2e 70 47 72 6f 75 70 3b 20 70 47 72 6f 75  ta.pGroup; pGrou
7430: 70 3b 20 70 47 72 6f 75 70 3d 70 47 72 6f 75 70  p; pGroup=pGroup
7440: 2d 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 70 47  ->pNext){.    pG
7450: 72 6f 75 70 54 65 72 6d 20 3d 20 54 63 6c 5f 4e  roupTerm = Tcl_N
7460: 65 77 4f 62 6a 28 29 3b 0a 20 20 20 20 54 63 6c  ewObj();.    Tcl
7470: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
7480: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 47  ement(interp, pG
7490: 72 6f 75 70 54 65 72 6d 2c 0a 20 20 20 20 20 20  roupTerm,.      
74a0: 20 20 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e      Tcl_NewStrin
74b0: 67 4f 62 6a 28 70 47 72 6f 75 70 2d 3e 7a 50 61  gObj(pGroup->zPa
74c0: 74 74 65 72 6e 2c 20 2d 31 29 29 3b 0a 20 20 20  ttern, -1));.   
74d0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
74e0: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
74f0: 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20 20  , pGroupTerm,.  
7500: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 57          Tcl_NewW
7510: 69 64 65 49 6e 74 4f 62 6a 28 70 47 72 6f 75 70  ideIntObj(pGroup
7520: 2d 3e 69 4c 69 6d 69 74 29 29 3b 0a 20 20 20 20  ->iLimit));.    
7530: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
7540: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
7550: 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20 20 20   pGroupTerm,.   
7560: 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 57 69         Tcl_NewWi
7570: 64 65 49 6e 74 4f 62 6a 28 70 47 72 6f 75 70 2d  deIntObj(pGroup-
7580: 3e 69 53 69 7a 65 29 29 3b 0a 20 20 20 20 66 6f  >iSize));.    fo
7590: 72 28 70 46 69 6c 65 3d 70 47 72 6f 75 70 2d 3e  r(pFile=pGroup->
75a0: 70 46 69 6c 65 73 3b 20 70 46 69 6c 65 3b 20 70  pFiles; pFile; p
75b0: 46 69 6c 65 3d 70 46 69 6c 65 2d 3e 70 4e 65 78  File=pFile->pNex
75c0: 74 29 7b 0a 20 20 20 20 20 20 70 46 69 6c 65 54  t){.      pFileT
75d0: 65 72 6d 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  erm = Tcl_NewObj
75e0: 28 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4c 69  ();.      Tcl_Li
75f0: 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65  stObjAppendEleme
7600: 6e 74 28 69 6e 74 65 72 70 2c 20 70 46 69 6c 65  nt(interp, pFile
7610: 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20  Term,.          
7620: 20 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f    Tcl_NewStringO
7630: 62 6a 28 70 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e  bj(pFile->zFilen
7640: 61 6d 65 2c 20 2d 31 29 29 3b 0a 20 20 20 20 20  ame, -1));.     
7650: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
7660: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
7670: 2c 20 70 46 69 6c 65 54 65 72 6d 2c 0a 20 20 20  , pFileTerm,.   
7680: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77           Tcl_New
7690: 57 69 64 65 49 6e 74 4f 62 6a 28 70 46 69 6c 65  WideIntObj(pFile
76a0: 2d 3e 69 53 69 7a 65 29 29 3b 0a 20 20 20 20 20  ->iSize));.     
76b0: 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65   Tcl_ListObjAppe
76c0: 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70  ndElement(interp
76d0: 2c 20 70 46 69 6c 65 54 65 72 6d 2c 0a 20 20 20  , pFileTerm,.   
76e0: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77           Tcl_New
76f0: 57 69 64 65 49 6e 74 4f 62 6a 28 70 46 69 6c 65  WideIntObj(pFile
7700: 2d 3e 6e 52 65 66 29 29 3b 0a 20 20 20 20 20 20  ->nRef));.      
7710: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
7720: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
7730: 20 70 47 72 6f 75 70 54 65 72 6d 2c 20 70 46 69   pGroupTerm, pFi
7740: 6c 65 54 65 72 6d 29 3b 0a 20 20 20 20 7d 0a 20  leTerm);.    }. 
7750: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
7760: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
7770: 72 70 2c 20 70 52 65 73 75 6c 74 2c 20 70 47 72  rp, pResult, pGr
7780: 6f 75 70 54 65 72 6d 29 3b 0a 20 20 7d 0a 20 20  oupTerm);.  }.  
7790: 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20  quotaLeave();.  
77a0: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
77b0: 28 69 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74  (interp, pResult
77c0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
77d0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  OK;.}../*.** Thi
77e0: 73 20 72 6f 75 74 69 6e 65 20 72 65 67 69 73 74  s routine regist
77f0: 65 72 73 20 74 68 65 20 63 75 73 74 6f 6d 20 54  ers the custom T
7800: 43 4c 20 63 6f 6d 6d 61 6e 64 73 20 64 65 66 69  CL commands defi
7810: 6e 65 64 20 69 6e 20 74 68 69 73 0a 2a 2a 20 6d  ned in this.** m
7820: 6f 64 75 6c 65 2e 20 20 54 68 69 73 20 73 68 6f  odule.  This sho
7830: 75 6c 64 20 62 65 20 74 68 65 20 6f 6e 6c 79 20  uld be the only 
7840: 70 72 6f 63 65 64 75 72 65 20 76 69 73 69 62 6c  procedure visibl
7850: 65 20 66 72 6f 6d 20 6f 75 74 73 69 64 65 0a 2a  e from outside.*
7860: 2a 20 6f 66 20 74 68 69 73 20 6d 6f 64 75 6c 65  * of this module
7870: 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69 74 65 71  ..*/.int Sqliteq
7880: 75 6f 74 61 5f 49 6e 69 74 28 54 63 6c 5f 49 6e  uota_Init(Tcl_In
7890: 74 65 72 70 20 2a 69 6e 74 65 72 70 29 7b 0a 20  terp *interp){. 
78a0: 20 73 74 61 74 69 63 20 73 74 72 75 63 74 20 7b   static struct {
78b0: 0a 20 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  .     char *zNam
78c0: 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f 62 6a 43  e;.     Tcl_ObjC
78d0: 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63 3b 0a 20  mdProc *xProc;. 
78e0: 20 7d 20 61 43 6d 64 5b 5d 20 3d 20 7b 0a 20 20   } aCmd[] = {.  
78f0: 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f    { "sqlite3_quo
7900: 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 22 2c 20  ta_initialize", 
7910: 74 65 73 74 5f 71 75 6f 74 61 5f 69 6e 69 74 69  test_quota_initi
7920: 61 6c 69 7a 65 20 7d 2c 0a 20 20 20 20 7b 20 22  alize },.    { "
7930: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68  sqlite3_quota_sh
7940: 75 74 64 6f 77 6e 22 2c 20 74 65 73 74 5f 71 75  utdown", test_qu
7950: 6f 74 61 5f 73 68 75 74 64 6f 77 6e 20 7d 2c 0a  ota_shutdown },.
7960: 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71      { "sqlite3_q
7970: 75 6f 74 61 5f 73 65 74 22 2c 20 74 65 73 74 5f  uota_set", test_
7980: 71 75 6f 74 61 5f 73 65 74 20 7d 2c 0a 20 20 20  quota_set },.   
7990: 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74   { "sqlite3_quot
79a0: 61 5f 64 75 6d 70 22 2c 20 74 65 73 74 5f 71 75  a_dump", test_qu
79b0: 6f 74 61 5f 64 75 6d 70 20 7d 2c 0a 20 20 7d 3b  ota_dump },.  };
79c0: 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20 66 6f 72  .  int i;..  for
79d0: 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f 66 28 61  (i=0; i<sizeof(a
79e0: 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61 43 6d 64  Cmd)/sizeof(aCmd
79f0: 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  [0]); i++){.    
7a00: 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a 43 6f 6d  Tcl_CreateObjCom
7a10: 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20 61 43 6d  mand(interp, aCm
7a20: 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 61 43 6d 64  d[i].zName, aCmd
7a30: 5b 69 5d 2e 78 50 72 6f 63 2c 20 30 2c 20 30 29  [i].xProc, 0, 0)
7a40: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
7a50: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 23 65 6e 64 69 66  TCL_OK;.}.#endif
7a60: 0a                                               .