/ Hex Artifact Content
Login

Artifact ec7d1056936f69be953c343bcb480305ce8928f3:


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 69 6e 74 20 64 65 6c 65 74 65 4f 6e 43  .  int deleteOnC
10c0: 6c 6f 73 65 3b 20 20 20 20 20 20 20 20 20 20 20  lose;           
10d0: 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 64 65     /* True to de
10e0: 6c 65 74 65 20 74 68 69 73 20 66 69 6c 65 20 77  lete this file w
10f0: 68 65 6e 20 69 74 20 63 6c 6f 73 65 73 20 2a 2f  hen it closes */
1100: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 4e  .  quotaFile *pN
1110: 65 78 74 2c 20 2a 2a 70 70 50 72 65 76 3b 20 20  ext, **ppPrev;  
1120: 20 20 20 2f 2a 20 4c 69 6e 6b 65 64 20 6c 69 73     /* Linked lis
1130: 74 20 6f 66 20 66 69 6c 65 73 20 69 6e 20 74 68  t of files in th
1140: 65 20 73 61 6d 65 20 67 72 6f 75 70 20 2a 2f 0a  e same group */.
1150: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69 6e 73  };../*.** An ins
1160: 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66 6f 6c  tance of the fol
1170: 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20 72 65  lowing object re
1180: 70 72 65 73 65 6e 74 73 20 65 61 63 68 20 6f 70  presents each op
1190: 65 6e 20 63 6f 6e 6e 65 63 74 69 6f 6e 0a 2a 2a  en connection.**
11a0: 20 74 6f 20 61 20 66 69 6c 65 20 74 68 61 74 20   to a file that 
11b0: 70 61 72 74 69 63 69 70 61 74 65 73 20 69 6e 20  participates in 
11c0: 71 75 6f 74 61 20 74 72 61 63 6b 69 6e 67 2e 20  quota tracking. 
11d0: 20 54 68 69 73 20 6f 62 6a 65 63 74 20 69 73 20   This object is 
11e0: 61 20 0a 2a 2a 20 73 75 62 63 6c 61 73 73 20 6f  a .** subclass o
11f0: 66 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2e 20  f sqlite3_file. 
1200: 20 54 68 65 20 73 71 6c 69 74 65 33 5f 66 69 6c   The sqlite3_fil
1210: 65 20 6f 62 6a 65 63 74 20 66 6f 72 20 74 68 65  e object for the
1220: 20 75 6e 64 65 72 6c 79 69 6e 67 0a 2a 2a 20 56   underlying.** V
1230: 46 53 20 69 73 20 61 70 70 65 6e 64 65 64 20 74  FS is appended t
1240: 6f 20 74 68 69 73 20 73 74 72 75 63 74 75 72 65  o this structure
1250: 2e 0a 2a 2f 0a 73 74 72 75 63 74 20 71 75 6f 74  ..*/.struct quot
1260: 61 43 6f 6e 6e 20 7b 0a 20 20 73 71 6c 69 74 65  aConn {.  sqlite
1270: 33 5f 66 69 6c 65 20 62 61 73 65 3b 20 20 20 20  3_file base;    
1280: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 42 61 73            /* Bas
1290: 65 20 63 6c 61 73 73 20 2d 20 6d 75 73 74 20 62  e class - must b
12a0: 65 20 66 69 72 73 74 20 2a 2f 0a 20 20 71 75 6f  e first */.  quo
12b0: 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20  taFile *pFile;  
12c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
12d0: 54 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 66  The underlying f
12e0: 69 6c 65 20 2a 2f 0a 20 20 2f 2a 20 54 68 65 20  ile */.  /* The 
12f0: 75 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20 73  underlying VFS s
1300: 71 6c 69 74 65 33 5f 66 69 6c 65 20 69 73 20 61  qlite3_file is a
1310: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 69 73 20  ppended to this 
1320: 6f 62 6a 65 63 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a  object */.};../*
1330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1340: 2a 2a 2a 2a 2a 2a 2a 2a 20 47 6c 6f 62 61 6c 20  ******** Global 
1350: 56 61 72 69 61 62 6c 65 73 20 2a 2a 2a 2a 2a 2a  Variables ******
1360: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1370: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1380: 0a 2a 2a 20 41 6c 6c 20 67 6c 6f 62 61 6c 20 76  .** All global v
1390: 61 72 69 61 62 6c 65 73 20 75 73 65 64 20 62 79  ariables used by
13a0: 20 74 68 69 73 20 66 69 6c 65 20 61 72 65 20 63   this file are c
13b0: 6f 6e 74 61 69 6e 69 6e 67 20 77 69 74 68 69 6e  ontaining within
13c0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a   the following.*
13d0: 2a 20 67 51 75 6f 74 61 20 73 74 72 75 63 74 75  * gQuota structu
13e0: 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74  re..*/.static st
13f0: 72 75 63 74 20 7b 0a 20 20 2f 2a 20 54 68 65 20  ruct {.  /* The 
1400: 70 4f 72 69 67 56 66 73 20 69 73 20 74 68 65 20  pOrigVfs is the 
1410: 72 65 61 6c 2c 20 6f 72 69 67 69 6e 61 6c 20 75  real, original u
1420: 6e 64 65 72 6c 79 69 6e 67 20 56 46 53 20 69 6d  nderlying VFS im
1430: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2e 0a 20 20  plementation..  
1440: 2a 2a 20 4d 6f 73 74 20 6f 70 65 72 61 74 69 6f  ** Most operatio
1450: 6e 73 20 70 61 73 73 2d 74 68 72 6f 75 67 68 20  ns pass-through 
1460: 74 6f 20 74 68 65 20 72 65 61 6c 20 56 46 53 2e  to the real VFS.
1470: 20 20 54 68 69 73 20 76 61 6c 75 65 20 69 73 20    This value is 
1480: 72 65 61 64 2d 6f 6e 6c 79 0a 20 20 2a 2a 20 64  read-only.  ** d
1490: 75 72 69 6e 67 20 6f 70 65 72 61 74 69 6f 6e 2e  uring operation.
14a0: 20 20 49 74 20 69 73 20 6f 6e 6c 79 20 6d 6f 64    It is only mod
14b0: 69 66 69 65 64 20 61 74 20 73 74 61 72 74 2d 74  ified at start-t
14c0: 69 6d 65 20 61 6e 64 20 74 68 75 73 20 64 6f 65  ime and thus doe
14d0: 73 20 6e 6f 74 0a 20 20 2a 2a 20 72 65 71 75 69  s not.  ** requi
14e0: 72 65 20 61 20 6d 75 74 65 78 2e 0a 20 20 2a 2f  re a mutex..  */
14f0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
1500: 70 4f 72 69 67 56 66 73 3b 0a 0a 20 20 2f 2a 20  pOrigVfs;..  /* 
1510: 54 68 65 20 73 54 68 69 73 56 66 73 20 69 73 20  The sThisVfs is 
1520: 74 68 65 20 56 46 53 20 73 74 72 75 63 74 75 72  the VFS structur
1530: 65 20 75 73 65 64 20 62 79 20 74 68 69 73 20 73  e used by this s
1540: 68 69 6d 2e 20 20 49 74 20 69 73 20 69 6e 69 74  him.  It is init
1550: 69 61 6c 69 7a 65 64 0a 20 20 2a 2a 20 61 74 20  ialized.  ** at 
1560: 73 74 61 72 74 2d 74 69 6d 65 20 61 6e 64 20 74  start-time and t
1570: 68 75 73 20 64 6f 65 73 20 6e 6f 74 20 72 65 71  hus does not req
1580: 75 69 72 65 20 61 20 6d 75 74 65 78 0a 20 20 2a  uire a mutex.  *
1590: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  /.  sqlite3_vfs 
15a0: 73 54 68 69 73 56 66 73 3b 0a 0a 20 20 2f 2a 20  sThisVfs;..  /* 
15b0: 54 68 65 20 73 49 6f 4d 65 74 68 6f 64 73 20 64  The sIoMethods d
15c0: 65 66 69 6e 65 73 20 74 68 65 20 6d 65 74 68 6f  efines the metho
15d0: 64 73 20 75 73 65 64 20 62 79 20 73 71 6c 69 74  ds used by sqlit
15e0: 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74 73 20  e3_file objects 
15f0: 0a 20 20 2a 2a 20 61 73 73 6f 63 69 61 74 65 64  .  ** associated
1600: 20 77 69 74 68 20 74 68 69 73 20 73 68 69 6d 2e   with this shim.
1610: 20 20 49 74 20 69 73 20 69 6e 69 74 69 61 6c 69    It is initiali
1620: 7a 65 64 20 61 74 20 73 74 61 72 74 2d 74 69 6d  zed at start-tim
1630: 65 20 61 6e 64 20 64 6f 65 73 0a 20 20 2a 2a 20  e and does.  ** 
1640: 6e 6f 74 20 72 65 71 75 69 72 65 20 61 20 6d 75  not require a mu
1650: 74 65 78 2e 0a 20 20 2a 2a 0a 20 20 2a 2a 20 57  tex..  **.  ** W
1660: 68 65 6e 20 74 68 65 20 75 6e 64 65 72 6c 79 69  hen the underlyi
1670: 6e 67 20 56 46 53 20 69 73 20 63 61 6c 6c 65 64  ng VFS is called
1680: 20 74 6f 20 6f 70 65 6e 20 61 20 66 69 6c 65 2c   to open a file,
1690: 20 69 74 20 6d 69 67 68 74 20 72 65 74 75 72 6e   it might return
16a0: 20 0a 20 20 2a 2a 20 65 69 74 68 65 72 20 61 20   .  ** either a 
16b0: 76 65 72 73 69 6f 6e 20 31 20 6f 72 20 61 20 76  version 1 or a v
16c0: 65 72 73 69 6f 6e 20 32 20 73 71 6c 69 74 65 33  ersion 2 sqlite3
16d0: 5f 66 69 6c 65 20 6f 62 6a 65 63 74 2e 20 20 54  _file object.  T
16e0: 68 69 73 20 73 68 69 6d 0a 20 20 2a 2a 20 68 61  his shim.  ** ha
16f0: 73 20 74 6f 20 63 72 65 61 74 65 20 61 20 77 72  s to create a wr
1700: 61 70 70 65 72 20 73 71 6c 69 74 65 33 5f 66 69  apper sqlite3_fi
1710: 6c 65 20 6f 66 20 74 68 65 20 73 61 6d 65 20 76  le of the same v
1720: 65 72 73 69 6f 6e 2e 20 20 48 65 6e 63 65 0a 20  ersion.  Hence. 
1730: 20 2a 2a 20 74 68 65 72 65 20 61 72 65 20 74 77   ** there are tw
1740: 6f 20 49 2f 4f 20 6d 65 74 68 6f 64 20 73 74 72  o I/O method str
1750: 75 63 74 75 72 65 73 2c 20 6f 6e 65 20 66 6f 72  uctures, one for
1760: 20 76 65 72 73 69 6f 6e 20 31 20 61 6e 64 20 74   version 1 and t
1770: 68 65 20 6f 74 68 65 72 0a 20 20 2a 2a 20 66 6f  he other.  ** fo
1780: 72 20 76 65 72 73 69 6f 6e 20 32 2e 0a 20 20 2a  r version 2..  *
1790: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  /.  sqlite3_io_m
17a0: 65 74 68 6f 64 73 20 73 49 6f 4d 65 74 68 6f 64  ethods sIoMethod
17b0: 73 56 31 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69  sV1;.  sqlite3_i
17c0: 6f 5f 6d 65 74 68 6f 64 73 20 73 49 6f 4d 65 74  o_methods sIoMet
17d0: 68 6f 64 73 56 32 3b 0a 0a 20 20 2f 2a 20 54 72  hodsV2;..  /* Tr
17e0: 75 65 20 77 68 65 6e 20 74 68 69 73 20 73 68 69  ue when this shi
17f0: 6d 20 61 73 20 62 65 65 6e 20 69 6e 69 74 69 61  m as been initia
1800: 6c 69 7a 65 64 2e 0a 20 20 2a 2f 0a 20 20 69 6e  lized..  */.  in
1810: 74 20 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 3b  t isInitialized;
1820: 0a 0a 20 20 2f 2a 20 46 6f 72 20 72 75 6e 2d 74  ..  /* For run-t
1830: 69 6d 65 20 61 63 63 65 73 73 20 61 6e 79 20 6f  ime access any o
1840: 66 20 74 68 65 20 6f 74 68 65 72 20 67 6c 6f 62  f the other glob
1850: 61 6c 20 64 61 74 61 20 73 74 72 75 63 74 75 72  al data structur
1860: 65 73 20 69 6e 20 74 68 69 73 0a 20 20 2a 2a 20  es in this.  ** 
1870: 73 68 69 6d 2c 20 74 68 65 20 66 6f 6c 6c 6f 77  shim, the follow
1880: 69 6e 67 20 6d 75 74 65 78 20 6d 75 73 74 20 62  ing mutex must b
1890: 65 20 68 65 6c 64 2e 0a 20 20 2a 2f 0a 20 20 73  e held..  */.  s
18a0: 71 6c 69 74 65 33 5f 6d 75 74 65 78 20 2a 70 4d  qlite3_mutex *pM
18b0: 75 74 65 78 3b 0a 0a 20 20 2f 2a 20 4c 69 73 74  utex;..  /* List
18c0: 20 6f 66 20 71 75 6f 74 61 47 72 6f 75 70 20 6f   of quotaGroup o
18d0: 62 6a 65 63 74 73 2e 0a 20 20 2a 2f 0a 20 20 71  bjects..  */.  q
18e0: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
18f0: 70 3b 0a 0a 7d 20 67 51 75 6f 74 61 3b 0a 0a 2f  p;..} gQuota;../
1900: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1910: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 55 74 69 6c 69 74  ********* Utilit
1920: 79 20 52 6f 75 74 69 6e 65 73 20 2a 2a 2a 2a 2a  y Routines *****
1930: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1940: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a  ************/./*
1950: 0a 2a 2a 20 41 63 71 75 69 72 65 20 61 6e 64 20  .** Acquire and 
1960: 72 65 6c 65 61 73 65 20 74 68 65 20 6d 75 74 65  release the mute
1970: 78 20 75 73 65 64 20 74 6f 20 73 65 72 69 61 6c  x used to serial
1980: 69 7a 65 20 61 63 63 65 73 73 20 74 6f 20 74 68  ize access to th
1990: 65 0a 2a 2a 20 6c 69 73 74 20 6f 66 20 71 75 6f  e.** list of quo
19a0: 74 61 47 72 6f 75 70 73 2e 0a 2a 2f 0a 73 74 61  taGroups..*/.sta
19b0: 74 69 63 20 76 6f 69 64 20 71 75 6f 74 61 45 6e  tic void quotaEn
19c0: 74 65 72 28 76 6f 69 64 29 7b 20 73 71 6c 69 74  ter(void){ sqlit
19d0: 65 33 5f 6d 75 74 65 78 5f 65 6e 74 65 72 28 67  e3_mutex_enter(g
19e0: 51 75 6f 74 61 2e 70 4d 75 74 65 78 29 3b 20 7d  Quota.pMutex); }
19f0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71 75 6f  .static void quo
1a00: 74 61 4c 65 61 76 65 28 76 6f 69 64 29 7b 20 73  taLeave(void){ s
1a10: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 6c 65 61  qlite3_mutex_lea
1a20: 76 65 28 67 51 75 6f 74 61 2e 70 4d 75 74 65 78  ve(gQuota.pMutex
1a30: 29 3b 20 7d 0a 0a 2f 2a 20 43 6f 75 6e 74 20 74  ); }../* Count t
1a40: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 6f 70 65  he number of ope
1a50: 6e 20 66 69 6c 65 73 20 69 6e 20 61 20 71 75 6f  n files in a quo
1a60: 74 61 47 72 6f 75 70 20 0a 2a 2f 0a 73 74 61 74  taGroup .*/.stat
1a70: 69 63 20 69 6e 74 20 71 75 6f 74 61 47 72 6f 75  ic int quotaGrou
1a80: 70 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28 71  pOpenFileCount(q
1a90: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
1aa0: 70 29 7b 0a 20 20 69 6e 74 20 4e 20 3d 20 30 3b  p){.  int N = 0;
1ab0: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46  .  quotaFile *pF
1ac0: 69 6c 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 46  ile = pGroup->pF
1ad0: 69 6c 65 73 3b 0a 20 20 77 68 69 6c 65 28 20 70  iles;.  while( p
1ae0: 46 69 6c 65 20 29 7b 0a 20 20 20 20 69 66 28 20  File ){.    if( 
1af0: 70 46 69 6c 65 2d 3e 6e 52 65 66 20 29 20 4e 2b  pFile->nRef ) N+
1b00: 2b 3b 0a 20 20 20 20 70 46 69 6c 65 20 3d 20 70  +;.    pFile = p
1b10: 46 69 6c 65 2d 3e 70 4e 65 78 74 3b 0a 20 20 7d  File->pNext;.  }
1b20: 0a 20 20 72 65 74 75 72 6e 20 4e 3b 0a 7d 0a 0a  .  return N;.}..
1b30: 2f 2a 20 52 65 6d 6f 76 65 20 61 20 66 69 6c 65  /* Remove a file
1b40: 20 66 72 6f 6d 20 61 20 71 75 6f 74 61 20 67 72   from a quota gr
1b50: 6f 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  oup..*/.static v
1b60: 6f 69 64 20 71 75 6f 74 61 52 65 6d 6f 76 65 46  oid quotaRemoveF
1b70: 69 6c 65 28 71 75 6f 74 61 46 69 6c 65 20 2a 70  ile(quotaFile *p
1b80: 46 69 6c 65 29 7b 0a 20 20 71 75 6f 74 61 47 72  File){.  quotaGr
1b90: 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20 70 46  oup *pGroup = pF
1ba0: 69 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 70  ile->pGroup;.  p
1bb0: 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2d 3d 20  Group->iSize -= 
1bc0: 70 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20  pFile->iSize;.  
1bd0: 2a 70 46 69 6c 65 2d 3e 70 70 50 72 65 76 20 3d  *pFile->ppPrev =
1be0: 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 3b 0a 20   pFile->pNext;. 
1bf0: 20 69 66 28 20 70 46 69 6c 65 2d 3e 70 4e 65 78   if( pFile->pNex
1c00: 74 20 29 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74  t ) pFile->pNext
1c10: 2d 3e 70 70 50 72 65 76 20 3d 20 70 46 69 6c 65  ->ppPrev = pFile
1c20: 2d 3e 70 70 50 72 65 76 3b 0a 20 20 73 71 6c 69  ->ppPrev;.  sqli
1c30: 74 65 33 5f 66 72 65 65 28 70 46 69 6c 65 29 3b  te3_free(pFile);
1c40: 0a 7d 0a 0a 2f 2a 20 52 65 6d 6f 76 65 20 61 6c  .}../* Remove al
1c50: 6c 20 66 69 6c 65 73 20 66 72 6f 6d 20 61 20 71  l files from a q
1c60: 75 6f 74 61 20 67 72 6f 75 70 2e 20 20 49 74 20  uota group.  It 
1c70: 69 73 20 61 6c 77 61 79 73 20 74 68 65 20 63 61  is always the ca
1c80: 73 65 20 74 68 61 74 0a 2a 2a 20 61 6c 6c 20 66  se that.** all f
1c90: 69 6c 65 73 20 77 69 6c 6c 20 62 65 20 63 6c 6f  iles will be clo
1ca0: 73 65 64 20 77 68 65 6e 20 74 68 69 73 20 72 6f  sed when this ro
1cb0: 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 2e  utine is called.
1cc0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
1cd0: 71 75 6f 74 61 52 65 6d 6f 76 65 41 6c 6c 46 69  quotaRemoveAllFi
1ce0: 6c 65 73 28 71 75 6f 74 61 47 72 6f 75 70 20 2a  les(quotaGroup *
1cf0: 70 47 72 6f 75 70 29 7b 0a 20 20 77 68 69 6c 65  pGroup){.  while
1d00: 28 20 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73  ( pGroup->pFiles
1d10: 20 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20   ){.    assert( 
1d20: 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 2d 3e  pGroup->pFiles->
1d30: 6e 52 65 66 3d 3d 30 20 29 3b 0a 20 20 20 20 71  nRef==0 );.    q
1d40: 75 6f 74 61 52 65 6d 6f 76 65 46 69 6c 65 28 70  uotaRemoveFile(p
1d50: 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 29 3b 0a  Group->pFiles);.
1d60: 20 20 7d 0a 7d 0a 0a 0a 2f 2a 20 49 66 20 74 68    }.}.../* If th
1d70: 65 20 72 65 66 65 72 65 6e 63 65 20 63 6f 75 6e  e reference coun
1d80: 74 20 61 6e 64 20 74 68 72 65 73 68 6f 6c 64 20  t and threshold 
1d90: 66 6f 72 20 61 20 71 75 6f 74 61 47 72 6f 75 70  for a quotaGroup
1da0: 20 61 72 65 20 62 6f 74 68 0a 2a 2a 20 7a 65 72   are both.** zer
1db0: 6f 2c 20 74 68 65 6e 20 64 65 73 74 72 6f 79 20  o, then destroy 
1dc0: 74 68 65 20 71 75 6f 74 61 47 72 6f 75 70 2e 0a  the quotaGroup..
1dd0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71  */.static void q
1de0: 75 6f 74 61 47 72 6f 75 70 44 65 72 65 66 28 71  uotaGroupDeref(q
1df0: 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75  uotaGroup *pGrou
1e00: 70 29 7b 0a 20 20 69 66 28 20 70 47 72 6f 75 70  p){.  if( pGroup
1e10: 2d 3e 69 4c 69 6d 69 74 3d 3d 30 20 26 26 20 71  ->iLimit==0 && q
1e20: 75 6f 74 61 47 72 6f 75 70 4f 70 65 6e 46 69 6c  uotaGroupOpenFil
1e30: 65 43 6f 75 6e 74 28 70 47 72 6f 75 70 29 3d 3d  eCount(pGroup)==
1e40: 30 20 29 7b 0a 20 20 20 20 71 75 6f 74 61 52 65  0 ){.    quotaRe
1e50: 6d 6f 76 65 41 6c 6c 46 69 6c 65 73 28 70 47 72  moveAllFiles(pGr
1e60: 6f 75 70 29 3b 0a 20 20 20 20 2a 70 47 72 6f 75  oup);.    *pGrou
1e70: 70 2d 3e 70 70 50 72 65 76 20 3d 20 70 47 72 6f  p->ppPrev = pGro
1e80: 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20 69  up->pNext;.    i
1e90: 66 28 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74  f( pGroup->pNext
1ea0: 20 29 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74   ) pGroup->pNext
1eb0: 2d 3e 70 70 50 72 65 76 20 3d 20 70 47 72 6f 75  ->ppPrev = pGrou
1ec0: 70 2d 3e 70 70 50 72 65 76 3b 0a 20 20 20 20 69  p->ppPrev;.    i
1ed0: 66 28 20 70 47 72 6f 75 70 2d 3e 78 44 65 73 74  f( pGroup->xDest
1ee0: 72 6f 79 20 29 20 70 47 72 6f 75 70 2d 3e 78 44  roy ) pGroup->xD
1ef0: 65 73 74 72 6f 79 28 70 47 72 6f 75 70 2d 3e 70  estroy(pGroup->p
1f00: 41 72 67 29 3b 0a 20 20 20 20 73 71 6c 69 74 65  Arg);.    sqlite
1f10: 33 5f 66 72 65 65 28 70 47 72 6f 75 70 29 3b 0a  3_free(pGroup);.
1f20: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74    }.}../*.** Ret
1f30: 75 72 6e 20 54 52 55 45 20 69 66 20 73 74 72 69  urn TRUE if stri
1f40: 6e 67 20 7a 20 6d 61 74 63 68 65 73 20 67 6c 6f  ng z matches glo
1f50: 62 20 70 61 74 74 65 72 6e 20 7a 47 6c 6f 62 2e  b pattern zGlob.
1f60: 0a 2a 2a 0a 2a 2a 20 47 6c 6f 62 62 69 6e 67 20  .**.** Globbing 
1f70: 72 75 6c 65 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  rules:.**.**    
1f80: 20 20 27 2a 27 20 20 20 20 20 20 20 4d 61 74 63    '*'       Matc
1f90: 68 65 73 20 61 6e 79 20 73 65 71 75 65 6e 63 65  hes any sequence
1fa0: 20 6f 66 20 7a 65 72 6f 20 6f 72 20 6d 6f 72 65   of zero or more
1fb0: 20 63 68 61 72 61 63 74 65 72 73 2e 0a 2a 2a 0a   characters..**.
1fc0: 2a 2a 20 20 20 20 20 20 27 3f 27 20 20 20 20 20  **      '?'     
1fd0: 20 20 4d 61 74 63 68 65 73 20 65 78 61 63 74 6c    Matches exactl
1fe0: 79 20 6f 6e 65 20 63 68 61 72 61 63 74 65 72 2e  y one character.
1ff0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 5b 2e 2e 2e 5d  .**.**     [...]
2000: 20 20 20 20 20 20 4d 61 74 63 68 65 73 20 6f 6e        Matches on
2010: 65 20 63 68 61 72 61 63 74 65 72 20 66 72 6f 6d  e character from
2020: 20 74 68 65 20 65 6e 63 6c 6f 73 65 64 20 6c 69   the enclosed li
2030: 73 74 20 6f 66 0a 2a 2a 20 20 20 20 20 20 20 20  st of.**        
2040: 20 20 20 20 20 20 20 20 63 68 61 72 61 63 74 65          characte
2050: 72 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 5b 5e  rs..**.**     [^
2060: 2e 2e 2e 5d 20 20 20 20 20 4d 61 74 63 68 65 73  ...]     Matches
2070: 20 6f 6e 65 20 63 68 61 72 61 63 74 65 72 20 6e   one character n
2080: 6f 74 20 69 6e 20 74 68 65 20 65 6e 63 6c 6f 73  ot in the enclos
2090: 65 64 20 6c 69 73 74 2e 0a 2a 2a 0a 2a 2f 0a 73  ed list..**.*/.s
20a0: 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 53  tatic int quotaS
20b0: 74 72 67 6c 6f 62 28 63 6f 6e 73 74 20 63 68 61  trglob(const cha
20c0: 72 20 2a 7a 47 6c 6f 62 2c 20 63 6f 6e 73 74 20  r *zGlob, const 
20d0: 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69 6e 74 20  char *z){.  int 
20e0: 63 2c 20 63 32 3b 0a 20 20 69 6e 74 20 69 6e 76  c, c2;.  int inv
20f0: 65 72 74 3b 0a 20 20 69 6e 74 20 73 65 65 6e 3b  ert;.  int seen;
2100: 0a 0a 20 20 77 68 69 6c 65 28 20 28 63 20 3d 20  ..  while( (c = 
2110: 28 2a 28 7a 47 6c 6f 62 2b 2b 29 29 29 21 3d 30  (*(zGlob++)))!=0
2120: 20 29 7b 0a 20 20 20 20 69 66 28 20 63 3d 3d 27   ){.    if( c=='
2130: 2a 27 20 29 7b 0a 20 20 20 20 20 20 77 68 69 6c  *' ){.      whil
2140: 65 28 20 28 63 3d 28 2a 28 7a 47 6c 6f 62 2b 2b  e( (c=(*(zGlob++
2150: 29 29 29 20 3d 3d 20 27 2a 27 20 7c 7c 20 63 3d  ))) == '*' || c=
2160: 3d 27 3f 27 20 29 7b 0a 20 20 20 20 20 20 20 20  ='?' ){.        
2170: 69 66 28 20 63 3d 3d 27 3f 27 20 26 26 20 28 2a  if( c=='?' && (*
2180: 28 7a 2b 2b 29 29 3d 3d 30 20 29 20 72 65 74 75  (z++))==0 ) retu
2190: 72 6e 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20  rn 0;.      }.  
21a0: 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a      if( c==0 ){.
21b0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 31          return 1
21c0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66  ;.      }else if
21d0: 28 20 63 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20  ( c=='[' ){.    
21e0: 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26      while( *z &&
21f0: 20 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 7a 47   quotaStrglob(zG
2200: 6c 6f 62 2d 31 2c 7a 29 3d 3d 30 20 29 7b 0a 20  lob-1,z)==0 ){. 
2210: 20 20 20 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20           z++;.  
2220: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
2230: 72 65 74 75 72 6e 20 28 2a 7a 29 21 3d 30 3b 0a  return (*z)!=0;.
2240: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77 68        }.      wh
2250: 69 6c 65 28 20 28 63 32 20 3d 20 28 2a 28 7a 2b  ile( (c2 = (*(z+
2260: 2b 29 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 20  +)))!=0 ){.     
2270: 20 20 20 77 68 69 6c 65 28 20 63 32 21 3d 63 20     while( c2!=c 
2280: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 32 20  ){.          c2 
2290: 3d 20 2a 28 7a 2b 2b 29 3b 0a 20 20 20 20 20 20  = *(z++);.      
22a0: 20 20 20 20 69 66 28 20 63 32 3d 3d 30 20 29 20      if( c2==0 ) 
22b0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20 20  return 0;.      
22c0: 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28 20    }.        if( 
22d0: 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 7a 47 6c  quotaStrglob(zGl
22e0: 6f 62 2c 7a 29 20 29 20 72 65 74 75 72 6e 20 31  ob,z) ) return 1
22f0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2300: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65  return 0;.    }e
2310: 6c 73 65 20 69 66 28 20 63 3d 3d 27 3f 27 20 29  lse if( c=='?' )
2320: 7b 0a 20 20 20 20 20 20 69 66 28 20 28 2a 28 7a  {.      if( (*(z
2330: 2b 2b 29 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  ++))==0 ) return
2340: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66   0;.    }else if
2350: 28 20 63 3d 3d 27 5b 27 20 29 7b 0a 20 20 20 20  ( c=='[' ){.    
2360: 20 20 69 6e 74 20 70 72 69 6f 72 5f 63 20 3d 20    int prior_c = 
2370: 30 3b 0a 20 20 20 20 20 20 73 65 65 6e 20 3d 20  0;.      seen = 
2380: 30 3b 0a 20 20 20 20 20 20 69 6e 76 65 72 74 20  0;.      invert 
2390: 3d 20 30 3b 0a 20 20 20 20 20 20 63 20 3d 20 2a  = 0;.      c = *
23a0: 28 7a 2b 2b 29 3b 0a 20 20 20 20 20 20 69 66 28  (z++);.      if(
23b0: 20 63 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30   c==0 ) return 0
23c0: 3b 0a 20 20 20 20 20 20 63 32 20 3d 20 2a 28 7a  ;.      c2 = *(z
23d0: 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20 20 69  Glob++);.      i
23e0: 66 28 20 63 32 3d 3d 27 5e 27 20 29 7b 0a 20 20  f( c2=='^' ){.  
23f0: 20 20 20 20 20 20 69 6e 76 65 72 74 20 3d 20 31        invert = 1
2400: 3b 0a 20 20 20 20 20 20 20 20 63 32 20 3d 20 2a  ;.        c2 = *
2410: 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20  (zGlob++);.     
2420: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 63 32 3d   }.      if( c2=
2430: 3d 27 5d 27 20 29 7b 0a 20 20 20 20 20 20 20 20  =']' ){.        
2440: 69 66 28 20 63 3d 3d 27 5d 27 20 29 20 73 65 65  if( c==']' ) see
2450: 6e 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 63  n = 1;.        c
2460: 32 20 3d 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a  2 = *(zGlob++);.
2470: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77 68        }.      wh
2480: 69 6c 65 28 20 63 32 20 26 26 20 63 32 21 3d 27  ile( c2 && c2!='
2490: 5d 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  ]' ){.        if
24a0: 28 20 63 32 3d 3d 27 2d 27 20 26 26 20 7a 47 6c  ( c2=='-' && zGl
24b0: 6f 62 5b 30 5d 21 3d 27 5d 27 20 26 26 20 7a 47  ob[0]!=']' && zG
24c0: 6c 6f 62 5b 30 5d 21 3d 30 20 26 26 20 70 72 69  lob[0]!=0 && pri
24d0: 6f 72 5f 63 3e 30 20 29 7b 0a 20 20 20 20 20 20  or_c>0 ){.      
24e0: 20 20 20 20 63 32 20 3d 20 2a 28 7a 47 6c 6f 62      c2 = *(zGlob
24f0: 2b 2b 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  ++);.          i
2500: 66 28 20 63 3e 3d 70 72 69 6f 72 5f 63 20 26 26  f( c>=prior_c &&
2510: 20 63 3c 3d 63 32 20 29 20 73 65 65 6e 20 3d 20   c<=c2 ) seen = 
2520: 31 3b 0a 20 20 20 20 20 20 20 20 20 20 70 72 69  1;.          pri
2530: 6f 72 5f 63 20 3d 20 30 3b 0a 20 20 20 20 20 20  or_c = 0;.      
2540: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
2550: 20 20 20 69 66 28 20 63 3d 3d 63 32 20 29 7b 0a     if( c==c2 ){.
2560: 20 20 20 20 20 20 20 20 20 20 20 20 73 65 65 6e              seen
2570: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20   = 1;.          
2580: 7d 0a 20 20 20 20 20 20 20 20 20 20 70 72 69 6f  }.          prio
2590: 72 5f 63 20 3d 20 63 32 3b 0a 20 20 20 20 20 20  r_c = c2;.      
25a0: 20 20 7d 0a 20 20 20 20 20 20 20 20 63 32 20 3d    }.        c2 =
25b0: 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20   *(zGlob++);.   
25c0: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 63     }.      if( c
25d0: 32 3d 3d 30 20 7c 7c 20 28 73 65 65 6e 20 5e 20  2==0 || (seen ^ 
25e0: 69 6e 76 65 72 74 29 3d 3d 30 20 29 20 72 65 74  invert)==0 ) ret
25f0: 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65  urn 0;.    }else
2600: 7b 0a 20 20 20 20 20 20 69 66 28 20 63 21 3d 28  {.      if( c!=(
2610: 2a 28 7a 2b 2b 29 29 20 29 20 72 65 74 75 72 6e  *(z++)) ) return
2620: 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   0;.    }.  }.  
2630: 72 65 74 75 72 6e 20 2a 7a 3d 3d 30 3b 0a 7d 0a  return *z==0;.}.
2640: 0a 0a 2f 2a 20 46 69 6e 64 20 61 20 71 75 6f 74  ../* Find a quot
2650: 61 47 72 6f 75 70 20 67 69 76 65 6e 20 74 68 65  aGroup given the
2660: 20 66 69 6c 65 6e 61 6d 65 2e 0a 2a 2a 0a 2a 2a   filename..**.**
2670: 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65   Return a pointe
2680: 72 20 74 6f 20 74 68 65 20 71 75 6f 74 61 47 72  r to the quotaGr
2690: 6f 75 70 20 6f 62 6a 65 63 74 2e 20 52 65 74 75  oup object. Retu
26a0: 72 6e 20 4e 55 4c 4c 20 69 66 20 6e 6f 74 20 66  rn NULL if not f
26b0: 6f 75 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ound..*/.static 
26c0: 71 75 6f 74 61 47 72 6f 75 70 20 2a 71 75 6f 74  quotaGroup *quot
26d0: 61 47 72 6f 75 70 46 69 6e 64 28 63 6f 6e 73 74  aGroupFind(const
26e0: 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65   char *zFilename
26f0: 29 7b 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20  ){.  quotaGroup 
2700: 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 67 51 75 6f  *p;.  for(p=gQuo
2710: 74 61 2e 70 47 72 6f 75 70 3b 20 70 20 26 26 20  ta.pGroup; p && 
2720: 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 70 2d 3e  quotaStrglob(p->
2730: 7a 50 61 74 74 65 72 6e 2c 20 7a 46 69 6c 65 6e  zPattern, zFilen
2740: 61 6d 65 29 3d 3d 30 3b 0a 20 20 20 20 20 20 70  ame)==0;.      p
2750: 3d 70 2d 3e 70 4e 65 78 74 29 7b 7d 0a 20 20 72  =p->pNext){}.  r
2760: 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a 20 54  eturn p;.}../* T
2770: 72 61 6e 73 6c 61 74 65 20 61 6e 20 73 71 6c 69  ranslate an sqli
2780: 74 65 33 5f 66 69 6c 65 2a 20 74 68 61 74 20 69  te3_file* that i
2790: 73 20 72 65 61 6c 6c 79 20 61 20 71 75 6f 74 61  s really a quota
27a0: 43 6f 6e 6e 2a 20 69 6e 74 6f 0a 2a 2a 20 74 68  Conn* into.** th
27b0: 65 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 20  e sqlite3_file* 
27c0: 66 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79 69  for the underlyi
27d0: 6e 67 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e  ng original VFS.
27e0: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
27f0: 65 33 5f 66 69 6c 65 20 2a 71 75 6f 74 61 53 75  e3_file *quotaSu
2800: 62 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 66 69  bOpen(sqlite3_fi
2810: 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 71 75  le *pConn){.  qu
2820: 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75  otaConn *p = (qu
2830: 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a  otaConn*)pConn;.
2840: 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69 74 65    return (sqlite
2850: 33 5f 66 69 6c 65 2a 29 26 70 5b 31 5d 3b 0a 7d  3_file*)&p[1];.}
2860: 0a 0a 2f 2a 20 46 69 6e 64 20 61 20 66 69 6c 65  ../* Find a file
2870: 20 69 6e 20 61 20 71 75 6f 74 61 20 67 72 6f 75   in a quota grou
2880: 70 20 61 6e 64 20 72 65 74 75 72 6e 20 61 20 70  p and return a p
2890: 6f 69 6e 74 65 72 20 74 6f 20 74 68 61 74 20 66  ointer to that f
28a0: 69 6c 65 2e 0a 2a 2a 20 52 65 74 75 72 6e 20 4e  ile..** Return N
28b0: 55 4c 4c 20 69 66 20 74 68 65 20 66 69 6c 65 20  ULL if the file 
28c0: 69 73 20 6e 6f 74 20 69 6e 20 74 68 65 20 67 72  is not in the gr
28d0: 6f 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 71  oup..*/.static q
28e0: 75 6f 74 61 46 69 6c 65 20 2a 71 75 6f 74 61 46  uotaFile *quotaF
28f0: 69 6e 64 46 69 6c 65 28 71 75 6f 74 61 47 72 6f  indFile(quotaGro
2900: 75 70 20 2a 70 47 72 6f 75 70 2c 20 63 6f 6e 73  up *pGroup, cons
2910: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a  t char *zName){.
2920: 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69    quotaFile *pFi
2930: 6c 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 46 69  le = pGroup->pFi
2940: 6c 65 73 3b 0a 20 20 77 68 69 6c 65 28 20 70 46  les;.  while( pF
2950: 69 6c 65 20 26 26 20 73 74 72 63 6d 70 28 70 46  ile && strcmp(pF
2960: 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  ile->zFilename, 
2970: 7a 4e 61 6d 65 29 21 3d 30 20 29 7b 0a 20 20 20  zName)!=0 ){.   
2980: 20 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 2d 3e   pFile = pFile->
2990: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72 65 74  pNext;.  }.  ret
29a0: 75 72 6e 20 70 46 69 6c 65 3b 0a 7d 0a 0a 2f 2a  urn pFile;.}../*
29b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29c0: 2a 2a 2a 2a 2a 2a 2a 2a 20 56 46 53 20 4d 65 74  ******** VFS Met
29d0: 68 6f 64 20 57 72 61 70 70 65 72 73 20 2a 2a 2a  hod Wrappers ***
29e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
29f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a  **********/./*.*
2a00: 2a 20 54 68 69 73 20 69 73 20 74 68 65 20 78 4f  * This is the xO
2a10: 70 65 6e 20 6d 65 74 68 6f 64 20 75 73 65 64 20  pen method used 
2a20: 66 6f 72 20 74 68 65 20 22 71 75 6f 74 61 22 20  for the "quota" 
2a30: 56 46 53 2e 0a 2a 2a 0a 2a 2a 20 4d 6f 73 74 20  VFS..**.** Most 
2a40: 6f 66 20 74 68 65 20 77 6f 72 6b 20 69 73 20 64  of the work is d
2a50: 6f 6e 65 20 62 79 20 74 68 65 20 75 6e 64 65 72  one by the under
2a60: 6c 79 69 6e 67 20 6f 72 69 67 69 6e 61 6c 20 56  lying original V
2a70: 46 53 2e 20 20 54 68 69 73 20 6d 65 74 68 6f 64  FS.  This method
2a80: 0a 2a 2a 20 73 69 6d 70 6c 79 20 6c 69 6e 6b 73  .** simply links
2a90: 20 74 68 65 20 6e 65 77 20 66 69 6c 65 20 69 6e   the new file in
2aa0: 74 6f 20 74 68 65 20 61 70 70 72 6f 70 72 69 61  to the appropria
2ab0: 74 65 20 71 75 6f 74 61 20 67 72 6f 75 70 20 69  te quota group i
2ac0: 66 20 69 74 20 69 73 20 61 0a 2a 2a 20 66 69 6c  f it is a.** fil
2ad0: 65 20 74 68 61 74 20 6e 65 65 64 73 20 74 6f 20  e that needs to 
2ae0: 62 65 20 74 72 61 63 6b 65 64 2e 0a 2a 2f 0a 73  be tracked..*/.s
2af0: 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 4f  tatic int quotaO
2b00: 70 65 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  pen(.  sqlite3_v
2b10: 66 73 20 2a 70 56 66 73 2c 20 20 20 20 20 20 20  fs *pVfs,       
2b20: 20 20 20 2f 2a 20 54 68 65 20 71 75 6f 74 61 20     /* The quota 
2b30: 56 46 53 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  VFS */.  const c
2b40: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20  har *zName,     
2b50: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
2b60: 66 69 6c 65 20 74 6f 20 62 65 20 6f 70 65 6e 65  file to be opene
2b70: 64 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66  d */.  sqlite3_f
2b80: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20 20  ile *pConn,     
2b90: 20 20 20 2f 2a 20 46 69 6c 6c 20 69 6e 20 74 68     /* Fill in th
2ba0: 69 73 20 66 69 6c 65 20 64 65 73 63 72 69 70 74  is file descript
2bb0: 6f 72 20 2a 2f 0a 20 20 69 6e 74 20 66 6c 61 67  or */.  int flag
2bc0: 73 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s,              
2bd0: 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 74 6f 20      /* Flags to 
2be0: 63 6f 6e 74 72 6f 6c 20 74 68 65 20 6f 70 65 6e  control the open
2bf0: 69 6e 67 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 4f  ing */.  int *pO
2c00: 75 74 46 6c 61 67 73 20 20 20 20 20 20 20 20 20  utFlags         
2c10: 20 20 20 20 20 2f 2a 20 46 6c 61 67 73 20 73 68       /* Flags sh
2c20: 6f 77 69 6e 67 20 72 65 73 75 6c 74 73 20 6f 66  owing results of
2c30: 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a 29 7b 0a 20   opening */.){. 
2c40: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
2c50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2c60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
2c70: 65 73 75 6c 74 20 63 6f 64 65 20 2a 2f 20 20 20  esult code */   
2c80: 20 20 20 20 20 20 0a 20 20 71 75 6f 74 61 43 6f        .  quotaCo
2c90: 6e 6e 20 2a 70 51 75 6f 74 61 4f 70 65 6e 3b 20  nn *pQuotaOpen; 
2ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2cb0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 71      /* The new q
2cc0: 75 6f 74 61 20 66 69 6c 65 20 64 65 73 63 72 69  uota file descri
2cd0: 70 74 6f 72 20 2a 2f 0a 20 20 71 75 6f 74 61 46  ptor */.  quotaF
2ce0: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
2cf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d00: 20 20 20 20 20 2f 2a 20 43 6f 72 72 65 73 70 6f       /* Correspo
2d10: 6e 64 69 6e 67 20 71 75 6f 74 61 46 69 6c 65 20  nding quotaFile 
2d20: 6f 62 6a 20 2a 2f 0a 20 20 71 75 6f 74 61 47 72  obj */.  quotaGr
2d30: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20  oup *pGroup;    
2d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2d50: 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70      /* The group
2d60: 20 66 69 6c 65 20 62 65 6c 6f 6e 67 73 20 74 6f   file belongs to
2d70: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
2d80: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 3b 20 20 20  le *pSubOpen;   
2d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2da0: 20 2f 2a 20 52 65 61 6c 20 66 69 6c 65 20 64 65   /* Real file de
2db0: 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20 20 73 71  scriptor */.  sq
2dc0: 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69 67  lite3_vfs *pOrig
2dd0: 56 66 73 20 3d 20 67 51 75 6f 74 61 2e 70 4f 72  Vfs = gQuota.pOr
2de0: 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61 6c  igVfs;   /* Real
2df0: 20 56 46 53 20 2a 2f 0a 0a 20 20 2f 2a 20 49 66   VFS */..  /* If
2e00: 20 74 68 65 20 66 69 6c 65 20 69 73 20 6e 6f 74   the file is not
2e10: 20 61 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65   a main database
2e20: 20 66 69 6c 65 20 6f 72 20 61 20 57 41 4c 2c 20   file or a WAL, 
2e30: 74 68 65 6e 20 75 73 65 20 74 68 65 0a 20 20 2a  then use the.  *
2e40: 2a 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20 6d  * normal xOpen m
2e50: 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 69 66  ethod..  */.  if
2e60: 28 20 28 66 6c 61 67 73 20 26 20 28 53 51 4c 49  ( (flags & (SQLI
2e70: 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 7c  TE_OPEN_MAIN_DB|
2e80: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29  SQLITE_OPEN_WAL)
2e90: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )==0 ){.    retu
2ea0: 72 6e 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f 70  rn pOrigVfs->xOp
2eb0: 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61  en(pOrigVfs, zNa
2ec0: 6d 65 2c 20 70 43 6f 6e 6e 2c 20 66 6c 61 67 73  me, pConn, flags
2ed0: 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20  , pOutFlags);.  
2ee0: 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 6e  }..  /* If the n
2ef0: 61 6d 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20  ame of the file 
2f00: 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 61  does not match a
2f10: 6e 79 20 71 75 6f 74 61 20 67 72 6f 75 70 2c 20  ny quota group, 
2f20: 74 68 65 6e 0a 20 20 2a 2a 20 75 73 65 20 74 68  then.  ** use th
2f30: 65 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20 6d  e normal xOpen m
2f40: 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 71 75  ethod..  */.  qu
2f50: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70 47  otaEnter();.  pG
2f60: 72 6f 75 70 20 3d 20 71 75 6f 74 61 47 72 6f 75  roup = quotaGrou
2f70: 70 46 69 6e 64 28 7a 4e 61 6d 65 29 3b 0a 20 20  pFind(zName);.  
2f80: 69 66 28 20 70 47 72 6f 75 70 3d 3d 30 20 29 7b  if( pGroup==0 ){
2f90: 0a 20 20 20 20 72 63 20 3d 20 70 4f 72 69 67 56  .    rc = pOrigV
2fa0: 66 73 2d 3e 78 4f 70 65 6e 28 70 4f 72 69 67 56  fs->xOpen(pOrigV
2fb0: 66 73 2c 20 7a 4e 61 6d 65 2c 20 70 43 6f 6e 6e  fs, zName, pConn
2fc0: 2c 20 66 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61  , flags, pOutFla
2fd0: 67 73 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  gs);.  }else{.  
2fe0: 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74    /* If we get t
2ff0: 6f 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 69 74  o this point, it
3000: 20 6d 65 61 6e 73 20 74 68 65 20 66 69 6c 65 20   means the file 
3010: 6e 65 65 64 73 20 74 6f 20 62 65 20 71 75 6f 74  needs to be quot
3020: 61 20 74 72 61 63 6b 65 64 2e 0a 20 20 20 20 2a  a tracked..    *
3030: 2f 0a 20 20 20 20 70 51 75 6f 74 61 4f 70 65 6e  /.    pQuotaOpen
3040: 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70   = (quotaConn*)p
3050: 43 6f 6e 6e 3b 0a 20 20 20 20 70 53 75 62 4f 70  Conn;.    pSubOp
3060: 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65  en = quotaSubOpe
3070: 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 20 20 72 63  n(pConn);.    rc
3080: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f 70   = pOrigVfs->xOp
3090: 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61  en(pOrigVfs, zNa
30a0: 6d 65 2c 20 70 53 75 62 4f 70 65 6e 2c 20 66 6c  me, pSubOpen, fl
30b0: 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b  ags, pOutFlags);
30c0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
30d0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
30e0: 70 46 69 6c 65 20 3d 20 71 75 6f 74 61 46 69 6e  pFile = quotaFin
30f0: 64 46 69 6c 65 28 70 47 72 6f 75 70 2c 20 7a 4e  dFile(pGroup, zN
3100: 61 6d 65 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ame);.      if( 
3110: 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20 20 20 20  pFile==0 ){.    
3120: 20 20 20 20 69 6e 74 20 6e 4e 61 6d 65 20 3d 20      int nName = 
3130: 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 3b 0a 20  strlen(zName);. 
3140: 20 20 20 20 20 20 20 70 46 69 6c 65 20 3d 20 28         pFile = (
3150: 71 75 6f 74 61 46 69 6c 65 20 2a 29 73 71 6c 69  quotaFile *)sqli
3160: 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65  te3_malloc( size
3170: 6f 66 28 2a 70 46 69 6c 65 29 20 2b 20 6e 4e 61  of(*pFile) + nNa
3180: 6d 65 20 2b 20 31 20 29 3b 0a 20 20 20 20 20 20  me + 1 );.      
3190: 20 20 69 66 28 20 70 46 69 6c 65 3d 3d 30 20 29    if( pFile==0 )
31a0: 7b 0a 20 20 20 20 20 20 20 20 20 20 71 75 6f 74  {.          quot
31b0: 61 4c 65 61 76 65 28 29 3b 0a 20 20 20 20 20 20  aLeave();.      
31c0: 20 20 20 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d      pSubOpen->pM
31d0: 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70  ethods->xClose(p
31e0: 53 75 62 4f 70 65 6e 29 3b 0a 20 20 20 20 20 20  SubOpen);.      
31f0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
3200: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 20  E_NOMEM;.       
3210: 20 7d 0a 20 20 20 20 20 20 20 20 6d 65 6d 73 65   }.        memse
3220: 74 28 70 46 69 6c 65 2c 20 30 2c 20 73 69 7a 65  t(pFile, 0, size
3230: 6f 66 28 2a 70 46 69 6c 65 29 29 3b 0a 20 20 20  of(*pFile));.   
3240: 20 20 20 20 20 70 46 69 6c 65 2d 3e 7a 46 69 6c       pFile->zFil
3250: 65 6e 61 6d 65 20 3d 20 28 63 68 61 72 2a 29 26  ename = (char*)&
3260: 70 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20 20 20  pFile[1];.      
3270: 20 20 6d 65 6d 63 70 79 28 70 46 69 6c 65 2d 3e    memcpy(pFile->
3280: 7a 46 69 6c 65 6e 61 6d 65 2c 20 7a 4e 61 6d 65  zFilename, zName
3290: 2c 20 6e 4e 61 6d 65 2b 31 29 3b 0a 20 20 20 20  , nName+1);.    
32a0: 20 20 20 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74      pFile->pNext
32b0: 20 3d 20 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65   = pGroup->pFile
32c0: 73 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 70  s;.        if( p
32d0: 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 20 29 20  Group->pFiles ) 
32e0: 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 2d 3e  pGroup->pFiles->
32f0: 70 70 50 72 65 76 20 3d 20 26 70 46 69 6c 65 2d  ppPrev = &pFile-
3300: 3e 70 4e 65 78 74 3b 0a 20 20 20 20 20 20 20 20  >pNext;.        
3310: 70 46 69 6c 65 2d 3e 70 70 50 72 65 76 20 3d 20  pFile->ppPrev = 
3320: 26 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3b  &pGroup->pFiles;
3330: 0a 20 20 20 20 20 20 20 20 70 47 72 6f 75 70 2d  .        pGroup-
3340: 3e 70 46 69 6c 65 73 20 3d 20 70 46 69 6c 65 3b  >pFiles = pFile;
3350: 0a 20 20 20 20 20 20 20 20 70 46 69 6c 65 2d 3e  .        pFile->
3360: 70 47 72 6f 75 70 20 3d 20 70 47 72 6f 75 70 3b  pGroup = pGroup;
3370: 0a 20 20 20 20 20 20 20 20 70 46 69 6c 65 2d 3e  .        pFile->
3380: 64 65 6c 65 74 65 4f 6e 43 6c 6f 73 65 20 3d 20  deleteOnClose = 
3390: 28 66 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f  (flags & SQLITE_
33a0: 4f 50 45 4e 5f 44 45 4c 45 54 45 4f 4e 43 4c 4f  OPEN_DELETEONCLO
33b0: 53 45 29 21 3d 30 3b 0a 20 20 20 20 20 20 7d 0a  SE)!=0;.      }.
33c0: 20 20 20 20 20 20 70 46 69 6c 65 2d 3e 6e 52 65        pFile->nRe
33d0: 66 2b 2b 3b 0a 20 20 20 20 20 20 70 51 75 6f 74  f++;.      pQuot
33e0: 61 4f 70 65 6e 2d 3e 70 46 69 6c 65 20 3d 20 70  aOpen->pFile = p
33f0: 46 69 6c 65 3b 0a 20 20 20 20 20 20 69 66 28 20  File;.      if( 
3400: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
3410: 64 73 2d 3e 69 56 65 72 73 69 6f 6e 3d 3d 31 20  ds->iVersion==1 
3420: 29 7b 0a 20 20 20 20 20 20 20 20 70 51 75 6f 74  ){.        pQuot
3430: 61 4f 70 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74  aOpen->base.pMet
3440: 68 6f 64 73 20 3d 20 26 67 51 75 6f 74 61 2e 73  hods = &gQuota.s
3450: 49 6f 4d 65 74 68 6f 64 73 56 31 3b 0a 20 20 20  IoMethodsV1;.   
3460: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3470: 20 20 70 51 75 6f 74 61 4f 70 65 6e 2d 3e 62 61    pQuotaOpen->ba
3480: 73 65 2e 70 4d 65 74 68 6f 64 73 20 3d 20 26 67  se.pMethods = &g
3490: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
34a0: 56 32 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  V2;.      }.    
34b0: 7d 0a 20 20 7d 0a 20 20 71 75 6f 74 61 4c 65 61  }.  }.  quotaLea
34c0: 76 65 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 72  ve();.  return r
34d0: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  c;.}../*.** This
34e0: 20 69 73 20 74 68 65 20 78 44 65 6c 65 74 65 20   is the xDelete 
34f0: 6d 65 74 68 6f 64 20 75 73 65 64 20 66 6f 72 20  method used for 
3500: 74 68 65 20 22 71 75 6f 74 61 22 20 56 46 53 2e  the "quota" VFS.
3510: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 66 69  .**.** If the fi
3520: 6c 65 20 62 65 69 6e 67 20 64 65 6c 65 74 65 64  le being deleted
3530: 20 69 73 20 70 61 72 74 20 6f 66 20 74 68 65 20   is part of the 
3540: 71 75 6f 74 61 20 67 72 6f 75 70 2c 20 74 68 65  quota group, the
3550: 6e 20 72 65 64 75 63 65 0a 2a 2a 20 74 68 65 20  n reduce.** the 
3560: 73 69 7a 65 20 6f 66 20 74 68 65 20 71 75 6f 74  size of the quot
3570: 61 20 67 72 6f 75 70 20 61 63 63 6f 72 64 69 6e  a group accordin
3580: 67 6c 79 2e 20 20 41 6e 64 20 72 65 6d 6f 76 65  gly.  And remove
3590: 20 74 68 65 20 66 69 6c 65 20 66 72 6f 6d 0a 2a   the file from.*
35a0: 2a 20 74 68 65 20 73 65 74 20 6f 66 20 66 69 6c  * the set of fil
35b0: 65 73 20 69 6e 20 74 68 65 20 71 75 6f 74 61 20  es in the quota 
35c0: 67 72 6f 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63  group..*/.static
35d0: 20 69 6e 74 20 71 75 6f 74 61 44 65 6c 65 74 65   int quotaDelete
35e0: 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20  (.  sqlite3_vfs 
35f0: 2a 70 56 66 73 2c 20 20 20 20 20 20 20 20 20 20  *pVfs,          
3600: 2f 2a 20 54 68 65 20 71 75 6f 74 61 20 56 46 53  /* The quota VFS
3610: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
3620: 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 20 20 20 20   *zName,        
3630: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c    /* Name of fil
3640: 65 20 74 6f 20 62 65 20 64 65 6c 65 74 65 64 20  e to be deleted 
3650: 2a 2f 0a 20 20 69 6e 74 20 73 79 6e 63 44 69 72  */.  int syncDir
3660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3670: 20 2f 2a 20 44 6f 20 61 20 64 69 72 65 63 74 6f   /* Do a directo
3680: 72 79 20 73 79 6e 63 20 61 66 74 65 72 20 64 65  ry sync after de
3690: 6c 65 74 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 69  leting */.){.  i
36a0: 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20  nt rc;          
36b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
36c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73            /* Res
36d0: 75 6c 74 20 63 6f 64 65 20 2a 2f 20 20 20 20 20  ult code */     
36e0: 20 20 20 20 0a 20 20 71 75 6f 74 61 46 69 6c 65      .  quotaFile
36f0: 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20   *pFile;        
3700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3710: 20 20 2f 2a 20 46 69 6c 65 73 20 69 6e 20 74 68    /* Files in th
3720: 65 20 71 75 6f 74 61 20 2a 2f 0a 20 20 71 75 6f  e quota */.  quo
3730: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b  taGroup *pGroup;
3740: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3750: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67          /* The g
3760: 72 6f 75 70 20 66 69 6c 65 20 62 65 6c 6f 6e 67  roup file belong
3770: 73 20 74 6f 20 2a 2f 0a 20 20 73 71 6c 69 74 65  s to */.  sqlite
3780: 33 5f 76 66 73 20 2a 70 4f 72 69 67 56 66 73 20  3_vfs *pOrigVfs 
3790: 3d 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66  = gQuota.pOrigVf
37a0: 73 3b 20 20 20 2f 2a 20 52 65 61 6c 20 56 46 53  s;   /* Real VFS
37b0: 20 2a 2f 0a 0a 20 20 2f 2a 20 44 6f 20 74 68 65   */..  /* Do the
37c0: 20 61 63 74 75 61 6c 20 66 69 6c 65 20 64 65 6c   actual file del
37d0: 65 74 65 20 2a 2f 0a 20 20 72 63 20 3d 20 70 4f  ete */.  rc = pO
37e0: 72 69 67 56 66 73 2d 3e 78 44 65 6c 65 74 65 28  rigVfs->xDelete(
37f0: 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61 6d 65 2c  pOrigVfs, zName,
3800: 20 73 79 6e 63 44 69 72 29 3b 0a 0a 20 20 2f 2a   syncDir);..  /*
3810: 20 49 66 20 74 68 65 20 66 69 6c 65 20 6a 75 73   If the file jus
3820: 74 20 64 65 6c 65 74 65 64 20 69 73 20 61 20 6d  t deleted is a m
3830: 65 6d 62 65 72 20 6f 66 20 61 20 71 75 6f 74 61  ember of a quota
3840: 20 67 72 6f 75 70 2c 20 74 68 65 6e 20 72 65 6d   group, then rem
3850: 6f 76 65 0a 20 20 2a 2a 20 69 74 20 66 72 6f 6d  ove.  ** it from
3860: 20 74 68 61 74 20 71 75 6f 74 61 20 67 72 6f 75   that quota grou
3870: 70 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 72 63  p..  */.  if( rc
3880: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
3890: 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29 3b     quotaEnter();
38a0: 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20 71 75  .    pGroup = qu
38b0: 6f 74 61 47 72 6f 75 70 46 69 6e 64 28 7a 4e 61  otaGroupFind(zNa
38c0: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 70 47 72  me);.    if( pGr
38d0: 6f 75 70 20 29 7b 0a 20 20 20 20 20 20 70 46 69  oup ){.      pFi
38e0: 6c 65 20 3d 20 71 75 6f 74 61 46 69 6e 64 46 69  le = quotaFindFi
38f0: 6c 65 28 70 47 72 6f 75 70 2c 20 7a 4e 61 6d 65  le(pGroup, zName
3900: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 46 69  );.      if( pFi
3910: 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  le ){.        if
3920: 28 20 70 46 69 6c 65 2d 3e 6e 52 65 66 20 29 7b  ( pFile->nRef ){
3930: 0a 20 20 20 20 20 20 20 20 20 20 70 46 69 6c 65  .          pFile
3940: 2d 3e 64 65 6c 65 74 65 4f 6e 43 6c 6f 73 65 20  ->deleteOnClose 
3950: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 1;.        }el
3960: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 71 75  se{.          qu
3970: 6f 74 61 52 65 6d 6f 76 65 46 69 6c 65 28 70 46  otaRemoveFile(pF
3980: 69 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ile);.          
3990: 71 75 6f 74 61 47 72 6f 75 70 44 65 72 65 66 28  quotaGroupDeref(
39a0: 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 20 20 20  pGroup);.       
39b0: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d   }.      }.    }
39c0: 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28  .    quotaLeave(
39d0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
39e0: 72 63 3b 0a 7d 0a 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a  rc;.}.../*******
39f0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a00: 2a 20 49 2f 4f 20 4d 65 74 68 6f 64 20 57 72 61  * I/O Method Wra
3a10: 70 70 65 72 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ppers **********
3a20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3a30: 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 78 43 6c 6f 73  *****/../* xClos
3a40: 65 20 72 65 71 75 65 73 74 73 20 67 65 74 20 70  e requests get p
3a50: 61 73 73 65 64 20 74 68 72 6f 75 67 68 20 74 6f  assed through to
3a60: 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46   the original VF
3a70: 53 2e 20 20 42 75 74 20 77 65 0a 2a 2a 20 61 6c  S.  But we.** al
3a80: 73 6f 20 68 61 76 65 20 74 6f 20 75 6e 6c 69 6e  so have to unlin
3a90: 6b 20 74 68 65 20 71 75 6f 74 61 43 6f 6e 6e 20  k the quotaConn 
3aa0: 66 72 6f 6d 20 74 68 65 20 71 75 6f 74 61 46 69  from the quotaFi
3ab0: 6c 65 20 61 6e 64 20 71 75 6f 74 61 47 72 6f 75  le and quotaGrou
3ac0: 70 2e 0a 2a 2a 20 54 68 65 20 71 75 6f 74 61 46  p..** The quotaF
3ad0: 69 6c 65 20 61 6e 64 2f 6f 72 20 71 75 6f 74 61  ile and/or quota
3ae0: 47 72 6f 75 70 20 61 72 65 20 66 72 65 65 64 20  Group are freed 
3af0: 69 66 20 74 68 65 79 20 61 72 65 20 6e 6f 20 6c  if they are no l
3b00: 6f 6e 67 65 72 20 69 6e 20 75 73 65 2e 0a 2a 2f  onger in use..*/
3b10: 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74  .static int quot
3b20: 61 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 66  aClose(sqlite3_f
3b30: 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 71  ile *pConn){.  q
3b40: 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71  uotaConn *p = (q
3b50: 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b  uotaConn*)pConn;
3b60: 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46  .  quotaFile *pF
3b70: 69 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a  ile = p->pFile;.
3b80: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a    sqlite3_file *
3b90: 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61  pSubOpen = quota
3ba0: 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a  SubOpen(pConn);.
3bb0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20 3d    int rc;.  rc =
3bc0: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
3bd0: 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 53 75 62  ods->xClose(pSub
3be0: 4f 70 65 6e 29 3b 0a 20 20 71 75 6f 74 61 45 6e  Open);.  quotaEn
3bf0: 74 65 72 28 29 3b 0a 20 20 70 46 69 6c 65 2d 3e  ter();.  pFile->
3c00: 6e 52 65 66 2d 2d 3b 0a 20 20 69 66 28 20 70 46  nRef--;.  if( pF
3c10: 69 6c 65 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a  ile->nRef==0 ){.
3c20: 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a      quotaGroup *
3c30: 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65 2d 3e  pGroup = pFile->
3c40: 70 47 72 6f 75 70 3b 0a 20 20 20 20 69 66 28 20  pGroup;.    if( 
3c50: 70 46 69 6c 65 2d 3e 64 65 6c 65 74 65 4f 6e 43  pFile->deleteOnC
3c60: 6c 6f 73 65 20 29 20 71 75 6f 74 61 52 65 6d 6f  lose ) quotaRemo
3c70: 76 65 46 69 6c 65 28 70 46 69 6c 65 29 3b 0a 20  veFile(pFile);. 
3c80: 20 20 20 71 75 6f 74 61 47 72 6f 75 70 44 65 72     quotaGroupDer
3c90: 65 66 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a  ef(pGroup);.  }.
3ca0: 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a    quotaLeave();.
3cb0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
3cc0: 2f 2a 20 50 61 73 73 20 78 52 65 61 64 20 72 65  /* Pass xRead re
3cd0: 71 75 65 73 74 73 20 64 69 72 65 63 74 6f 72 79  quests directory
3ce0: 20 74 68 72 75 20 74 6f 20 74 68 65 20 6f 72 69   thru to the ori
3cf0: 67 69 6e 61 6c 20 56 46 53 20 77 69 74 68 6f 75  ginal VFS withou
3d00: 74 0a 2a 2a 20 66 75 72 74 68 65 72 20 70 72 6f  t.** further pro
3d10: 63 65 73 73 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74  cessing..*/.stat
3d20: 69 63 20 69 6e 74 20 71 75 6f 74 61 52 65 61 64  ic int quotaRead
3d30: 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  (.  sqlite3_file
3d40: 20 2a 70 43 6f 6e 6e 2c 0a 20 20 76 6f 69 64 20   *pConn,.  void 
3d50: 2a 70 42 75 66 2c 0a 20 20 69 6e 74 20 69 41 6d  *pBuf,.  int iAm
3d60: 74 2c 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  t,.  sqlite3_int
3d70: 36 34 20 69 4f 66 73 74 0a 29 7b 0a 20 20 73 71  64 iOfst.){.  sq
3d80: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
3d90: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
3da0: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65  pen(pConn);.  re
3db0: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
3dc0: 4d 65 74 68 6f 64 73 2d 3e 78 52 65 61 64 28 70  Methods->xRead(p
3dd0: 53 75 62 4f 70 65 6e 2c 20 70 42 75 66 2c 20 69  SubOpen, pBuf, i
3de0: 41 6d 74 2c 20 69 4f 66 73 74 29 3b 0a 7d 0a 0a  Amt, iOfst);.}..
3df0: 2f 2a 20 43 68 65 63 6b 20 78 57 72 69 74 65 20  /* Check xWrite 
3e00: 72 65 71 75 65 73 74 73 20 74 6f 20 73 65 65 20  requests to see 
3e10: 69 66 20 74 68 65 79 20 65 78 70 61 6e 64 20 74  if they expand t
3e20: 68 65 20 66 69 6c 65 2e 20 20 49 66 20 74 68 65  he file.  If the
3e30: 79 20 64 6f 2c 0a 2a 2a 20 74 68 65 20 70 65 72  y do,.** the per
3e40: 66 6f 72 6d 20 61 20 71 75 6f 74 61 20 63 68 65  form a quota che
3e50: 63 6b 20 62 65 66 6f 72 65 20 70 61 73 73 69 6e  ck before passin
3e60: 67 20 74 68 65 6d 20 74 68 72 6f 75 67 68 20 74  g them through t
3e70: 6f 20 74 68 65 0a 2a 2a 20 6f 72 69 67 69 6e 61  o the.** origina
3e80: 6c 20 56 46 53 2e 0a 2a 2f 0a 73 74 61 74 69 63  l VFS..*/.static
3e90: 20 69 6e 74 20 71 75 6f 74 61 57 72 69 74 65 28   int quotaWrite(
3ea0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
3eb0: 2a 70 43 6f 6e 6e 2c 0a 20 20 63 6f 6e 73 74 20  *pConn,.  const 
3ec0: 76 6f 69 64 20 2a 70 42 75 66 2c 0a 20 20 69 6e  void *pBuf,.  in
3ed0: 74 20 69 41 6d 74 2c 0a 20 20 73 71 6c 69 74 65  t iAmt,.  sqlite
3ee0: 33 5f 69 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b  3_int64 iOfst.){
3ef0: 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20  .  quotaConn *p 
3f00: 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43  = (quotaConn*)pC
3f10: 6f 6e 6e 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  onn;.  sqlite3_f
3f20: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
3f30: 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f  quotaSubOpen(pCo
3f40: 6e 6e 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69  nn);.  sqlite3_i
3f50: 6e 74 36 34 20 69 45 6e 64 20 3d 20 69 4f 66 73  nt64 iEnd = iOfs
3f60: 74 2b 69 41 6d 74 3b 0a 20 20 71 75 6f 74 61 47  t+iAmt;.  quotaG
3f70: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20  roup *pGroup;.  
3f80: 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65  quotaFile *pFile
3f90: 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20 73   = p->pFile;.  s
3fa0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 7a 4e  qlite3_int64 szN
3fb0: 65 77 3b 0a 0a 20 20 69 66 28 20 70 46 69 6c 65  ew;..  if( pFile
3fc0: 2d 3e 69 53 69 7a 65 3c 69 45 6e 64 20 29 7b 0a  ->iSize<iEnd ){.
3fd0: 20 20 20 20 70 47 72 6f 75 70 20 3d 20 70 46 69      pGroup = pFi
3fe0: 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20  le->pGroup;.    
3ff0: 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20  quotaEnter();.  
4000: 20 20 73 7a 4e 65 77 20 3d 20 70 47 72 6f 75 70    szNew = pGroup
4010: 2d 3e 69 53 69 7a 65 20 2d 20 70 46 69 6c 65 2d  ->iSize - pFile-
4020: 3e 69 53 69 7a 65 20 2b 20 69 45 6e 64 3b 0a 20  >iSize + iEnd;. 
4030: 20 20 20 69 66 28 20 73 7a 4e 65 77 3e 70 47 72     if( szNew>pGr
4040: 6f 75 70 2d 3e 69 4c 69 6d 69 74 20 26 26 20 70  oup->iLimit && p
4050: 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 3e 30 20  Group->iLimit>0 
4060: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 70 47 72  ){.      if( pGr
4070: 6f 75 70 2d 3e 78 43 61 6c 6c 62 61 63 6b 20 29  oup->xCallback )
4080: 7b 0a 20 20 20 20 20 20 20 20 70 47 72 6f 75 70  {.        pGroup
4090: 2d 3e 78 43 61 6c 6c 62 61 63 6b 28 70 46 69 6c  ->xCallback(pFil
40a0: 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 26 70  e->zFilename, &p
40b0: 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 2c 20 73  Group->iLimit, s
40c0: 7a 4e 65 77 2c 20 0a 20 20 20 20 20 20 20 20 20  zNew, .         
40d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
40e0: 20 70 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a   pGroup->pArg);.
40f0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
4100: 28 20 73 7a 4e 65 77 3e 70 47 72 6f 75 70 2d 3e  ( szNew>pGroup->
4110: 69 4c 69 6d 69 74 20 26 26 20 70 47 72 6f 75 70  iLimit && pGroup
4120: 2d 3e 69 4c 69 6d 69 74 3e 30 20 29 7b 0a 20 20  ->iLimit>0 ){.  
4130: 20 20 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65        quotaLeave
4140: 28 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  ();.        retu
4150: 72 6e 20 53 51 4c 49 54 45 5f 46 55 4c 4c 3b 0a  rn SQLITE_FULL;.
4160: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
4170: 20 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20    pGroup->iSize 
4180: 3d 20 73 7a 4e 65 77 3b 0a 20 20 20 20 70 46 69  = szNew;.    pFi
4190: 6c 65 2d 3e 69 53 69 7a 65 20 3d 20 69 45 6e 64  le->iSize = iEnd
41a0: 3b 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65  ;.    quotaLeave
41b0: 28 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ();.  }.  return
41c0: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
41d0: 6f 64 73 2d 3e 78 57 72 69 74 65 28 70 53 75 62  ods->xWrite(pSub
41e0: 4f 70 65 6e 2c 20 70 42 75 66 2c 20 69 41 6d 74  Open, pBuf, iAmt
41f0: 2c 20 69 4f 66 73 74 29 3b 0a 7d 0a 0a 2f 2a 20  , iOfst);.}../* 
4200: 50 61 73 73 20 78 54 72 75 6e 63 61 74 65 20 72  Pass xTruncate r
4210: 65 71 75 65 73 74 73 20 74 68 72 75 20 74 6f 20  equests thru to 
4220: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  the original VFS
4230: 2e 20 20 49 66 20 74 68 65 0a 2a 2a 20 73 75 63  .  If the.** suc
4240: 63 65 73 73 2c 20 75 70 64 61 74 65 20 74 68 65  cess, update the
4250: 20 66 69 6c 65 20 73 69 7a 65 2e 0a 2a 2f 0a 73   file size..*/.s
4260: 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 54  tatic int quotaT
4270: 72 75 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f  runcate(sqlite3_
4280: 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 73 71 6c  file *pConn, sql
4290: 69 74 65 33 5f 69 6e 74 36 34 20 73 69 7a 65 29  ite3_int64 size)
42a0: 7b 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70  {.  quotaConn *p
42b0: 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70   = (quotaConn*)p
42c0: 43 6f 6e 6e 3b 0a 20 20 73 71 6c 69 74 65 33 5f  Conn;.  sqlite3_
42d0: 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d  file *pSubOpen =
42e0: 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43   quotaSubOpen(pC
42f0: 6f 6e 6e 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d  onn);.  int rc =
4300: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
4310: 6f 64 73 2d 3e 78 54 72 75 6e 63 61 74 65 28 70  ods->xTruncate(p
4320: 53 75 62 4f 70 65 6e 2c 20 73 69 7a 65 29 3b 0a  SubOpen, size);.
4330: 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69    quotaFile *pFi
4340: 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a 20  le = p->pFile;. 
4350: 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72   quotaGroup *pGr
4360: 6f 75 70 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  oup;.  if( rc==S
4370: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
4380: 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20  quotaEnter();.  
4390: 20 20 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65    pGroup = pFile
43a0: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47  ->pGroup;.    pG
43b0: 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2d 3d 20 70  roup->iSize -= p
43c0: 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20 20  File->iSize;.   
43d0: 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 20 3d 20   pFile->iSize = 
43e0: 73 69 7a 65 3b 0a 20 20 20 20 70 47 72 6f 75 70  size;.    pGroup
43f0: 2d 3e 69 53 69 7a 65 20 2b 3d 20 73 69 7a 65 3b  ->iSize += size;
4400: 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28  .    quotaLeave(
4410: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
4420: 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78  rc;.}../* Pass x
4430: 53 79 6e 63 20 72 65 71 75 65 73 74 73 20 74 68  Sync requests th
4440: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69  rough to the ori
4450: 67 69 6e 61 6c 20 56 46 53 20 77 69 74 68 6f 75  ginal VFS withou
4460: 74 20 63 68 61 6e 67 65 0a 2a 2f 0a 73 74 61 74  t change.*/.stat
4470: 69 63 20 69 6e 74 20 71 75 6f 74 61 53 79 6e 63  ic int quotaSync
4480: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
4490: 43 6f 6e 6e 2c 20 69 6e 74 20 66 6c 61 67 73 29  Conn, int flags)
44a0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  {.  sqlite3_file
44b0: 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f   *pSubOpen = quo
44c0: 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29  taSubOpen(pConn)
44d0: 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f  ;.  return pSubO
44e0: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
44f0: 53 79 6e 63 28 70 53 75 62 4f 70 65 6e 2c 20 66  Sync(pSubOpen, f
4500: 6c 61 67 73 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73  lags);.}../* Pas
4510: 73 20 78 46 69 6c 65 53 69 7a 65 20 72 65 71 75  s xFileSize requ
4520: 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20  ests through to 
4530: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  the original VFS
4540: 20 62 75 74 20 74 68 65 6e 0a 2a 2a 20 75 70 64   but then.** upd
4550: 61 74 65 20 74 68 65 20 71 75 6f 74 61 47 72 6f  ate the quotaGro
4560: 75 70 20 77 69 74 68 20 74 68 65 20 6e 65 77 20  up with the new 
4570: 73 69 7a 65 20 62 65 66 6f 72 65 20 72 65 74 75  size before retu
4580: 72 6e 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63  rning..*/.static
4590: 20 69 6e 74 20 71 75 6f 74 61 46 69 6c 65 53 69   int quotaFileSi
45a0: 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ze(sqlite3_file 
45b0: 2a 70 43 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f  *pConn, sqlite3_
45c0: 69 6e 74 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20  int64 *pSize){. 
45d0: 20 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20   quotaConn *p = 
45e0: 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e  (quotaConn*)pCon
45f0: 6e 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c  n;.  sqlite3_fil
4600: 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75  e *pSubOpen = qu
4610: 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e  otaSubOpen(pConn
4620: 29 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a  );.  quotaFile *
4630: 70 46 69 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65  pFile = p->pFile
4640: 3b 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a  ;.  quotaGroup *
4650: 70 47 72 6f 75 70 3b 0a 20 20 73 71 6c 69 74 65  pGroup;.  sqlite
4660: 33 5f 69 6e 74 36 34 20 73 7a 3b 0a 20 20 69 6e  3_int64 sz;.  in
4670: 74 20 72 63 3b 0a 0a 20 20 72 63 20 3d 20 70 53  t rc;..  rc = pS
4680: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
4690: 2d 3e 78 46 69 6c 65 53 69 7a 65 28 70 53 75 62  ->xFileSize(pSub
46a0: 4f 70 65 6e 2c 20 26 73 7a 29 3b 0a 20 20 69 66  Open, &sz);.  if
46b0: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
46c0: 29 7b 0a 20 20 20 20 71 75 6f 74 61 45 6e 74 65  ){.    quotaEnte
46d0: 72 28 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 20  r();.    pGroup 
46e0: 3d 20 70 46 69 6c 65 2d 3e 70 47 72 6f 75 70 3b  = pFile->pGroup;
46f0: 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 69 53 69  .    pGroup->iSi
4700: 7a 65 20 2d 3d 20 70 46 69 6c 65 2d 3e 69 53 69  ze -= pFile->iSi
4710: 7a 65 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e 69  ze;.    pFile->i
4720: 53 69 7a 65 20 3d 20 73 7a 3b 0a 20 20 20 20 70  Size = sz;.    p
4730: 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2b 3d 20  Group->iSize += 
4740: 73 7a 3b 0a 20 20 20 20 71 75 6f 74 61 4c 65 61  sz;.    quotaLea
4750: 76 65 28 29 3b 0a 20 20 20 20 2a 70 53 69 7a 65  ve();.    *pSize
4760: 20 3d 20 73 7a 3b 0a 20 20 7d 0a 20 20 72 65 74   = sz;.  }.  ret
4770: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61  urn rc;.}../* Pa
4780: 73 73 20 78 4c 6f 63 6b 20 72 65 71 75 65 73 74  ss xLock request
4790: 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65  s through to the
47a0: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e   original VFS un
47b0: 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74  changed..*/.stat
47c0: 69 63 20 69 6e 74 20 71 75 6f 74 61 4c 6f 63 6b  ic int quotaLock
47d0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
47e0: 43 6f 6e 6e 2c 20 69 6e 74 20 6c 6f 63 6b 29 7b  Conn, int lock){
47f0: 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  .  sqlite3_file 
4800: 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74  *pSubOpen = quot
4810: 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b  aSubOpen(pConn);
4820: 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70  .  return pSubOp
4830: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 4c  en->pMethods->xL
4840: 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6c 6f  ock(pSubOpen, lo
4850: 63 6b 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20  ck);.}../* Pass 
4860: 78 55 6e 6c 6f 63 6b 20 72 65 71 75 65 73 74 73  xUnlock requests
4870: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20   through to the 
4880: 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63  original VFS unc
4890: 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69  hanged..*/.stati
48a0: 63 20 69 6e 74 20 71 75 6f 74 61 55 6e 6c 6f 63  c int quotaUnloc
48b0: 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a  k(sqlite3_file *
48c0: 70 43 6f 6e 6e 2c 20 69 6e 74 20 6c 6f 63 6b 29  pConn, int lock)
48d0: 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  {.  sqlite3_file
48e0: 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f   *pSubOpen = quo
48f0: 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29  taSubOpen(pConn)
4900: 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f  ;.  return pSubO
4910: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
4920: 55 6e 6c 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c  Unlock(pSubOpen,
4930: 20 6c 6f 63 6b 29 3b 0a 7d 0a 0a 2f 2a 20 50 61   lock);.}../* Pa
4940: 73 73 20 78 43 68 65 63 6b 52 65 73 65 72 76 65  ss xCheckReserve
4950: 64 4c 6f 63 6b 20 72 65 71 75 65 73 74 73 20 74  dLock requests t
4960: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
4970: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
4980: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
4990: 69 6e 74 20 71 75 6f 74 61 43 68 65 63 6b 52 65  int quotaCheckRe
49a0: 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69 74  servedLock(sqlit
49b0: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20  e3_file *pConn, 
49c0: 69 6e 74 20 2a 70 52 65 73 4f 75 74 29 7b 0a 20  int *pResOut){. 
49d0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
49e0: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
49f0: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
4a00: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
4a10: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 68 65  ->pMethods->xChe
4a20: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 70  ckReservedLock(p
4a30: 53 75 62 4f 70 65 6e 2c 20 70 52 65 73 4f 75 74  SubOpen, pResOut
4a40: 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 46  );.}../* Pass xF
4a50: 69 6c 65 43 6f 6e 74 72 6f 6c 20 72 65 71 75 65  ileControl reque
4a60: 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  sts through to t
4a70: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
4a80: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74  unchanged..*/.st
4a90: 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 46 69  atic int quotaFi
4aa0: 6c 65 43 6f 6e 74 72 6f 6c 28 73 71 6c 69 74 65  leControl(sqlite
4ab0: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
4ac0: 6e 74 20 6f 70 2c 20 76 6f 69 64 20 2a 70 41 72  nt op, void *pAr
4ad0: 67 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  g){.  sqlite3_fi
4ae0: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71  le *pSubOpen = q
4af0: 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e  uotaSubOpen(pCon
4b00: 6e 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 70  n);.  int rc = p
4b10: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
4b20: 73 2d 3e 78 46 69 6c 65 43 6f 6e 74 72 6f 6c 28  s->xFileControl(
4b30: 70 53 75 62 4f 70 65 6e 2c 20 6f 70 2c 20 70 41  pSubOpen, op, pA
4b40: 72 67 29 3b 0a 20 20 69 66 28 20 6f 70 3d 3d 53  rg);.  if( op==S
4b50: 51 4c 49 54 45 5f 46 43 4e 54 4c 5f 56 46 53 4e  QLITE_FCNTL_VFSN
4b60: 41 4d 45 20 26 26 20 72 63 3d 3d 53 51 4c 49 54  AME && rc==SQLIT
4b70: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 2a 28 63 68  E_OK ){.    *(ch
4b80: 61 72 2a 2a 29 70 41 72 67 20 3d 20 73 71 6c 69  ar**)pArg = sqli
4b90: 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 71 75 6f  te3_mprintf("quo
4ba0: 74 61 2f 25 7a 22 2c 20 2a 28 63 68 61 72 2a 2a  ta/%z", *(char**
4bb0: 29 70 41 72 67 29 3b 0a 20 20 7d 0a 20 20 72 65  )pArg);.  }.  re
4bc0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50  turn rc;.}../* P
4bd0: 61 73 73 20 78 53 65 63 74 6f 72 53 69 7a 65 20  ass xSectorSize 
4be0: 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68  requests through
4bf0: 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c   to the original
4c00: 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a   VFS unchanged..
4c10: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75  */.static int qu
4c20: 6f 74 61 53 65 63 74 6f 72 53 69 7a 65 28 73 71  otaSectorSize(sq
4c30: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e  lite3_file *pCon
4c40: 6e 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  n){.  sqlite3_fi
4c50: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20 71  le *pSubOpen = q
4c60: 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f 6e  uotaSubOpen(pCon
4c70: 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 53 75  n);.  return pSu
4c80: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
4c90: 3e 78 53 65 63 74 6f 72 53 69 7a 65 28 70 53 75  >xSectorSize(pSu
4ca0: 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  bOpen);.}../* Pa
4cb0: 73 73 20 78 44 65 76 69 63 65 43 68 61 72 61 63  ss xDeviceCharac
4cc0: 74 65 72 69 73 74 69 63 73 20 72 65 71 75 65 73  teristics reques
4cd0: 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68  ts through to th
4ce0: 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75  e original VFS u
4cf0: 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61  nchanged..*/.sta
4d00: 74 69 63 20 69 6e 74 20 71 75 6f 74 61 44 65 76  tic int quotaDev
4d10: 69 63 65 43 68 61 72 61 63 74 65 72 69 73 74 69  iceCharacteristi
4d20: 63 73 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  cs(sqlite3_file 
4d30: 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71 6c 69 74  *pConn){.  sqlit
4d40: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
4d50: 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e  n = quotaSubOpen
4d60: 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72  (pConn);.  retur
4d70: 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74  n pSubOpen->pMet
4d80: 68 6f 64 73 2d 3e 78 44 65 76 69 63 65 43 68 61  hods->xDeviceCha
4d90: 72 61 63 74 65 72 69 73 74 69 63 73 28 70 53 75  racteristics(pSu
4da0: 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  bOpen);.}../* Pa
4db0: 73 73 20 78 53 68 6d 4d 61 70 20 72 65 71 75 65  ss xShmMap reque
4dc0: 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  sts through to t
4dd0: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
4de0: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74  unchanged..*/.st
4df0: 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 53 68  atic int quotaSh
4e00: 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65 33 5f  mMap(.  sqlite3_
4e10: 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20  file *pConn,    
4e20: 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e 64 6c          /* Handl
4e30: 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61 62 61  e open on databa
4e40: 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74  se file */.  int
4e50: 20 69 52 65 67 69 6f 6e 2c 20 20 20 20 20 20 20   iRegion,       
4e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
4e70: 52 65 67 69 6f 6e 20 74 6f 20 72 65 74 72 69 65  Region to retrie
4e80: 76 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a 52 65  ve */.  int szRe
4e90: 67 69 6f 6e 2c 20 20 20 20 20 20 20 20 20 20 20  gion,           
4ea0: 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20          /* Size 
4eb0: 6f 66 20 72 65 67 69 6f 6e 73 20 2a 2f 0a 20 20  of regions */.  
4ec0: 69 6e 74 20 62 45 78 74 65 6e 64 2c 20 20 20 20  int bExtend,    
4ed0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4ee0: 2f 2a 20 54 72 75 65 20 74 6f 20 65 78 74 65 6e  /* True to exten
4ef0: 64 20 66 69 6c 65 20 69 66 20 6e 65 63 65 73 73  d file if necess
4f00: 61 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20 76 6f  ary */.  void vo
4f10: 6c 61 74 69 6c 65 20 2a 2a 70 70 20 20 20 20 20  latile **pp     
4f20: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55 54 3a           /* OUT:
4f30: 20 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79 20 2a   Mapped memory *
4f40: 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66  /.){.  sqlite3_f
4f50: 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d 20  ile *pSubOpen = 
4f60: 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43 6f  quotaSubOpen(pCo
4f70: 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 53  nn);.  return pS
4f80: 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73  ubOpen->pMethods
4f90: 2d 3e 78 53 68 6d 4d 61 70 28 70 53 75 62 4f 70  ->xShmMap(pSubOp
4fa0: 65 6e 2c 20 69 52 65 67 69 6f 6e 2c 20 73 7a 52  en, iRegion, szR
4fb0: 65 67 69 6f 6e 2c 20 62 45 78 74 65 6e 64 2c 20  egion, bExtend, 
4fc0: 70 70 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20  pp);.}../* Pass 
4fd0: 78 53 68 6d 4c 6f 63 6b 20 72 65 71 75 65 73 74  xShmLock request
4fe0: 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65  s through to the
4ff0: 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20 75 6e   original VFS un
5000: 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74  changed..*/.stat
5010: 69 63 20 69 6e 74 20 71 75 6f 74 61 53 68 6d 4c  ic int quotaShmL
5020: 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33 5f 66  ock(.  sqlite3_f
5030: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20 20 20  ile *pConn,     
5040: 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20 66 69    /* Database fi
5050: 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65 20 73  le holding the s
5060: 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a  hared memory */.
5070: 20 20 69 6e 74 20 6f 66 73 74 2c 20 20 20 20 20    int ofst,     
5080: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5090: 46 69 72 73 74 20 6c 6f 63 6b 20 74 6f 20 61 63  First lock to ac
50a0: 71 75 69 72 65 20 6f 72 20 72 65 6c 65 61 73 65  quire or release
50b0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 2c 20 20 20 20   */.  int n,    
50c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
50d0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 6c 6f   /* Number of lo
50e0: 63 6b 73 20 74 6f 20 61 63 71 75 69 72 65 20 6f  cks to acquire o
50f0: 72 20 72 65 6c 65 61 73 65 20 2a 2f 0a 20 20 69  r release */.  i
5100: 6e 74 20 66 6c 61 67 73 20 20 20 20 20 20 20 20  nt flags        
5110: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57 68 61            /* Wha
5120: 74 20 74 6f 20 64 6f 20 77 69 74 68 20 74 68 65  t to do with the
5130: 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20 73 71   lock */.){.  sq
5140: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
5150: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
5160: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65  pen(pConn);.  re
5170: 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70  turn pSubOpen->p
5180: 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f 63  Methods->xShmLoc
5190: 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6f 66 73 74  k(pSubOpen, ofst
51a0: 2c 20 6e 2c 20 66 6c 61 67 73 29 3b 0a 7d 0a 0a  , n, flags);.}..
51b0: 2f 2a 20 50 61 73 73 20 78 53 68 6d 42 61 72 72  /* Pass xShmBarr
51c0: 69 65 72 20 72 65 71 75 65 73 74 73 20 74 68 72  ier requests thr
51d0: 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67  ough to the orig
51e0: 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67  inal VFS unchang
51f0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  ed..*/.static vo
5200: 69 64 20 71 75 6f 74 61 53 68 6d 42 61 72 72 69  id quotaShmBarri
5210: 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  er(sqlite3_file 
5220: 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71 6c 69 74  *pConn){.  sqlit
5230: 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65  e3_file *pSubOpe
5240: 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e  n = quotaSubOpen
5250: 28 70 43 6f 6e 6e 29 3b 0a 20 20 70 53 75 62 4f  (pConn);.  pSubO
5260: 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78  pen->pMethods->x
5270: 53 68 6d 42 61 72 72 69 65 72 28 70 53 75 62 4f  ShmBarrier(pSubO
5280: 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73  pen);.}../* Pass
5290: 20 78 53 68 6d 55 6e 6d 61 70 20 72 65 71 75 65   xShmUnmap reque
52a0: 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  sts through to t
52b0: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
52c0: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74  unchanged..*/.st
52d0: 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 53 68  atic int quotaSh
52e0: 6d 55 6e 6d 61 70 28 73 71 6c 69 74 65 33 5f 66  mUnmap(sqlite3_f
52f0: 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20  ile *pConn, int 
5300: 64 65 6c 65 74 65 46 6c 61 67 29 7b 0a 20 20 73  deleteFlag){.  s
5310: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
5320: 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62  bOpen = quotaSub
5330: 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72  Open(pConn);.  r
5340: 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e  eturn pSubOpen->
5350: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e  pMethods->xShmUn
5360: 6d 61 70 28 70 53 75 62 4f 70 65 6e 2c 20 64 65  map(pSubOpen, de
5370: 6c 65 74 65 46 6c 61 67 29 3b 0a 7d 0a 0a 2f 2a  leteFlag);.}../*
5380: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5390: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 50 75 62 6c 69 63  ********* Public
53a0: 20 49 6e 74 65 72 66 61 63 65 73 20 2a 2a 2a 2a   Interfaces ****
53b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
53c0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a  *********/./*.**
53d0: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
53e0: 71 75 6f 74 61 20 56 46 53 20 73 68 69 6d 2e 20  quota VFS shim. 
53f0: 20 55 73 65 20 74 68 65 20 56 46 53 20 6e 61 6d   Use the VFS nam
5400: 65 64 20 7a 4f 72 69 67 56 66 73 4e 61 6d 65 0a  ed zOrigVfsName.
5410: 2a 2a 20 61 73 20 74 68 65 20 56 46 53 20 74 68  ** as the VFS th
5420: 61 74 20 64 6f 65 73 20 74 68 65 20 61 63 74 75  at does the actu
5430: 61 6c 20 77 6f 72 6b 2e 20 20 55 73 65 20 74 68  al work.  Use th
5440: 65 20 64 65 66 61 75 6c 74 20 69 66 0a 2a 2a 20  e default if.** 
5450: 7a 4f 72 69 67 56 66 73 4e 61 6d 65 3d 3d 4e 55  zOrigVfsName==NU
5460: 4c 4c 2e 20 20 0a 2a 2a 0a 2a 2a 20 54 68 65 20  LL.  .**.** The 
5470: 71 75 6f 74 61 20 56 46 53 20 73 68 69 6d 20 69  quota VFS shim i
5480: 73 20 6e 61 6d 65 64 20 22 71 75 6f 74 61 22 2e  s named "quota".
5490: 20 20 49 74 20 77 69 6c 6c 20 62 65 63 6f 6d 65    It will become
54a0: 20 74 68 65 20 64 65 66 61 75 6c 74 0a 2a 2a 20   the default.** 
54b0: 56 46 53 20 69 66 20 6d 61 6b 65 44 65 66 61 75  VFS if makeDefau
54c0: 6c 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a  lt is non-zero..
54d0: 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54 49  **.** THIS ROUTI
54e0: 4e 45 20 49 53 20 4e 4f 54 20 54 48 52 45 41 44  NE IS NOT THREAD
54f0: 53 41 46 45 2e 20 20 43 61 6c 6c 20 74 68 69 73  SAFE.  Call this
5500: 20 72 6f 75 74 69 6e 65 20 65 78 61 63 74 6c 79   routine exactly
5510: 20 6f 6e 63 65 0a 2a 2a 20 64 75 72 69 6e 67 20   once.** during 
5520: 73 74 61 72 74 2d 75 70 2e 0a 2a 2f 0a 69 6e 74  start-up..*/.int
5530: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 69   sqlite3_quota_i
5540: 6e 69 74 69 61 6c 69 7a 65 28 63 6f 6e 73 74 20  nitialize(const 
5550: 63 68 61 72 20 2a 7a 4f 72 69 67 56 66 73 4e 61  char *zOrigVfsNa
5560: 6d 65 2c 20 69 6e 74 20 6d 61 6b 65 44 65 66 61  me, int makeDefa
5570: 75 6c 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ult){.  sqlite3_
5580: 76 66 73 20 2a 70 4f 72 69 67 56 66 73 3b 0a 20  vfs *pOrigVfs;. 
5590: 20 69 66 28 20 67 51 75 6f 74 61 2e 69 73 49 6e   if( gQuota.isIn
55a0: 69 74 69 61 6c 69 7a 65 64 20 29 20 72 65 74 75  itialized ) retu
55b0: 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45  rn SQLITE_MISUSE
55c0: 3b 0a 20 20 70 4f 72 69 67 56 66 73 20 3d 20 73  ;.  pOrigVfs = s
55d0: 71 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28  qlite3_vfs_find(
55e0: 7a 4f 72 69 67 56 66 73 4e 61 6d 65 29 3b 0a 20  zOrigVfsName);. 
55f0: 20 69 66 28 20 70 4f 72 69 67 56 66 73 3d 3d 30   if( pOrigVfs==0
5600: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
5610: 5f 45 52 52 4f 52 3b 0a 20 20 61 73 73 65 72 74  _ERROR;.  assert
5620: 28 20 70 4f 72 69 67 56 66 73 21 3d 26 67 51 75  ( pOrigVfs!=&gQu
5630: 6f 74 61 2e 73 54 68 69 73 56 66 73 20 29 3b 0a  ota.sThisVfs );.
5640: 20 20 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 20    gQuota.pMutex 
5650: 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  = sqlite3_mutex_
5660: 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54  alloc(SQLITE_MUT
5670: 45 58 5f 46 41 53 54 29 3b 0a 20 20 69 66 28 20  EX_FAST);.  if( 
5680: 21 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 20 29  !gQuota.pMutex )
5690: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
56a0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
56b0: 20 67 51 75 6f 74 61 2e 69 73 49 6e 69 74 69 61   gQuota.isInitia
56c0: 6c 69 7a 65 64 20 3d 20 31 3b 0a 20 20 67 51 75  lized = 1;.  gQu
56d0: 6f 74 61 2e 70 4f 72 69 67 56 66 73 20 3d 20 70  ota.pOrigVfs = p
56e0: 4f 72 69 67 56 66 73 3b 0a 20 20 67 51 75 6f 74  OrigVfs;.  gQuot
56f0: 61 2e 73 54 68 69 73 56 66 73 20 3d 20 2a 70 4f  a.sThisVfs = *pO
5700: 72 69 67 56 66 73 3b 0a 20 20 67 51 75 6f 74 61  rigVfs;.  gQuota
5710: 2e 73 54 68 69 73 56 66 73 2e 78 4f 70 65 6e 20  .sThisVfs.xOpen 
5720: 3d 20 71 75 6f 74 61 4f 70 65 6e 3b 0a 20 20 67  = quotaOpen;.  g
5730: 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 78  Quota.sThisVfs.x
5740: 44 65 6c 65 74 65 20 3d 20 71 75 6f 74 61 44 65  Delete = quotaDe
5750: 6c 65 74 65 3b 0a 20 20 67 51 75 6f 74 61 2e 73  lete;.  gQuota.s
5760: 54 68 69 73 56 66 73 2e 73 7a 4f 73 46 69 6c 65  ThisVfs.szOsFile
5770: 20 2b 3d 20 73 69 7a 65 6f 66 28 71 75 6f 74 61   += sizeof(quota
5780: 43 6f 6e 6e 29 3b 0a 20 20 67 51 75 6f 74 61 2e  Conn);.  gQuota.
5790: 73 54 68 69 73 56 66 73 2e 7a 4e 61 6d 65 20 3d  sThisVfs.zName =
57a0: 20 22 71 75 6f 74 61 22 3b 0a 20 20 67 51 75 6f   "quota";.  gQuo
57b0: 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e  ta.sIoMethodsV1.
57c0: 69 56 65 72 73 69 6f 6e 20 3d 20 31 3b 0a 20 20  iVersion = 1;.  
57d0: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
57e0: 73 56 31 2e 78 43 6c 6f 73 65 20 3d 20 71 75 6f  sV1.xClose = quo
57f0: 74 61 43 6c 6f 73 65 3b 0a 20 20 67 51 75 6f 74  taClose;.  gQuot
5800: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78  a.sIoMethodsV1.x
5810: 52 65 61 64 20 3d 20 71 75 6f 74 61 52 65 61 64  Read = quotaRead
5820: 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65  ;.  gQuota.sIoMe
5830: 74 68 6f 64 73 56 31 2e 78 57 72 69 74 65 20 3d  thodsV1.xWrite =
5840: 20 71 75 6f 74 61 57 72 69 74 65 3b 0a 20 20 67   quotaWrite;.  g
5850: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
5860: 56 31 2e 78 54 72 75 6e 63 61 74 65 20 3d 20 71  V1.xTruncate = q
5870: 75 6f 74 61 54 72 75 6e 63 61 74 65 3b 0a 20 20  uotaTruncate;.  
5880: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
5890: 73 56 31 2e 78 53 79 6e 63 20 3d 20 71 75 6f 74  sV1.xSync = quot
58a0: 61 53 79 6e 63 3b 0a 20 20 67 51 75 6f 74 61 2e  aSync;.  gQuota.
58b0: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 46 69  sIoMethodsV1.xFi
58c0: 6c 65 53 69 7a 65 20 3d 20 71 75 6f 74 61 46 69  leSize = quotaFi
58d0: 6c 65 53 69 7a 65 3b 0a 20 20 67 51 75 6f 74 61  leSize;.  gQuota
58e0: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 4c  .sIoMethodsV1.xL
58f0: 6f 63 6b 20 3d 20 71 75 6f 74 61 4c 6f 63 6b 3b  ock = quotaLock;
5900: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
5910: 68 6f 64 73 56 31 2e 78 55 6e 6c 6f 63 6b 20 3d  hodsV1.xUnlock =
5920: 20 71 75 6f 74 61 55 6e 6c 6f 63 6b 3b 0a 20 20   quotaUnlock;.  
5930: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
5940: 73 56 31 2e 78 43 68 65 63 6b 52 65 73 65 72 76  sV1.xCheckReserv
5950: 65 64 4c 6f 63 6b 20 3d 20 71 75 6f 74 61 43 68  edLock = quotaCh
5960: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 3b  eckReservedLock;
5970: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
5980: 68 6f 64 73 56 31 2e 78 46 69 6c 65 43 6f 6e 74  hodsV1.xFileCont
5990: 72 6f 6c 20 3d 20 71 75 6f 74 61 46 69 6c 65 43  rol = quotaFileC
59a0: 6f 6e 74 72 6f 6c 3b 0a 20 20 67 51 75 6f 74 61  ontrol;.  gQuota
59b0: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 53  .sIoMethodsV1.xS
59c0: 65 63 74 6f 72 53 69 7a 65 20 3d 20 71 75 6f 74  ectorSize = quot
59d0: 61 53 65 63 74 6f 72 53 69 7a 65 3b 0a 20 20 67  aSectorSize;.  g
59e0: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
59f0: 56 31 2e 78 44 65 76 69 63 65 43 68 61 72 61 63  V1.xDeviceCharac
5a00: 74 65 72 69 73 74 69 63 73 20 3d 20 71 75 6f 74  teristics = quot
5a10: 61 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72  aDeviceCharacter
5a20: 69 73 74 69 63 73 3b 0a 20 20 67 51 75 6f 74 61  istics;.  gQuota
5a30: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 20 3d 20  .sIoMethodsV2 = 
5a40: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
5a50: 73 56 31 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49  sV1;.  gQuota.sI
5a60: 6f 4d 65 74 68 6f 64 73 56 32 2e 69 56 65 72 73  oMethodsV2.iVers
5a70: 69 6f 6e 20 3d 20 32 3b 0a 20 20 67 51 75 6f 74  ion = 2;.  gQuot
5a80: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78  a.sIoMethodsV2.x
5a90: 53 68 6d 4d 61 70 20 3d 20 71 75 6f 74 61 53 68  ShmMap = quotaSh
5aa0: 6d 4d 61 70 3b 0a 20 20 67 51 75 6f 74 61 2e 73  mMap;.  gQuota.s
5ab0: 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d  IoMethodsV2.xShm
5ac0: 4c 6f 63 6b 20 3d 20 71 75 6f 74 61 53 68 6d 4c  Lock = quotaShmL
5ad0: 6f 63 6b 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49  ock;.  gQuota.sI
5ae0: 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 42  oMethodsV2.xShmB
5af0: 61 72 72 69 65 72 20 3d 20 71 75 6f 74 61 53 68  arrier = quotaSh
5b00: 6d 42 61 72 72 69 65 72 3b 0a 20 20 67 51 75 6f  mBarrier;.  gQuo
5b10: 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e  ta.sIoMethodsV2.
5b20: 78 53 68 6d 55 6e 6d 61 70 20 3d 20 71 75 6f 74  xShmUnmap = quot
5b30: 61 53 68 6d 55 6e 6d 61 70 3b 0a 20 20 73 71 6c  aShmUnmap;.  sql
5b40: 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74 65  ite3_vfs_registe
5b50: 72 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73 56  r(&gQuota.sThisV
5b60: 66 73 2c 20 6d 61 6b 65 44 65 66 61 75 6c 74 29  fs, makeDefault)
5b70: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
5b80: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  E_OK;.}../*.** S
5b90: 68 75 74 64 6f 77 6e 20 74 68 65 20 71 75 6f 74  hutdown the quot
5ba0: 61 20 73 79 73 74 65 6d 2e 0a 2a 2a 0a 2a 2a 20  a system..**.** 
5bb0: 41 6c 6c 20 53 51 4c 69 74 65 20 64 61 74 61 62  All SQLite datab
5bc0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20  ase connections 
5bd0: 6d 75 73 74 20 62 65 20 63 6c 6f 73 65 64 20 62  must be closed b
5be0: 65 66 6f 72 65 20 63 61 6c 6c 69 6e 67 20 74 68  efore calling th
5bf0: 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 2e 0a 2a  is.** routine..*
5c00: 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54 49 4e  *.** THIS ROUTIN
5c10: 45 20 49 53 20 4e 4f 54 20 54 48 52 45 41 44 53  E IS NOT THREADS
5c20: 41 46 45 2e 20 20 43 61 6c 6c 20 74 68 69 73 20  AFE.  Call this 
5c30: 72 6f 75 74 69 6e 65 20 65 78 61 63 74 6c 79 20  routine exactly 
5c40: 6f 6e 63 65 20 77 68 69 6c 65 0a 2a 2a 20 73 68  once while.** sh
5c50: 75 74 74 69 6e 67 20 64 6f 77 6e 20 69 6e 20 6f  utting down in o
5c60: 72 64 65 72 20 74 6f 20 66 72 65 65 20 61 6c 6c  rder to free all
5c70: 20 72 65 6d 61 69 6e 69 6e 67 20 71 75 6f 74 61   remaining quota
5c80: 20 67 72 6f 75 70 73 2e 0a 2a 2f 0a 69 6e 74 20   groups..*/.int 
5c90: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68  sqlite3_quota_sh
5ca0: 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20  utdown(void){.  
5cb0: 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f  quotaGroup *pGro
5cc0: 75 70 3b 0a 20 20 69 66 28 20 67 51 75 6f 74 61  up;.  if( gQuota
5cd0: 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 3d 3d  .isInitialized==
5ce0: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
5cf0: 45 5f 4d 49 53 55 53 45 3b 0a 20 20 66 6f 72 28  E_MISUSE;.  for(
5d00: 70 47 72 6f 75 70 3d 67 51 75 6f 74 61 2e 70 47  pGroup=gQuota.pG
5d10: 72 6f 75 70 3b 20 70 47 72 6f 75 70 3b 20 70 47  roup; pGroup; pG
5d20: 72 6f 75 70 3d 70 47 72 6f 75 70 2d 3e 70 4e 65  roup=pGroup->pNe
5d30: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 71 75 6f  xt){.    if( quo
5d40: 74 61 47 72 6f 75 70 4f 70 65 6e 46 69 6c 65 43  taGroupOpenFileC
5d50: 6f 75 6e 74 28 70 47 72 6f 75 70 29 3e 30 20 29  ount(pGroup)>0 )
5d60: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d   return SQLITE_M
5d70: 49 53 55 53 45 3b 0a 20 20 7d 0a 20 20 77 68 69  ISUSE;.  }.  whi
5d80: 6c 65 28 20 67 51 75 6f 74 61 2e 70 47 72 6f 75  le( gQuota.pGrou
5d90: 70 20 29 7b 0a 20 20 20 20 70 47 72 6f 75 70 20  p ){.    pGroup 
5da0: 3d 20 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b  = gQuota.pGroup;
5db0: 0a 20 20 20 20 67 51 75 6f 74 61 2e 70 47 72 6f  .    gQuota.pGro
5dc0: 75 70 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e 65  up = pGroup->pNe
5dd0: 78 74 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  xt;.    pGroup->
5de0: 69 4c 69 6d 69 74 20 3d 20 30 3b 0a 20 20 20 20  iLimit = 0;.    
5df0: 61 73 73 65 72 74 28 20 71 75 6f 74 61 47 72 6f  assert( quotaGro
5e00: 75 70 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28  upOpenFileCount(
5e10: 70 47 72 6f 75 70 29 3d 3d 30 20 29 3b 0a 20 20  pGroup)==0 );.  
5e20: 20 20 71 75 6f 74 61 47 72 6f 75 70 44 65 72 65    quotaGroupDere
5e30: 66 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 20  f(pGroup);.  }. 
5e40: 20 67 51 75 6f 74 61 2e 69 73 49 6e 69 74 69 61   gQuota.isInitia
5e50: 6c 69 7a 65 64 20 3d 20 30 3b 0a 20 20 73 71 6c  lized = 0;.  sql
5e60: 69 74 65 33 5f 6d 75 74 65 78 5f 66 72 65 65 28  ite3_mutex_free(
5e70: 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 29 3b 0a  gQuota.pMutex);.
5e80: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e    sqlite3_vfs_un
5e90: 72 65 67 69 73 74 65 72 28 26 67 51 75 6f 74 61  register(&gQuota
5ea0: 2e 73 54 68 69 73 56 66 73 29 3b 0a 20 20 6d 65  .sThisVfs);.  me
5eb0: 6d 73 65 74 28 26 67 51 75 6f 74 61 2c 20 30 2c  mset(&gQuota, 0,
5ec0: 20 73 69 7a 65 6f 66 28 67 51 75 6f 74 61 29 29   sizeof(gQuota))
5ed0: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
5ee0: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
5ef0: 72 65 61 74 65 20 6f 72 20 64 65 73 74 72 6f 79  reate or destroy
5f00: 20 61 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 0a   a quota group..
5f10: 2a 2a 0a 2a 2a 20 54 68 65 20 71 75 6f 74 61 20  **.** The quota 
5f20: 67 72 6f 75 70 20 69 73 20 64 65 66 69 6e 65 64  group is defined
5f30: 20 62 79 20 74 68 65 20 7a 50 61 74 74 65 72 6e   by the zPattern
5f40: 2e 20 20 57 68 65 6e 20 63 61 6c 6c 69 6e 67 20  .  When calling 
5f50: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
5f60: 77 69 74 68 20 61 20 7a 50 61 74 74 65 72 6e 20  with a zPattern 
5f70: 66 6f 72 20 61 20 71 75 6f 74 61 20 67 72 6f 75  for a quota grou
5f80: 70 20 74 68 61 74 20 61 6c 72 65 61 64 79 20 65  p that already e
5f90: 78 69 73 74 73 2c 20 74 68 69 73 20 72 6f 75 74  xists, this rout
5fa0: 69 6e 65 0a 2a 2a 20 6d 65 72 65 6c 79 20 75 70  ine.** merely up
5fb0: 64 61 74 65 73 20 74 68 65 20 69 4c 69 6d 69 74  dates the iLimit
5fc0: 2c 20 78 43 61 6c 6c 62 61 63 6b 2c 20 61 6e 64  , xCallback, and
5fd0: 20 70 41 72 67 20 76 61 6c 75 65 73 20 66 6f 72   pArg values for
5fe0: 20 74 68 61 74 20 71 75 6f 74 61 0a 2a 2a 20 67   that quota.** g
5ff0: 72 6f 75 70 2e 20 20 49 66 20 7a 50 61 74 74 65  roup.  If zPatte
6000: 72 6e 20 69 73 20 6e 65 77 2c 20 74 68 65 6e 20  rn is new, then 
6010: 61 20 6e 65 77 20 71 75 6f 74 61 20 67 72 6f 75  a new quota grou
6020: 70 20 69 73 20 63 72 65 61 74 65 64 2e 0a 2a 2a  p is created..**
6030: 0a 2a 2a 20 49 66 20 74 68 65 20 69 4c 69 6d 69  .** If the iLimi
6040: 74 20 66 6f 72 20 61 20 71 75 6f 74 61 20 67 72  t for a quota gr
6050: 6f 75 70 20 69 73 20 73 65 74 20 74 6f 20 7a 65  oup is set to ze
6060: 72 6f 2c 20 74 68 65 6e 20 74 68 65 20 71 75 6f  ro, then the quo
6070: 74 61 20 67 72 6f 75 70 0a 2a 2a 20 69 73 20 64  ta group.** is d
6080: 69 73 61 62 6c 65 64 20 61 6e 64 20 77 69 6c 6c  isabled and will
6090: 20 62 65 20 64 65 6c 65 74 65 64 20 77 68 65 6e   be deleted when
60a0: 20 74 68 65 20 6c 61 73 74 20 64 61 74 61 62 61   the last databa
60b0: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 75 73  se connection us
60c0: 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75 6f 74 61  ing.** the quota
60d0: 20 67 72 6f 75 70 20 69 73 20 63 6c 6f 73 65 64   group is closed
60e0: 2e 0a 2a 2a 0a 2a 2a 20 43 61 6c 6c 69 6e 67 20  ..**.** Calling 
60f0: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 6e 20  this routine on 
6100: 61 20 7a 50 61 74 74 65 72 6e 20 74 68 61 74 20  a zPattern that 
6110: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61  does not exist a
6120: 6e 64 20 77 69 74 68 20 61 0a 2a 2a 20 7a 65 72  nd with a.** zer
6130: 6f 20 69 4c 69 6d 69 74 20 69 73 20 61 20 6e 6f  o iLimit is a no
6140: 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 41 20 71 75 6f  -op..**.** A quo
6150: 74 61 20 67 72 6f 75 70 20 6d 75 73 74 20 65 78  ta group must ex
6160: 69 73 74 20 77 69 74 68 20 61 20 6e 6f 6e 2d 7a  ist with a non-z
6170: 65 72 6f 20 69 4c 69 6d 69 74 20 70 72 69 6f 72  ero iLimit prior
6180: 20 74 6f 20 6f 70 65 6e 69 6e 67 0a 2a 2a 20 64   to opening.** d
6190: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
61a0: 6f 6e 73 20 69 66 20 74 68 6f 73 65 20 63 6f 6e  ons if those con
61b0: 6e 65 63 74 69 6f 6e 73 20 61 72 65 20 74 6f 20  nections are to 
61c0: 70 61 72 74 69 63 69 70 61 74 65 20 69 6e 20 74  participate in t
61d0: 68 65 0a 2a 2a 20 71 75 6f 74 61 20 67 72 6f 75  he.** quota grou
61e0: 70 2e 20 20 43 72 65 61 74 69 6e 67 20 61 20 71  p.  Creating a q
61f0: 75 6f 74 61 20 67 72 6f 75 70 20 64 6f 65 73 20  uota group does 
6200: 6e 6f 74 20 61 66 66 65 63 74 20 64 61 74 61 62  not affect datab
6210: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 0a  ase connections.
6220: 2a 2a 20 74 68 61 74 20 61 72 65 20 61 6c 72 65  ** that are alre
6230: 61 64 79 20 6f 70 65 6e 2e 0a 2a 2f 0a 69 6e 74  ady open..*/.int
6240: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73   sqlite3_quota_s
6250: 65 74 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  et(.  const char
6260: 20 2a 7a 50 61 74 74 65 72 6e 2c 20 20 20 20 20   *zPattern,     
6270: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 69 6c        /* The fil
6280: 65 6e 61 6d 65 20 70 61 74 74 65 72 6e 20 2a 2f  ename pattern */
6290: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
62a0: 20 69 4c 69 6d 69 74 2c 20 20 20 20 20 20 20 20   iLimit,        
62b0: 20 20 20 2f 2a 20 4e 65 77 20 71 75 6f 74 61 20     /* New quota 
62c0: 74 6f 20 73 65 74 20 66 6f 72 20 74 68 69 73 20  to set for this 
62d0: 71 75 6f 74 61 20 67 72 6f 75 70 20 2a 2f 0a 20  quota group */. 
62e0: 20 76 6f 69 64 20 28 2a 78 43 61 6c 6c 62 61 63   void (*xCallbac
62f0: 6b 29 28 20 20 20 20 20 20 20 20 20 20 20 20 20  k)(             
6300: 20 2f 2a 20 43 61 6c 6c 62 61 63 6b 20 69 6e 76   /* Callback inv
6310: 6f 6b 65 64 20 77 68 65 6e 20 67 6f 69 6e 67 20  oked when going 
6320: 6f 76 65 72 20 71 75 6f 74 61 20 2a 2f 0a 20 20  over quota */.  
6330: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
6340: 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20 20 20  Filename,       
6350: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c    /* Name of fil
6360: 65 20 77 68 6f 73 65 20 73 69 7a 65 20 69 6e 63  e whose size inc
6370: 72 65 61 73 65 73 20 2a 2f 0a 20 20 20 20 20 73  reases */.     s
6380: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 69  qlite3_int64 *pi
6390: 4c 69 6d 69 74 2c 20 20 20 20 20 20 20 20 2f 2a  Limit,        /*
63a0: 20 49 4e 2f 4f 55 54 3a 20 54 68 65 20 63 75 72   IN/OUT: The cur
63b0: 72 65 6e 74 20 6c 69 6d 69 74 20 2a 2f 0a 20 20  rent limit */.  
63c0: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
63d0: 20 69 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20   iSize,         
63e0: 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20    /* Total size 
63f0: 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20  of all files in 
6400: 74 68 65 20 67 72 6f 75 70 20 2a 2f 0a 20 20 20  the group */.   
6410: 20 20 76 6f 69 64 20 2a 70 41 72 67 20 20 20 20    void *pArg    
6420: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6430: 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61 74 61 20   /* Client data 
6440: 2a 2f 0a 20 20 29 2c 0a 20 20 76 6f 69 64 20 2a  */.  ),.  void *
6450: 70 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20  pArg,           
6460: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 6c 69            /* cli
6470: 65 6e 74 20 64 61 74 61 20 70 61 73 73 65 64 20  ent data passed 
6480: 74 68 72 75 20 74 6f 20 63 61 6c 6c 62 61 63 6b  thru to callback
6490: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 44 65   */.  void (*xDe
64a0: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 20 20 20  stroy)(void*)   
64b0: 20 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f 6e 61        /* Optiona
64c0: 6c 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72  l destructor for
64d0: 20 70 41 72 67 20 2a 2f 0a 29 7b 0a 20 20 71 75   pArg */.){.  qu
64e0: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
64f0: 3b 0a 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29  ;.  quotaEnter()
6500: 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20 67 51 75  ;.  pGroup = gQu
6510: 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20 20 77 68  ota.pGroup;.  wh
6520: 69 6c 65 28 20 70 47 72 6f 75 70 20 26 26 20 73  ile( pGroup && s
6530: 74 72 63 6d 70 28 70 47 72 6f 75 70 2d 3e 7a 50  trcmp(pGroup->zP
6540: 61 74 74 65 72 6e 2c 20 7a 50 61 74 74 65 72 6e  attern, zPattern
6550: 29 21 3d 30 20 29 7b 0a 20 20 20 20 70 47 72 6f  )!=0 ){.    pGro
6560: 75 70 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e 65  up = pGroup->pNe
6570: 78 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 47  xt;.  }.  if( pG
6580: 72 6f 75 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  roup==0 ){.    i
6590: 6e 74 20 6e 50 61 74 74 65 72 6e 20 3d 20 73 74  nt nPattern = st
65a0: 72 6c 65 6e 28 7a 50 61 74 74 65 72 6e 29 3b 0a  rlen(zPattern);.
65b0: 20 20 20 20 69 66 28 20 69 4c 69 6d 69 74 3c 3d      if( iLimit<=
65c0: 30 20 29 7b 0a 20 20 20 20 20 20 71 75 6f 74 61  0 ){.      quota
65d0: 4c 65 61 76 65 28 29 3b 0a 20 20 20 20 20 20 72  Leave();.      r
65e0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
65f0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 47 72 6f 75  .    }.    pGrou
6600: 70 20 3d 20 28 71 75 6f 74 61 47 72 6f 75 70 20  p = (quotaGroup 
6610: 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  *)sqlite3_malloc
6620: 28 20 73 69 7a 65 6f 66 28 2a 70 47 72 6f 75 70  ( sizeof(*pGroup
6630: 29 20 2b 20 6e 50 61 74 74 65 72 6e 20 2b 20 31  ) + nPattern + 1
6640: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 47 72 6f   );.    if( pGro
6650: 75 70 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 71  up==0 ){.      q
6660: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 20  uotaLeave();.   
6670: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
6680: 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 7d 0a 20 20  _NOMEM;.    }.  
6690: 20 20 6d 65 6d 73 65 74 28 70 47 72 6f 75 70 2c    memset(pGroup,
66a0: 20 30 2c 20 73 69 7a 65 6f 66 28 2a 70 47 72 6f   0, sizeof(*pGro
66b0: 75 70 29 29 3b 0a 20 20 20 20 70 47 72 6f 75 70  up));.    pGroup
66c0: 2d 3e 7a 50 61 74 74 65 72 6e 20 3d 20 28 63 68  ->zPattern = (ch
66d0: 61 72 2a 29 26 70 47 72 6f 75 70 5b 31 5d 3b 0a  ar*)&pGroup[1];.
66e0: 20 20 20 20 6d 65 6d 63 70 79 28 28 63 68 61 72      memcpy((char
66f0: 20 2a 29 70 47 72 6f 75 70 2d 3e 7a 50 61 74 74   *)pGroup->zPatt
6700: 65 72 6e 2c 20 7a 50 61 74 74 65 72 6e 2c 20 6e  ern, zPattern, n
6710: 50 61 74 74 65 72 6e 2b 31 29 3b 0a 20 20 20 20  Pattern+1);.    
6720: 69 66 28 20 67 51 75 6f 74 61 2e 70 47 72 6f 75  if( gQuota.pGrou
6730: 70 20 29 20 67 51 75 6f 74 61 2e 70 47 72 6f 75  p ) gQuota.pGrou
6740: 70 2d 3e 70 70 50 72 65 76 20 3d 20 26 70 47 72  p->ppPrev = &pGr
6750: 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a 20 20 20 20  oup->pNext;.    
6760: 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 20 3d 20  pGroup->pNext = 
6770: 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20  gQuota.pGroup;. 
6780: 20 20 20 70 47 72 6f 75 70 2d 3e 70 70 50 72 65     pGroup->ppPre
6790: 76 20 3d 20 26 67 51 75 6f 74 61 2e 70 47 72 6f  v = &gQuota.pGro
67a0: 75 70 3b 0a 20 20 20 20 67 51 75 6f 74 61 2e 70  up;.    gQuota.p
67b0: 47 72 6f 75 70 20 3d 20 70 47 72 6f 75 70 3b 0a  Group = pGroup;.
67c0: 20 20 7d 0a 20 20 70 47 72 6f 75 70 2d 3e 69 4c    }.  pGroup->iL
67d0: 69 6d 69 74 20 3d 20 69 4c 69 6d 69 74 3b 0a 20  imit = iLimit;. 
67e0: 20 70 47 72 6f 75 70 2d 3e 78 43 61 6c 6c 62 61   pGroup->xCallba
67f0: 63 6b 20 3d 20 78 43 61 6c 6c 62 61 63 6b 3b 0a  ck = xCallback;.
6800: 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 78 44    if( pGroup->xD
6810: 65 73 74 72 6f 79 20 26 26 20 70 47 72 6f 75 70  estroy && pGroup
6820: 2d 3e 70 41 72 67 21 3d 70 41 72 67 20 29 7b 0a  ->pArg!=pArg ){.
6830: 20 20 20 20 70 47 72 6f 75 70 2d 3e 78 44 65 73      pGroup->xDes
6840: 74 72 6f 79 28 70 47 72 6f 75 70 2d 3e 70 41 72  troy(pGroup->pAr
6850: 67 29 3b 0a 20 20 7d 0a 20 20 70 47 72 6f 75 70  g);.  }.  pGroup
6860: 2d 3e 70 41 72 67 20 3d 20 70 41 72 67 3b 0a 20  ->pArg = pArg;. 
6870: 20 70 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f   pGroup->xDestro
6880: 79 20 3d 20 78 44 65 73 74 72 6f 79 3b 0a 20 20  y = xDestroy;.  
6890: 71 75 6f 74 61 47 72 6f 75 70 44 65 72 65 66 28  quotaGroupDeref(
68a0: 70 47 72 6f 75 70 29 3b 0a 20 20 71 75 6f 74 61  pGroup);.  quota
68b0: 4c 65 61 76 65 28 29 3b 0a 20 20 72 65 74 75 72  Leave();.  retur
68c0: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
68d0: 2f 2a 0a 2a 2a 20 42 72 69 6e 67 20 74 68 65 20  /*.** Bring the 
68e0: 6e 61 6d 65 64 20 66 69 6c 65 20 75 6e 64 65 72  named file under
68f0: 20 71 75 6f 74 61 20 6d 61 6e 61 67 65 6d 65 6e   quota managemen
6900: 74 2e 20 20 4f 72 20 69 66 20 69 74 20 69 73 20  t.  Or if it is 
6910: 61 6c 72 65 61 64 79 20 75 6e 64 65 72 0a 2a 2a  already under.**
6920: 20 6d 61 6e 61 67 65 6d 65 6e 74 2c 20 75 70 64   management, upd
6930: 61 74 65 20 69 74 73 20 73 69 7a 65 2e 0a 2a 2f  ate its size..*/
6940: 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 71 75 6f  .int sqlite3_quo
6950: 74 61 5f 66 69 6c 65 28 63 6f 6e 73 74 20 63 68  ta_file(const ch
6960: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a  ar *zFilename){.
6970: 20 20 63 68 61 72 20 2a 7a 46 75 6c 6c 3b 0a 20    char *zFull;. 
6980: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 66   sqlite3_file *f
6990: 64 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 69  d;.  int rc;.  i
69a0: 6e 74 20 6f 75 74 46 6c 61 67 73 20 3d 20 30 3b  nt outFlags = 0;
69b0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
69c0: 20 69 53 69 7a 65 3b 0a 20 20 66 64 20 3d 20 73   iSize;.  fd = s
69d0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 67 51  qlite3_malloc(gQ
69e0: 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 73 7a  uota.sThisVfs.sz
69f0: 4f 73 46 69 6c 65 20 2b 20 67 51 75 6f 74 61 2e  OsFile + gQuota.
6a00: 73 54 68 69 73 56 66 73 2e 6d 78 50 61 74 68 6e  sThisVfs.mxPathn
6a10: 61 6d 65 2b 31 29 3b 0a 20 20 69 66 28 20 66 64  ame+1);.  if( fd
6a20: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
6a30: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7a 46 75  ITE_NOMEM;.  zFu
6a40: 6c 6c 20 3d 20 67 51 75 6f 74 61 2e 73 54 68 69  ll = gQuota.sThi
6a50: 73 56 66 73 2e 73 7a 4f 73 46 69 6c 65 20 2b 20  sVfs.szOsFile + 
6a60: 28 63 68 61 72 2a 29 66 64 3b 0a 20 20 72 63 20  (char*)fd;.  rc 
6a70: 3d 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66  = gQuota.pOrigVf
6a80: 73 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65  s->xFullPathname
6a90: 28 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73  (gQuota.pOrigVfs
6aa0: 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 0a 20 20 20  , zFilename,.   
6ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ad0: 20 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56     gQuota.sThisV
6ae0: 66 73 2e 6d 78 50 61 74 68 6e 61 6d 65 2b 31 2c  fs.mxPathname+1,
6af0: 20 7a 46 75 6c 6c 29 3b 0a 20 20 69 66 28 20 72   zFull);.  if( r
6b00: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
6b10: 20 20 20 20 72 63 20 3d 20 71 75 6f 74 61 4f 70      rc = quotaOp
6b20: 65 6e 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73  en(&gQuota.sThis
6b30: 56 66 73 2c 20 7a 46 75 6c 6c 2c 20 66 64 2c 20  Vfs, zFull, fd, 
6b40: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
6b50: 20 20 20 20 53 51 4c 49 54 45 5f 4f 50 45 4e 5f      SQLITE_OPEN_
6b60: 52 45 41 44 4f 4e 4c 59 20 7c 20 53 51 4c 49 54  READONLY | SQLIT
6b70: 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 2c 20  E_OPEN_MAIN_DB, 
6b80: 26 6f 75 74 46 6c 61 67 73 29 3b 0a 20 20 7d 0a  &outFlags);.  }.
6b90: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6ba0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 66 64 2d 3e 70  _OK ){.    fd->p
6bb0: 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69  Methods->xFileSi
6bc0: 7a 65 28 66 64 2c 20 26 69 53 69 7a 65 29 3b 0a  ze(fd, &iSize);.
6bd0: 20 20 20 20 66 64 2d 3e 70 4d 65 74 68 6f 64 73      fd->pMethods
6be0: 2d 3e 78 43 6c 6f 73 65 28 66 64 29 3b 0a 20 20  ->xClose(fd);.  
6bf0: 7d 65 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51  }else if( rc==SQ
6c00: 4c 49 54 45 5f 43 41 4e 54 4f 50 45 4e 20 29 7b  LITE_CANTOPEN ){
6c10: 0a 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70 20  .    quotaGroup 
6c20: 2a 70 47 72 6f 75 70 3b 0a 20 20 20 20 71 75 6f  *pGroup;.    quo
6c30: 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a 20  taFile *pFile;. 
6c40: 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29 3b     quotaEnter();
6c50: 0a 20 20 20 20 70 47 72 6f 75 70 20 3d 20 71 75  .    pGroup = qu
6c60: 6f 74 61 47 72 6f 75 70 46 69 6e 64 28 7a 46 75  otaGroupFind(zFu
6c70: 6c 6c 29 3b 0a 20 20 20 20 69 66 28 20 70 47 72  ll);.    if( pGr
6c80: 6f 75 70 20 29 7b 0a 20 20 20 20 20 20 70 46 69  oup ){.      pFi
6c90: 6c 65 20 3d 20 71 75 6f 74 61 46 69 6e 64 46 69  le = quotaFindFi
6ca0: 6c 65 28 70 47 72 6f 75 70 2c 20 7a 46 75 6c 6c  le(pGroup, zFull
6cb0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 70 46 69  );.      if( pFi
6cc0: 6c 65 20 29 20 71 75 6f 74 61 52 65 6d 6f 76 65  le ) quotaRemove
6cd0: 46 69 6c 65 28 70 46 69 6c 65 29 3b 0a 20 20 20  File(pFile);.   
6ce0: 20 7d 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76   }.    quotaLeav
6cf0: 65 28 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  e();.  }.  sqlit
6d00: 65 33 5f 66 72 65 65 28 66 64 29 3b 0a 20 20 72  e3_free(fd);.  r
6d10: 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 20 20 0a  eturn rc;.}..  .
6d20: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
6d30: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 54  ************** T
6d40: 65 73 74 20 43 6f 64 65 20 2a 2a 2a 2a 2a 2a 2a  est Code *******
6d50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
6d60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 69  ************/.#i
6d70: 66 64 65 66 20 53 51 4c 49 54 45 5f 54 45 53 54  fdef SQLITE_TEST
6d80: 0a 23 69 6e 63 6c 75 64 65 20 3c 74 63 6c 2e 68  .#include <tcl.h
6d90: 3e 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e  >../*.** Argumen
6da0: 74 20 70 61 73 73 65 64 20 74 6f 20 61 20 54 43  t passed to a TC
6db0: 4c 20 71 75 6f 74 61 2d 6f 76 65 72 2d 6c 69 6d  L quota-over-lim
6dc0: 69 74 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a  it callback..*/.
6dd0: 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20 54  typedef struct T
6de0: 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20  clQuotaCallback 
6df0: 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b  TclQuotaCallback
6e00: 3b 0a 73 74 72 75 63 74 20 54 63 6c 51 75 6f 74  ;.struct TclQuot
6e10: 61 43 61 6c 6c 62 61 63 6b 20 7b 0a 20 20 54 63  aCallback {.  Tc
6e20: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
6e30: 3b 20 20 20 20 2f 2a 20 49 6e 74 65 72 70 72 65  ;    /* Interpre
6e40: 74 65 72 20 69 6e 20 77 68 69 63 68 20 74 6f 20  ter in which to 
6e50: 72 75 6e 20 74 68 65 20 73 63 72 69 70 74 20 2a  run the script *
6e60: 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63  /.  Tcl_Obj *pSc
6e70: 72 69 70 74 3b 20 20 20 20 20 20 2f 2a 20 53 63  ript;      /* Sc
6e80: 72 69 70 74 20 74 6f 20 62 65 20 72 75 6e 20 2a  ript to be run *
6e90: 2f 0a 7d 3b 0a 0a 65 78 74 65 72 6e 20 63 6f 6e  /.};..extern con
6ea0: 73 74 20 63 68 61 72 20 2a 73 71 6c 69 74 65 33  st char *sqlite3
6eb0: 54 65 73 74 45 72 72 6f 72 4e 61 6d 65 28 69 6e  TestErrorName(in
6ec0: 74 29 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  t);.../*.** This
6ed0: 20 69 73 20 74 68 65 20 63 61 6c 6c 62 61 63 6b   is the callback
6ee0: 20 66 72 6f 6d 20 61 20 71 75 6f 74 61 2d 6f 76   from a quota-ov
6ef0: 65 72 2d 6c 69 6d 69 74 2e 0a 2a 2f 0a 73 74 61  er-limit..*/.sta
6f00: 74 69 63 20 76 6f 69 64 20 74 63 6c 51 75 6f 74  tic void tclQuot
6f10: 61 43 61 6c 6c 62 61 63 6b 28 0a 20 20 63 6f 6e  aCallback(.  con
6f20: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61  st char *zFilena
6f30: 6d 65 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  me,          /* 
6f40: 4e 61 6d 65 20 6f 66 20 66 69 6c 65 20 77 68 6f  Name of file who
6f50: 73 65 20 73 69 7a 65 20 69 6e 63 72 65 61 73 65  se size increase
6f60: 73 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69  s */.  sqlite3_i
6f70: 6e 74 36 34 20 2a 70 69 4c 69 6d 69 74 2c 20 20  nt64 *piLimit,  
6f80: 20 20 20 20 20 20 20 2f 2a 20 49 4e 2f 4f 55 54         /* IN/OUT
6f90: 3a 20 54 68 65 20 63 75 72 72 65 6e 74 20 6c 69  : The current li
6fa0: 6d 69 74 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  mit */.  sqlite3
6fb0: 5f 69 6e 74 36 34 20 69 53 69 7a 65 2c 20 20 20  _int64 iSize,   
6fc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 6f 74 61           /* Tota
6fd0: 6c 20 73 69 7a 65 20 6f 66 20 61 6c 6c 20 66 69  l size of all fi
6fe0: 6c 65 73 20 69 6e 20 74 68 65 20 67 72 6f 75 70  les in the group
6ff0: 20 2a 2f 0a 20 20 76 6f 69 64 20 2a 70 41 72 67   */.  void *pArg
7000: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7010: 20 20 20 20 20 20 2f 2a 20 43 6c 69 65 6e 74 20        /* Client 
7020: 64 61 74 61 20 2a 2f 0a 29 7b 0a 20 20 54 63 6c  data */.){.  Tcl
7030: 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70  QuotaCallback *p
7040: 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  ;            /* 
7050: 43 61 6c 6c 62 61 63 6b 20 73 63 72 69 70 74 20  Callback script 
7060: 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 54 63 6c 5f  object */.  Tcl_
7070: 4f 62 6a 20 2a 70 45 76 61 6c 3b 20 20 20 20 20  Obj *pEval;     
7080: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53              /* S
7090: 63 72 69 70 74 20 74 6f 20 65 76 61 6c 75 61 74  cript to evaluat
70a0: 65 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  e */.  Tcl_Obj *
70b0: 70 56 61 72 6e 61 6d 65 3b 20 20 20 20 20 20 20  pVarname;       
70c0: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
70d0: 66 20 76 61 72 69 61 62 6c 65 20 74 6f 20 70 61  f variable to pa
70e0: 73 73 20 61 73 20 32 6e 64 20 61 72 67 20 2a 2f  ss as 2nd arg */
70f0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  .  unsigned int 
7100: 72 6e 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  rnd;            
7110: 20 20 20 2f 2a 20 52 61 6e 64 6f 6d 20 70 61 72     /* Random par
7120: 74 20 6f 66 20 70 56 61 72 6e 61 6d 65 20 2a 2f  t of pVarname */
7130: 0a 20 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20  .  int rc;      
7140: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7150: 20 20 20 2f 2a 20 54 63 6c 20 65 72 72 6f 72 20     /* Tcl error 
7160: 63 6f 64 65 20 2a 2f 0a 0a 20 20 70 20 3d 20 28  code */..  p = (
7170: 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b  TclQuotaCallback
7180: 20 2a 29 70 41 72 67 3b 0a 20 20 69 66 28 20 70   *)pArg;.  if( p
7190: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 0a 20  ==0 ) return;.. 
71a0: 20 70 56 61 72 6e 61 6d 65 20 3d 20 54 63 6c 5f   pVarname = Tcl_
71b0: 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 22 3a 3a  NewStringObj("::
71c0: 70 69 4c 69 6d 69 74 5f 22 2c 20 2d 31 29 3b 0a  piLimit_", -1);.
71d0: 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f 75    Tcl_IncrRefCou
71e0: 6e 74 28 70 56 61 72 6e 61 6d 65 29 3b 0a 20 20  nt(pVarname);.  
71f0: 73 71 6c 69 74 65 33 5f 72 61 6e 64 6f 6d 6e 65  sqlite3_randomne
7200: 73 73 28 73 69 7a 65 6f 66 28 72 6e 64 29 2c 20  ss(sizeof(rnd), 
7210: 28 76 6f 69 64 20 2a 29 26 72 6e 64 29 3b 0a 20  (void *)&rnd);. 
7220: 20 54 63 6c 5f 41 70 70 65 6e 64 4f 62 6a 54 6f   Tcl_AppendObjTo
7230: 4f 62 6a 28 70 56 61 72 6e 61 6d 65 2c 20 54 63  Obj(pVarname, Tc
7240: 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 28 69 6e 74  l_NewIntObj((int
7250: 29 28 72 6e 64 26 30 78 37 46 46 46 46 46 46 46  )(rnd&0x7FFFFFFF
7260: 29 29 29 3b 0a 20 20 54 63 6c 5f 4f 62 6a 53 65  )));.  Tcl_ObjSe
7270: 74 56 61 72 32 28 70 2d 3e 69 6e 74 65 72 70 2c  tVar2(p->interp,
7280: 20 70 56 61 72 6e 61 6d 65 2c 20 30 2c 20 54 63   pVarname, 0, Tc
7290: 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28  l_NewWideIntObj(
72a0: 2a 70 69 4c 69 6d 69 74 29 2c 20 30 29 3b 0a 0a  *piLimit), 0);..
72b0: 20 20 70 45 76 61 6c 20 3d 20 54 63 6c 5f 44 75    pEval = Tcl_Du
72c0: 70 6c 69 63 61 74 65 4f 62 6a 28 70 2d 3e 70 53  plicateObj(p->pS
72d0: 63 72 69 70 74 29 3b 0a 20 20 54 63 6c 5f 49 6e  cript);.  Tcl_In
72e0: 63 72 52 65 66 43 6f 75 6e 74 28 70 45 76 61 6c  crRefCount(pEval
72f0: 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  );.  Tcl_ListObj
7300: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 30 2c  AppendElement(0,
7310: 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65 77 53   pEval, Tcl_NewS
7320: 74 72 69 6e 67 4f 62 6a 28 7a 46 69 6c 65 6e 61  tringObj(zFilena
7330: 6d 65 2c 20 2d 31 29 29 3b 0a 20 20 54 63 6c 5f  me, -1));.  Tcl_
7340: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
7350: 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 70  ment(0, pEval, p
7360: 56 61 72 6e 61 6d 65 29 3b 0a 20 20 54 63 6c 5f  Varname);.  Tcl_
7370: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
7380: 6d 65 6e 74 28 30 2c 20 70 45 76 61 6c 2c 20 54  ment(0, pEval, T
7390: 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a  cl_NewWideIntObj
73a0: 28 69 53 69 7a 65 29 29 3b 0a 20 20 72 63 20 3d  (iSize));.  rc =
73b0: 20 54 63 6c 5f 45 76 61 6c 4f 62 6a 45 78 28 70   Tcl_EvalObjEx(p
73c0: 2d 3e 69 6e 74 65 72 70 2c 20 70 45 76 61 6c 2c  ->interp, pEval,
73d0: 20 54 43 4c 5f 45 56 41 4c 5f 47 4c 4f 42 41 4c   TCL_EVAL_GLOBAL
73e0: 29 3b 0a 0a 20 20 69 66 28 20 72 63 3d 3d 54 43  );..  if( rc==TC
73f0: 4c 5f 4f 4b 20 29 7b 0a 20 20 20 20 54 63 6c 5f  L_OK ){.    Tcl_
7400: 4f 62 6a 20 2a 70 4c 69 6d 69 74 20 3d 20 54 63  Obj *pLimit = Tc
7410: 6c 5f 4f 62 6a 47 65 74 56 61 72 32 28 70 2d 3e  l_ObjGetVar2(p->
7420: 69 6e 74 65 72 70 2c 20 70 56 61 72 6e 61 6d 65  interp, pVarname
7430: 2c 20 30 2c 20 30 29 3b 0a 20 20 20 20 72 63 20  , 0, 0);.    rc 
7440: 3d 20 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74  = Tcl_GetWideInt
7450: 46 72 6f 6d 4f 62 6a 28 70 2d 3e 69 6e 74 65 72  FromObj(p->inter
7460: 70 2c 20 70 4c 69 6d 69 74 2c 20 70 69 4c 69 6d  p, pLimit, piLim
7470: 69 74 29 3b 0a 20 20 20 20 54 63 6c 5f 55 6e 73  it);.    Tcl_Uns
7480: 65 74 56 61 72 28 70 2d 3e 69 6e 74 65 72 70 2c  etVar(p->interp,
7490: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 70   Tcl_GetString(p
74a0: 56 61 72 6e 61 6d 65 29 2c 20 30 29 3b 0a 20 20  Varname), 0);.  
74b0: 7d 0a 0a 20 20 54 63 6c 5f 44 65 63 72 52 65 66  }..  Tcl_DecrRef
74c0: 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a 20 20  Count(pEval);.  
74d0: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
74e0: 28 70 56 61 72 6e 61 6d 65 29 3b 0a 20 20 69 66  (pVarname);.  if
74f0: 28 20 72 63 21 3d 54 43 4c 5f 4f 4b 20 29 20 54  ( rc!=TCL_OK ) T
7500: 63 6c 5f 42 61 63 6b 67 72 6f 75 6e 64 45 72 72  cl_BackgroundErr
7510: 6f 72 28 70 2d 3e 69 6e 74 65 72 70 29 3b 0a 7d  or(p->interp);.}
7520: 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 75 63 74  ../*.** Destruct
7530: 6f 72 20 66 6f 72 20 61 20 54 43 4c 20 71 75 6f  or for a TCL quo
7540: 74 61 2d 6f 76 65 72 2d 6c 69 6d 69 74 20 63 61  ta-over-limit ca
7550: 6c 6c 62 61 63 6b 2e 0a 2a 2f 0a 73 74 61 74 69  llback..*/.stati
7560: 63 20 76 6f 69 64 20 74 63 6c 43 61 6c 6c 62 61  c void tclCallba
7570: 63 6b 44 65 73 74 72 75 63 74 6f 72 28 76 6f 69  ckDestructor(voi
7580: 64 20 2a 70 4f 62 6a 29 7b 0a 20 20 54 63 6c 51  d *pObj){.  TclQ
7590: 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 70 20  uotaCallback *p 
75a0: 3d 20 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62  = (TclQuotaCallb
75b0: 61 63 6b 2a 29 70 4f 62 6a 3b 0a 20 20 69 66 28  ack*)pObj;.  if(
75c0: 20 70 20 29 7b 0a 20 20 20 20 54 63 6c 5f 44 65   p ){.    Tcl_De
75d0: 63 72 52 65 66 43 6f 75 6e 74 28 70 2d 3e 70 53  crRefCount(p->pS
75e0: 63 72 69 70 74 29 3b 0a 20 20 20 20 73 71 6c 69  cript);.    sqli
75f0: 74 65 33 5f 66 72 65 65 28 28 63 68 61 72 20 2a  te3_free((char *
7600: 29 70 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  )p);.  }.}../*.*
7610: 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65  * tclcmd: sqlite
7620: 33 5f 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69  3_quota_initiali
7630: 7a 65 20 4e 41 4d 45 20 4d 41 4b 45 44 45 46 41  ze NAME MAKEDEFA
7640: 55 4c 54 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ULT.*/.static in
7650: 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 69 6e 69  t test_quota_ini
7660: 74 69 61 6c 69 7a 65 28 0a 20 20 76 6f 69 64 20  tialize(.  void 
7670: 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20  * clientData,.  
7680: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
7690: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
76a0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
76b0: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e   objv[].){.  con
76c0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20  st char *zName; 
76d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
76e0: 4e 61 6d 65 20 6f 66 20 6e 65 77 20 71 75 6f 74  Name of new quot
76f0: 61 20 56 46 53 20 2a 2f 0a 20 20 69 6e 74 20 6d  a VFS */.  int m
7700: 61 6b 65 44 65 66 61 75 6c 74 3b 20 20 20 20 20  akeDefault;     
7710: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54 72             /* Tr
7720: 75 65 20 74 6f 20 6d 61 6b 65 20 74 68 65 20 6e  ue to make the n
7730: 65 77 20 56 46 53 20 74 68 65 20 64 65 66 61 75  ew VFS the defau
7740: 6c 74 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  lt */.  int rc; 
7750: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7760: 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
7770: 20 72 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f   returned by quo
7780: 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 28 29 20  ta_initialize() 
7790: 2a 2f 0a 0a 20 20 2f 2a 20 50 72 6f 63 65 73 73  */..  /* Process
77a0: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 20 20   arguments */.  
77b0: 69 66 28 20 6f 62 6a 63 21 3d 33 20 29 7b 0a 20  if( objc!=3 ){. 
77c0: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
77d0: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
77e0: 62 6a 76 2c 20 22 4e 41 4d 45 20 4d 41 4b 45 44  bjv, "NAME MAKED
77f0: 45 46 41 55 4c 54 22 29 3b 0a 20 20 20 20 72 65  EFAULT");.    re
7800: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
7810: 20 20 7d 0a 20 20 7a 4e 61 6d 65 20 3d 20 54 63    }.  zName = Tc
7820: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
7830: 5b 31 5d 29 3b 0a 20 20 69 66 28 20 54 63 6c 5f  [1]);.  if( Tcl_
7840: 47 65 74 42 6f 6f 6c 65 61 6e 46 72 6f 6d 4f 62  GetBooleanFromOb
7850: 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32  j(interp, objv[2
7860: 5d 2c 20 26 6d 61 6b 65 44 65 66 61 75 6c 74 29  ], &makeDefault)
7870: 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52   ) return TCL_ER
7880: 52 4f 52 3b 0a 20 20 69 66 28 20 7a 4e 61 6d 65  ROR;.  if( zName
7890: 5b 30 5d 3d 3d 27 5c 30 27 20 29 20 7a 4e 61 6d  [0]=='\0' ) zNam
78a0: 65 20 3d 20 30 3b 0a 0a 20 20 2f 2a 20 43 61 6c  e = 0;..  /* Cal
78b0: 6c 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  l sqlite3_quota_
78c0: 69 6e 69 74 69 61 6c 69 7a 65 28 29 20 2a 2f 0a  initialize() */.
78d0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 71    rc = sqlite3_q
78e0: 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 28  uota_initialize(
78f0: 7a 4e 61 6d 65 2c 20 6d 61 6b 65 44 65 66 61 75  zName, makeDefau
7900: 6c 74 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52 65  lt);.  Tcl_SetRe
7910: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68  sult(interp, (ch
7920: 61 72 20 2a 29 73 71 6c 69 74 65 33 54 65 73 74  ar *)sqlite3Test
7930: 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20 54  ErrorName(rc), T
7940: 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a 20 20 72  CL_STATIC);..  r
7950: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
7960: 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73  ./*.** tclcmd: s
7970: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68 75  qlite3_quota_shu
7980: 74 64 6f 77 6e 0a 2a 2f 0a 73 74 61 74 69 63 20  tdown.*/.static 
7990: 69 6e 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 73  int test_quota_s
79a0: 68 75 74 64 6f 77 6e 28 0a 20 20 76 6f 69 64 20  hutdown(.  void 
79b0: 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20  * clientData,.  
79c0: 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65  Tcl_Interp *inte
79d0: 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a  rp,.  int objc,.
79e0: 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54    Tcl_Obj *CONST
79f0: 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e 74   objv[].){.  int
7a00: 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20   rc;            
7a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7a20: 56 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20 62  Value returned b
7a30: 79 20 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e  y quota_shutdown
7a40: 28 29 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62 6a  () */..  if( obj
7a50: 63 21 3d 31 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=1 ){.    Tcl_
7a60: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
7a70: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 22  erp, 1, objv, ""
7a80: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
7a90: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  L_ERROR;.  }..  
7aa0: 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65 33 5f  /* Call sqlite3_
7ab0: 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28 29  quota_shutdown()
7ac0: 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74   */.  rc = sqlit
7ad0: 65 33 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77  e3_quota_shutdow
7ae0: 6e 28 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52 65  n();.  Tcl_SetRe
7af0: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68  sult(interp, (ch
7b00: 61 72 20 2a 29 73 71 6c 69 74 65 33 54 65 73 74  ar *)sqlite3Test
7b10: 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c 20 54  ErrorName(rc), T
7b20: 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a 20 20 72  CL_STATIC);..  r
7b30: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
7b40: 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73  ./*.** tclcmd: s
7b50: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 65 74  qlite3_quota_set
7b60: 20 50 41 54 54 45 52 4e 20 4c 49 4d 49 54 20 53   PATTERN LIMIT S
7b70: 43 52 49 50 54 0a 2a 2f 0a 73 74 61 74 69 63 20  CRIPT.*/.static 
7b80: 69 6e 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 73  int test_quota_s
7b90: 65 74 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69  et(.  void * cli
7ba0: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
7bb0: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
7bc0: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
7bd0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
7be0: 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  [].){.  const ch
7bf0: 61 72 20 2a 7a 50 61 74 74 65 72 6e 3b 20 20 20  ar *zPattern;   
7c00: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
7c10: 70 61 74 74 65 72 6e 20 74 6f 20 63 6f 6e 66 69  pattern to confi
7c20: 67 75 72 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65  gure */.  sqlite
7c30: 33 5f 69 6e 74 36 34 20 69 4c 69 6d 69 74 3b 20  3_int64 iLimit; 
7c40: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 69            /* Ini
7c50: 74 69 61 6c 20 71 75 6f 74 61 20 69 6e 20 62 79  tial quota in by
7c60: 74 65 73 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a  tes */.  Tcl_Obj
7c70: 20 2a 70 53 63 72 69 70 74 3b 20 20 20 20 20 20   *pScript;      
7c80: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 63 6c 20           /* Tcl 
7c90: 73 63 72 69 70 74 20 74 6f 20 69 6e 76 6f 6b 65  script to invoke
7ca0: 20 74 6f 20 69 6e 63 72 65 61 73 65 20 71 75 6f   to increase quo
7cb0: 74 61 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  ta */.  int rc; 
7cc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cd0: 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
7ce0: 20 72 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f   returned by quo
7cf0: 74 61 5f 73 65 74 28 29 20 2a 2f 0a 20 20 54 63  ta_set() */.  Tc
7d00: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a  lQuotaCallback *
7d10: 70 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  p;            /*
7d20: 20 43 61 6c 6c 62 61 63 6b 20 6f 62 6a 65 63 74   Callback object
7d30: 20 2a 2f 0a 20 20 69 6e 74 20 6e 53 63 72 69 70   */.  int nScrip
7d40: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  t;              
7d50: 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20        /* Length 
7d60: 6f 66 20 63 61 6c 6c 62 61 63 6b 20 73 63 72 69  of callback scri
7d70: 70 74 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78  pt */.  void (*x
7d80: 44 65 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b  Destroy)(void*);
7d90: 20 20 20 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f          /* Optio
7da0: 6e 61 6c 20 64 65 73 74 72 75 63 74 6f 72 20 66  nal destructor f
7db0: 6f 72 20 70 41 72 67 20 2a 2f 0a 20 20 76 6f 69  or pArg */.  voi
7dc0: 64 20 28 2a 78 43 61 6c 6c 62 61 63 6b 29 28 63  d (*xCallback)(c
7dd0: 6f 6e 73 74 20 63 68 61 72 20 2a 2c 20 73 71 6c  onst char *, sql
7de0: 69 74 65 33 5f 69 6e 74 36 34 20 2a 2c 20 73 71  ite3_int64 *, sq
7df0: 6c 69 74 65 33 5f 69 6e 74 36 34 2c 20 76 6f 69  lite3_int64, voi
7e00: 64 20 2a 29 3b 0a 0a 20 20 2f 2a 20 50 72 6f 63  d *);..  /* Proc
7e10: 65 73 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ess arguments */
7e20: 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 34 20 29  .  if( objc!=4 )
7e30: 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e  {.    Tcl_WrongN
7e40: 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31  umArgs(interp, 1
7e50: 2c 20 6f 62 6a 76 2c 20 22 50 41 54 54 45 52 4e  , objv, "PATTERN
7e60: 20 4c 49 4d 49 54 20 53 43 52 49 50 54 22 29 3b   LIMIT SCRIPT");
7e70: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
7e80: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 7a 50 61  ERROR;.  }.  zPa
7e90: 74 74 65 72 6e 20 3d 20 54 63 6c 5f 47 65 74 53  ttern = Tcl_GetS
7ea0: 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a  tring(objv[1]);.
7eb0: 20 20 69 66 28 20 54 63 6c 5f 47 65 74 57 69 64    if( Tcl_GetWid
7ec0: 65 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74 65  eIntFromObj(inte
7ed0: 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 69 4c  rp, objv[2], &iL
7ee0: 69 6d 69 74 29 20 29 20 72 65 74 75 72 6e 20 54  imit) ) return T
7ef0: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 70 53 63 72  CL_ERROR;.  pScr
7f00: 69 70 74 20 3d 20 6f 62 6a 76 5b 33 5d 3b 0a 20  ipt = objv[3];. 
7f10: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 46 72   Tcl_GetStringFr
7f20: 6f 6d 4f 62 6a 28 70 53 63 72 69 70 74 2c 20 26  omObj(pScript, &
7f30: 6e 53 63 72 69 70 74 29 3b 0a 0a 20 20 69 66 28  nScript);..  if(
7f40: 20 6e 53 63 72 69 70 74 3e 30 20 29 7b 0a 20 20   nScript>0 ){.  
7f50: 20 20 2f 2a 20 41 6c 6c 6f 63 61 74 65 20 61 20    /* Allocate a 
7f60: 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b  TclQuotaCallback
7f70: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 20 20 70   object */.    p
7f80: 20 3d 20 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c   = (TclQuotaCall
7f90: 62 61 63 6b 20 2a 29 73 71 6c 69 74 65 33 5f 6d  back *)sqlite3_m
7fa0: 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 54 63 6c  alloc(sizeof(Tcl
7fb0: 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 29 29 3b  QuotaCallback));
7fc0: 0a 20 20 20 20 69 66 28 20 21 70 20 29 7b 0a 20  .    if( !p ){. 
7fd0: 20 20 20 20 20 54 63 6c 5f 53 65 74 52 65 73 75       Tcl_SetResu
7fe0: 6c 74 28 69 6e 74 65 72 70 2c 20 28 63 68 61 72  lt(interp, (char
7ff0: 20 2a 29 22 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d   *)"SQLITE_NOMEM
8000: 22 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a  ", TCL_STATIC);.
8010: 20 20 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c        return TCL
8020: 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6d  _OK;.    }.    m
8030: 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69 7a 65  emset(p, 0, size
8040: 6f 66 28 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62  of(TclQuotaCallb
8050: 61 63 6b 29 29 3b 0a 20 20 20 20 70 2d 3e 69 6e  ack));.    p->in
8060: 74 65 72 70 20 3d 20 69 6e 74 65 72 70 3b 0a 20  terp = interp;. 
8070: 20 20 20 54 63 6c 5f 49 6e 63 72 52 65 66 43 6f     Tcl_IncrRefCo
8080: 75 6e 74 28 70 53 63 72 69 70 74 29 3b 0a 20 20  unt(pScript);.  
8090: 20 20 70 2d 3e 70 53 63 72 69 70 74 20 3d 20 70    p->pScript = p
80a0: 53 63 72 69 70 74 3b 0a 20 20 20 20 78 44 65 73  Script;.    xDes
80b0: 74 72 6f 79 20 3d 20 74 63 6c 43 61 6c 6c 62 61  troy = tclCallba
80c0: 63 6b 44 65 73 74 72 75 63 74 6f 72 3b 0a 20 20  ckDestructor;.  
80d0: 20 20 78 43 61 6c 6c 62 61 63 6b 20 3d 20 74 63    xCallback = tc
80e0: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 3b 0a  lQuotaCallback;.
80f0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 20 3d    }else{.    p =
8100: 20 30 3b 0a 20 20 20 20 78 44 65 73 74 72 6f 79   0;.    xDestroy
8110: 20 3d 20 30 3b 0a 20 20 20 20 78 43 61 6c 6c 62   = 0;.    xCallb
8120: 61 63 6b 20 3d 20 30 3b 0a 20 20 7d 0a 0a 20 20  ack = 0;.  }..  
8130: 2f 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65  /* Invoke sqlite
8140: 33 5f 71 75 6f 74 61 5f 73 65 74 28 29 20 2a 2f  3_quota_set() */
8150: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
8160: 71 75 6f 74 61 5f 73 65 74 28 7a 50 61 74 74 65  quota_set(zPatte
8170: 72 6e 2c 20 69 4c 69 6d 69 74 2c 20 78 43 61 6c  rn, iLimit, xCal
8180: 6c 62 61 63 6b 2c 20 28 76 6f 69 64 2a 29 70 2c  lback, (void*)p,
8190: 20 78 44 65 73 74 72 6f 79 29 3b 0a 0a 20 20 54   xDestroy);..  T
81a0: 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74  cl_SetResult(int
81b0: 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71 6c  erp, (char *)sql
81c0: 69 74 65 33 54 65 73 74 45 72 72 6f 72 4e 61 6d  ite3TestErrorNam
81d0: 65 28 72 63 29 2c 20 54 43 4c 5f 53 54 41 54 49  e(rc), TCL_STATI
81e0: 43 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  C);.  return TCL
81f0: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63  _OK;.}../*.** tc
8200: 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75  lcmd: sqlite3_qu
8210: 6f 74 61 5f 66 69 6c 65 20 46 49 4c 45 4e 41 4d  ota_file FILENAM
8220: 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  E.*/.static int 
8230: 74 65 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65 28  test_quota_file(
8240: 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74  .  void * client
8250: 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65  Data,.  Tcl_Inte
8260: 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e  rp *interp,.  in
8270: 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62  t objc,.  Tcl_Ob
8280: 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a  j *CONST objv[].
8290: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
82a0: 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20 20 20 20  *zFilename;     
82b0: 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 70 61 74       /* File pat
82c0: 74 65 72 6e 20 74 6f 20 63 6f 6e 66 69 67 75 72  tern to configur
82d0: 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20 20  e */.  int rc;  
82e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
82f0: 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20         /* Value 
8300: 72 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f 74  returned by quot
8310: 61 5f 66 69 6c 65 28 29 20 2a 2f 0a 0a 20 20 2f  a_file() */..  /
8320: 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d 65  * Process argume
8330: 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20 6f 62 6a  nts */.  if( obj
8340: 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=2 ){.    Tcl_
8350: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
8360: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 46  erp, 1, objv, "F
8370: 49 4c 45 4e 41 4d 45 22 29 3b 0a 20 20 20 20 72  ILENAME");.    r
8380: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
8390: 0a 20 20 7d 0a 20 20 7a 46 69 6c 65 6e 61 6d 65  .  }.  zFilename
83a0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
83b0: 28 6f 62 6a 76 5b 31 5d 29 3b 0a 0a 20 20 2f 2a  (objv[1]);..  /*
83c0: 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33 5f   Invoke sqlite3_
83d0: 71 75 6f 74 61 5f 66 69 6c 65 28 29 20 2a 2f 0a  quota_file() */.
83e0: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 71    rc = sqlite3_q
83f0: 75 6f 74 61 5f 66 69 6c 65 28 7a 46 69 6c 65 6e  uota_file(zFilen
8400: 61 6d 65 29 3b 0a 0a 20 20 54 63 6c 5f 53 65 74  ame);..  Tcl_Set
8410: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28  Result(interp, (
8420: 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 54 65  char *)sqlite3Te
8430: 73 74 45 72 72 6f 72 4e 61 6d 65 28 72 63 29 2c  stErrorName(rc),
8440: 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 20 20   TCL_STATIC);.  
8450: 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d  return TCL_OK;.}
8460: 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20  ../*.** tclcmd: 
8470: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 64   sqlite3_quota_d
8480: 75 6d 70 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ump.*/.static in
8490: 74 20 74 65 73 74 5f 71 75 6f 74 61 5f 64 75 6d  t test_quota_dum
84a0: 70 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65  p(.  void * clie
84b0: 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e  ntData,.  Tcl_In
84c0: 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20  terp *interp,.  
84d0: 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f  int objc,.  Tcl_
84e0: 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b  Obj *CONST objv[
84f0: 5d 0a 29 7b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  ].){.  Tcl_Obj *
8500: 70 52 65 73 75 6c 74 3b 0a 20 20 54 63 6c 5f 4f  pResult;.  Tcl_O
8510: 62 6a 20 2a 70 47 72 6f 75 70 54 65 72 6d 3b 0a  bj *pGroupTerm;.
8520: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 46 69 6c 65    Tcl_Obj *pFile
8530: 54 65 72 6d 3b 0a 20 20 71 75 6f 74 61 47 72 6f  Term;.  quotaGro
8540: 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 71 75  up *pGroup;.  qu
8550: 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a  otaFile *pFile;.
8560: 0a 20 20 70 52 65 73 75 6c 74 20 3d 20 54 63 6c  .  pResult = Tcl
8570: 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20 71 75 6f  _NewObj();.  quo
8580: 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 66 6f 72  taEnter();.  for
8590: 28 70 47 72 6f 75 70 3d 67 51 75 6f 74 61 2e 70  (pGroup=gQuota.p
85a0: 47 72 6f 75 70 3b 20 70 47 72 6f 75 70 3b 20 70  Group; pGroup; p
85b0: 47 72 6f 75 70 3d 70 47 72 6f 75 70 2d 3e 70 4e  Group=pGroup->pN
85c0: 65 78 74 29 7b 0a 20 20 20 20 70 47 72 6f 75 70  ext){.    pGroup
85d0: 54 65 72 6d 20 3d 20 54 63 6c 5f 4e 65 77 4f 62  Term = Tcl_NewOb
85e0: 6a 28 29 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73  j();.    Tcl_Lis
85f0: 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e  tObjAppendElemen
8600: 74 28 69 6e 74 65 72 70 2c 20 70 47 72 6f 75 70  t(interp, pGroup
8610: 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20 20  Term,.          
8620: 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a  Tcl_NewStringObj
8630: 28 70 47 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72  (pGroup->zPatter
8640: 6e 2c 20 2d 31 29 29 3b 0a 20 20 20 20 54 63 6c  n, -1));.    Tcl
8650: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
8660: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 47  ement(interp, pG
8670: 72 6f 75 70 54 65 72 6d 2c 0a 20 20 20 20 20 20  roupTerm,.      
8680: 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49      Tcl_NewWideI
8690: 6e 74 4f 62 6a 28 70 47 72 6f 75 70 2d 3e 69 4c  ntObj(pGroup->iL
86a0: 69 6d 69 74 29 29 3b 0a 20 20 20 20 54 63 6c 5f  imit));.    Tcl_
86b0: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
86c0: 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 47 72  ment(interp, pGr
86d0: 6f 75 70 54 65 72 6d 2c 0a 20 20 20 20 20 20 20  oupTerm,.       
86e0: 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e     Tcl_NewWideIn
86f0: 74 4f 62 6a 28 70 47 72 6f 75 70 2d 3e 69 53 69  tObj(pGroup->iSi
8700: 7a 65 29 29 3b 0a 20 20 20 20 66 6f 72 28 70 46  ze));.    for(pF
8710: 69 6c 65 3d 70 47 72 6f 75 70 2d 3e 70 46 69 6c  ile=pGroup->pFil
8720: 65 73 3b 20 70 46 69 6c 65 3b 20 70 46 69 6c 65  es; pFile; pFile
8730: 3d 70 46 69 6c 65 2d 3e 70 4e 65 78 74 29 7b 0a  =pFile->pNext){.
8740: 20 20 20 20 20 20 70 46 69 6c 65 54 65 72 6d 20        pFileTerm 
8750: 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a  = Tcl_NewObj();.
8760: 20 20 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62        Tcl_ListOb
8770: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
8780: 6e 74 65 72 70 2c 20 70 46 69 6c 65 54 65 72 6d  nterp, pFileTerm
8790: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 54 63  ,.            Tc
87a0: 6c 5f 4e 65 77 53 74 72 69 6e 67 4f 62 6a 28 70  l_NewStringObj(p
87b0: 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c  File->zFilename,
87c0: 20 2d 31 29 29 3b 0a 20 20 20 20 20 20 54 63 6c   -1));.      Tcl
87d0: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
87e0: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46  ement(interp, pF
87f0: 69 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20  ileTerm,.       
8800: 20 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65       Tcl_NewWide
8810: 49 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 69 53  IntObj(pFile->iS
8820: 69 7a 65 29 29 3b 0a 20 20 20 20 20 20 54 63 6c  ize));.      Tcl
8830: 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c  _ListObjAppendEl
8840: 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46  ement(interp, pF
8850: 69 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20  ileTerm,.       
8860: 20 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65       Tcl_NewWide
8870: 49 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 6e 52  IntObj(pFile->nR
8880: 65 66 29 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f  ef));.      Tcl_
8890: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
88a0: 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46 69  ment(interp, pFi
88b0: 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20  leTerm,.        
88c0: 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49      Tcl_NewWideI
88d0: 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 64 65 6c  ntObj(pFile->del
88e0: 65 74 65 4f 6e 43 6c 6f 73 65 29 29 3b 0a 20 20  eteOnClose));.  
88f0: 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41      Tcl_ListObjA
8900: 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74  ppendElement(int
8910: 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c  erp, pGroupTerm,
8920: 20 70 46 69 6c 65 54 65 72 6d 29 3b 0a 20 20 20   pFileTerm);.   
8930: 20 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f   }.    Tcl_ListO
8940: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
8950: 69 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74 2c  interp, pResult,
8960: 20 70 47 72 6f 75 70 54 65 72 6d 29 3b 0a 20 20   pGroupTerm);.  
8970: 7d 0a 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29  }.  quotaLeave()
8980: 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65  ;.  Tcl_SetObjRe
8990: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 52 65  sult(interp, pRe
89a0: 73 75 6c 74 29 3b 0a 20 20 72 65 74 75 72 6e 20  sult);.  return 
89b0: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
89c0: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65   This routine re
89d0: 67 69 73 74 65 72 73 20 74 68 65 20 63 75 73 74  gisters the cust
89e0: 6f 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 73 20  om TCL commands 
89f0: 64 65 66 69 6e 65 64 20 69 6e 20 74 68 69 73 0a  defined in this.
8a00: 2a 2a 20 6d 6f 64 75 6c 65 2e 20 20 54 68 69 73  ** module.  This
8a10: 20 73 68 6f 75 6c 64 20 62 65 20 74 68 65 20 6f   should be the o
8a20: 6e 6c 79 20 70 72 6f 63 65 64 75 72 65 20 76 69  nly procedure vi
8a30: 73 69 62 6c 65 20 66 72 6f 6d 20 6f 75 74 73 69  sible from outsi
8a40: 64 65 0a 2a 2a 20 6f 66 20 74 68 69 73 20 6d 6f  de.** of this mo
8a50: 64 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c  dule..*/.int Sql
8a60: 69 74 65 71 75 6f 74 61 5f 49 6e 69 74 28 54 63  itequota_Init(Tc
8a70: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
8a80: 29 7b 0a 20 20 73 74 61 74 69 63 20 73 74 72 75  ){.  static stru
8a90: 63 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a  ct {.     char *
8aa0: 7a 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f  zName;.     Tcl_
8ab0: 4f 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f  ObjCmdProc *xPro
8ac0: 63 3b 0a 20 20 7d 20 61 43 6d 64 5b 5d 20 3d 20  c;.  } aCmd[] = 
8ad0: 7b 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  {.    { "sqlite3
8ae0: 5f 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a  _quota_initializ
8af0: 65 22 2c 20 74 65 73 74 5f 71 75 6f 74 61 5f 69  e", test_quota_i
8b00: 6e 69 74 69 61 6c 69 7a 65 20 7d 2c 0a 20 20 20  nitialize },.   
8b10: 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74   { "sqlite3_quot
8b20: 61 5f 73 68 75 74 64 6f 77 6e 22 2c 20 74 65 73  a_shutdown", tes
8b30: 74 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e  t_quota_shutdown
8b40: 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74   },.    { "sqlit
8b50: 65 33 5f 71 75 6f 74 61 5f 73 65 74 22 2c 20 74  e3_quota_set", t
8b60: 65 73 74 5f 71 75 6f 74 61 5f 73 65 74 20 7d 2c  est_quota_set },
8b70: 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f  .    { "sqlite3_
8b80: 71 75 6f 74 61 5f 66 69 6c 65 22 2c 20 74 65 73  quota_file", tes
8b90: 74 5f 71 75 6f 74 61 5f 66 69 6c 65 20 7d 2c 0a  t_quota_file },.
8ba0: 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71      { "sqlite3_q
8bb0: 75 6f 74 61 5f 64 75 6d 70 22 2c 20 74 65 73 74  uota_dump", test
8bc0: 5f 71 75 6f 74 61 5f 64 75 6d 70 20 7d 2c 0a 20  _quota_dump },. 
8bd0: 20 7d 3b 0a 20 20 69 6e 74 20 69 3b 0a 0a 20 20   };.  int i;..  
8be0: 66 6f 72 28 69 3d 30 3b 20 69 3c 73 69 7a 65 6f  for(i=0; i<sizeo
8bf0: 66 28 61 43 6d 64 29 2f 73 69 7a 65 6f 66 28 61  f(aCmd)/sizeof(a
8c00: 43 6d 64 5b 30 5d 29 3b 20 69 2b 2b 29 7b 0a 20  Cmd[0]); i++){. 
8c10: 20 20 20 54 63 6c 5f 43 72 65 61 74 65 4f 62 6a     Tcl_CreateObj
8c20: 43 6f 6d 6d 61 6e 64 28 69 6e 74 65 72 70 2c 20  Command(interp, 
8c30: 61 43 6d 64 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 61  aCmd[i].zName, a
8c40: 43 6d 64 5b 69 5d 2e 78 50 72 6f 63 2c 20 30 2c  Cmd[i].xProc, 0,
8c50: 20 30 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75   0);.  }..  retu
8c60: 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 23 65 6e  rn TCL_OK;.}.#en
8c70: 64 69 66 0a                                      dif.