/ Hex Artifact Content
Login

Artifact 6cb9297115b551f433a9ad1741817a9831abed99:


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 74 65 73 74 5f 71 75 6f 74  clude "test_quot
0510: 61 2e 68 22 0a 23 69 6e 63 6c 75 64 65 20 3c 73  a.h".#include <s
0520: 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64  tring.h>.#includ
0530: 65 20 3c 61 73 73 65 72 74 2e 68 3e 0a 0a 2f 2a  e <assert.h>../*
0540: 0a 2a 2a 20 46 6f 72 20 61 6e 20 62 75 69 6c 64  .** For an build
0550: 20 77 69 74 68 6f 75 74 20 6d 75 74 65 78 65 73   without mutexes
0560: 2c 20 6e 6f 2d 6f 70 20 74 68 65 20 6d 75 74 65  , no-op the mute
0570: 78 20 63 61 6c 6c 73 2e 0a 2a 2f 0a 23 69 66 20  x calls..*/.#if 
0580: 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45 5f 54  defined(SQLITE_T
0590: 48 52 45 41 44 53 41 46 45 29 20 26 26 20 53 51  HREADSAFE) && SQ
05a0: 4c 49 54 45 5f 54 48 52 45 41 44 53 41 46 45 3d  LITE_THREADSAFE=
05b0: 3d 30 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74  =0.#define sqlit
05c0: 65 33 5f 6d 75 74 65 78 5f 61 6c 6c 6f 63 28 58  e3_mutex_alloc(X
05d0: 29 20 20 20 20 28 28 73 71 6c 69 74 65 33 5f 6d  )    ((sqlite3_m
05e0: 75 74 65 78 2a 29 38 29 0a 23 64 65 66 69 6e 65  utex*)8).#define
05f0: 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 66   sqlite3_mutex_f
0600: 72 65 65 28 58 29 0a 23 64 65 66 69 6e 65 20 73  ree(X).#define s
0610: 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f 65 6e 74  qlite3_mutex_ent
0620: 65 72 28 58 29 0a 23 64 65 66 69 6e 65 20 73 71  er(X).#define sq
0630: 6c 69 74 65 33 5f 6d 75 74 65 78 5f 74 72 79 28  lite3_mutex_try(
0640: 58 29 20 20 20 20 20 20 53 51 4c 49 54 45 5f 4f  X)      SQLITE_O
0650: 4b 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65  K.#define sqlite
0660: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 58 29  3_mutex_leave(X)
0670: 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33  .#define sqlite3
0680: 5f 6d 75 74 65 78 5f 68 65 6c 64 28 58 29 20 20  _mutex_held(X)  
0690: 20 20 20 28 28 76 6f 69 64 29 28 58 29 2c 31 29     ((void)(X),1)
06a0: 0a 23 64 65 66 69 6e 65 20 73 71 6c 69 74 65 33  .#define sqlite3
06b0: 5f 6d 75 74 65 78 5f 6e 6f 74 68 65 6c 64 28 58  _mutex_notheld(X
06c0: 29 20 20 28 28 76 6f 69 64 29 28 58 29 2c 31 29  )  ((void)(X),1)
06d0: 0a 23 65 6e 64 69 66 20 2f 2a 20 53 51 4c 49 54  .#endif /* SQLIT
06e0: 45 5f 54 48 52 45 41 44 53 41 46 45 3d 3d 30 20  E_THREADSAFE==0 
06f0: 2a 2f 0a 0a 23 69 6e 63 6c 75 64 65 20 22 6f 73  */..#include "os
0700: 5f 73 65 74 75 70 2e 68 22 0a 0a 23 69 66 20 53  _setup.h"..#if S
0710: 51 4c 49 54 45 5f 4f 53 5f 55 4e 49 58 0a 23 20  QLITE_OS_UNIX.# 
0720: 69 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e  include <unistd.
0730: 68 3e 0a 23 65 6e 64 69 66 0a 23 69 66 20 53 51  h>.#endif.#if SQ
0740: 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a 23 20 69 6e  LITE_OS_WIN.# in
0750: 63 6c 75 64 65 20 22 6f 73 5f 77 69 6e 2e 68 22  clude "os_win.h"
0760: 0a 23 20 69 6e 63 6c 75 64 65 20 3c 69 6f 2e 68  .# include <io.h
0770: 3e 0a 23 65 6e 64 69 66 0a 0a 0a 2f 2a 2a 2a 2a  >.#endif.../****
0780: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0790: 2a 2a 2a 2a 20 4f 62 6a 65 63 74 20 44 65 66 69  **** Object Defi
07a0: 6e 69 74 69 6f 6e 73 20 2a 2a 2a 2a 2a 2a 2a 2a  nitions ********
07b0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
07c0: 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f 2a 20 46 6f 72 77  ******/../* Forw
07d0: 61 72 64 20 64 65 63 6c 61 72 61 74 69 6f 6e 20  ard declaration 
07e0: 6f 66 20 61 6c 6c 20 6f 62 6a 65 63 74 20 74 79  of all object ty
07f0: 70 65 73 20 2a 2f 0a 74 79 70 65 64 65 66 20 73  pes */.typedef s
0800: 74 72 75 63 74 20 71 75 6f 74 61 47 72 6f 75 70  truct quotaGroup
0810: 20 71 75 6f 74 61 47 72 6f 75 70 3b 0a 74 79 70   quotaGroup;.typ
0820: 65 64 65 66 20 73 74 72 75 63 74 20 71 75 6f 74  edef struct quot
0830: 61 43 6f 6e 6e 20 71 75 6f 74 61 43 6f 6e 6e 3b  aConn quotaConn;
0840: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
0850: 71 75 6f 74 61 46 69 6c 65 20 71 75 6f 74 61 46  quotaFile quotaF
0860: 69 6c 65 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 22 71  ile;../*.** A "q
0870: 75 6f 74 61 20 67 72 6f 75 70 22 20 69 73 20 61  uota group" is a
0880: 20 63 6f 6c 6c 65 63 74 69 6f 6e 20 6f 66 20 66   collection of f
0890: 69 6c 65 73 20 77 68 6f 73 65 20 63 6f 6c 6c 65  iles whose colle
08a0: 63 74 69 76 65 20 73 69 7a 65 20 77 65 20 77 61  ctive size we wa
08b0: 6e 74 0a 2a 2a 20 74 6f 20 6c 69 6d 69 74 2e 20  nt.** to limit. 
08c0: 20 45 61 63 68 20 71 75 6f 74 61 20 67 72 6f 75   Each quota grou
08d0: 70 20 69 73 20 64 65 66 69 6e 65 64 20 62 79 20  p is defined by 
08e0: 61 20 47 4c 4f 42 20 70 61 74 74 65 72 6e 2e 0a  a GLOB pattern..
08f0: 2a 2a 0a 2a 2a 20 54 68 65 72 65 20 69 73 20 61  **.** There is a
0900: 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74 68  n instance of th
0910: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65  e following obje
0920: 63 74 20 66 6f 72 20 65 61 63 68 20 64 65 66 69  ct for each defi
0930: 6e 65 64 20 71 75 6f 74 61 0a 2a 2a 20 67 72 6f  ned quota.** gro
0940: 75 70 2e 20 20 54 68 69 73 20 6f 62 6a 65 63 74  up.  This object
0950: 20 72 65 63 6f 72 64 73 20 74 68 65 20 47 4c 4f   records the GLO
0960: 42 20 70 61 74 74 65 72 6e 20 74 68 61 74 20 64  B pattern that d
0970: 65 66 69 6e 65 73 20 77 68 69 63 68 20 66 69 6c  efines which fil
0980: 65 73 0a 2a 2a 20 62 65 6c 6f 6e 67 20 74 6f 20  es.** belong to 
0990: 74 68 65 20 71 75 6f 74 61 20 67 72 6f 75 70 2e  the quota group.
09a0: 20 20 54 68 65 20 6f 62 6a 65 63 74 20 61 6c 73    The object als
09b0: 6f 20 72 65 6d 65 6d 62 65 72 73 20 74 68 65 20  o remembers the 
09c0: 73 69 7a 65 20 6c 69 6d 69 74 0a 2a 2a 20 66 6f  size limit.** fo
09d0: 72 20 74 68 65 20 67 72 6f 75 70 20 28 74 68 65  r the group (the
09e0: 20 71 75 6f 74 61 29 20 61 6e 64 20 74 68 65 20   quota) and the 
09f0: 63 61 6c 6c 62 61 63 6b 20 74 6f 20 62 65 20 69  callback to be i
0a00: 6e 76 6f 6b 65 64 20 77 68 65 6e 20 74 68 65 0a  nvoked when the.
0a10: 2a 2a 20 73 75 6d 20 6f 66 20 74 68 65 20 73 69  ** sum of the si
0a20: 7a 65 73 20 6f 66 20 74 68 65 20 66 69 6c 65 73  zes of the files
0a30: 20 77 69 74 68 69 6e 20 74 68 65 20 67 72 6f 75   within the grou
0a40: 70 20 67 6f 65 73 20 6f 76 65 72 20 74 68 65 20  p goes over the 
0a50: 6c 69 6d 69 74 2e 0a 2a 2a 0a 2a 2a 20 41 20 71  limit..**.** A q
0a60: 75 6f 74 61 20 67 72 6f 75 70 20 6d 75 73 74 20  uota group must 
0a70: 62 65 20 65 73 74 61 62 6c 69 73 68 65 64 20 28  be established (
0a80: 75 73 69 6e 67 20 73 71 6c 69 74 65 33 5f 71 75  using sqlite3_qu
0a90: 6f 74 61 5f 73 65 74 28 2e 2e 2e 29 29 0a 2a 2a  ota_set(...)).**
0aa0: 20 70 72 69 6f 72 20 74 6f 20 6f 70 65 6e 69 6e   prior to openin
0ab0: 67 20 61 6e 79 20 6f 66 20 74 68 65 20 64 61 74  g any of the dat
0ac0: 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e  abase connection
0ad0: 73 20 74 68 61 74 20 61 63 63 65 73 73 20 66 69  s that access fi
0ae0: 6c 65 73 0a 2a 2a 20 77 69 74 68 69 6e 20 74 68  les.** within th
0af0: 65 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 0a 2a  e quota group..*
0b00: 2f 0a 73 74 72 75 63 74 20 71 75 6f 74 61 47 72  /.struct quotaGr
0b10: 6f 75 70 20 7b 0a 20 20 63 6f 6e 73 74 20 63 68  oup {.  const ch
0b20: 61 72 20 2a 7a 50 61 74 74 65 72 6e 3b 20 20 20  ar *zPattern;   
0b30: 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 6e 61         /* Filena
0b40: 6d 65 20 70 61 74 74 65 72 6e 20 74 6f 20 62 65  me pattern to be
0b50: 20 71 75 6f 74 61 65 64 20 2a 2f 0a 20 20 73 71   quotaed */.  sq
0b60: 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4c 69 6d  lite3_int64 iLim
0b70: 69 74 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20  it;          /* 
0b80: 55 70 70 65 72 20 62 6f 75 6e 64 20 6f 6e 20 74  Upper bound on t
0b90: 6f 74 61 6c 20 66 69 6c 65 20 73 69 7a 65 20 2a  otal file size *
0ba0: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  /.  sqlite3_int6
0bb0: 34 20 69 53 69 7a 65 3b 20 20 20 20 20 20 20 20  4 iSize;        
0bc0: 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 73 69     /* Current si
0bd0: 7a 65 20 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20  ze of all files 
0be0: 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 43 61 6c  */.  void (*xCal
0bf0: 6c 62 61 63 6b 29 28 20 20 20 20 20 20 20 20 20  lback)(         
0c00: 20 20 20 20 2f 2a 20 43 61 6c 6c 62 61 63 6b 20      /* Callback 
0c10: 69 6e 76 6f 6b 65 64 20 77 68 65 6e 20 67 6f 69  invoked when goi
0c20: 6e 67 20 6f 76 65 72 20 71 75 6f 74 61 20 2a 2f  ng over quota */
0c30: 0a 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  .     const char
0c40: 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20   *zFilename,    
0c50: 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20       /* Name of 
0c60: 66 69 6c 65 20 77 68 6f 73 65 20 73 69 7a 65 20  file whose size 
0c70: 69 6e 63 72 65 61 73 65 73 20 2a 2f 0a 20 20 20  increases */.   
0c80: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
0c90: 2a 70 69 4c 69 6d 69 74 2c 20 20 20 20 20 20 20  *piLimit,       
0ca0: 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 54 68 65 20   /* IN/OUT: The 
0cb0: 63 75 72 72 65 6e 74 20 6c 69 6d 69 74 20 2a 2f  current limit */
0cc0: 0a 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e  .     sqlite3_in
0cd0: 74 36 34 20 69 53 69 7a 65 2c 20 20 20 20 20 20  t64 iSize,      
0ce0: 20 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69       /* Total si
0cf0: 7a 65 20 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20  ze of all files 
0d00: 69 6e 20 74 68 65 20 67 72 6f 75 70 20 2a 2f 0a  in the group */.
0d10: 20 20 20 20 20 76 6f 69 64 20 2a 70 41 72 67 20       void *pArg 
0d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
0d30: 20 20 20 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61      /* Client da
0d40: 74 61 20 2a 2f 0a 20 20 29 3b 0a 20 20 76 6f 69  ta */.  );.  voi
0d50: 64 20 2a 70 41 72 67 3b 20 20 20 20 20 20 20 20  d *pArg;        
0d60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
0d70: 68 69 72 64 20 61 72 67 75 6d 65 6e 74 20 74 6f  hird argument to
0d80: 20 74 68 65 20 78 43 61 6c 6c 62 61 63 6b 28 29   the xCallback()
0d90: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 44 65   */.  void (*xDe
0da0: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 3b 20 20  stroy)(void*);  
0db0: 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f 6e 61 6c       /* Optional
0dc0: 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20   destructor for 
0dd0: 70 41 72 67 20 2a 2f 0a 20 20 71 75 6f 74 61 47  pArg */.  quotaG
0de0: 72 6f 75 70 20 2a 70 4e 65 78 74 2c 20 2a 2a 70  roup *pNext, **p
0df0: 70 50 72 65 76 3b 20 20 20 2f 2a 20 44 6f 75 62  pPrev;   /* Doub
0e00: 6c 79 20 6c 69 6e 6b 65 64 20 6c 69 73 74 20 6f  ly linked list o
0e10: 66 20 61 6c 6c 20 71 75 6f 74 61 20 6f 62 6a 65  f all quota obje
0e20: 63 74 73 20 2a 2f 0a 20 20 71 75 6f 74 61 46 69  cts */.  quotaFi
0e30: 6c 65 20 2a 70 46 69 6c 65 73 3b 20 20 20 20 20  le *pFiles;     
0e40: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 73          /* Files
0e50: 20 77 69 74 68 69 6e 20 74 68 69 73 20 67 72 6f   within this gro
0e60: 75 70 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20  up */.};../*.** 
0e70: 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f 66 20 74  An instance of t
0e80: 68 69 73 20 73 74 72 75 63 74 75 72 65 20 72 65  his structure re
0e90: 70 72 65 73 65 6e 74 73 20 61 20 73 69 6e 67 6c  presents a singl
0ea0: 65 20 66 69 6c 65 20 74 68 61 74 20 69 73 20 70  e file that is p
0eb0: 61 72 74 0a 2a 2a 20 6f 66 20 61 20 71 75 6f 74  art.** of a quot
0ec0: 61 20 67 72 6f 75 70 2e 20 20 41 20 73 69 6e 67  a group.  A sing
0ed0: 6c 65 20 66 69 6c 65 20 63 61 6e 20 62 65 20 6f  le file can be o
0ee0: 70 65 6e 65 64 20 6d 75 6c 74 69 70 6c 65 20 74  pened multiple t
0ef0: 69 6d 65 73 2e 20 20 49 6e 0a 2a 2a 20 6f 72 64  imes.  In.** ord
0f00: 65 72 20 6b 65 65 70 20 6d 75 6c 74 69 70 6c 65  er keep multiple
0f10: 20 6f 70 65 6e 69 6e 67 73 20 6f 66 20 74 68 65   openings of the
0f20: 20 73 61 6d 65 20 66 69 6c 65 20 66 72 6f 6d 20   same file from 
0f30: 63 61 75 73 69 6e 67 20 74 68 65 20 73 69 7a 65  causing the size
0f40: 0a 2a 2a 20 6f 66 20 74 68 65 20 66 69 6c 65 20  .** of the file 
0f50: 74 6f 20 63 6f 75 6e 74 20 61 67 61 69 6e 73 74  to count against
0f60: 20 74 68 65 20 71 75 6f 74 61 20 6d 75 6c 74 69   the quota multi
0f70: 70 6c 65 20 74 69 6d 65 73 2c 20 65 61 63 68 20  ple times, each 
0f80: 66 69 6c 65 0a 2a 2a 20 68 61 73 20 61 20 75 6e  file.** has a un
0f90: 69 71 75 65 20 69 6e 73 74 61 6e 63 65 20 6f 66  ique instance of
0fa0: 20 74 68 69 73 20 6f 62 6a 65 63 74 20 61 6e 64   this object and
0fb0: 20 6d 75 6c 74 69 70 6c 65 20 6f 70 65 6e 20 63   multiple open c
0fc0: 6f 6e 6e 65 63 74 69 6f 6e 73 0a 2a 2a 20 74 6f  onnections.** to
0fd0: 20 74 68 65 20 73 61 6d 65 20 66 69 6c 65 20 65   the same file e
0fe0: 61 63 68 20 70 6f 69 6e 74 20 74 6f 20 61 20 73  ach point to a s
0ff0: 69 6e 67 6c 65 20 69 6e 73 74 61 6e 63 65 20 6f  ingle instance o
1000: 66 20 74 68 69 73 20 6f 62 6a 65 63 74 2e 0a 2a  f this object..*
1010: 2f 0a 73 74 72 75 63 74 20 71 75 6f 74 61 46 69  /.struct quotaFi
1020: 6c 65 20 7b 0a 20 20 63 68 61 72 20 2a 7a 46 69  le {.  char *zFi
1030: 6c 65 6e 61 6d 65 3b 20 20 20 20 20 20 20 20 20  lename;         
1040: 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f         /* Name o
1050: 66 20 74 68 69 73 20 66 69 6c 65 20 2a 2f 0a 20  f this file */. 
1060: 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72   quotaGroup *pGr
1070: 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20 20 20  oup;            
1080: 20 2f 2a 20 51 75 6f 74 61 20 67 72 6f 75 70 20   /* Quota group 
1090: 74 6f 20 77 68 69 63 68 20 74 68 69 73 20 66 69  to which this fi
10a0: 6c 65 20 62 65 6c 6f 6e 67 73 20 2a 2f 0a 20 20  le belongs */.  
10b0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 53  sqlite3_int64 iS
10c0: 69 7a 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ize;            
10d0: 2f 2a 20 43 75 72 72 65 6e 74 20 73 69 7a 65 20  /* Current size 
10e0: 6f 66 20 74 68 69 73 20 66 69 6c 65 20 2a 2f 0a  of this file */.
10f0: 20 20 69 6e 74 20 6e 52 65 66 3b 20 20 20 20 20    int nRef;     
1100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1110: 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 74    /* Number of t
1120: 69 6d 65 73 20 74 68 69 73 20 66 69 6c 65 20 69  imes this file i
1130: 73 20 6f 70 65 6e 20 2a 2f 0a 20 20 69 6e 74 20  s open */.  int 
1140: 64 65 6c 65 74 65 4f 6e 43 6c 6f 73 65 3b 20 20  deleteOnClose;  
1150: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
1160: 72 75 65 20 74 6f 20 64 65 6c 65 74 65 20 74 68  rue to delete th
1170: 69 73 20 66 69 6c 65 20 77 68 65 6e 20 69 74 20  is file when it 
1180: 63 6c 6f 73 65 73 20 2a 2f 0a 20 20 71 75 6f 74  closes */.  quot
1190: 61 46 69 6c 65 20 2a 70 4e 65 78 74 2c 20 2a 2a  aFile *pNext, **
11a0: 70 70 50 72 65 76 3b 20 20 20 20 20 2f 2a 20 4c  ppPrev;     /* L
11b0: 69 6e 6b 65 64 20 6c 69 73 74 20 6f 66 20 66 69  inked list of fi
11c0: 6c 65 73 20 69 6e 20 74 68 65 20 73 61 6d 65 20  les in the same 
11d0: 67 72 6f 75 70 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a  group */.};../*.
11e0: 2a 2a 20 41 6e 20 69 6e 73 74 61 6e 63 65 20 6f  ** An instance o
11f0: 66 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20  f the following 
1200: 6f 62 6a 65 63 74 20 72 65 70 72 65 73 65 6e 74  object represent
1210: 73 20 65 61 63 68 20 6f 70 65 6e 20 63 6f 6e 6e  s each open conn
1220: 65 63 74 69 6f 6e 0a 2a 2a 20 74 6f 20 61 20 66  ection.** to a f
1230: 69 6c 65 20 74 68 61 74 20 70 61 72 74 69 63 69  ile that partici
1240: 70 61 74 65 73 20 69 6e 20 71 75 6f 74 61 20 74  pates in quota t
1250: 72 61 63 6b 69 6e 67 2e 20 20 54 68 69 73 20 6f  racking.  This o
1260: 62 6a 65 63 74 20 69 73 20 61 0a 2a 2a 20 73 75  bject is a.** su
1270: 62 63 6c 61 73 73 20 6f 66 20 73 71 6c 69 74 65  bclass of sqlite
1280: 33 5f 66 69 6c 65 2e 20 20 54 68 65 20 73 71 6c  3_file.  The sql
1290: 69 74 65 33 5f 66 69 6c 65 20 6f 62 6a 65 63 74  ite3_file object
12a0: 20 66 6f 72 20 74 68 65 20 75 6e 64 65 72 6c 79   for the underly
12b0: 69 6e 67 0a 2a 2a 20 56 46 53 20 69 73 20 61 70  ing.** VFS is ap
12c0: 70 65 6e 64 65 64 20 74 6f 20 74 68 69 73 20 73  pended to this s
12d0: 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 73 74 72  tructure..*/.str
12e0: 75 63 74 20 71 75 6f 74 61 43 6f 6e 6e 20 7b 0a  uct quotaConn {.
12f0: 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 62    sqlite3_file b
1300: 61 73 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ase;            
1310: 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20    /* Base class 
1320: 2d 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20  - must be first 
1330: 2a 2f 0a 20 20 71 75 6f 74 61 46 69 6c 65 20 2a  */.  quotaFile *
1340: 70 46 69 6c 65 3b 20 20 20 20 20 20 20 20 20 20  pFile;          
1350: 20 20 20 20 20 2f 2a 20 54 68 65 20 75 6e 64 65       /* The unde
1360: 72 6c 79 69 6e 67 20 66 69 6c 65 20 2a 2f 0a 20  rlying file */. 
1370: 20 2f 2a 20 54 68 65 20 75 6e 64 65 72 6c 79 69   /* The underlyi
1380: 6e 67 20 56 46 53 20 73 71 6c 69 74 65 33 5f 66  ng VFS sqlite3_f
1390: 69 6c 65 20 69 73 20 61 70 70 65 6e 64 65 64 20  ile is appended 
13a0: 74 6f 20 74 68 69 73 20 6f 62 6a 65 63 74 20 2a  to this object *
13b0: 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 41 6e 20 69  /.};../*.** An i
13c0: 6e 73 74 61 6e 63 65 20 6f 66 20 74 68 65 20 66  nstance of the f
13d0: 6f 6c 6c 6f 77 69 6e 67 20 6f 62 6a 65 63 74 20  ollowing object 
13e0: 72 65 63 6f 72 64 73 20 74 68 65 20 73 74 61 74  records the stat
13f0: 65 20 6f 66 20 61 6e 0a 2a 2a 20 6f 70 65 6e 20  e of an.** open 
1400: 66 69 6c 65 2e 20 20 54 68 69 73 20 6f 62 6a 65  file.  This obje
1410: 63 74 20 69 73 20 6f 70 61 71 75 65 20 74 6f 20  ct is opaque to 
1420: 61 6c 6c 20 75 73 65 72 73 20 2d 20 74 68 65 20  all users - the 
1430: 69 6e 74 65 72 6e 61 6c 0a 2a 2a 20 73 74 72 75  internal.** stru
1440: 63 74 75 72 65 20 69 73 20 6f 6e 6c 79 20 76 69  cture is only vi
1450: 73 69 62 6c 65 20 74 6f 20 74 68 65 20 66 75 6e  sible to the fun
1460: 63 74 69 6f 6e 73 20 62 65 6c 6f 77 2e 0a 2a 2f  ctions below..*/
1470: 0a 73 74 72 75 63 74 20 71 75 6f 74 61 5f 46 49  .struct quota_FI
1480: 4c 45 20 7b 0a 20 20 46 49 4c 45 20 2a 66 3b 20  LE {.  FILE *f; 
1490: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
14a0: 2a 20 4f 70 65 6e 20 73 74 64 69 6f 20 66 69 6c  * Open stdio fil
14b0: 65 20 70 6f 69 6e 74 65 72 20 2a 2f 0a 20 20 73  e pointer */.  s
14c0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
14d0: 73 74 3b 20 20 20 20 2f 2a 20 43 75 72 72 65 6e  st;    /* Curren
14e0: 74 20 6f 66 66 73 65 74 20 69 6e 74 6f 20 74 68  t offset into th
14f0: 65 20 66 69 6c 65 20 2a 2f 0a 20 20 71 75 6f 74  e file */.  quot
1500: 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20  aFile *pFile;   
1510: 20 20 20 20 2f 2a 20 54 68 65 20 66 69 6c 65 20      /* The file 
1520: 72 65 63 6f 72 64 20 69 6e 20 74 68 65 20 71 75  record in the qu
1530: 6f 74 61 20 73 79 73 74 65 6d 20 2a 2f 0a 23 69  ota system */.#i
1540: 66 20 53 51 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a  f SQLITE_OS_WIN.
1550: 20 20 63 68 61 72 20 2a 7a 4d 62 63 73 4e 61 6d    char *zMbcsNam
1560: 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 46 75 6c  e;        /* Ful
1570: 6c 20 4d 42 43 53 20 70 61 74 68 6e 61 6d 65 20  l MBCS pathname 
1580: 6f 66 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a 23  of the file */.#
1590: 65 6e 64 69 66 0a 7d 3b 0a 0a 0a 2f 2a 2a 2a 2a  endif.};.../****
15a0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15b0: 2a 2a 2a 2a 2a 20 47 6c 6f 62 61 6c 20 56 61 72  ***** Global Var
15c0: 69 61 62 6c 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a  iables *********
15d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
15e0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a  *********/./*.**
15f0: 20 41 6c 6c 20 67 6c 6f 62 61 6c 20 76 61 72 69   All global vari
1600: 61 62 6c 65 73 20 75 73 65 64 20 62 79 20 74 68  ables used by th
1610: 69 73 20 66 69 6c 65 20 61 72 65 20 63 6f 6e 74  is file are cont
1620: 61 69 6e 69 6e 67 20 77 69 74 68 69 6e 20 74 68  aining within th
1630: 65 20 66 6f 6c 6c 6f 77 69 6e 67 0a 2a 2a 20 67  e following.** g
1640: 51 75 6f 74 61 20 73 74 72 75 63 74 75 72 65 2e  Quota structure.
1650: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63  .*/.static struc
1660: 74 20 7b 0a 20 20 2f 2a 20 54 68 65 20 70 4f 72  t {.  /* The pOr
1670: 69 67 56 66 73 20 69 73 20 74 68 65 20 72 65 61  igVfs is the rea
1680: 6c 2c 20 6f 72 69 67 69 6e 61 6c 20 75 6e 64 65  l, original unde
1690: 72 6c 79 69 6e 67 20 56 46 53 20 69 6d 70 6c 65  rlying VFS imple
16a0: 6d 65 6e 74 61 74 69 6f 6e 2e 0a 20 20 2a 2a 20  mentation..  ** 
16b0: 4d 6f 73 74 20 6f 70 65 72 61 74 69 6f 6e 73 20  Most operations 
16c0: 70 61 73 73 2d 74 68 72 6f 75 67 68 20 74 6f 20  pass-through to 
16d0: 74 68 65 20 72 65 61 6c 20 56 46 53 2e 20 20 54  the real VFS.  T
16e0: 68 69 73 20 76 61 6c 75 65 20 69 73 20 72 65 61  his value is rea
16f0: 64 2d 6f 6e 6c 79 0a 20 20 2a 2a 20 64 75 72 69  d-only.  ** duri
1700: 6e 67 20 6f 70 65 72 61 74 69 6f 6e 2e 20 20 49  ng operation.  I
1710: 74 20 69 73 20 6f 6e 6c 79 20 6d 6f 64 69 66 69  t is only modifi
1720: 65 64 20 61 74 20 73 74 61 72 74 2d 74 69 6d 65  ed at start-time
1730: 20 61 6e 64 20 74 68 75 73 20 64 6f 65 73 20 6e   and thus does n
1740: 6f 74 0a 20 20 2a 2a 20 72 65 71 75 69 72 65 20  ot.  ** require 
1750: 61 20 6d 75 74 65 78 2e 0a 20 20 2a 2f 0a 20 20  a mutex..  */.  
1760: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72  sqlite3_vfs *pOr
1770: 69 67 56 66 73 3b 0a 0a 20 20 2f 2a 20 54 68 65  igVfs;..  /* The
1780: 20 73 54 68 69 73 56 66 73 20 69 73 20 74 68 65   sThisVfs is the
1790: 20 56 46 53 20 73 74 72 75 63 74 75 72 65 20 75   VFS structure u
17a0: 73 65 64 20 62 79 20 74 68 69 73 20 73 68 69 6d  sed by this shim
17b0: 2e 20 20 49 74 20 69 73 20 69 6e 69 74 69 61 6c  .  It is initial
17c0: 69 7a 65 64 0a 20 20 2a 2a 20 61 74 20 73 74 61  ized.  ** at sta
17d0: 72 74 2d 74 69 6d 65 20 61 6e 64 20 74 68 75 73  rt-time and thus
17e0: 20 64 6f 65 73 20 6e 6f 74 20 72 65 71 75 69 72   does not requir
17f0: 65 20 61 20 6d 75 74 65 78 0a 20 20 2a 2f 0a 20  e a mutex.  */. 
1800: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 73 54 68   sqlite3_vfs sTh
1810: 69 73 56 66 73 3b 0a 0a 20 20 2f 2a 20 54 68 65  isVfs;..  /* The
1820: 20 73 49 6f 4d 65 74 68 6f 64 73 20 64 65 66 69   sIoMethods defi
1830: 6e 65 73 20 74 68 65 20 6d 65 74 68 6f 64 73 20  nes the methods 
1840: 75 73 65 64 20 62 79 20 73 71 6c 69 74 65 33 5f  used by sqlite3_
1850: 66 69 6c 65 20 6f 62 6a 65 63 74 73 0a 20 20 2a  file objects.  *
1860: 2a 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74  * associated wit
1870: 68 20 74 68 69 73 20 73 68 69 6d 2e 20 20 49 74  h this shim.  It
1880: 20 69 73 20 69 6e 69 74 69 61 6c 69 7a 65 64 20   is initialized 
1890: 61 74 20 73 74 61 72 74 2d 74 69 6d 65 20 61 6e  at start-time an
18a0: 64 20 64 6f 65 73 0a 20 20 2a 2a 20 6e 6f 74 20  d does.  ** not 
18b0: 72 65 71 75 69 72 65 20 61 20 6d 75 74 65 78 2e  require a mutex.
18c0: 0a 20 20 2a 2a 0a 20 20 2a 2a 20 57 68 65 6e 20  .  **.  ** When 
18d0: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 56  the underlying V
18e0: 46 53 20 69 73 20 63 61 6c 6c 65 64 20 74 6f 20  FS is called to 
18f0: 6f 70 65 6e 20 61 20 66 69 6c 65 2c 20 69 74 20  open a file, it 
1900: 6d 69 67 68 74 20 72 65 74 75 72 6e 0a 20 20 2a  might return.  *
1910: 2a 20 65 69 74 68 65 72 20 61 20 76 65 72 73 69  * either a versi
1920: 6f 6e 20 31 20 6f 72 20 61 20 76 65 72 73 69 6f  on 1 or a versio
1930: 6e 20 32 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  n 2 sqlite3_file
1940: 20 6f 62 6a 65 63 74 2e 20 20 54 68 69 73 20 73   object.  This s
1950: 68 69 6d 0a 20 20 2a 2a 20 68 61 73 20 74 6f 20  him.  ** has to 
1960: 63 72 65 61 74 65 20 61 20 77 72 61 70 70 65 72  create a wrapper
1970: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 6f 66   sqlite3_file of
1980: 20 74 68 65 20 73 61 6d 65 20 76 65 72 73 69 6f   the same versio
1990: 6e 2e 20 20 48 65 6e 63 65 0a 20 20 2a 2a 20 74  n.  Hence.  ** t
19a0: 68 65 72 65 20 61 72 65 20 74 77 6f 20 49 2f 4f  here are two I/O
19b0: 20 6d 65 74 68 6f 64 20 73 74 72 75 63 74 75 72   method structur
19c0: 65 73 2c 20 6f 6e 65 20 66 6f 72 20 76 65 72 73  es, one for vers
19d0: 69 6f 6e 20 31 20 61 6e 64 20 74 68 65 20 6f 74  ion 1 and the ot
19e0: 68 65 72 0a 20 20 2a 2a 20 66 6f 72 20 76 65 72  her.  ** for ver
19f0: 73 69 6f 6e 20 32 2e 0a 20 20 2a 2f 0a 20 20 73  sion 2..  */.  s
1a00: 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74 68 6f 64  qlite3_io_method
1a10: 73 20 73 49 6f 4d 65 74 68 6f 64 73 56 31 3b 0a  s sIoMethodsV1;.
1a20: 20 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d 65 74    sqlite3_io_met
1a30: 68 6f 64 73 20 73 49 6f 4d 65 74 68 6f 64 73 56  hods sIoMethodsV
1a40: 32 3b 0a 0a 20 20 2f 2a 20 54 72 75 65 20 77 68  2;..  /* True wh
1a50: 65 6e 20 74 68 69 73 20 73 68 69 6d 20 61 73 20  en this shim as 
1a60: 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65 64  been initialized
1a70: 2e 0a 20 20 2a 2f 0a 20 20 69 6e 74 20 69 73 49  ..  */.  int isI
1a80: 6e 69 74 69 61 6c 69 7a 65 64 3b 0a 0a 20 20 2f  nitialized;..  /
1a90: 2a 20 46 6f 72 20 72 75 6e 2d 74 69 6d 65 20 61  * For run-time a
1aa0: 63 63 65 73 73 20 61 6e 79 20 6f 66 20 74 68 65  ccess any of the
1ab0: 20 6f 74 68 65 72 20 67 6c 6f 62 61 6c 20 64 61   other global da
1ac0: 74 61 20 73 74 72 75 63 74 75 72 65 73 20 69 6e  ta structures in
1ad0: 20 74 68 69 73 0a 20 20 2a 2a 20 73 68 69 6d 2c   this.  ** shim,
1ae0: 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 6d   the following m
1af0: 75 74 65 78 20 6d 75 73 74 20 62 65 20 68 65 6c  utex must be hel
1b00: 64 2e 0a 20 20 2a 2f 0a 20 20 73 71 6c 69 74 65  d..  */.  sqlite
1b10: 33 5f 6d 75 74 65 78 20 2a 70 4d 75 74 65 78 3b  3_mutex *pMutex;
1b20: 0a 0a 20 20 2f 2a 20 4c 69 73 74 20 6f 66 20 71  ..  /* List of q
1b30: 75 6f 74 61 47 72 6f 75 70 20 6f 62 6a 65 63 74  uotaGroup object
1b40: 73 2e 0a 20 20 2a 2f 0a 20 20 71 75 6f 74 61 47  s..  */.  quotaG
1b50: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 0a 7d  roup *pGroup;..}
1b60: 20 67 51 75 6f 74 61 3b 0a 0a 2f 2a 2a 2a 2a 2a   gQuota;../*****
1b70: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1b80: 2a 2a 2a 2a 20 55 74 69 6c 69 74 79 20 52 6f 75  **** Utility Rou
1b90: 74 69 6e 65 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  tines **********
1ba0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
1bb0: 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 41  *******/./*.** A
1bc0: 63 71 75 69 72 65 20 61 6e 64 20 72 65 6c 65 61  cquire and relea
1bd0: 73 65 20 74 68 65 20 6d 75 74 65 78 20 75 73 65  se the mutex use
1be0: 64 20 74 6f 20 73 65 72 69 61 6c 69 7a 65 20 61  d to serialize a
1bf0: 63 63 65 73 73 20 74 6f 20 74 68 65 0a 2a 2a 20  ccess to the.** 
1c00: 6c 69 73 74 20 6f 66 20 71 75 6f 74 61 47 72 6f  list of quotaGro
1c10: 75 70 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ups..*/.static v
1c20: 6f 69 64 20 71 75 6f 74 61 45 6e 74 65 72 28 76  oid quotaEnter(v
1c30: 6f 69 64 29 7b 20 73 71 6c 69 74 65 33 5f 6d 75  oid){ sqlite3_mu
1c40: 74 65 78 5f 65 6e 74 65 72 28 67 51 75 6f 74 61  tex_enter(gQuota
1c50: 2e 70 4d 75 74 65 78 29 3b 20 7d 0a 73 74 61 74  .pMutex); }.stat
1c60: 69 63 20 76 6f 69 64 20 71 75 6f 74 61 4c 65 61  ic void quotaLea
1c70: 76 65 28 76 6f 69 64 29 7b 20 73 71 6c 69 74 65  ve(void){ sqlite
1c80: 33 5f 6d 75 74 65 78 5f 6c 65 61 76 65 28 67 51  3_mutex_leave(gQ
1c90: 75 6f 74 61 2e 70 4d 75 74 65 78 29 3b 20 7d 0a  uota.pMutex); }.
1ca0: 0a 2f 2a 20 43 6f 75 6e 74 20 74 68 65 20 6e 75  ./* Count the nu
1cb0: 6d 62 65 72 20 6f 66 20 6f 70 65 6e 20 66 69 6c  mber of open fil
1cc0: 65 73 20 69 6e 20 61 20 71 75 6f 74 61 47 72 6f  es in a quotaGro
1cd0: 75 70 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  up.*/.static int
1ce0: 20 71 75 6f 74 61 47 72 6f 75 70 4f 70 65 6e 46   quotaGroupOpenF
1cf0: 69 6c 65 43 6f 75 6e 74 28 71 75 6f 74 61 47 72  ileCount(quotaGr
1d00: 6f 75 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20  oup *pGroup){.  
1d10: 69 6e 74 20 4e 20 3d 20 30 3b 0a 20 20 71 75 6f  int N = 0;.  quo
1d20: 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20  taFile *pFile = 
1d30: 70 47 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3b 0a  pGroup->pFiles;.
1d40: 20 20 77 68 69 6c 65 28 20 70 46 69 6c 65 20 29    while( pFile )
1d50: 7b 0a 20 20 20 20 69 66 28 20 70 46 69 6c 65 2d  {.    if( pFile-
1d60: 3e 6e 52 65 66 20 29 20 4e 2b 2b 3b 0a 20 20 20  >nRef ) N++;.   
1d70: 20 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 2d 3e   pFile = pFile->
1d80: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 72 65 74  pNext;.  }.  ret
1d90: 75 72 6e 20 4e 3b 0a 7d 0a 0a 2f 2a 20 52 65 6d  urn N;.}../* Rem
1da0: 6f 76 65 20 61 20 66 69 6c 65 20 66 72 6f 6d 20  ove a file from 
1db0: 61 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 0a 2a  a quota group..*
1dc0: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 71 75  /.static void qu
1dd0: 6f 74 61 52 65 6d 6f 76 65 46 69 6c 65 28 71 75  otaRemoveFile(qu
1de0: 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 29 7b  otaFile *pFile){
1df0: 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70  .  quotaGroup *p
1e00: 47 72 6f 75 70 20 3d 20 70 46 69 6c 65 2d 3e 70  Group = pFile->p
1e10: 47 72 6f 75 70 3b 0a 20 20 70 47 72 6f 75 70 2d  Group;.  pGroup-
1e20: 3e 69 53 69 7a 65 20 2d 3d 20 70 46 69 6c 65 2d  >iSize -= pFile-
1e30: 3e 69 53 69 7a 65 3b 0a 20 20 2a 70 46 69 6c 65  >iSize;.  *pFile
1e40: 2d 3e 70 70 50 72 65 76 20 3d 20 70 46 69 6c 65  ->ppPrev = pFile
1e50: 2d 3e 70 4e 65 78 74 3b 0a 20 20 69 66 28 20 70  ->pNext;.  if( p
1e60: 46 69 6c 65 2d 3e 70 4e 65 78 74 20 29 20 70 46  File->pNext ) pF
1e70: 69 6c 65 2d 3e 70 4e 65 78 74 2d 3e 70 70 50 72  ile->pNext->ppPr
1e80: 65 76 20 3d 20 70 46 69 6c 65 2d 3e 70 70 50 72  ev = pFile->ppPr
1e90: 65 76 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ev;.  sqlite3_fr
1ea0: 65 65 28 70 46 69 6c 65 29 3b 0a 7d 0a 0a 2f 2a  ee(pFile);.}../*
1eb0: 20 52 65 6d 6f 76 65 20 61 6c 6c 20 66 69 6c 65   Remove all file
1ec0: 73 20 66 72 6f 6d 20 61 20 71 75 6f 74 61 20 67  s from a quota g
1ed0: 72 6f 75 70 2e 20 20 49 74 20 69 73 20 61 6c 77  roup.  It is alw
1ee0: 61 79 73 20 74 68 65 20 63 61 73 65 20 74 68 61  ays the case tha
1ef0: 74 0a 2a 2a 20 61 6c 6c 20 66 69 6c 65 73 20 77  t.** all files w
1f00: 69 6c 6c 20 62 65 20 63 6c 6f 73 65 64 20 77 68  ill be closed wh
1f10: 65 6e 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20  en this routine 
1f20: 69 73 20 63 61 6c 6c 65 64 2e 0a 2a 2f 0a 73 74  is called..*/.st
1f30: 61 74 69 63 20 76 6f 69 64 20 71 75 6f 74 61 52  atic void quotaR
1f40: 65 6d 6f 76 65 41 6c 6c 46 69 6c 65 73 28 71 75  emoveAllFiles(qu
1f50: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
1f60: 29 7b 0a 20 20 77 68 69 6c 65 28 20 70 47 72 6f  ){.  while( pGro
1f70: 75 70 2d 3e 70 46 69 6c 65 73 20 29 7b 0a 20 20  up->pFiles ){.  
1f80: 20 20 61 73 73 65 72 74 28 20 70 47 72 6f 75 70    assert( pGroup
1f90: 2d 3e 70 46 69 6c 65 73 2d 3e 6e 52 65 66 3d 3d  ->pFiles->nRef==
1fa0: 30 20 29 3b 0a 20 20 20 20 71 75 6f 74 61 52 65  0 );.    quotaRe
1fb0: 6d 6f 76 65 46 69 6c 65 28 70 47 72 6f 75 70 2d  moveFile(pGroup-
1fc0: 3e 70 46 69 6c 65 73 29 3b 0a 20 20 7d 0a 7d 0a  >pFiles);.  }.}.
1fd0: 0a 0a 2f 2a 20 49 66 20 74 68 65 20 72 65 66 65  ../* If the refe
1fe0: 72 65 6e 63 65 20 63 6f 75 6e 74 20 61 6e 64 20  rence count and 
1ff0: 74 68 72 65 73 68 6f 6c 64 20 66 6f 72 20 61 20  threshold for a 
2000: 71 75 6f 74 61 47 72 6f 75 70 20 61 72 65 20 62  quotaGroup are b
2010: 6f 74 68 0a 2a 2a 20 7a 65 72 6f 2c 20 74 68 65  oth.** zero, the
2020: 6e 20 64 65 73 74 72 6f 79 20 74 68 65 20 71 75  n destroy the qu
2030: 6f 74 61 47 72 6f 75 70 2e 0a 2a 2f 0a 73 74 61  otaGroup..*/.sta
2040: 74 69 63 20 76 6f 69 64 20 71 75 6f 74 61 47 72  tic void quotaGr
2050: 6f 75 70 44 65 72 65 66 28 71 75 6f 74 61 47 72  oupDeref(quotaGr
2060: 6f 75 70 20 2a 70 47 72 6f 75 70 29 7b 0a 20 20  oup *pGroup){.  
2070: 69 66 28 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d  if( pGroup->iLim
2080: 69 74 3d 3d 30 20 26 26 20 71 75 6f 74 61 47 72  it==0 && quotaGr
2090: 6f 75 70 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74  oupOpenFileCount
20a0: 28 70 47 72 6f 75 70 29 3d 3d 30 20 29 7b 0a 20  (pGroup)==0 ){. 
20b0: 20 20 20 71 75 6f 74 61 52 65 6d 6f 76 65 41 6c     quotaRemoveAl
20c0: 6c 46 69 6c 65 73 28 70 47 72 6f 75 70 29 3b 0a  lFiles(pGroup);.
20d0: 20 20 20 20 2a 70 47 72 6f 75 70 2d 3e 70 70 50      *pGroup->ppP
20e0: 72 65 76 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e  rev = pGroup->pN
20f0: 65 78 74 3b 0a 20 20 20 20 69 66 28 20 70 47 72  ext;.    if( pGr
2100: 6f 75 70 2d 3e 70 4e 65 78 74 20 29 20 70 47 72  oup->pNext ) pGr
2110: 6f 75 70 2d 3e 70 4e 65 78 74 2d 3e 70 70 50 72  oup->pNext->ppPr
2120: 65 76 20 3d 20 70 47 72 6f 75 70 2d 3e 70 70 50  ev = pGroup->ppP
2130: 72 65 76 3b 0a 20 20 20 20 69 66 28 20 70 47 72  rev;.    if( pGr
2140: 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79 20 29 20  oup->xDestroy ) 
2150: 70 47 72 6f 75 70 2d 3e 78 44 65 73 74 72 6f 79  pGroup->xDestroy
2160: 28 70 47 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a  (pGroup->pArg);.
2170: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
2180: 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 7d 0a  (pGroup);.  }.}.
2190: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52  ./*.** Return TR
21a0: 55 45 20 69 66 20 73 74 72 69 6e 67 20 7a 20 6d  UE if string z m
21b0: 61 74 63 68 65 73 20 67 6c 6f 62 20 70 61 74 74  atches glob patt
21c0: 65 72 6e 20 7a 47 6c 6f 62 2e 0a 2a 2a 0a 2a 2a  ern zGlob..**.**
21d0: 20 47 6c 6f 62 62 69 6e 67 20 72 75 6c 65 73 3a   Globbing rules:
21e0: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 27 2a 27 20  .**.**      '*' 
21f0: 20 20 20 20 20 20 4d 61 74 63 68 65 73 20 61 6e        Matches an
2200: 79 20 73 65 71 75 65 6e 63 65 20 6f 66 20 7a 65  y sequence of ze
2210: 72 6f 20 6f 72 20 6d 6f 72 65 20 63 68 61 72 61  ro or more chara
2220: 63 74 65 72 73 2e 0a 2a 2a 0a 2a 2a 20 20 20 20  cters..**.**    
2230: 20 20 27 3f 27 20 20 20 20 20 20 20 4d 61 74 63    '?'       Matc
2240: 68 65 73 20 65 78 61 63 74 6c 79 20 6f 6e 65 20  hes exactly one 
2250: 63 68 61 72 61 63 74 65 72 2e 0a 2a 2a 0a 2a 2a  character..**.**
2260: 20 20 20 20 20 5b 2e 2e 2e 5d 20 20 20 20 20 20       [...]      
2270: 4d 61 74 63 68 65 73 20 6f 6e 65 20 63 68 61 72  Matches one char
2280: 61 63 74 65 72 20 66 72 6f 6d 20 74 68 65 20 65  acter from the e
2290: 6e 63 6c 6f 73 65 64 20 6c 69 73 74 20 6f 66 0a  nclosed list of.
22a0: 2a 2a 20 20 20 20 20 20 20 20 20 20 20 20 20 20  **              
22b0: 20 20 63 68 61 72 61 63 74 65 72 73 2e 0a 2a 2a    characters..**
22c0: 0a 2a 2a 20 20 20 20 20 5b 5e 2e 2e 2e 5d 20 20  .**     [^...]  
22d0: 20 20 20 4d 61 74 63 68 65 73 20 6f 6e 65 20 63     Matches one c
22e0: 68 61 72 61 63 74 65 72 20 6e 6f 74 20 69 6e 20  haracter not in 
22f0: 74 68 65 20 65 6e 63 6c 6f 73 65 64 20 6c 69 73  the enclosed lis
2300: 74 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 2f 20 20  t..**.**     /  
2310: 20 20 20 20 20 20 20 20 4d 61 74 63 68 65 73 20          Matches 
2320: 22 2f 22 20 6f 72 20 22 5c 5c 22 0a 2a 2a 0a 2a  "/" or "\\".**.*
2330: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f  /.static int quo
2340: 74 61 53 74 72 67 6c 6f 62 28 63 6f 6e 73 74 20  taStrglob(const 
2350: 63 68 61 72 20 2a 7a 47 6c 6f 62 2c 20 63 6f 6e  char *zGlob, con
2360: 73 74 20 63 68 61 72 20 2a 7a 29 7b 0a 20 20 69  st char *z){.  i
2370: 6e 74 20 63 2c 20 63 32 2c 20 63 78 3b 0a 20 20  nt c, c2, cx;.  
2380: 69 6e 74 20 69 6e 76 65 72 74 3b 0a 20 20 69 6e  int invert;.  in
2390: 74 20 73 65 65 6e 3b 0a 0a 20 20 77 68 69 6c 65  t seen;..  while
23a0: 28 20 28 63 20 3d 20 28 2a 28 7a 47 6c 6f 62 2b  ( (c = (*(zGlob+
23b0: 2b 29 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69  +)))!=0 ){.    i
23c0: 66 28 20 63 3d 3d 27 2a 27 20 29 7b 0a 20 20 20  f( c=='*' ){.   
23d0: 20 20 20 77 68 69 6c 65 28 20 28 63 3d 28 2a 28     while( (c=(*(
23e0: 7a 47 6c 6f 62 2b 2b 29 29 29 20 3d 3d 20 27 2a  zGlob++))) == '*
23f0: 27 20 7c 7c 20 63 3d 3d 27 3f 27 20 29 7b 0a 20  ' || c=='?' ){. 
2400: 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27 3f         if( c=='?
2410: 27 20 26 26 20 28 2a 28 7a 2b 2b 29 29 3d 3d 30  ' && (*(z++))==0
2420: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20   ) return 0;.   
2430: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 63     }.      if( c
2440: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 72  ==0 ){.        r
2450: 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20 7d  eturn 1;.      }
2460: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 5b 27 20  else if( c=='[' 
2470: 29 7b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65  ){.        while
2480: 28 20 2a 7a 20 26 26 20 71 75 6f 74 61 53 74 72  ( *z && quotaStr
2490: 67 6c 6f 62 28 7a 47 6c 6f 62 2d 31 2c 7a 29 3d  glob(zGlob-1,z)=
24a0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
24b0: 7a 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  z++;.        }. 
24c0: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 28 2a         return (*
24d0: 7a 29 21 3d 30 3b 0a 20 20 20 20 20 20 7d 0a 20  z)!=0;.      }. 
24e0: 20 20 20 20 20 63 78 20 3d 20 28 63 3d 3d 27 2f       cx = (c=='/
24f0: 27 29 20 3f 20 27 5c 5c 27 20 3a 20 63 3b 0a 20  ') ? '\\' : c;. 
2500: 20 20 20 20 20 77 68 69 6c 65 28 20 28 63 32 20       while( (c2 
2510: 3d 20 28 2a 28 7a 2b 2b 29 29 29 21 3d 30 20 29  = (*(z++)))!=0 )
2520: 7b 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28  {.        while(
2530: 20 63 32 21 3d 63 20 26 26 20 63 32 21 3d 63 78   c2!=c && c2!=cx
2540: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 32   ){.          c2
2550: 20 3d 20 2a 28 7a 2b 2b 29 3b 0a 20 20 20 20 20   = *(z++);.     
2560: 20 20 20 20 20 69 66 28 20 63 32 3d 3d 30 20 29       if( c2==0 )
2570: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 20   return 0;.     
2580: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 69 66 28     }.        if(
2590: 20 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 7a 47   quotaStrglob(zG
25a0: 6c 6f 62 2c 7a 29 20 29 20 72 65 74 75 72 6e 20  lob,z) ) return 
25b0: 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  1;.      }.     
25c0: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d   return 0;.    }
25d0: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 3f 27 20  else if( c=='?' 
25e0: 29 7b 0a 20 20 20 20 20 20 69 66 28 20 28 2a 28  ){.      if( (*(
25f0: 7a 2b 2b 29 29 3d 3d 30 20 29 20 72 65 74 75 72  z++))==0 ) retur
2600: 6e 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  n 0;.    }else i
2610: 66 28 20 63 3d 3d 27 5b 27 20 29 7b 0a 20 20 20  f( c=='[' ){.   
2620: 20 20 20 69 6e 74 20 70 72 69 6f 72 5f 63 20 3d     int prior_c =
2630: 20 30 3b 0a 20 20 20 20 20 20 73 65 65 6e 20 3d   0;.      seen =
2640: 20 30 3b 0a 20 20 20 20 20 20 69 6e 76 65 72 74   0;.      invert
2650: 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 20 3d 20   = 0;.      c = 
2660: 2a 28 7a 2b 2b 29 3b 0a 20 20 20 20 20 20 69 66  *(z++);.      if
2670: 28 20 63 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ( c==0 ) return 
2680: 30 3b 0a 20 20 20 20 20 20 63 32 20 3d 20 2a 28  0;.      c2 = *(
2690: 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20 20 20  zGlob++);.      
26a0: 69 66 28 20 63 32 3d 3d 27 5e 27 20 29 7b 0a 20  if( c2=='^' ){. 
26b0: 20 20 20 20 20 20 20 69 6e 76 65 72 74 20 3d 20         invert = 
26c0: 31 3b 0a 20 20 20 20 20 20 20 20 63 32 20 3d 20  1;.        c2 = 
26d0: 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20 20 20  *(zGlob++);.    
26e0: 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 63 32    }.      if( c2
26f0: 3d 3d 27 5d 27 20 29 7b 0a 20 20 20 20 20 20 20  ==']' ){.       
2700: 20 69 66 28 20 63 3d 3d 27 5d 27 20 29 20 73 65   if( c==']' ) se
2710: 65 6e 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  en = 1;.        
2720: 63 32 20 3d 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b  c2 = *(zGlob++);
2730: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 77  .      }.      w
2740: 68 69 6c 65 28 20 63 32 20 26 26 20 63 32 21 3d  hile( c2 && c2!=
2750: 27 5d 27 20 29 7b 0a 20 20 20 20 20 20 20 20 69  ']' ){.        i
2760: 66 28 20 63 32 3d 3d 27 2d 27 20 26 26 20 7a 47  f( c2=='-' && zG
2770: 6c 6f 62 5b 30 5d 21 3d 27 5d 27 20 26 26 20 7a  lob[0]!=']' && z
2780: 47 6c 6f 62 5b 30 5d 21 3d 30 20 26 26 20 70 72  Glob[0]!=0 && pr
2790: 69 6f 72 5f 63 3e 30 20 29 7b 0a 20 20 20 20 20  ior_c>0 ){.     
27a0: 20 20 20 20 20 63 32 20 3d 20 2a 28 7a 47 6c 6f       c2 = *(zGlo
27b0: 62 2b 2b 29 3b 0a 20 20 20 20 20 20 20 20 20 20  b++);.          
27c0: 69 66 28 20 63 3e 3d 70 72 69 6f 72 5f 63 20 26  if( c>=prior_c &
27d0: 26 20 63 3c 3d 63 32 20 29 20 73 65 65 6e 20 3d  & c<=c2 ) seen =
27e0: 20 31 3b 0a 20 20 20 20 20 20 20 20 20 20 70 72   1;.          pr
27f0: 69 6f 72 5f 63 20 3d 20 30 3b 0a 20 20 20 20 20  ior_c = 0;.     
2800: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
2810: 20 20 20 20 69 66 28 20 63 3d 3d 63 32 20 29 7b      if( c==c2 ){
2820: 0a 20 20 20 20 20 20 20 20 20 20 20 20 73 65 65  .            see
2830: 6e 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 20  n = 1;.         
2840: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 70 72 69   }.          pri
2850: 6f 72 5f 63 20 3d 20 63 32 3b 0a 20 20 20 20 20  or_c = c2;.     
2860: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 63 32 20     }.        c2 
2870: 3d 20 2a 28 7a 47 6c 6f 62 2b 2b 29 3b 0a 20 20  = *(zGlob++);.  
2880: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
2890: 63 32 3d 3d 30 20 7c 7c 20 28 73 65 65 6e 20 5e  c2==0 || (seen ^
28a0: 20 69 6e 76 65 72 74 29 3d 3d 30 20 29 20 72 65   invert)==0 ) re
28b0: 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 65 6c 73  turn 0;.    }els
28c0: 65 20 69 66 28 20 63 3d 3d 27 2f 27 20 29 7b 0a  e if( c=='/' ){.
28d0: 20 20 20 20 20 20 69 66 28 20 7a 5b 30 5d 21 3d        if( z[0]!=
28e0: 27 2f 27 20 26 26 20 7a 5b 30 5d 21 3d 27 5c 5c  '/' && z[0]!='\\
28f0: 27 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  ' ) return 0;.  
2900: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 7d 65 6c      z++;.    }el
2910: 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 63 21  se{.      if( c!
2920: 3d 28 2a 28 7a 2b 2b 29 29 20 29 20 72 65 74 75  =(*(z++)) ) retu
2930: 72 6e 20 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  rn 0;.    }.  }.
2940: 20 20 72 65 74 75 72 6e 20 2a 7a 3d 3d 30 3b 0a    return *z==0;.
2950: 7d 0a 0a 0a 2f 2a 20 46 69 6e 64 20 61 20 71 75  }.../* Find a qu
2960: 6f 74 61 47 72 6f 75 70 20 67 69 76 65 6e 20 74  otaGroup given t
2970: 68 65 20 66 69 6c 65 6e 61 6d 65 2e 0a 2a 2a 0a  he filename..**.
2980: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
2990: 74 65 72 20 74 6f 20 74 68 65 20 71 75 6f 74 61  ter to the quota
29a0: 47 72 6f 75 70 20 6f 62 6a 65 63 74 2e 20 52 65  Group object. Re
29b0: 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20 6e 6f 74  turn NULL if not
29c0: 20 66 6f 75 6e 64 2e 0a 2a 2f 0a 73 74 61 74 69   found..*/.stati
29d0: 63 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 71 75  c quotaGroup *qu
29e0: 6f 74 61 47 72 6f 75 70 46 69 6e 64 28 63 6f 6e  otaGroupFind(con
29f0: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61  st char *zFilena
2a00: 6d 65 29 7b 0a 20 20 71 75 6f 74 61 47 72 6f 75  me){.  quotaGrou
2a10: 70 20 2a 70 3b 0a 20 20 66 6f 72 28 70 3d 67 51  p *p;.  for(p=gQ
2a20: 75 6f 74 61 2e 70 47 72 6f 75 70 3b 20 70 20 26  uota.pGroup; p &
2a30: 26 20 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 70  & quotaStrglob(p
2a40: 2d 3e 7a 50 61 74 74 65 72 6e 2c 20 7a 46 69 6c  ->zPattern, zFil
2a50: 65 6e 61 6d 65 29 3d 3d 30 3b 0a 20 20 20 20 20  ename)==0;.     
2a60: 20 70 3d 70 2d 3e 70 4e 65 78 74 29 7b 7d 0a 20   p=p->pNext){}. 
2a70: 20 72 65 74 75 72 6e 20 70 3b 0a 7d 0a 0a 2f 2a   return p;.}../*
2a80: 20 54 72 61 6e 73 6c 61 74 65 20 61 6e 20 73 71   Translate an sq
2a90: 6c 69 74 65 33 5f 66 69 6c 65 2a 20 74 68 61 74  lite3_file* that
2aa0: 20 69 73 20 72 65 61 6c 6c 79 20 61 20 71 75 6f   is really a quo
2ab0: 74 61 43 6f 6e 6e 2a 20 69 6e 74 6f 0a 2a 2a 20  taConn* into.** 
2ac0: 74 68 65 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  the sqlite3_file
2ad0: 2a 20 66 6f 72 20 74 68 65 20 75 6e 64 65 72 6c  * for the underl
2ae0: 79 69 6e 67 20 6f 72 69 67 69 6e 61 6c 20 56 46  ying original VF
2af0: 53 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c  S..*/.static sql
2b00: 69 74 65 33 5f 66 69 6c 65 20 2a 71 75 6f 74 61  ite3_file *quota
2b10: 53 75 62 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  SubOpen(sqlite3_
2b20: 66 69 6c 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20  file *pConn){.  
2b30: 71 75 6f 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28  quotaConn *p = (
2b40: 71 75 6f 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e  quotaConn*)pConn
2b50: 3b 0a 20 20 72 65 74 75 72 6e 20 28 73 71 6c 69  ;.  return (sqli
2b60: 74 65 33 5f 66 69 6c 65 2a 29 26 70 5b 31 5d 3b  te3_file*)&p[1];
2b70: 0a 7d 0a 0a 2f 2a 20 46 69 6e 64 20 61 20 66 69  .}../* Find a fi
2b80: 6c 65 20 69 6e 20 61 20 71 75 6f 74 61 20 67 72  le in a quota gr
2b90: 6f 75 70 20 61 6e 64 20 72 65 74 75 72 6e 20 61  oup and return a
2ba0: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 61 74   pointer to that
2bb0: 20 66 69 6c 65 2e 0a 2a 2a 20 52 65 74 75 72 6e   file..** Return
2bc0: 20 4e 55 4c 4c 20 69 66 20 74 68 65 20 66 69 6c   NULL if the fil
2bd0: 65 20 69 73 20 6e 6f 74 20 69 6e 20 74 68 65 20  e is not in the 
2be0: 67 72 6f 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63  group..*/.static
2bf0: 20 71 75 6f 74 61 46 69 6c 65 20 2a 71 75 6f 74   quotaFile *quot
2c00: 61 46 69 6e 64 46 69 6c 65 28 0a 20 20 71 75 6f  aFindFile(.  quo
2c10: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 2c  taGroup *pGroup,
2c20: 20 20 20 20 20 2f 2a 20 47 72 6f 75 70 20 69 6e       /* Group in
2c30: 20 77 68 69 63 68 20 74 6f 20 6c 6f 6f 6b 20 66   which to look f
2c40: 6f 72 20 74 68 65 20 66 69 6c 65 20 2a 2f 0a 20  or the file */. 
2c50: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
2c60: 6d 65 2c 20 20 20 20 20 20 2f 2a 20 46 75 6c 6c  me,      /* Full
2c70: 20 70 61 74 68 6e 61 6d 65 20 6f 66 20 74 68 65   pathname of the
2c80: 20 66 69 6c 65 20 2a 2f 0a 20 20 69 6e 74 20 63   file */.  int c
2c90: 72 65 61 74 65 46 6c 61 67 20 20 20 20 20 20 20  reateFlag       
2ca0: 20 20 20 2f 2a 20 54 72 79 20 74 6f 20 63 72 65     /* Try to cre
2cb0: 61 74 65 20 74 68 65 20 66 69 6c 65 20 69 66 20  ate the file if 
2cc0: 6e 6f 74 20 66 6f 75 6e 64 20 2a 2f 0a 29 7b 0a  not found */.){.
2cd0: 20 20 71 75 6f 74 61 46 69 6c 65 20 2a 70 46 69    quotaFile *pFi
2ce0: 6c 65 20 3d 20 70 47 72 6f 75 70 2d 3e 70 46 69  le = pGroup->pFi
2cf0: 6c 65 73 3b 0a 20 20 77 68 69 6c 65 28 20 70 46  les;.  while( pF
2d00: 69 6c 65 20 26 26 20 73 74 72 63 6d 70 28 70 46  ile && strcmp(pF
2d10: 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20  ile->zFilename, 
2d20: 7a 4e 61 6d 65 29 21 3d 30 20 29 7b 0a 20 20 20  zName)!=0 ){.   
2d30: 20 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 2d 3e   pFile = pFile->
2d40: 70 4e 65 78 74 3b 0a 20 20 7d 0a 20 20 69 66 28  pNext;.  }.  if(
2d50: 20 70 46 69 6c 65 3d 3d 30 20 26 26 20 63 72 65   pFile==0 && cre
2d60: 61 74 65 46 6c 61 67 20 29 7b 0a 20 20 20 20 69  ateFlag ){.    i
2d70: 6e 74 20 6e 4e 61 6d 65 20 3d 20 28 69 6e 74 29  nt nName = (int)
2d80: 28 73 74 72 6c 65 6e 28 7a 4e 61 6d 65 29 20 26  (strlen(zName) &
2d90: 20 30 78 33 66 66 66 66 66 66 66 29 3b 0a 20 20   0x3fffffff);.  
2da0: 20 20 70 46 69 6c 65 20 3d 20 28 71 75 6f 74 61    pFile = (quota
2db0: 46 69 6c 65 20 2a 29 73 71 6c 69 74 65 33 5f 6d  File *)sqlite3_m
2dc0: 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70  alloc( sizeof(*p
2dd0: 46 69 6c 65 29 20 2b 20 6e 4e 61 6d 65 20 2b 20  File) + nName + 
2de0: 31 20 29 3b 0a 20 20 20 20 69 66 28 20 70 46 69  1 );.    if( pFi
2df0: 6c 65 20 29 7b 0a 20 20 20 20 20 20 6d 65 6d 73  le ){.      mems
2e00: 65 74 28 70 46 69 6c 65 2c 20 30 2c 20 73 69 7a  et(pFile, 0, siz
2e10: 65 6f 66 28 2a 70 46 69 6c 65 29 29 3b 0a 20 20  eof(*pFile));.  
2e20: 20 20 20 20 70 46 69 6c 65 2d 3e 7a 46 69 6c 65      pFile->zFile
2e30: 6e 61 6d 65 20 3d 20 28 63 68 61 72 2a 29 26 70  name = (char*)&p
2e40: 46 69 6c 65 5b 31 5d 3b 0a 20 20 20 20 20 20 6d  File[1];.      m
2e50: 65 6d 63 70 79 28 70 46 69 6c 65 2d 3e 7a 46 69  emcpy(pFile->zFi
2e60: 6c 65 6e 61 6d 65 2c 20 7a 4e 61 6d 65 2c 20 6e  lename, zName, n
2e70: 4e 61 6d 65 2b 31 29 3b 0a 20 20 20 20 20 20 70  Name+1);.      p
2e80: 46 69 6c 65 2d 3e 70 4e 65 78 74 20 3d 20 70 47  File->pNext = pG
2e90: 72 6f 75 70 2d 3e 70 46 69 6c 65 73 3b 0a 20 20  roup->pFiles;.  
2ea0: 20 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e      if( pGroup->
2eb0: 70 46 69 6c 65 73 20 29 20 70 47 72 6f 75 70 2d  pFiles ) pGroup-
2ec0: 3e 70 46 69 6c 65 73 2d 3e 70 70 50 72 65 76 20  >pFiles->ppPrev 
2ed0: 3d 20 26 70 46 69 6c 65 2d 3e 70 4e 65 78 74 3b  = &pFile->pNext;
2ee0: 0a 20 20 20 20 20 20 70 46 69 6c 65 2d 3e 70 70  .      pFile->pp
2ef0: 50 72 65 76 20 3d 20 26 70 47 72 6f 75 70 2d 3e  Prev = &pGroup->
2f00: 70 46 69 6c 65 73 3b 0a 20 20 20 20 20 20 70 47  pFiles;.      pG
2f10: 72 6f 75 70 2d 3e 70 46 69 6c 65 73 20 3d 20 70  roup->pFiles = p
2f20: 46 69 6c 65 3b 0a 20 20 20 20 20 20 70 46 69 6c  File;.      pFil
2f30: 65 2d 3e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f  e->pGroup = pGro
2f40: 75 70 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  up;.    }.  }.  
2f50: 72 65 74 75 72 6e 20 70 46 69 6c 65 3b 0a 7d 0a  return pFile;.}.
2f60: 2f 2a 0a 2a 2a 20 54 72 61 6e 73 6c 61 74 65 20  /*.** Translate 
2f70: 55 54 46 38 20 74 6f 20 4d 42 43 53 20 66 6f 72  UTF8 to MBCS for
2f80: 20 75 73 65 20 69 6e 20 66 6f 70 65 6e 28 29 20   use in fopen() 
2f90: 63 61 6c 6c 73 2e 20 20 52 65 74 75 72 6e 20 61  calls.  Return a
2fa0: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 0a   pointer to the.
2fb0: 2a 2a 20 74 72 61 6e 73 6c 61 74 65 64 20 74 65  ** translated te
2fc0: 78 74 2e 2e 20 20 43 61 6c 6c 20 71 75 6f 74 61  xt..  Call quota
2fd0: 5f 6d 62 63 73 5f 66 72 65 65 28 29 20 74 6f 20  _mbcs_free() to 
2fe0: 64 65 61 6c 6c 6f 63 61 74 65 20 61 6e 79 20 6d  deallocate any m
2ff0: 65 6d 6f 72 79 0a 2a 2a 20 75 73 65 64 20 74 6f  emory.** used to
3000: 20 73 74 6f 72 65 20 74 68 65 20 72 65 74 75 72   store the retur
3010: 6e 65 64 20 70 6f 69 6e 74 65 72 20 77 68 65 6e  ned pointer when
3020: 20 64 6f 6e 65 2e 0a 2a 2f 0a 73 74 61 74 69 63   done..*/.static
3030: 20 63 68 61 72 20 2a 71 75 6f 74 61 5f 75 74 66   char *quota_utf
3040: 38 5f 74 6f 5f 6d 62 63 73 28 63 6f 6e 73 74 20  8_to_mbcs(const 
3050: 63 68 61 72 20 2a 7a 55 74 66 38 29 7b 0a 23 69  char *zUtf8){.#i
3060: 66 20 53 51 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a  f SQLITE_OS_WIN.
3070: 20 20 73 69 7a 65 5f 74 20 6e 3b 20 20 20 20 20    size_t n;     
3080: 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 69 6e       /* Bytes in
3090: 20 7a 55 74 66 38 20 2a 2f 0a 20 20 69 6e 74 20   zUtf8 */.  int 
30a0: 6e 57 69 64 65 3b 20 20 20 20 20 20 20 20 20 2f  nWide;         /
30b0: 2a 20 6e 75 6d 62 65 72 20 6f 66 20 55 54 46 2d  * number of UTF-
30c0: 31 36 20 63 68 61 72 61 63 74 65 72 73 20 2a 2f  16 characters */
30d0: 0a 20 20 69 6e 74 20 6e 4d 62 63 73 3b 20 20 20  .  int nMbcs;   
30e0: 20 20 20 20 20 20 2f 2a 20 42 79 74 65 73 20 6f        /* Bytes o
30f0: 66 20 4d 42 43 53 20 2a 2f 0a 20 20 4c 50 57 53  f MBCS */.  LPWS
3100: 54 52 20 7a 54 6d 70 57 69 64 65 3b 20 20 20 2f  TR zTmpWide;   /
3110: 2a 20 54 68 65 20 55 54 46 31 36 20 74 65 78 74  * The UTF16 text
3120: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 4d 62 63   */.  char *zMbc
3130: 73 3b 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20  s;       /* The 
3140: 4d 42 43 53 20 74 65 78 74 20 2a 2f 0a 20 20 69  MBCS text */.  i
3150: 6e 74 20 63 6f 64 65 70 61 67 65 3b 20 20 20 20  nt codepage;    
3160: 20 20 2f 2a 20 43 6f 64 65 20 70 61 67 65 20 75    /* Code page u
3170: 73 65 64 20 62 79 20 66 6f 70 65 6e 28 29 20 2a  sed by fopen() *
3180: 2f 0a 0a 20 20 6e 20 3d 20 73 74 72 6c 65 6e 28  /..  n = strlen(
3190: 7a 55 74 66 38 29 3b 0a 20 20 6e 57 69 64 65 20  zUtf8);.  nWide 
31a0: 3d 20 4d 75 6c 74 69 42 79 74 65 54 6f 57 69 64  = MultiByteToWid
31b0: 65 43 68 61 72 28 43 50 5f 55 54 46 38 2c 20 30  eChar(CP_UTF8, 0
31c0: 2c 20 7a 55 74 66 38 2c 20 2d 31 2c 20 4e 55 4c  , zUtf8, -1, NUL
31d0: 4c 2c 20 30 29 3b 0a 20 20 69 66 28 20 6e 57 69  L, 0);.  if( nWi
31e0: 64 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  de==0 ) return 0
31f0: 3b 0a 20 20 7a 54 6d 70 57 69 64 65 20 3d 20 28  ;.  zTmpWide = (
3200: 4c 50 57 53 54 52 29 73 71 6c 69 74 65 33 5f 6d  LPWSTR)sqlite3_m
3210: 61 6c 6c 6f 63 28 20 28 6e 57 69 64 65 2b 31 29  alloc( (nWide+1)
3220: 2a 73 69 7a 65 6f 66 28 7a 54 6d 70 57 69 64 65  *sizeof(zTmpWide
3230: 5b 30 5d 29 20 29 3b 0a 20 20 69 66 28 20 7a 54  [0]) );.  if( zT
3240: 6d 70 57 69 64 65 3d 3d 30 20 29 20 72 65 74 75  mpWide==0 ) retu
3250: 72 6e 20 30 3b 0a 20 20 4d 75 6c 74 69 42 79 74  rn 0;.  MultiByt
3260: 65 54 6f 57 69 64 65 43 68 61 72 28 43 50 5f 55  eToWideChar(CP_U
3270: 54 46 38 2c 20 30 2c 20 7a 55 74 66 38 2c 20 2d  TF8, 0, zUtf8, -
3280: 31 2c 20 7a 54 6d 70 57 69 64 65 2c 20 6e 57 69  1, zTmpWide, nWi
3290: 64 65 29 3b 0a 20 20 63 6f 64 65 70 61 67 65 20  de);.  codepage 
32a0: 3d 20 41 72 65 46 69 6c 65 41 70 69 73 41 4e 53  = AreFileApisANS
32b0: 49 28 29 20 3f 20 43 50 5f 41 43 50 20 3a 20 43  I() ? CP_ACP : C
32c0: 50 5f 4f 45 4d 43 50 3b 0a 20 20 6e 4d 62 63 73  P_OEMCP;.  nMbcs
32d0: 20 3d 20 57 69 64 65 43 68 61 72 54 6f 4d 75 6c   = WideCharToMul
32e0: 74 69 42 79 74 65 28 63 6f 64 65 70 61 67 65 2c  tiByte(codepage,
32f0: 20 30 2c 20 7a 54 6d 70 57 69 64 65 2c 20 6e 57   0, zTmpWide, nW
3300: 69 64 65 2c 20 30 2c 20 30 2c 20 30 2c 20 30 29  ide, 0, 0, 0, 0)
3310: 3b 0a 20 20 7a 4d 62 63 73 20 3d 20 6e 4d 62 63  ;.  zMbcs = nMbc
3320: 73 20 3f 20 28 63 68 61 72 2a 29 73 71 6c 69 74  s ? (char*)sqlit
3330: 65 33 5f 6d 61 6c 6c 6f 63 28 20 6e 4d 62 63 73  e3_malloc( nMbcs
3340: 2b 31 20 29 20 3a 20 30 3b 0a 20 20 69 66 28 20  +1 ) : 0;.  if( 
3350: 7a 4d 62 63 73 20 29 7b 0a 20 20 20 20 57 69 64  zMbcs ){.    Wid
3360: 65 43 68 61 72 54 6f 4d 75 6c 74 69 42 79 74 65  eCharToMultiByte
3370: 28 63 6f 64 65 70 61 67 65 2c 20 30 2c 20 7a 54  (codepage, 0, zT
3380: 6d 70 57 69 64 65 2c 20 6e 57 69 64 65 2c 20 7a  mpWide, nWide, z
3390: 4d 62 63 73 2c 20 6e 4d 62 63 73 2c 20 30 2c 20  Mbcs, nMbcs, 0, 
33a0: 30 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74 65  0);.  }.  sqlite
33b0: 33 5f 66 72 65 65 28 7a 54 6d 70 57 69 64 65 29  3_free(zTmpWide)
33c0: 3b 0a 20 20 72 65 74 75 72 6e 20 7a 4d 62 63 73  ;.  return zMbcs
33d0: 3b 0a 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e  ;.#else.  return
33e0: 20 28 63 68 61 72 2a 29 7a 55 74 66 38 3b 20 20   (char*)zUtf8;  
33f0: 2f 2a 20 4e 6f 2d 6f 70 20 6f 6e 20 75 6e 69 78  /* No-op on unix
3400: 20 2a 2f 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a   */.#endif.}../*
3410: 0a 2a 2a 20 44 65 61 6c 6c 6f 63 61 74 65 20 61  .** Deallocate a
3420: 6e 79 20 6d 65 6d 6f 72 79 20 61 6c 6c 6f 63 61  ny memory alloca
3430: 74 65 64 20 62 79 20 71 75 6f 74 61 5f 75 74 66  ted by quota_utf
3440: 38 5f 74 6f 5f 6d 62 63 73 28 29 2e 0a 2a 2f 0a  8_to_mbcs()..*/.
3450: 73 74 61 74 69 63 20 76 6f 69 64 20 71 75 6f 74  static void quot
3460: 61 5f 6d 62 63 73 5f 66 72 65 65 28 63 68 61 72  a_mbcs_free(char
3470: 20 2a 7a 4f 6c 64 29 7b 0a 23 69 66 20 53 51 4c   *zOld){.#if SQL
3480: 49 54 45 5f 4f 53 5f 57 49 4e 0a 20 20 73 71 6c  ITE_OS_WIN.  sql
3490: 69 74 65 33 5f 66 72 65 65 28 7a 4f 6c 64 29 3b  ite3_free(zOld);
34a0: 0a 23 65 6c 73 65 0a 20 20 2f 2a 20 4e 6f 2d 6f  .#else.  /* No-o
34b0: 70 20 6f 6e 20 75 6e 69 78 20 2a 2f 0a 23 65 6e  p on unix */.#en
34c0: 64 69 66 0a 7d 0a 0a 2f 2a 2a 2a 2a 2a 2a 2a 2a  dif.}../********
34d0: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
34e0: 2a 20 56 46 53 20 4d 65 74 68 6f 64 20 57 72 61  * VFS Method Wra
34f0: 70 70 65 72 73 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ppers **********
3500: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
3510: 2a 2a 2a 2f 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ***/./*.** This 
3520: 69 73 20 74 68 65 20 78 4f 70 65 6e 20 6d 65 74  is the xOpen met
3530: 68 6f 64 20 75 73 65 64 20 66 6f 72 20 74 68 65  hod used for the
3540: 20 22 71 75 6f 74 61 22 20 56 46 53 2e 0a 2a 2a   "quota" VFS..**
3550: 0a 2a 2a 20 4d 6f 73 74 20 6f 66 20 74 68 65 20  .** Most of the 
3560: 77 6f 72 6b 20 69 73 20 64 6f 6e 65 20 62 79 20  work is done by 
3570: 74 68 65 20 75 6e 64 65 72 6c 79 69 6e 67 20 6f  the underlying o
3580: 72 69 67 69 6e 61 6c 20 56 46 53 2e 20 20 54 68  riginal VFS.  Th
3590: 69 73 20 6d 65 74 68 6f 64 0a 2a 2a 20 73 69 6d  is method.** sim
35a0: 70 6c 79 20 6c 69 6e 6b 73 20 74 68 65 20 6e 65  ply links the ne
35b0: 77 20 66 69 6c 65 20 69 6e 74 6f 20 74 68 65 20  w file into the 
35c0: 61 70 70 72 6f 70 72 69 61 74 65 20 71 75 6f 74  appropriate quot
35d0: 61 20 67 72 6f 75 70 20 69 66 20 69 74 20 69 73  a group if it is
35e0: 20 61 0a 2a 2a 20 66 69 6c 65 20 74 68 61 74 20   a.** file that 
35f0: 6e 65 65 64 73 20 74 6f 20 62 65 20 74 72 61 63  needs to be trac
3600: 6b 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ked..*/.static i
3610: 6e 74 20 71 75 6f 74 61 4f 70 65 6e 28 0a 20 20  nt quotaOpen(.  
3620: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
3630: 73 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54  s,          /* T
3640: 68 65 20 71 75 6f 74 61 20 56 46 53 20 2a 2f 0a  he quota VFS */.
3650: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
3660: 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 2f 2a  ame,          /*
3670: 20 4e 61 6d 65 20 6f 66 20 66 69 6c 65 20 74 6f   Name of file to
3680: 20 62 65 20 6f 70 65 6e 65 64 20 2a 2f 0a 20 20   be opened */.  
3690: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
36a0: 6f 6e 6e 2c 20 20 20 20 20 20 20 20 2f 2a 20 46  onn,        /* F
36b0: 69 6c 6c 20 69 6e 20 74 68 69 73 20 66 69 6c 65  ill in this file
36c0: 20 64 65 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20   descriptor */. 
36d0: 20 69 6e 74 20 66 6c 61 67 73 2c 20 20 20 20 20   int flags,     
36e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
36f0: 46 6c 61 67 73 20 74 6f 20 63 6f 6e 74 72 6f 6c  Flags to control
3700: 20 74 68 65 20 6f 70 65 6e 69 6e 67 20 2a 2f 0a   the opening */.
3710: 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67 73    int *pOutFlags
3720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3730: 20 46 6c 61 67 73 20 73 68 6f 77 69 6e 67 20 72   Flags showing r
3740: 65 73 75 6c 74 73 20 6f 66 20 6f 70 65 6e 69 6e  esults of openin
3750: 67 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20 72 63  g */.){.  int rc
3760: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
3770: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3780: 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74 20 63       /* Result c
3790: 6f 64 65 20 2a 2f 0a 20 20 71 75 6f 74 61 43 6f  ode */.  quotaCo
37a0: 6e 6e 20 2a 70 51 75 6f 74 61 4f 70 65 6e 3b 20  nn *pQuotaOpen; 
37b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
37c0: 20 20 20 20 2f 2a 20 54 68 65 20 6e 65 77 20 71      /* The new q
37d0: 75 6f 74 61 20 66 69 6c 65 20 64 65 73 63 72 69  uota file descri
37e0: 70 74 6f 72 20 2a 2f 0a 20 20 71 75 6f 74 61 46  ptor */.  quotaF
37f0: 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20  ile *pFile;     
3800: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3810: 20 20 20 20 20 2f 2a 20 43 6f 72 72 65 73 70 6f       /* Correspo
3820: 6e 64 69 6e 67 20 71 75 6f 74 61 46 69 6c 65 20  nding quotaFile 
3830: 6f 62 6a 20 2a 2f 0a 20 20 71 75 6f 74 61 47 72  obj */.  quotaGr
3840: 6f 75 70 20 2a 70 47 72 6f 75 70 3b 20 20 20 20  oup *pGroup;    
3850: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3860: 20 20 20 20 2f 2a 20 54 68 65 20 67 72 6f 75 70      /* The group
3870: 20 66 69 6c 65 20 62 65 6c 6f 6e 67 73 20 74 6f   file belongs to
3880: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 66 69   */.  sqlite3_fi
3890: 6c 65 20 2a 70 53 75 62 4f 70 65 6e 3b 20 20 20  le *pSubOpen;   
38a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
38b0: 20 2f 2a 20 52 65 61 6c 20 66 69 6c 65 20 64 65   /* Real file de
38c0: 73 63 72 69 70 74 6f 72 20 2a 2f 0a 20 20 73 71  scriptor */.  sq
38d0: 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69 67  lite3_vfs *pOrig
38e0: 56 66 73 20 3d 20 67 51 75 6f 74 61 2e 70 4f 72  Vfs = gQuota.pOr
38f0: 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61 6c  igVfs;   /* Real
3900: 20 56 46 53 20 2a 2f 0a 0a 20 20 2f 2a 20 49 66   VFS */..  /* If
3910: 20 74 68 65 20 66 69 6c 65 20 69 73 20 6e 6f 74   the file is not
3920: 20 61 20 6d 61 69 6e 20 64 61 74 61 62 61 73 65   a main database
3930: 20 66 69 6c 65 20 6f 72 20 61 20 57 41 4c 2c 20   file or a WAL, 
3940: 74 68 65 6e 20 75 73 65 20 74 68 65 0a 20 20 2a  then use the.  *
3950: 2a 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20 6d  * normal xOpen m
3960: 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 69 66  ethod..  */.  if
3970: 28 20 28 66 6c 61 67 73 20 26 20 28 53 51 4c 49  ( (flags & (SQLI
3980: 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44 42 7c  TE_OPEN_MAIN_DB|
3990: 53 51 4c 49 54 45 5f 4f 50 45 4e 5f 57 41 4c 29  SQLITE_OPEN_WAL)
39a0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  )==0 ){.    retu
39b0: 72 6e 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f 70  rn pOrigVfs->xOp
39c0: 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61  en(pOrigVfs, zNa
39d0: 6d 65 2c 20 70 43 6f 6e 6e 2c 20 66 6c 61 67 73  me, pConn, flags
39e0: 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20  , pOutFlags);.  
39f0: 7d 0a 0a 20 20 2f 2a 20 49 66 20 74 68 65 20 6e  }..  /* If the n
3a00: 61 6d 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20  ame of the file 
3a10: 64 6f 65 73 20 6e 6f 74 20 6d 61 74 63 68 20 61  does not match a
3a20: 6e 79 20 71 75 6f 74 61 20 67 72 6f 75 70 2c 20  ny quota group, 
3a30: 74 68 65 6e 0a 20 20 2a 2a 20 75 73 65 20 74 68  then.  ** use th
3a40: 65 20 6e 6f 72 6d 61 6c 20 78 4f 70 65 6e 20 6d  e normal xOpen m
3a50: 65 74 68 6f 64 2e 0a 20 20 2a 2f 0a 20 20 71 75  ethod..  */.  qu
3a60: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70 47  otaEnter();.  pG
3a70: 72 6f 75 70 20 3d 20 71 75 6f 74 61 47 72 6f 75  roup = quotaGrou
3a80: 70 46 69 6e 64 28 7a 4e 61 6d 65 29 3b 0a 20 20  pFind(zName);.  
3a90: 69 66 28 20 70 47 72 6f 75 70 3d 3d 30 20 29 7b  if( pGroup==0 ){
3aa0: 0a 20 20 20 20 72 63 20 3d 20 70 4f 72 69 67 56  .    rc = pOrigV
3ab0: 66 73 2d 3e 78 4f 70 65 6e 28 70 4f 72 69 67 56  fs->xOpen(pOrigV
3ac0: 66 73 2c 20 7a 4e 61 6d 65 2c 20 70 43 6f 6e 6e  fs, zName, pConn
3ad0: 2c 20 66 6c 61 67 73 2c 20 70 4f 75 74 46 6c 61  , flags, pOutFla
3ae0: 67 73 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  gs);.  }else{.  
3af0: 20 20 2f 2a 20 49 66 20 77 65 20 67 65 74 20 74    /* If we get t
3b00: 6f 20 74 68 69 73 20 70 6f 69 6e 74 2c 20 69 74  o this point, it
3b10: 20 6d 65 61 6e 73 20 74 68 65 20 66 69 6c 65 20   means the file 
3b20: 6e 65 65 64 73 20 74 6f 20 62 65 20 71 75 6f 74  needs to be quot
3b30: 61 20 74 72 61 63 6b 65 64 2e 0a 20 20 20 20 2a  a tracked..    *
3b40: 2f 0a 20 20 20 20 70 51 75 6f 74 61 4f 70 65 6e  /.    pQuotaOpen
3b50: 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a 29 70   = (quotaConn*)p
3b60: 43 6f 6e 6e 3b 0a 20 20 20 20 70 53 75 62 4f 70  Conn;.    pSubOp
3b70: 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65  en = quotaSubOpe
3b80: 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 20 20 72 63  n(pConn);.    rc
3b90: 20 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 4f 70   = pOrigVfs->xOp
3ba0: 65 6e 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e 61  en(pOrigVfs, zNa
3bb0: 6d 65 2c 20 70 53 75 62 4f 70 65 6e 2c 20 66 6c  me, pSubOpen, fl
3bc0: 61 67 73 2c 20 70 4f 75 74 46 6c 61 67 73 29 3b  ags, pOutFlags);
3bd0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
3be0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
3bf0: 70 46 69 6c 65 20 3d 20 71 75 6f 74 61 46 69 6e  pFile = quotaFin
3c00: 64 46 69 6c 65 28 70 47 72 6f 75 70 2c 20 7a 4e  dFile(pGroup, zN
3c10: 61 6d 65 2c 20 31 29 3b 0a 20 20 20 20 20 20 69  ame, 1);.      i
3c20: 66 28 20 70 46 69 6c 65 3d 3d 30 20 29 7b 0a 20  f( pFile==0 ){. 
3c30: 20 20 20 20 20 20 20 71 75 6f 74 61 4c 65 61 76         quotaLeav
3c40: 65 28 29 3b 0a 20 20 20 20 20 20 20 20 70 53 75  e();.        pSu
3c50: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
3c60: 3e 78 43 6c 6f 73 65 28 70 53 75 62 4f 70 65 6e  >xClose(pSubOpen
3c70: 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  );.        retur
3c80: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
3c90: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 70 46        }.      pF
3ca0: 69 6c 65 2d 3e 64 65 6c 65 74 65 4f 6e 43 6c 6f  ile->deleteOnClo
3cb0: 73 65 20 3d 20 28 66 6c 61 67 73 20 26 20 53 51  se = (flags & SQ
3cc0: 4c 49 54 45 5f 4f 50 45 4e 5f 44 45 4c 45 54 45  LITE_OPEN_DELETE
3cd0: 4f 4e 43 4c 4f 53 45 29 21 3d 30 3b 0a 20 20 20  ONCLOSE)!=0;.   
3ce0: 20 20 20 70 46 69 6c 65 2d 3e 6e 52 65 66 2b 2b     pFile->nRef++
3cf0: 3b 0a 20 20 20 20 20 20 70 51 75 6f 74 61 4f 70  ;.      pQuotaOp
3d00: 65 6e 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69 6c  en->pFile = pFil
3d10: 65 3b 0a 20 20 20 20 20 20 69 66 28 20 70 53 75  e;.      if( pSu
3d20: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
3d30: 3e 69 56 65 72 73 69 6f 6e 3d 3d 31 20 29 7b 0a  >iVersion==1 ){.
3d40: 20 20 20 20 20 20 20 20 70 51 75 6f 74 61 4f 70          pQuotaOp
3d50: 65 6e 2d 3e 62 61 73 65 2e 70 4d 65 74 68 6f 64  en->base.pMethod
3d60: 73 20 3d 20 26 67 51 75 6f 74 61 2e 73 49 6f 4d  s = &gQuota.sIoM
3d70: 65 74 68 6f 64 73 56 31 3b 0a 20 20 20 20 20 20  ethodsV1;.      
3d80: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70  }else{.        p
3d90: 51 75 6f 74 61 4f 70 65 6e 2d 3e 62 61 73 65 2e  QuotaOpen->base.
3da0: 70 4d 65 74 68 6f 64 73 20 3d 20 26 67 51 75 6f  pMethods = &gQuo
3db0: 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 3b  ta.sIoMethodsV2;
3dc0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3dd0: 20 7d 0a 20 20 71 75 6f 74 61 4c 65 61 76 65 28   }.  quotaLeave(
3de0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
3df0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73  }../*.** This is
3e00: 20 74 68 65 20 78 44 65 6c 65 74 65 20 6d 65 74   the xDelete met
3e10: 68 6f 64 20 75 73 65 64 20 66 6f 72 20 74 68 65  hod used for the
3e20: 20 22 71 75 6f 74 61 22 20 56 46 53 2e 0a 2a 2a   "quota" VFS..**
3e30: 0a 2a 2a 20 49 66 20 74 68 65 20 66 69 6c 65 20  .** If the file 
3e40: 62 65 69 6e 67 20 64 65 6c 65 74 65 64 20 69 73  being deleted is
3e50: 20 70 61 72 74 20 6f 66 20 74 68 65 20 71 75 6f   part of the quo
3e60: 74 61 20 67 72 6f 75 70 2c 20 74 68 65 6e 20 72  ta group, then r
3e70: 65 64 75 63 65 0a 2a 2a 20 74 68 65 20 73 69 7a  educe.** the siz
3e80: 65 20 6f 66 20 74 68 65 20 71 75 6f 74 61 20 67  e of the quota g
3e90: 72 6f 75 70 20 61 63 63 6f 72 64 69 6e 67 6c 79  roup accordingly
3ea0: 2e 20 20 41 6e 64 20 72 65 6d 6f 76 65 20 74 68  .  And remove th
3eb0: 65 20 66 69 6c 65 20 66 72 6f 6d 0a 2a 2a 20 74  e file from.** t
3ec0: 68 65 20 73 65 74 20 6f 66 20 66 69 6c 65 73 20  he set of files 
3ed0: 69 6e 20 74 68 65 20 71 75 6f 74 61 20 67 72 6f  in the quota gro
3ee0: 75 70 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  up..*/.static in
3ef0: 74 20 71 75 6f 74 61 44 65 6c 65 74 65 28 0a 20  t quotaDelete(. 
3f00: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
3f10: 66 73 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  fs,          /* 
3f20: 54 68 65 20 71 75 6f 74 61 20 56 46 53 20 2a 2f  The quota VFS */
3f30: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
3f40: 4e 61 6d 65 2c 20 20 20 20 20 20 20 20 20 20 2f  Name,          /
3f50: 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c 65 20 74  * Name of file t
3f60: 6f 20 62 65 20 64 65 6c 65 74 65 64 20 2a 2f 0a  o be deleted */.
3f70: 20 20 69 6e 74 20 73 79 6e 63 44 69 72 20 20 20    int syncDir   
3f80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3f90: 20 44 6f 20 61 20 64 69 72 65 63 74 6f 72 79 20   Do a directory 
3fa0: 73 79 6e 63 20 61 66 74 65 72 20 64 65 6c 65 74  sync after delet
3fb0: 69 6e 67 20 2a 2f 0a 29 7b 0a 20 20 69 6e 74 20  ing */.){.  int 
3fc0: 72 63 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  rc;             
3fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3fe0: 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75 6c 74         /* Result
3ff0: 20 63 6f 64 65 20 2a 2f 0a 20 20 71 75 6f 74 61   code */.  quota
4000: 46 69 6c 65 20 2a 70 46 69 6c 65 3b 20 20 20 20  File *pFile;    
4010: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4020: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 73 20 69        /* Files i
4030: 6e 20 74 68 65 20 71 75 6f 74 61 20 2a 2f 0a 20  n the quota */. 
4040: 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72   quotaGroup *pGr
4050: 6f 75 70 3b 20 20 20 20 20 20 20 20 20 20 20 20  oup;            
4060: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
4070: 68 65 20 67 72 6f 75 70 20 66 69 6c 65 20 62 65  he group file be
4080: 6c 6f 6e 67 73 20 74 6f 20 2a 2f 0a 20 20 73 71  longs to */.  sq
4090: 6c 69 74 65 33 5f 76 66 73 20 2a 70 4f 72 69 67  lite3_vfs *pOrig
40a0: 56 66 73 20 3d 20 67 51 75 6f 74 61 2e 70 4f 72  Vfs = gQuota.pOr
40b0: 69 67 56 66 73 3b 20 20 20 2f 2a 20 52 65 61 6c  igVfs;   /* Real
40c0: 20 56 46 53 20 2a 2f 0a 0a 20 20 2f 2a 20 44 6f   VFS */..  /* Do
40d0: 20 74 68 65 20 61 63 74 75 61 6c 20 66 69 6c 65   the actual file
40e0: 20 64 65 6c 65 74 65 20 2a 2f 0a 20 20 72 63 20   delete */.  rc 
40f0: 3d 20 70 4f 72 69 67 56 66 73 2d 3e 78 44 65 6c  = pOrigVfs->xDel
4100: 65 74 65 28 70 4f 72 69 67 56 66 73 2c 20 7a 4e  ete(pOrigVfs, zN
4110: 61 6d 65 2c 20 73 79 6e 63 44 69 72 29 3b 0a 0a  ame, syncDir);..
4120: 20 20 2f 2a 20 49 66 20 74 68 65 20 66 69 6c 65    /* If the file
4130: 20 6a 75 73 74 20 64 65 6c 65 74 65 64 20 69 73   just deleted is
4140: 20 61 20 6d 65 6d 62 65 72 20 6f 66 20 61 20 71   a member of a q
4150: 75 6f 74 61 20 67 72 6f 75 70 2c 20 74 68 65 6e  uota group, then
4160: 20 72 65 6d 6f 76 65 0a 20 20 2a 2a 20 69 74 20   remove.  ** it 
4170: 66 72 6f 6d 20 74 68 61 74 20 71 75 6f 74 61 20  from that quota 
4180: 67 72 6f 75 70 2e 0a 20 20 2a 2f 0a 20 20 69 66  group..  */.  if
4190: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
41a0: 29 7b 0a 20 20 20 20 71 75 6f 74 61 45 6e 74 65  ){.    quotaEnte
41b0: 72 28 29 3b 0a 20 20 20 20 70 47 72 6f 75 70 20  r();.    pGroup 
41c0: 3d 20 71 75 6f 74 61 47 72 6f 75 70 46 69 6e 64  = quotaGroupFind
41d0: 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  (zName);.    if(
41e0: 20 70 47 72 6f 75 70 20 29 7b 0a 20 20 20 20 20   pGroup ){.     
41f0: 20 70 46 69 6c 65 20 3d 20 71 75 6f 74 61 46 69   pFile = quotaFi
4200: 6e 64 46 69 6c 65 28 70 47 72 6f 75 70 2c 20 7a  ndFile(pGroup, z
4210: 4e 61 6d 65 2c 20 30 29 3b 0a 20 20 20 20 20 20  Name, 0);.      
4220: 69 66 28 20 70 46 69 6c 65 20 29 7b 0a 20 20 20  if( pFile ){.   
4230: 20 20 20 20 20 69 66 28 20 70 46 69 6c 65 2d 3e       if( pFile->
4240: 6e 52 65 66 20 29 7b 0a 20 20 20 20 20 20 20 20  nRef ){.        
4250: 20 20 70 46 69 6c 65 2d 3e 64 65 6c 65 74 65 4f    pFile->deleteO
4260: 6e 43 6c 6f 73 65 20 3d 20 31 3b 0a 20 20 20 20  nClose = 1;.    
4270: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4280: 20 20 20 20 20 71 75 6f 74 61 52 65 6d 6f 76 65       quotaRemove
4290: 46 69 6c 65 28 70 46 69 6c 65 29 3b 0a 20 20 20  File(pFile);.   
42a0: 20 20 20 20 20 20 20 71 75 6f 74 61 47 72 6f 75         quotaGrou
42b0: 70 44 65 72 65 66 28 70 47 72 6f 75 70 29 3b 0a  pDeref(pGroup);.
42c0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
42d0: 7d 0a 20 20 20 20 7d 0a 20 20 20 20 71 75 6f 74  }.    }.    quot
42e0: 61 4c 65 61 76 65 28 29 3b 0a 20 20 7d 0a 20 20  aLeave();.  }.  
42f0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 0a 2f  return rc;.}.../
4300: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4310: 2a 2a 2a 2a 2a 2a 2a 2a 20 49 2f 4f 20 4d 65 74  ******** I/O Met
4320: 68 6f 64 20 57 72 61 70 70 65 72 73 20 2a 2a 2a  hod Wrappers ***
4330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
4340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 0a 2f  ************/../
4350: 2a 20 78 43 6c 6f 73 65 20 72 65 71 75 65 73 74  * xClose request
4360: 73 20 67 65 74 20 70 61 73 73 65 64 20 74 68 72  s get passed thr
4370: 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67  ough to the orig
4380: 69 6e 61 6c 20 56 46 53 2e 20 20 42 75 74 20 77  inal VFS.  But w
4390: 65 0a 2a 2a 20 61 6c 73 6f 20 68 61 76 65 20 74  e.** also have t
43a0: 6f 20 75 6e 6c 69 6e 6b 20 74 68 65 20 71 75 6f  o unlink the quo
43b0: 74 61 43 6f 6e 6e 20 66 72 6f 6d 20 74 68 65 20  taConn from the 
43c0: 71 75 6f 74 61 46 69 6c 65 20 61 6e 64 20 71 75  quotaFile and qu
43d0: 6f 74 61 47 72 6f 75 70 2e 0a 2a 2a 20 54 68 65  otaGroup..** The
43e0: 20 71 75 6f 74 61 46 69 6c 65 20 61 6e 64 2f 6f   quotaFile and/o
43f0: 72 20 71 75 6f 74 61 47 72 6f 75 70 20 61 72 65  r quotaGroup are
4400: 20 66 72 65 65 64 20 69 66 20 74 68 65 79 20 61   freed if they a
4410: 72 65 20 6e 6f 20 6c 6f 6e 67 65 72 20 69 6e 20  re no longer in 
4420: 75 73 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  use..*/.static i
4430: 6e 74 20 71 75 6f 74 61 43 6c 6f 73 65 28 73 71  nt quotaClose(sq
4440: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e  lite3_file *pCon
4450: 6e 29 7b 0a 20 20 71 75 6f 74 61 43 6f 6e 6e 20  n){.  quotaConn 
4460: 2a 70 20 3d 20 28 71 75 6f 74 61 43 6f 6e 6e 2a  *p = (quotaConn*
4470: 29 70 43 6f 6e 6e 3b 0a 20 20 71 75 6f 74 61 46  )pConn;.  quotaF
4480: 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70 2d 3e  ile *pFile = p->
4490: 70 46 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33  pFile;.  sqlite3
44a0: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
44b0: 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70  = quotaSubOpen(p
44c0: 43 6f 6e 6e 29 3b 0a 20 20 69 6e 74 20 72 63 3b  Conn);.  int rc;
44d0: 0a 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e  .  rc = pSubOpen
44e0: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f  ->pMethods->xClo
44f0: 73 65 28 70 53 75 62 4f 70 65 6e 29 3b 0a 20 20  se(pSubOpen);.  
4500: 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20  quotaEnter();.  
4510: 70 46 69 6c 65 2d 3e 6e 52 65 66 2d 2d 3b 0a 20  pFile->nRef--;. 
4520: 20 69 66 28 20 70 46 69 6c 65 2d 3e 6e 52 65 66   if( pFile->nRef
4530: 3d 3d 30 20 29 7b 0a 20 20 20 20 71 75 6f 74 61  ==0 ){.    quota
4540: 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 20 3d 20  Group *pGroup = 
4550: 70 46 69 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a 20  pFile->pGroup;. 
4560: 20 20 20 69 66 28 20 70 46 69 6c 65 2d 3e 64 65     if( pFile->de
4570: 6c 65 74 65 4f 6e 43 6c 6f 73 65 20 29 7b 0a 20  leteOnClose ){. 
4580: 20 20 20 20 20 67 51 75 6f 74 61 2e 70 4f 72 69       gQuota.pOri
4590: 67 56 66 73 2d 3e 78 44 65 6c 65 74 65 28 67 51  gVfs->xDelete(gQ
45a0: 75 6f 74 61 2e 70 4f 72 69 67 56 66 73 2c 20 70  uota.pOrigVfs, p
45b0: 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c  File->zFilename,
45c0: 20 30 29 3b 0a 20 20 20 20 20 20 71 75 6f 74 61   0);.      quota
45d0: 52 65 6d 6f 76 65 46 69 6c 65 28 70 46 69 6c 65  RemoveFile(pFile
45e0: 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 71 75 6f  );.    }.    quo
45f0: 74 61 47 72 6f 75 70 44 65 72 65 66 28 70 47 72  taGroupDeref(pGr
4600: 6f 75 70 29 3b 0a 20 20 7d 0a 20 20 71 75 6f 74  oup);.  }.  quot
4610: 61 4c 65 61 76 65 28 29 3b 0a 20 20 72 65 74 75  aLeave();.  retu
4620: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 20 50 61 73  rn rc;.}../* Pas
4630: 73 20 78 52 65 61 64 20 72 65 71 75 65 73 74 73  s xRead requests
4640: 20 64 69 72 65 63 74 6f 72 79 20 74 68 72 75 20   directory thru 
4650: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
4660: 56 46 53 20 77 69 74 68 6f 75 74 0a 2a 2a 20 66  VFS without.** f
4670: 75 72 74 68 65 72 20 70 72 6f 63 65 73 73 69 6e  urther processin
4680: 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  g..*/.static int
4690: 20 71 75 6f 74 61 52 65 61 64 28 0a 20 20 73 71   quotaRead(.  sq
46a0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e  lite3_file *pCon
46b0: 6e 2c 0a 20 20 76 6f 69 64 20 2a 70 42 75 66 2c  n,.  void *pBuf,
46c0: 0a 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20 20 73  .  int iAmt,.  s
46d0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4f 66  qlite3_int64 iOf
46e0: 73 74 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  st.){.  sqlite3_
46f0: 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d  file *pSubOpen =
4700: 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43   quotaSubOpen(pC
4710: 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  onn);.  return p
4720: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
4730: 73 2d 3e 78 52 65 61 64 28 70 53 75 62 4f 70 65  s->xRead(pSubOpe
4740: 6e 2c 20 70 42 75 66 2c 20 69 41 6d 74 2c 20 69  n, pBuf, iAmt, i
4750: 4f 66 73 74 29 3b 0a 7d 0a 0a 2f 2a 20 43 68 65  Ofst);.}../* Che
4760: 63 6b 20 78 57 72 69 74 65 20 72 65 71 75 65 73  ck xWrite reques
4770: 74 73 20 74 6f 20 73 65 65 20 69 66 20 74 68 65  ts to see if the
4780: 79 20 65 78 70 61 6e 64 20 74 68 65 20 66 69 6c  y expand the fil
4790: 65 2e 20 20 49 66 20 74 68 65 79 20 64 6f 2c 0a  e.  If they do,.
47a0: 2a 2a 20 74 68 65 20 70 65 72 66 6f 72 6d 20 61  ** the perform a
47b0: 20 71 75 6f 74 61 20 63 68 65 63 6b 20 62 65 66   quota check bef
47c0: 6f 72 65 20 70 61 73 73 69 6e 67 20 74 68 65 6d  ore passing them
47d0: 20 74 68 72 6f 75 67 68 20 74 6f 20 74 68 65 0a   through to the.
47e0: 2a 2a 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 2e  ** original VFS.
47f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71  .*/.static int q
4800: 75 6f 74 61 57 72 69 74 65 28 0a 20 20 73 71 6c  uotaWrite(.  sql
4810: 69 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e  ite3_file *pConn
4820: 2c 0a 20 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a  ,.  const void *
4830: 70 42 75 66 2c 0a 20 20 69 6e 74 20 69 41 6d 74  pBuf,.  int iAmt
4840: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  ,.  sqlite3_int6
4850: 34 20 69 4f 66 73 74 0a 29 7b 0a 20 20 71 75 6f  4 iOfst.){.  quo
4860: 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f  taConn *p = (quo
4870: 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  taConn*)pConn;. 
4880: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
4890: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
48a0: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
48b0: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
48c0: 45 6e 64 20 3d 20 69 4f 66 73 74 2b 69 41 6d 74  End = iOfst+iAmt
48d0: 3b 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20 2a  ;.  quotaGroup *
48e0: 70 47 72 6f 75 70 3b 0a 20 20 71 75 6f 74 61 46  pGroup;.  quotaF
48f0: 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70 2d 3e  ile *pFile = p->
4900: 70 46 69 6c 65 3b 0a 20 20 73 71 6c 69 74 65 33  pFile;.  sqlite3
4910: 5f 69 6e 74 36 34 20 73 7a 4e 65 77 3b 0a 0a 20  _int64 szNew;.. 
4920: 20 69 66 28 20 70 46 69 6c 65 2d 3e 69 53 69 7a   if( pFile->iSiz
4930: 65 3c 69 45 6e 64 20 29 7b 0a 20 20 20 20 70 47  e<iEnd ){.    pG
4940: 72 6f 75 70 20 3d 20 70 46 69 6c 65 2d 3e 70 47  roup = pFile->pG
4950: 72 6f 75 70 3b 0a 20 20 20 20 71 75 6f 74 61 45  roup;.    quotaE
4960: 6e 74 65 72 28 29 3b 0a 20 20 20 20 73 7a 4e 65  nter();.    szNe
4970: 77 20 3d 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a  w = pGroup->iSiz
4980: 65 20 2d 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65  e - pFile->iSize
4990: 20 2b 20 69 45 6e 64 3b 0a 20 20 20 20 69 66 28   + iEnd;.    if(
49a0: 20 73 7a 4e 65 77 3e 70 47 72 6f 75 70 2d 3e 69   szNew>pGroup->i
49b0: 4c 69 6d 69 74 20 26 26 20 70 47 72 6f 75 70 2d  Limit && pGroup-
49c0: 3e 69 4c 69 6d 69 74 3e 30 20 29 7b 0a 20 20 20  >iLimit>0 ){.   
49d0: 20 20 20 69 66 28 20 70 47 72 6f 75 70 2d 3e 78     if( pGroup->x
49e0: 43 61 6c 6c 62 61 63 6b 20 29 7b 0a 20 20 20 20  Callback ){.    
49f0: 20 20 20 20 70 47 72 6f 75 70 2d 3e 78 43 61 6c      pGroup->xCal
4a00: 6c 62 61 63 6b 28 70 46 69 6c 65 2d 3e 7a 46 69  lback(pFile->zFi
4a10: 6c 65 6e 61 6d 65 2c 20 26 70 47 72 6f 75 70 2d  lename, &pGroup-
4a20: 3e 69 4c 69 6d 69 74 2c 20 73 7a 4e 65 77 2c 0a  >iLimit, szNew,.
4a30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4a40: 20 20 20 20 20 20 20 20 20 20 70 47 72 6f 75 70            pGroup
4a50: 2d 3e 70 41 72 67 29 3b 0a 20 20 20 20 20 20 7d  ->pArg);.      }
4a60: 0a 20 20 20 20 20 20 69 66 28 20 73 7a 4e 65 77  .      if( szNew
4a70: 3e 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 20  >pGroup->iLimit 
4a80: 26 26 20 70 47 72 6f 75 70 2d 3e 69 4c 69 6d 69  && pGroup->iLimi
4a90: 74 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 71  t>0 ){.        q
4aa0: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 20  uotaLeave();.   
4ab0: 20 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49       return SQLI
4ac0: 54 45 5f 46 55 4c 4c 3b 0a 20 20 20 20 20 20 7d  TE_FULL;.      }
4ad0: 0a 20 20 20 20 7d 0a 20 20 20 20 70 47 72 6f 75  .    }.    pGrou
4ae0: 70 2d 3e 69 53 69 7a 65 20 3d 20 73 7a 4e 65 77  p->iSize = szNew
4af0: 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e 69 53 69  ;.    pFile->iSi
4b00: 7a 65 20 3d 20 69 45 6e 64 3b 0a 20 20 20 20 71  ze = iEnd;.    q
4b10: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 7d  uotaLeave();.  }
4b20: 0a 20 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70  .  return pSubOp
4b30: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57  en->pMethods->xW
4b40: 72 69 74 65 28 70 53 75 62 4f 70 65 6e 2c 20 70  rite(pSubOpen, p
4b50: 42 75 66 2c 20 69 41 6d 74 2c 20 69 4f 66 73 74  Buf, iAmt, iOfst
4b60: 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 54  );.}../* Pass xT
4b70: 72 75 6e 63 61 74 65 20 72 65 71 75 65 73 74 73  runcate requests
4b80: 20 74 68 72 75 20 74 6f 20 74 68 65 20 6f 72 69   thru to the ori
4b90: 67 69 6e 61 6c 20 56 46 53 2e 20 20 49 66 20 74  ginal VFS.  If t
4ba0: 68 65 0a 2a 2a 20 73 75 63 63 65 73 73 2c 20 75  he.** success, u
4bb0: 70 64 61 74 65 20 74 68 65 20 66 69 6c 65 20 73  pdate the file s
4bc0: 69 7a 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ize..*/.static i
4bd0: 6e 74 20 71 75 6f 74 61 54 72 75 6e 63 61 74 65  nt quotaTruncate
4be0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
4bf0: 43 6f 6e 6e 2c 20 73 71 6c 69 74 65 33 5f 69 6e  Conn, sqlite3_in
4c00: 74 36 34 20 73 69 7a 65 29 7b 0a 20 20 71 75 6f  t64 size){.  quo
4c10: 74 61 43 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f  taConn *p = (quo
4c20: 74 61 43 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20  taConn*)pConn;. 
4c30: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
4c40: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
4c50: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
4c60: 20 69 6e 74 20 72 63 20 3d 20 70 53 75 62 4f 70   int rc = pSubOp
4c70: 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 54  en->pMethods->xT
4c80: 72 75 6e 63 61 74 65 28 70 53 75 62 4f 70 65 6e  runcate(pSubOpen
4c90: 2c 20 73 69 7a 65 29 3b 0a 20 20 71 75 6f 74 61  , size);.  quota
4ca0: 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d 20 70 2d  File *pFile = p-
4cb0: 3e 70 46 69 6c 65 3b 0a 20 20 71 75 6f 74 61 47  >pFile;.  quotaG
4cc0: 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20  roup *pGroup;.  
4cd0: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4ce0: 4b 20 29 7b 0a 20 20 20 20 71 75 6f 74 61 45 6e  K ){.    quotaEn
4cf0: 74 65 72 28 29 3b 0a 20 20 20 20 70 47 72 6f 75  ter();.    pGrou
4d00: 70 20 3d 20 70 46 69 6c 65 2d 3e 70 47 72 6f 75  p = pFile->pGrou
4d10: 70 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 69  p;.    pGroup->i
4d20: 53 69 7a 65 20 2d 3d 20 70 46 69 6c 65 2d 3e 69  Size -= pFile->i
4d30: 53 69 7a 65 3b 0a 20 20 20 20 70 46 69 6c 65 2d  Size;.    pFile-
4d40: 3e 69 53 69 7a 65 20 3d 20 73 69 7a 65 3b 0a 20  >iSize = size;. 
4d50: 20 20 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65     pGroup->iSize
4d60: 20 2b 3d 20 73 69 7a 65 3b 0a 20 20 20 20 71 75   += size;.    qu
4d70: 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 7d 0a  otaLeave();.  }.
4d80: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
4d90: 2f 2a 20 50 61 73 73 20 78 53 79 6e 63 20 72 65  /* Pass xSync re
4da0: 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74  quests through t
4db0: 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56  o the original V
4dc0: 46 53 20 77 69 74 68 6f 75 74 20 63 68 61 6e 67  FS without chang
4dd0: 65 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  e.*/.static int 
4de0: 71 75 6f 74 61 53 79 6e 63 28 73 71 6c 69 74 65  quotaSync(sqlite
4df0: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
4e00: 6e 74 20 66 6c 61 67 73 29 7b 0a 20 20 73 71 6c  nt flags){.  sql
4e10: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
4e20: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
4e30: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74  en(pConn);.  ret
4e40: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
4e50: 65 74 68 6f 64 73 2d 3e 78 53 79 6e 63 28 70 53  ethods->xSync(pS
4e60: 75 62 4f 70 65 6e 2c 20 66 6c 61 67 73 29 3b 0a  ubOpen, flags);.
4e70: 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 46 69 6c 65  }../* Pass xFile
4e80: 53 69 7a 65 20 72 65 71 75 65 73 74 73 20 74 68  Size requests th
4e90: 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69  rough to the ori
4ea0: 67 69 6e 61 6c 20 56 46 53 20 62 75 74 20 74 68  ginal VFS but th
4eb0: 65 6e 0a 2a 2a 20 75 70 64 61 74 65 20 74 68 65  en.** update the
4ec0: 20 71 75 6f 74 61 47 72 6f 75 70 20 77 69 74 68   quotaGroup with
4ed0: 20 74 68 65 20 6e 65 77 20 73 69 7a 65 20 62 65   the new size be
4ee0: 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e 0a  fore returning..
4ef0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75  */.static int qu
4f00: 6f 74 61 46 69 6c 65 53 69 7a 65 28 73 71 6c 69  otaFileSize(sqli
4f10: 74 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c  te3_file *pConn,
4f20: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a   sqlite3_int64 *
4f30: 70 53 69 7a 65 29 7b 0a 20 20 71 75 6f 74 61 43  pSize){.  quotaC
4f40: 6f 6e 6e 20 2a 70 20 3d 20 28 71 75 6f 74 61 43  onn *p = (quotaC
4f50: 6f 6e 6e 2a 29 70 43 6f 6e 6e 3b 0a 20 20 73 71  onn*)pConn;.  sq
4f60: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62  lite3_file *pSub
4f70: 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f  Open = quotaSubO
4f80: 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 71 75  pen(pConn);.  qu
4f90: 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 20 3d  otaFile *pFile =
4fa0: 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20 71 75 6f   p->pFile;.  quo
4fb0: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b  taGroup *pGroup;
4fc0: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
4fd0: 20 73 7a 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a   sz;.  int rc;..
4fe0: 20 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e 2d    rc = pSubOpen-
4ff0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65  >pMethods->xFile
5000: 53 69 7a 65 28 70 53 75 62 4f 70 65 6e 2c 20 26  Size(pSubOpen, &
5010: 73 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  sz);.  if( rc==S
5020: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
5030: 71 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20  quotaEnter();.  
5040: 20 20 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65    pGroup = pFile
5050: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 70 47  ->pGroup;.    pG
5060: 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2d 3d 20 70  roup->iSize -= p
5070: 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20 20  File->iSize;.   
5080: 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 20 3d 20   pFile->iSize = 
5090: 73 7a 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  sz;.    pGroup->
50a0: 69 53 69 7a 65 20 2b 3d 20 73 7a 3b 0a 20 20 20  iSize += sz;.   
50b0: 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20   quotaLeave();. 
50c0: 20 20 20 2a 70 53 69 7a 65 20 3d 20 73 7a 3b 0a     *pSize = sz;.
50d0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
50e0: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 4c 6f 63  .}../* Pass xLoc
50f0: 6b 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75  k requests throu
5100: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
5110: 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64  al VFS unchanged
5120: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
5130: 71 75 6f 74 61 4c 6f 63 6b 28 73 71 6c 69 74 65  quotaLock(sqlite
5140: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69  3_file *pConn, i
5150: 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 73 71 6c 69  nt lock){.  sqli
5160: 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70  te3_file *pSubOp
5170: 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65  en = quotaSubOpe
5180: 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75  n(pConn);.  retu
5190: 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65  rn pSubOpen->pMe
51a0: 74 68 6f 64 73 2d 3e 78 4c 6f 63 6b 28 70 53 75  thods->xLock(pSu
51b0: 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29 3b 0a 7d 0a  bOpen, lock);.}.
51c0: 0a 2f 2a 20 50 61 73 73 20 78 55 6e 6c 6f 63 6b  ./* Pass xUnlock
51d0: 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75 67   requests throug
51e0: 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61  h to the origina
51f0: 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e  l VFS unchanged.
5200: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71  .*/.static int q
5210: 75 6f 74 61 55 6e 6c 6f 63 6b 28 73 71 6c 69 74  uotaUnlock(sqlit
5220: 65 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20  e3_file *pConn, 
5230: 69 6e 74 20 6c 6f 63 6b 29 7b 0a 20 20 73 71 6c  int lock){.  sql
5240: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
5250: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
5260: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74  en(pConn);.  ret
5270: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
5280: 65 74 68 6f 64 73 2d 3e 78 55 6e 6c 6f 63 6b 28  ethods->xUnlock(
5290: 70 53 75 62 4f 70 65 6e 2c 20 6c 6f 63 6b 29 3b  pSubOpen, lock);
52a0: 0a 7d 0a 0a 2f 2a 20 50 61 73 73 20 78 43 68 65  .}../* Pass xChe
52b0: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 20 72  ckReservedLock r
52c0: 65 71 75 65 73 74 73 20 74 68 72 6f 75 67 68 20  equests through 
52d0: 74 6f 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20  to the original 
52e0: 56 46 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a  VFS unchanged..*
52f0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f  /.static int quo
5300: 74 61 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c  taCheckReservedL
5310: 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ock(sqlite3_file
5320: 20 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 2a 70 52   *pConn, int *pR
5330: 65 73 4f 75 74 29 7b 0a 20 20 73 71 6c 69 74 65  esOut){.  sqlite
5340: 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e  3_file *pSubOpen
5350: 20 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28   = quotaSubOpen(
5360: 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e  pConn);.  return
5370: 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68   pSubOpen->pMeth
5380: 6f 64 73 2d 3e 78 43 68 65 63 6b 52 65 73 65 72  ods->xCheckReser
5390: 76 65 64 4c 6f 63 6b 28 70 53 75 62 4f 70 65 6e  vedLock(pSubOpen
53a0: 2c 20 70 52 65 73 4f 75 74 29 3b 0a 7d 0a 0a 2f  , pResOut);.}../
53b0: 2a 20 50 61 73 73 20 78 46 69 6c 65 43 6f 6e 74  * Pass xFileCont
53c0: 72 6f 6c 20 72 65 71 75 65 73 74 73 20 74 68 72  rol requests thr
53d0: 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67  ough to the orig
53e0: 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67  inal VFS unchang
53f0: 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ed..*/.static in
5400: 74 20 71 75 6f 74 61 46 69 6c 65 43 6f 6e 74 72  t quotaFileContr
5410: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ol(sqlite3_file 
5420: 2a 70 43 6f 6e 6e 2c 20 69 6e 74 20 6f 70 2c 20  *pConn, int op, 
5430: 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20 20 73  void *pArg){.  s
5440: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75  qlite3_file *pSu
5450: 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62  bOpen = quotaSub
5460: 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 69  Open(pConn);.  i
5470: 6e 74 20 72 63 20 3d 20 70 53 75 62 4f 70 65 6e  nt rc = pSubOpen
5480: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c  ->pMethods->xFil
5490: 65 43 6f 6e 74 72 6f 6c 28 70 53 75 62 4f 70 65  eControl(pSubOpe
54a0: 6e 2c 20 6f 70 2c 20 70 41 72 67 29 3b 0a 23 69  n, op, pArg);.#i
54b0: 66 20 64 65 66 69 6e 65 64 28 53 51 4c 49 54 45  f defined(SQLITE
54c0: 5f 46 43 4e 54 4c 5f 56 46 53 4e 41 4d 45 29 0a  _FCNTL_VFSNAME).
54d0: 20 20 69 66 28 20 6f 70 3d 3d 53 51 4c 49 54 45    if( op==SQLITE
54e0: 5f 46 43 4e 54 4c 5f 56 46 53 4e 41 4d 45 20 26  _FCNTL_VFSNAME &
54f0: 26 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  & rc==SQLITE_OK 
5500: 29 7b 0a 20 20 20 20 2a 28 63 68 61 72 2a 2a 29  ){.    *(char**)
5510: 70 41 72 67 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pArg = sqlite3_m
5520: 70 72 69 6e 74 66 28 22 71 75 6f 74 61 2f 25 7a  printf("quota/%z
5530: 22 2c 20 2a 28 63 68 61 72 2a 2a 29 70 41 72 67  ", *(char**)pArg
5540: 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20  );.  }.#endif.  
5550: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
5560: 20 50 61 73 73 20 78 53 65 63 74 6f 72 53 69 7a   Pass xSectorSiz
5570: 65 20 72 65 71 75 65 73 74 73 20 74 68 72 6f 75  e requests throu
5580: 67 68 20 74 6f 20 74 68 65 20 6f 72 69 67 69 6e  gh to the origin
5590: 61 6c 20 56 46 53 20 75 6e 63 68 61 6e 67 65 64  al VFS unchanged
55a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
55b0: 71 75 6f 74 61 53 65 63 74 6f 72 53 69 7a 65 28  quotaSectorSize(
55c0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 43  sqlite3_file *pC
55d0: 6f 6e 6e 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  onn){.  sqlite3_
55e0: 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20 3d  file *pSubOpen =
55f0: 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70 43   quotaSubOpen(pC
5600: 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 70  onn);.  return p
5610: 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64  SubOpen->pMethod
5620: 73 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65 28 70  s->xSectorSize(p
5630: 53 75 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20  SubOpen);.}../* 
5640: 50 61 73 73 20 78 44 65 76 69 63 65 43 68 61 72  Pass xDeviceChar
5650: 61 63 74 65 72 69 73 74 69 63 73 20 72 65 71 75  acteristics requ
5660: 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20  ests through to 
5670: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53  the original VFS
5680: 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73   unchanged..*/.s
5690: 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 44  tatic int quotaD
56a0: 65 76 69 63 65 43 68 61 72 61 63 74 65 72 69 73  eviceCharacteris
56b0: 74 69 63 73 28 73 71 6c 69 74 65 33 5f 66 69 6c  tics(sqlite3_fil
56c0: 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71 6c  e *pConn){.  sql
56d0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
56e0: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
56f0: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 72 65 74  en(pConn);.  ret
5700: 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d 3e 70 4d  urn pSubOpen->pM
5710: 65 74 68 6f 64 73 2d 3e 78 44 65 76 69 63 65 43  ethods->xDeviceC
5720: 68 61 72 61 63 74 65 72 69 73 74 69 63 73 28 70  haracteristics(p
5730: 53 75 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20  SubOpen);.}../* 
5740: 50 61 73 73 20 78 53 68 6d 4d 61 70 20 72 65 71  Pass xShmMap req
5750: 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f  uests through to
5760: 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46   the original VF
5770: 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a  S unchanged..*/.
5780: 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61  static int quota
5790: 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65  ShmMap(.  sqlite
57a0: 33 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20  3_file *pConn,  
57b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48 61 6e            /* Han
57c0: 64 6c 65 20 6f 70 65 6e 20 6f 6e 20 64 61 74 61  dle open on data
57d0: 62 61 73 65 20 66 69 6c 65 20 2a 2f 0a 20 20 69  base file */.  i
57e0: 6e 74 20 69 52 65 67 69 6f 6e 2c 20 20 20 20 20  nt iRegion,     
57f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5800: 2a 20 52 65 67 69 6f 6e 20 74 6f 20 72 65 74 72  * Region to retr
5810: 69 65 76 65 20 2a 2f 0a 20 20 69 6e 74 20 73 7a  ieve */.  int sz
5820: 52 65 67 69 6f 6e 2c 20 20 20 20 20 20 20 20 20  Region,         
5830: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 69 7a            /* Siz
5840: 65 20 6f 66 20 72 65 67 69 6f 6e 73 20 2a 2f 0a  e of regions */.
5850: 20 20 69 6e 74 20 62 45 78 74 65 6e 64 2c 20 20    int bExtend,  
5860: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5870: 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 65 78 74    /* True to ext
5880: 65 6e 64 20 66 69 6c 65 20 69 66 20 6e 65 63 65  end file if nece
5890: 73 73 61 72 79 20 2a 2f 0a 20 20 76 6f 69 64 20  ssary */.  void 
58a0: 76 6f 6c 61 74 69 6c 65 20 2a 2a 70 70 20 20 20  volatile **pp   
58b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 55             /* OU
58c0: 54 3a 20 4d 61 70 70 65 64 20 6d 65 6d 6f 72 79  T: Mapped memory
58d0: 20 2a 2f 0a 29 7b 0a 20 20 73 71 6c 69 74 65 33   */.){.  sqlite3
58e0: 5f 66 69 6c 65 20 2a 70 53 75 62 4f 70 65 6e 20  _file *pSubOpen 
58f0: 3d 20 71 75 6f 74 61 53 75 62 4f 70 65 6e 28 70  = quotaSubOpen(p
5900: 43 6f 6e 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20  Conn);.  return 
5910: 70 53 75 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f  pSubOpen->pMetho
5920: 64 73 2d 3e 78 53 68 6d 4d 61 70 28 70 53 75 62  ds->xShmMap(pSub
5930: 4f 70 65 6e 2c 20 69 52 65 67 69 6f 6e 2c 20 73  Open, iRegion, s
5940: 7a 52 65 67 69 6f 6e 2c 20 62 45 78 74 65 6e 64  zRegion, bExtend
5950: 2c 20 70 70 29 3b 0a 7d 0a 0a 2f 2a 20 50 61 73  , pp);.}../* Pas
5960: 73 20 78 53 68 6d 4c 6f 63 6b 20 72 65 71 75 65  s xShmLock reque
5970: 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f 20 74  sts through to t
5980: 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46 53 20  he original VFS 
5990: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 73 74  unchanged..*/.st
59a0: 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61 53 68  atic int quotaSh
59b0: 6d 4c 6f 63 6b 28 0a 20 20 73 71 6c 69 74 65 33  mLock(.  sqlite3
59c0: 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 20 20  _file *pConn,   
59d0: 20 20 20 20 2f 2a 20 44 61 74 61 62 61 73 65 20      /* Database 
59e0: 66 69 6c 65 20 68 6f 6c 64 69 6e 67 20 74 68 65  file holding the
59f0: 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79 20 2a   shared memory *
5a00: 2f 0a 20 20 69 6e 74 20 6f 66 73 74 2c 20 20 20  /.  int ofst,   
5a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
5a20: 2a 20 46 69 72 73 74 20 6c 6f 63 6b 20 74 6f 20  * First lock to 
5a30: 61 63 71 75 69 72 65 20 6f 72 20 72 65 6c 65 61  acquire or relea
5a40: 73 65 20 2a 2f 0a 20 20 69 6e 74 20 6e 2c 20 20  se */.  int n,  
5a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5a60: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20     /* Number of 
5a70: 6c 6f 63 6b 73 20 74 6f 20 61 63 71 75 69 72 65  locks to acquire
5a80: 20 6f 72 20 72 65 6c 65 61 73 65 20 2a 2f 0a 20   or release */. 
5a90: 20 69 6e 74 20 66 6c 61 67 73 20 20 20 20 20 20   int flags      
5aa0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 57              /* W
5ab0: 68 61 74 20 74 6f 20 64 6f 20 77 69 74 68 20 74  hat to do with t
5ac0: 68 65 20 6c 6f 63 6b 20 2a 2f 0a 29 7b 0a 20 20  he lock */.){.  
5ad0: 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 53  sqlite3_file *pS
5ae0: 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53 75  ubOpen = quotaSu
5af0: 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20  bOpen(pConn);.  
5b00: 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e 2d  return pSubOpen-
5b10: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c  >pMethods->xShmL
5b20: 6f 63 6b 28 70 53 75 62 4f 70 65 6e 2c 20 6f 66  ock(pSubOpen, of
5b30: 73 74 2c 20 6e 2c 20 66 6c 61 67 73 29 3b 0a 7d  st, n, flags);.}
5b40: 0a 0a 2f 2a 20 50 61 73 73 20 78 53 68 6d 42 61  ../* Pass xShmBa
5b50: 72 72 69 65 72 20 72 65 71 75 65 73 74 73 20 74  rrier requests t
5b60: 68 72 6f 75 67 68 20 74 6f 20 74 68 65 20 6f 72  hrough to the or
5b70: 69 67 69 6e 61 6c 20 56 46 53 20 75 6e 63 68 61  iginal VFS uncha
5b80: 6e 67 65 64 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  nged..*/.static 
5b90: 76 6f 69 64 20 71 75 6f 74 61 53 68 6d 42 61 72  void quotaShmBar
5ba0: 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66 69 6c  rier(sqlite3_fil
5bb0: 65 20 2a 70 43 6f 6e 6e 29 7b 0a 20 20 73 71 6c  e *pConn){.  sql
5bc0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 53 75 62 4f  ite3_file *pSubO
5bd0: 70 65 6e 20 3d 20 71 75 6f 74 61 53 75 62 4f 70  pen = quotaSubOp
5be0: 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20 20 70 53 75  en(pConn);.  pSu
5bf0: 62 4f 70 65 6e 2d 3e 70 4d 65 74 68 6f 64 73 2d  bOpen->pMethods-
5c00: 3e 78 53 68 6d 42 61 72 72 69 65 72 28 70 53 75  >xShmBarrier(pSu
5c10: 62 4f 70 65 6e 29 3b 0a 7d 0a 0a 2f 2a 20 50 61  bOpen);.}../* Pa
5c20: 73 73 20 78 53 68 6d 55 6e 6d 61 70 20 72 65 71  ss xShmUnmap req
5c30: 75 65 73 74 73 20 74 68 72 6f 75 67 68 20 74 6f  uests through to
5c40: 20 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 56 46   the original VF
5c50: 53 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a  S unchanged..*/.
5c60: 73 74 61 74 69 63 20 69 6e 74 20 71 75 6f 74 61  static int quota
5c70: 53 68 6d 55 6e 6d 61 70 28 73 71 6c 69 74 65 33  ShmUnmap(sqlite3
5c80: 5f 66 69 6c 65 20 2a 70 43 6f 6e 6e 2c 20 69 6e  _file *pConn, in
5c90: 74 20 64 65 6c 65 74 65 46 6c 61 67 29 7b 0a 20  t deleteFlag){. 
5ca0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
5cb0: 53 75 62 4f 70 65 6e 20 3d 20 71 75 6f 74 61 53  SubOpen = quotaS
5cc0: 75 62 4f 70 65 6e 28 70 43 6f 6e 6e 29 3b 0a 20  ubOpen(pConn);. 
5cd0: 20 72 65 74 75 72 6e 20 70 53 75 62 4f 70 65 6e   return pSubOpen
5ce0: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d  ->pMethods->xShm
5cf0: 55 6e 6d 61 70 28 70 53 75 62 4f 70 65 6e 2c 20  Unmap(pSubOpen, 
5d00: 64 65 6c 65 74 65 46 6c 61 67 29 3b 0a 7d 0a 0a  deleteFlag);.}..
5d10: 2f 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  /***************
5d20: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 50 75 62 6c  *********** Publ
5d30: 69 63 20 49 6e 74 65 72 66 61 63 65 73 20 2a 2a  ic Interfaces **
5d40: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
5d50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2f 0a 2f 2a 0a  ***********/./*.
5d60: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68  ** Initialize th
5d70: 65 20 71 75 6f 74 61 20 56 46 53 20 73 68 69 6d  e quota VFS shim
5d80: 2e 20 20 55 73 65 20 74 68 65 20 56 46 53 20 6e  .  Use the VFS n
5d90: 61 6d 65 64 20 7a 4f 72 69 67 56 66 73 4e 61 6d  amed zOrigVfsNam
5da0: 65 0a 2a 2a 20 61 73 20 74 68 65 20 56 46 53 20  e.** as the VFS 
5db0: 74 68 61 74 20 64 6f 65 73 20 74 68 65 20 61 63  that does the ac
5dc0: 74 75 61 6c 20 77 6f 72 6b 2e 20 20 55 73 65 20  tual work.  Use 
5dd0: 74 68 65 20 64 65 66 61 75 6c 74 20 69 66 0a 2a  the default if.*
5de0: 2a 20 7a 4f 72 69 67 56 66 73 4e 61 6d 65 3d 3d  * zOrigVfsName==
5df0: 4e 55 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  NULL..**.** The 
5e00: 71 75 6f 74 61 20 56 46 53 20 73 68 69 6d 20 69  quota VFS shim i
5e10: 73 20 6e 61 6d 65 64 20 22 71 75 6f 74 61 22 2e  s named "quota".
5e20: 20 20 49 74 20 77 69 6c 6c 20 62 65 63 6f 6d 65    It will become
5e30: 20 74 68 65 20 64 65 66 61 75 6c 74 0a 2a 2a 20   the default.** 
5e40: 56 46 53 20 69 66 20 6d 61 6b 65 44 65 66 61 75  VFS if makeDefau
5e50: 6c 74 20 69 73 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a  lt is non-zero..
5e60: 2a 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54 49  **.** THIS ROUTI
5e70: 4e 45 20 49 53 20 4e 4f 54 20 54 48 52 45 41 44  NE IS NOT THREAD
5e80: 53 41 46 45 2e 20 20 43 61 6c 6c 20 74 68 69 73  SAFE.  Call this
5e90: 20 72 6f 75 74 69 6e 65 20 65 78 61 63 74 6c 79   routine exactly
5ea0: 20 6f 6e 63 65 0a 2a 2a 20 64 75 72 69 6e 67 20   once.** during 
5eb0: 73 74 61 72 74 2d 75 70 2e 0a 2a 2f 0a 69 6e 74  start-up..*/.int
5ec0: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 69   sqlite3_quota_i
5ed0: 6e 69 74 69 61 6c 69 7a 65 28 63 6f 6e 73 74 20  nitialize(const 
5ee0: 63 68 61 72 20 2a 7a 4f 72 69 67 56 66 73 4e 61  char *zOrigVfsNa
5ef0: 6d 65 2c 20 69 6e 74 20 6d 61 6b 65 44 65 66 61  me, int makeDefa
5f00: 75 6c 74 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f  ult){.  sqlite3_
5f10: 76 66 73 20 2a 70 4f 72 69 67 56 66 73 3b 0a 20  vfs *pOrigVfs;. 
5f20: 20 69 66 28 20 67 51 75 6f 74 61 2e 69 73 49 6e   if( gQuota.isIn
5f30: 69 74 69 61 6c 69 7a 65 64 20 29 20 72 65 74 75  itialized ) retu
5f40: 72 6e 20 53 51 4c 49 54 45 5f 4d 49 53 55 53 45  rn SQLITE_MISUSE
5f50: 3b 0a 20 20 70 4f 72 69 67 56 66 73 20 3d 20 73  ;.  pOrigVfs = s
5f60: 71 6c 69 74 65 33 5f 76 66 73 5f 66 69 6e 64 28  qlite3_vfs_find(
5f70: 7a 4f 72 69 67 56 66 73 4e 61 6d 65 29 3b 0a 20  zOrigVfsName);. 
5f80: 20 69 66 28 20 70 4f 72 69 67 56 66 73 3d 3d 30   if( pOrigVfs==0
5f90: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
5fa0: 5f 45 52 52 4f 52 3b 0a 20 20 61 73 73 65 72 74  _ERROR;.  assert
5fb0: 28 20 70 4f 72 69 67 56 66 73 21 3d 26 67 51 75  ( pOrigVfs!=&gQu
5fc0: 6f 74 61 2e 73 54 68 69 73 56 66 73 20 29 3b 0a  ota.sThisVfs );.
5fd0: 20 20 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 20    gQuota.pMutex 
5fe0: 3d 20 73 71 6c 69 74 65 33 5f 6d 75 74 65 78 5f  = sqlite3_mutex_
5ff0: 61 6c 6c 6f 63 28 53 51 4c 49 54 45 5f 4d 55 54  alloc(SQLITE_MUT
6000: 45 58 5f 46 41 53 54 29 3b 0a 20 20 69 66 28 20  EX_FAST);.  if( 
6010: 21 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 20 29  !gQuota.pMutex )
6020: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  {.    return SQL
6030: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20  ITE_NOMEM;.  }. 
6040: 20 67 51 75 6f 74 61 2e 69 73 49 6e 69 74 69 61   gQuota.isInitia
6050: 6c 69 7a 65 64 20 3d 20 31 3b 0a 20 20 67 51 75  lized = 1;.  gQu
6060: 6f 74 61 2e 70 4f 72 69 67 56 66 73 20 3d 20 70  ota.pOrigVfs = p
6070: 4f 72 69 67 56 66 73 3b 0a 20 20 67 51 75 6f 74  OrigVfs;.  gQuot
6080: 61 2e 73 54 68 69 73 56 66 73 20 3d 20 2a 70 4f  a.sThisVfs = *pO
6090: 72 69 67 56 66 73 3b 0a 20 20 67 51 75 6f 74 61  rigVfs;.  gQuota
60a0: 2e 73 54 68 69 73 56 66 73 2e 78 4f 70 65 6e 20  .sThisVfs.xOpen 
60b0: 3d 20 71 75 6f 74 61 4f 70 65 6e 3b 0a 20 20 67  = quotaOpen;.  g
60c0: 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 78  Quota.sThisVfs.x
60d0: 44 65 6c 65 74 65 20 3d 20 71 75 6f 74 61 44 65  Delete = quotaDe
60e0: 6c 65 74 65 3b 0a 20 20 67 51 75 6f 74 61 2e 73  lete;.  gQuota.s
60f0: 54 68 69 73 56 66 73 2e 73 7a 4f 73 46 69 6c 65  ThisVfs.szOsFile
6100: 20 2b 3d 20 73 69 7a 65 6f 66 28 71 75 6f 74 61   += sizeof(quota
6110: 43 6f 6e 6e 29 3b 0a 20 20 67 51 75 6f 74 61 2e  Conn);.  gQuota.
6120: 73 54 68 69 73 56 66 73 2e 7a 4e 61 6d 65 20 3d  sThisVfs.zName =
6130: 20 22 71 75 6f 74 61 22 3b 0a 20 20 67 51 75 6f   "quota";.  gQuo
6140: 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e  ta.sIoMethodsV1.
6150: 69 56 65 72 73 69 6f 6e 20 3d 20 31 3b 0a 20 20  iVersion = 1;.  
6160: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
6170: 73 56 31 2e 78 43 6c 6f 73 65 20 3d 20 71 75 6f  sV1.xClose = quo
6180: 74 61 43 6c 6f 73 65 3b 0a 20 20 67 51 75 6f 74  taClose;.  gQuot
6190: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78  a.sIoMethodsV1.x
61a0: 52 65 61 64 20 3d 20 71 75 6f 74 61 52 65 61 64  Read = quotaRead
61b0: 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65  ;.  gQuota.sIoMe
61c0: 74 68 6f 64 73 56 31 2e 78 57 72 69 74 65 20 3d  thodsV1.xWrite =
61d0: 20 71 75 6f 74 61 57 72 69 74 65 3b 0a 20 20 67   quotaWrite;.  g
61e0: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
61f0: 56 31 2e 78 54 72 75 6e 63 61 74 65 20 3d 20 71  V1.xTruncate = q
6200: 75 6f 74 61 54 72 75 6e 63 61 74 65 3b 0a 20 20  uotaTruncate;.  
6210: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
6220: 73 56 31 2e 78 53 79 6e 63 20 3d 20 71 75 6f 74  sV1.xSync = quot
6230: 61 53 79 6e 63 3b 0a 20 20 67 51 75 6f 74 61 2e  aSync;.  gQuota.
6240: 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 46 69  sIoMethodsV1.xFi
6250: 6c 65 53 69 7a 65 20 3d 20 71 75 6f 74 61 46 69  leSize = quotaFi
6260: 6c 65 53 69 7a 65 3b 0a 20 20 67 51 75 6f 74 61  leSize;.  gQuota
6270: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 4c  .sIoMethodsV1.xL
6280: 6f 63 6b 20 3d 20 71 75 6f 74 61 4c 6f 63 6b 3b  ock = quotaLock;
6290: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
62a0: 68 6f 64 73 56 31 2e 78 55 6e 6c 6f 63 6b 20 3d  hodsV1.xUnlock =
62b0: 20 71 75 6f 74 61 55 6e 6c 6f 63 6b 3b 0a 20 20   quotaUnlock;.  
62c0: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
62d0: 73 56 31 2e 78 43 68 65 63 6b 52 65 73 65 72 76  sV1.xCheckReserv
62e0: 65 64 4c 6f 63 6b 20 3d 20 71 75 6f 74 61 43 68  edLock = quotaCh
62f0: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 3b  eckReservedLock;
6300: 0a 20 20 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74  .  gQuota.sIoMet
6310: 68 6f 64 73 56 31 2e 78 46 69 6c 65 43 6f 6e 74  hodsV1.xFileCont
6320: 72 6f 6c 20 3d 20 71 75 6f 74 61 46 69 6c 65 43  rol = quotaFileC
6330: 6f 6e 74 72 6f 6c 3b 0a 20 20 67 51 75 6f 74 61  ontrol;.  gQuota
6340: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 31 2e 78 53  .sIoMethodsV1.xS
6350: 65 63 74 6f 72 53 69 7a 65 20 3d 20 71 75 6f 74  ectorSize = quot
6360: 61 53 65 63 74 6f 72 53 69 7a 65 3b 0a 20 20 67  aSectorSize;.  g
6370: 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73  Quota.sIoMethods
6380: 56 31 2e 78 44 65 76 69 63 65 43 68 61 72 61 63  V1.xDeviceCharac
6390: 74 65 72 69 73 74 69 63 73 20 3d 20 71 75 6f 74  teristics = quot
63a0: 61 44 65 76 69 63 65 43 68 61 72 61 63 74 65 72  aDeviceCharacter
63b0: 69 73 74 69 63 73 3b 0a 20 20 67 51 75 6f 74 61  istics;.  gQuota
63c0: 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 20 3d 20  .sIoMethodsV2 = 
63d0: 67 51 75 6f 74 61 2e 73 49 6f 4d 65 74 68 6f 64  gQuota.sIoMethod
63e0: 73 56 31 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49  sV1;.  gQuota.sI
63f0: 6f 4d 65 74 68 6f 64 73 56 32 2e 69 56 65 72 73  oMethodsV2.iVers
6400: 69 6f 6e 20 3d 20 32 3b 0a 20 20 67 51 75 6f 74  ion = 2;.  gQuot
6410: 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78  a.sIoMethodsV2.x
6420: 53 68 6d 4d 61 70 20 3d 20 71 75 6f 74 61 53 68  ShmMap = quotaSh
6430: 6d 4d 61 70 3b 0a 20 20 67 51 75 6f 74 61 2e 73  mMap;.  gQuota.s
6440: 49 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d  IoMethodsV2.xShm
6450: 4c 6f 63 6b 20 3d 20 71 75 6f 74 61 53 68 6d 4c  Lock = quotaShmL
6460: 6f 63 6b 3b 0a 20 20 67 51 75 6f 74 61 2e 73 49  ock;.  gQuota.sI
6470: 6f 4d 65 74 68 6f 64 73 56 32 2e 78 53 68 6d 42  oMethodsV2.xShmB
6480: 61 72 72 69 65 72 20 3d 20 71 75 6f 74 61 53 68  arrier = quotaSh
6490: 6d 42 61 72 72 69 65 72 3b 0a 20 20 67 51 75 6f  mBarrier;.  gQuo
64a0: 74 61 2e 73 49 6f 4d 65 74 68 6f 64 73 56 32 2e  ta.sIoMethodsV2.
64b0: 78 53 68 6d 55 6e 6d 61 70 20 3d 20 71 75 6f 74  xShmUnmap = quot
64c0: 61 53 68 6d 55 6e 6d 61 70 3b 0a 20 20 73 71 6c  aShmUnmap;.  sql
64d0: 69 74 65 33 5f 76 66 73 5f 72 65 67 69 73 74 65  ite3_vfs_registe
64e0: 72 28 26 67 51 75 6f 74 61 2e 73 54 68 69 73 56  r(&gQuota.sThisV
64f0: 66 73 2c 20 6d 61 6b 65 44 65 66 61 75 6c 74 29  fs, makeDefault)
6500: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
6510: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  E_OK;.}../*.** S
6520: 68 75 74 64 6f 77 6e 20 74 68 65 20 71 75 6f 74  hutdown the quot
6530: 61 20 73 79 73 74 65 6d 2e 0a 2a 2a 0a 2a 2a 20  a system..**.** 
6540: 41 6c 6c 20 53 51 4c 69 74 65 20 64 61 74 61 62  All SQLite datab
6550: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20  ase connections 
6560: 6d 75 73 74 20 62 65 20 63 6c 6f 73 65 64 20 62  must be closed b
6570: 65 66 6f 72 65 20 63 61 6c 6c 69 6e 67 20 74 68  efore calling th
6580: 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 2e 0a 2a  is.** routine..*
6590: 2a 0a 2a 2a 20 54 48 49 53 20 52 4f 55 54 49 4e  *.** THIS ROUTIN
65a0: 45 20 49 53 20 4e 4f 54 20 54 48 52 45 41 44 53  E IS NOT THREADS
65b0: 41 46 45 2e 20 20 43 61 6c 6c 20 74 68 69 73 20  AFE.  Call this 
65c0: 72 6f 75 74 69 6e 65 20 65 78 61 63 74 6c 79 20  routine exactly 
65d0: 6f 6e 63 65 20 77 68 69 6c 65 0a 2a 2a 20 73 68  once while.** sh
65e0: 75 74 74 69 6e 67 20 64 6f 77 6e 20 69 6e 20 6f  utting down in o
65f0: 72 64 65 72 20 74 6f 20 66 72 65 65 20 61 6c 6c  rder to free all
6600: 20 72 65 6d 61 69 6e 69 6e 67 20 71 75 6f 74 61   remaining quota
6610: 20 67 72 6f 75 70 73 2e 0a 2a 2f 0a 69 6e 74 20   groups..*/.int 
6620: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73 68  sqlite3_quota_sh
6630: 75 74 64 6f 77 6e 28 76 6f 69 64 29 7b 0a 20 20  utdown(void){.  
6640: 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f  quotaGroup *pGro
6650: 75 70 3b 0a 20 20 69 66 28 20 67 51 75 6f 74 61  up;.  if( gQuota
6660: 2e 69 73 49 6e 69 74 69 61 6c 69 7a 65 64 3d 3d  .isInitialized==
6670: 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54  0 ) return SQLIT
6680: 45 5f 4d 49 53 55 53 45 3b 0a 20 20 66 6f 72 28  E_MISUSE;.  for(
6690: 70 47 72 6f 75 70 3d 67 51 75 6f 74 61 2e 70 47  pGroup=gQuota.pG
66a0: 72 6f 75 70 3b 20 70 47 72 6f 75 70 3b 20 70 47  roup; pGroup; pG
66b0: 72 6f 75 70 3d 70 47 72 6f 75 70 2d 3e 70 4e 65  roup=pGroup->pNe
66c0: 78 74 29 7b 0a 20 20 20 20 69 66 28 20 71 75 6f  xt){.    if( quo
66d0: 74 61 47 72 6f 75 70 4f 70 65 6e 46 69 6c 65 43  taGroupOpenFileC
66e0: 6f 75 6e 74 28 70 47 72 6f 75 70 29 3e 30 20 29  ount(pGroup)>0 )
66f0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4d   return SQLITE_M
6700: 49 53 55 53 45 3b 0a 20 20 7d 0a 20 20 77 68 69  ISUSE;.  }.  whi
6710: 6c 65 28 20 67 51 75 6f 74 61 2e 70 47 72 6f 75  le( gQuota.pGrou
6720: 70 20 29 7b 0a 20 20 20 20 70 47 72 6f 75 70 20  p ){.    pGroup 
6730: 3d 20 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b  = gQuota.pGroup;
6740: 0a 20 20 20 20 67 51 75 6f 74 61 2e 70 47 72 6f  .    gQuota.pGro
6750: 75 70 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e 65  up = pGroup->pNe
6760: 78 74 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e  xt;.    pGroup->
6770: 69 4c 69 6d 69 74 20 3d 20 30 3b 0a 20 20 20 20  iLimit = 0;.    
6780: 61 73 73 65 72 74 28 20 71 75 6f 74 61 47 72 6f  assert( quotaGro
6790: 75 70 4f 70 65 6e 46 69 6c 65 43 6f 75 6e 74 28  upOpenFileCount(
67a0: 70 47 72 6f 75 70 29 3d 3d 30 20 29 3b 0a 20 20  pGroup)==0 );.  
67b0: 20 20 71 75 6f 74 61 47 72 6f 75 70 44 65 72 65    quotaGroupDere
67c0: 66 28 70 47 72 6f 75 70 29 3b 0a 20 20 7d 0a 20  f(pGroup);.  }. 
67d0: 20 67 51 75 6f 74 61 2e 69 73 49 6e 69 74 69 61   gQuota.isInitia
67e0: 6c 69 7a 65 64 20 3d 20 30 3b 0a 20 20 73 71 6c  lized = 0;.  sql
67f0: 69 74 65 33 5f 6d 75 74 65 78 5f 66 72 65 65 28  ite3_mutex_free(
6800: 67 51 75 6f 74 61 2e 70 4d 75 74 65 78 29 3b 0a  gQuota.pMutex);.
6810: 20 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 75 6e    sqlite3_vfs_un
6820: 72 65 67 69 73 74 65 72 28 26 67 51 75 6f 74 61  register(&gQuota
6830: 2e 73 54 68 69 73 56 66 73 29 3b 0a 20 20 6d 65  .sThisVfs);.  me
6840: 6d 73 65 74 28 26 67 51 75 6f 74 61 2c 20 30 2c  mset(&gQuota, 0,
6850: 20 73 69 7a 65 6f 66 28 67 51 75 6f 74 61 29 29   sizeof(gQuota))
6860: 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54  ;.  return SQLIT
6870: 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  E_OK;.}../*.** C
6880: 72 65 61 74 65 20 6f 72 20 64 65 73 74 72 6f 79  reate or destroy
6890: 20 61 20 71 75 6f 74 61 20 67 72 6f 75 70 2e 0a   a quota group..
68a0: 2a 2a 0a 2a 2a 20 54 68 65 20 71 75 6f 74 61 20  **.** The quota 
68b0: 67 72 6f 75 70 20 69 73 20 64 65 66 69 6e 65 64  group is defined
68c0: 20 62 79 20 74 68 65 20 7a 50 61 74 74 65 72 6e   by the zPattern
68d0: 2e 20 20 57 68 65 6e 20 63 61 6c 6c 69 6e 67 20  .  When calling 
68e0: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20  this routine.** 
68f0: 77 69 74 68 20 61 20 7a 50 61 74 74 65 72 6e 20  with a zPattern 
6900: 66 6f 72 20 61 20 71 75 6f 74 61 20 67 72 6f 75  for a quota grou
6910: 70 20 74 68 61 74 20 61 6c 72 65 61 64 79 20 65  p that already e
6920: 78 69 73 74 73 2c 20 74 68 69 73 20 72 6f 75 74  xists, this rout
6930: 69 6e 65 0a 2a 2a 20 6d 65 72 65 6c 79 20 75 70  ine.** merely up
6940: 64 61 74 65 73 20 74 68 65 20 69 4c 69 6d 69 74  dates the iLimit
6950: 2c 20 78 43 61 6c 6c 62 61 63 6b 2c 20 61 6e 64  , xCallback, and
6960: 20 70 41 72 67 20 76 61 6c 75 65 73 20 66 6f 72   pArg values for
6970: 20 74 68 61 74 20 71 75 6f 74 61 0a 2a 2a 20 67   that quota.** g
6980: 72 6f 75 70 2e 20 20 49 66 20 7a 50 61 74 74 65  roup.  If zPatte
6990: 72 6e 20 69 73 20 6e 65 77 2c 20 74 68 65 6e 20  rn is new, then 
69a0: 61 20 6e 65 77 20 71 75 6f 74 61 20 67 72 6f 75  a new quota grou
69b0: 70 20 69 73 20 63 72 65 61 74 65 64 2e 0a 2a 2a  p is created..**
69c0: 0a 2a 2a 20 49 66 20 74 68 65 20 69 4c 69 6d 69  .** If the iLimi
69d0: 74 20 66 6f 72 20 61 20 71 75 6f 74 61 20 67 72  t for a quota gr
69e0: 6f 75 70 20 69 73 20 73 65 74 20 74 6f 20 7a 65  oup is set to ze
69f0: 72 6f 2c 20 74 68 65 6e 20 74 68 65 20 71 75 6f  ro, then the quo
6a00: 74 61 20 67 72 6f 75 70 0a 2a 2a 20 69 73 20 64  ta group.** is d
6a10: 69 73 61 62 6c 65 64 20 61 6e 64 20 77 69 6c 6c  isabled and will
6a20: 20 62 65 20 64 65 6c 65 74 65 64 20 77 68 65 6e   be deleted when
6a30: 20 74 68 65 20 6c 61 73 74 20 64 61 74 61 62 61   the last databa
6a40: 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 75 73  se connection us
6a50: 69 6e 67 0a 2a 2a 20 74 68 65 20 71 75 6f 74 61  ing.** the quota
6a60: 20 67 72 6f 75 70 20 69 73 20 63 6c 6f 73 65 64   group is closed
6a70: 2e 0a 2a 2a 0a 2a 2a 20 43 61 6c 6c 69 6e 67 20  ..**.** Calling 
6a80: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f 6e 20  this routine on 
6a90: 61 20 7a 50 61 74 74 65 72 6e 20 74 68 61 74 20  a zPattern that 
6aa0: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 61  does not exist a
6ab0: 6e 64 20 77 69 74 68 20 61 0a 2a 2a 20 7a 65 72  nd with a.** zer
6ac0: 6f 20 69 4c 69 6d 69 74 20 69 73 20 61 20 6e 6f  o iLimit is a no
6ad0: 2d 6f 70 2e 0a 2a 2a 0a 2a 2a 20 41 20 71 75 6f  -op..**.** A quo
6ae0: 74 61 20 67 72 6f 75 70 20 6d 75 73 74 20 65 78  ta group must ex
6af0: 69 73 74 20 77 69 74 68 20 61 20 6e 6f 6e 2d 7a  ist with a non-z
6b00: 65 72 6f 20 69 4c 69 6d 69 74 20 70 72 69 6f 72  ero iLimit prior
6b10: 20 74 6f 20 6f 70 65 6e 69 6e 67 0a 2a 2a 20 64   to opening.** d
6b20: 61 74 61 62 61 73 65 20 63 6f 6e 6e 65 63 74 69  atabase connecti
6b30: 6f 6e 73 20 69 66 20 74 68 6f 73 65 20 63 6f 6e  ons if those con
6b40: 6e 65 63 74 69 6f 6e 73 20 61 72 65 20 74 6f 20  nections are to 
6b50: 70 61 72 74 69 63 69 70 61 74 65 20 69 6e 20 74  participate in t
6b60: 68 65 0a 2a 2a 20 71 75 6f 74 61 20 67 72 6f 75  he.** quota grou
6b70: 70 2e 20 20 43 72 65 61 74 69 6e 67 20 61 20 71  p.  Creating a q
6b80: 75 6f 74 61 20 67 72 6f 75 70 20 64 6f 65 73 20  uota group does 
6b90: 6e 6f 74 20 61 66 66 65 63 74 20 64 61 74 61 62  not affect datab
6ba0: 61 73 65 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 0a  ase connections.
6bb0: 2a 2a 20 74 68 61 74 20 61 72 65 20 61 6c 72 65  ** that are alre
6bc0: 61 64 79 20 6f 70 65 6e 2e 0a 2a 2f 0a 69 6e 74  ady open..*/.int
6bd0: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73   sqlite3_quota_s
6be0: 65 74 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  et(.  const char
6bf0: 20 2a 7a 50 61 74 74 65 72 6e 2c 20 20 20 20 20   *zPattern,     
6c00: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 66 69 6c        /* The fil
6c10: 65 6e 61 6d 65 20 70 61 74 74 65 72 6e 20 2a 2f  ename pattern */
6c20: 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  .  sqlite3_int64
6c30: 20 69 4c 69 6d 69 74 2c 20 20 20 20 20 20 20 20   iLimit,        
6c40: 20 20 20 2f 2a 20 4e 65 77 20 71 75 6f 74 61 20     /* New quota 
6c50: 74 6f 20 73 65 74 20 66 6f 72 20 74 68 69 73 20  to set for this 
6c60: 71 75 6f 74 61 20 67 72 6f 75 70 20 2a 2f 0a 20  quota group */. 
6c70: 20 76 6f 69 64 20 28 2a 78 43 61 6c 6c 62 61 63   void (*xCallbac
6c80: 6b 29 28 20 20 20 20 20 20 20 20 20 20 20 20 20  k)(             
6c90: 20 2f 2a 20 43 61 6c 6c 62 61 63 6b 20 69 6e 76   /* Callback inv
6ca0: 6f 6b 65 64 20 77 68 65 6e 20 67 6f 69 6e 67 20  oked when going 
6cb0: 6f 76 65 72 20 71 75 6f 74 61 20 2a 2f 0a 20 20  over quota */.  
6cc0: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a     const char *z
6cd0: 46 69 6c 65 6e 61 6d 65 2c 20 20 20 20 20 20 20  Filename,       
6ce0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 66 69 6c    /* Name of fil
6cf0: 65 20 77 68 6f 73 65 20 73 69 7a 65 20 69 6e 63  e whose size inc
6d00: 72 65 61 73 65 73 20 2a 2f 0a 20 20 20 20 20 73  reases */.     s
6d10: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70 69  qlite3_int64 *pi
6d20: 4c 69 6d 69 74 2c 20 20 20 20 20 20 20 20 2f 2a  Limit,        /*
6d30: 20 49 4e 2f 4f 55 54 3a 20 54 68 65 20 63 75 72   IN/OUT: The cur
6d40: 72 65 6e 74 20 6c 69 6d 69 74 20 2a 2f 0a 20 20  rent limit */.  
6d50: 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34     sqlite3_int64
6d60: 20 69 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20   iSize,         
6d70: 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a 65 20    /* Total size 
6d80: 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 69 6e 20  of all files in 
6d90: 74 68 65 20 67 72 6f 75 70 20 2a 2f 0a 20 20 20  the group */.   
6da0: 20 20 76 6f 69 64 20 2a 70 41 72 67 20 20 20 20    void *pArg    
6db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dc0: 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61 74 61 20   /* Client data 
6dd0: 2a 2f 0a 20 20 29 2c 0a 20 20 76 6f 69 64 20 2a  */.  ),.  void *
6de0: 70 41 72 67 2c 20 20 20 20 20 20 20 20 20 20 20  pArg,           
6df0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 63 6c 69            /* cli
6e00: 65 6e 74 20 64 61 74 61 20 70 61 73 73 65 64 20  ent data passed 
6e10: 74 68 72 75 20 74 6f 20 63 61 6c 6c 62 61 63 6b  thru to callback
6e20: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 44 65   */.  void (*xDe
6e30: 73 74 72 6f 79 29 28 76 6f 69 64 2a 29 20 20 20  stroy)(void*)   
6e40: 20 20 20 20 20 20 2f 2a 20 4f 70 74 69 6f 6e 61        /* Optiona
6e50: 6c 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72  l destructor for
6e60: 20 70 41 72 67 20 2a 2f 0a 29 7b 0a 20 20 71 75   pArg */.){.  qu
6e70: 6f 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70  otaGroup *pGroup
6e80: 3b 0a 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29  ;.  quotaEnter()
6e90: 3b 0a 20 20 70 47 72 6f 75 70 20 3d 20 67 51 75  ;.  pGroup = gQu
6ea0: 6f 74 61 2e 70 47 72 6f 75 70 3b 0a 20 20 77 68  ota.pGroup;.  wh
6eb0: 69 6c 65 28 20 70 47 72 6f 75 70 20 26 26 20 73  ile( pGroup && s
6ec0: 74 72 63 6d 70 28 70 47 72 6f 75 70 2d 3e 7a 50  trcmp(pGroup->zP
6ed0: 61 74 74 65 72 6e 2c 20 7a 50 61 74 74 65 72 6e  attern, zPattern
6ee0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 70 47 72 6f  )!=0 ){.    pGro
6ef0: 75 70 20 3d 20 70 47 72 6f 75 70 2d 3e 70 4e 65  up = pGroup->pNe
6f00: 78 74 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 47  xt;.  }.  if( pG
6f10: 72 6f 75 70 3d 3d 30 20 29 7b 0a 20 20 20 20 69  roup==0 ){.    i
6f20: 6e 74 20 6e 50 61 74 74 65 72 6e 20 3d 20 28 69  nt nPattern = (i
6f30: 6e 74 29 28 73 74 72 6c 65 6e 28 7a 50 61 74 74  nt)(strlen(zPatt
6f40: 65 72 6e 29 20 26 20 30 78 33 66 66 66 66 66 66  ern) & 0x3ffffff
6f50: 66 29 3b 0a 20 20 20 20 69 66 28 20 69 4c 69 6d  f);.    if( iLim
6f60: 69 74 3c 3d 30 20 29 7b 0a 20 20 20 20 20 20 71  it<=0 ){.      q
6f70: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 20  uotaLeave();.   
6f80: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
6f90: 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70  _OK;.    }.    p
6fa0: 47 72 6f 75 70 20 3d 20 28 71 75 6f 74 61 47 72  Group = (quotaGr
6fb0: 6f 75 70 20 2a 29 73 71 6c 69 74 65 33 5f 6d 61  oup *)sqlite3_ma
6fc0: 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70 47  lloc( sizeof(*pG
6fd0: 72 6f 75 70 29 20 2b 20 6e 50 61 74 74 65 72 6e  roup) + nPattern
6fe0: 20 2b 20 31 20 29 3b 0a 20 20 20 20 69 66 28 20   + 1 );.    if( 
6ff0: 70 47 72 6f 75 70 3d 3d 30 20 29 7b 0a 20 20 20  pGroup==0 ){.   
7000: 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b     quotaLeave();
7010: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 53 51  .      return SQ
7020: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
7030: 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 70 47 72  }.    memset(pGr
7040: 6f 75 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a  oup, 0, sizeof(*
7050: 70 47 72 6f 75 70 29 29 3b 0a 20 20 20 20 70 47  pGroup));.    pG
7060: 72 6f 75 70 2d 3e 7a 50 61 74 74 65 72 6e 20 3d  roup->zPattern =
7070: 20 28 63 68 61 72 2a 29 26 70 47 72 6f 75 70 5b   (char*)&pGroup[
7080: 31 5d 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 28  1];.    memcpy((
7090: 63 68 61 72 20 2a 29 70 47 72 6f 75 70 2d 3e 7a  char *)pGroup->z
70a0: 50 61 74 74 65 72 6e 2c 20 7a 50 61 74 74 65 72  Pattern, zPatter
70b0: 6e 2c 20 6e 50 61 74 74 65 72 6e 2b 31 29 3b 0a  n, nPattern+1);.
70c0: 20 20 20 20 69 66 28 20 67 51 75 6f 74 61 2e 70      if( gQuota.p
70d0: 47 72 6f 75 70 20 29 20 67 51 75 6f 74 61 2e 70  Group ) gQuota.p
70e0: 47 72 6f 75 70 2d 3e 70 70 50 72 65 76 20 3d 20  Group->ppPrev = 
70f0: 26 70 47 72 6f 75 70 2d 3e 70 4e 65 78 74 3b 0a  &pGroup->pNext;.
7100: 20 20 20 20 70 47 72 6f 75 70 2d 3e 70 4e 65 78      pGroup->pNex
7110: 74 20 3d 20 67 51 75 6f 74 61 2e 70 47 72 6f 75  t = gQuota.pGrou
7120: 70 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 70  p;.    pGroup->p
7130: 70 50 72 65 76 20 3d 20 26 67 51 75 6f 74 61 2e  pPrev = &gQuota.
7140: 70 47 72 6f 75 70 3b 0a 20 20 20 20 67 51 75 6f  pGroup;.    gQuo
7150: 74 61 2e 70 47 72 6f 75 70 20 3d 20 70 47 72 6f  ta.pGroup = pGro
7160: 75 70 3b 0a 20 20 7d 0a 20 20 70 47 72 6f 75 70  up;.  }.  pGroup
7170: 2d 3e 69 4c 69 6d 69 74 20 3d 20 69 4c 69 6d 69  ->iLimit = iLimi
7180: 74 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 78 43 61  t;.  pGroup->xCa
7190: 6c 6c 62 61 63 6b 20 3d 20 78 43 61 6c 6c 62 61  llback = xCallba
71a0: 63 6b 3b 0a 20 20 69 66 28 20 70 47 72 6f 75 70  ck;.  if( pGroup
71b0: 2d 3e 78 44 65 73 74 72 6f 79 20 26 26 20 70 47  ->xDestroy && pG
71c0: 72 6f 75 70 2d 3e 70 41 72 67 21 3d 70 41 72 67  roup->pArg!=pArg
71d0: 20 29 7b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e   ){.    pGroup->
71e0: 78 44 65 73 74 72 6f 79 28 70 47 72 6f 75 70 2d  xDestroy(pGroup-
71f0: 3e 70 41 72 67 29 3b 0a 20 20 7d 0a 20 20 70 47  >pArg);.  }.  pG
7200: 72 6f 75 70 2d 3e 70 41 72 67 20 3d 20 70 41 72  roup->pArg = pAr
7210: 67 3b 0a 20 20 70 47 72 6f 75 70 2d 3e 78 44 65  g;.  pGroup->xDe
7220: 73 74 72 6f 79 20 3d 20 78 44 65 73 74 72 6f 79  stroy = xDestroy
7230: 3b 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 44 65  ;.  quotaGroupDe
7240: 72 65 66 28 70 47 72 6f 75 70 29 3b 0a 20 20 71  ref(pGroup);.  q
7250: 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20 20 72  uotaLeave();.  r
7260: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
7270: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 42 72 69 6e 67 20  .}../*.** Bring 
7280: 74 68 65 20 6e 61 6d 65 64 20 66 69 6c 65 20 75  the named file u
7290: 6e 64 65 72 20 71 75 6f 74 61 20 6d 61 6e 61 67  nder quota manag
72a0: 65 6d 65 6e 74 2e 20 20 4f 72 20 69 66 20 69 74  ement.  Or if it
72b0: 20 69 73 20 61 6c 72 65 61 64 79 20 75 6e 64 65   is already unde
72c0: 72 0a 2a 2a 20 6d 61 6e 61 67 65 6d 65 6e 74 2c  r.** management,
72d0: 20 75 70 64 61 74 65 20 69 74 73 20 73 69 7a 65   update its size
72e0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
72f0: 5f 71 75 6f 74 61 5f 66 69 6c 65 28 63 6f 6e 73  _quota_file(cons
7300: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
7310: 65 29 7b 0a 20 20 63 68 61 72 20 2a 7a 46 75 6c  e){.  char *zFul
7320: 6c 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74 65 33  l = 0;.  sqlite3
7330: 5f 66 69 6c 65 20 2a 66 64 3b 0a 20 20 69 6e 74  _file *fd;.  int
7340: 20 72 63 3b 0a 20 20 69 6e 74 20 6f 75 74 46 6c   rc;.  int outFl
7350: 61 67 73 20 3d 20 30 3b 0a 20 20 73 71 6c 69 74  ags = 0;.  sqlit
7360: 65 33 5f 69 6e 74 36 34 20 69 53 69 7a 65 3b 0a  e3_int64 iSize;.
7370: 20 20 69 6e 74 20 6e 41 6c 6c 6f 63 20 3d 20 67    int nAlloc = g
7380: 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 73  Quota.sThisVfs.s
7390: 7a 4f 73 46 69 6c 65 20 2b 20 67 51 75 6f 74 61  zOsFile + gQuota
73a0: 2e 73 54 68 69 73 56 66 73 2e 6d 78 50 61 74 68  .sThisVfs.mxPath
73b0: 6e 61 6d 65 2b 32 3b 0a 0a 20 20 2f 2a 20 41 6c  name+2;..  /* Al
73c0: 6c 6f 63 61 74 65 20 73 70 61 63 65 20 66 6f 72  locate space for
73d0: 20 61 20 66 69 6c 65 2d 68 61 6e 64 6c 65 20 61   a file-handle a
73e0: 6e 64 20 74 68 65 20 66 75 6c 6c 20 70 61 74 68  nd the full path
73f0: 20 66 6f 72 20 66 69 6c 65 20 7a 46 69 6c 65 6e   for file zFilen
7400: 61 6d 65 20 2a 2f 0a 20 20 66 64 20 3d 20 28 73  ame */.  fd = (s
7410: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 29 73 71  qlite3_file *)sq
7420: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e 41 6c  lite3_malloc(nAl
7430: 6c 6f 63 29 3b 0a 20 20 69 66 28 20 66 64 3d 3d  loc);.  if( fd==
7440: 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51  0 ){.    rc = SQ
7450: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65  LITE_NOMEM;.  }e
7460: 6c 73 65 7b 0a 20 20 20 20 7a 46 75 6c 6c 20 3d  lse{.    zFull =
7470: 20 26 28 28 63 68 61 72 20 2a 29 66 64 29 5b 67   &((char *)fd)[g
7480: 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 73  Quota.sThisVfs.s
7490: 7a 4f 73 46 69 6c 65 5d 3b 0a 20 20 20 20 72 63  zOsFile];.    rc
74a0: 20 3d 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56   = gQuota.pOrigV
74b0: 66 73 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d  fs->xFullPathnam
74c0: 65 28 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66  e(gQuota.pOrigVf
74d0: 73 2c 20 7a 46 69 6c 65 6e 61 6d 65 2c 0a 20 20  s, zFilename,.  
74e0: 20 20 20 20 20 20 67 51 75 6f 74 61 2e 73 54 68        gQuota.sTh
74f0: 69 73 56 66 73 2e 6d 78 50 61 74 68 6e 61 6d 65  isVfs.mxPathname
7500: 2b 31 2c 20 7a 46 75 6c 6c 29 3b 0a 20 20 7d 0a  +1, zFull);.  }.
7510: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
7520: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 7a 46 75 6c  E_OK ){.    zFul
7530: 6c 5b 73 74 72 6c 65 6e 28 7a 46 75 6c 6c 29 2b  l[strlen(zFull)+
7540: 31 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 20 20 72  1] = '\0';.    r
7550: 63 20 3d 20 71 75 6f 74 61 4f 70 65 6e 28 26 67  c = quotaOpen(&g
7560: 51 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2c 20  Quota.sThisVfs, 
7570: 7a 46 75 6c 6c 2c 20 66 64 2c 0a 20 20 20 20 20  zFull, fd,.     
7580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 53 51                SQ
7590: 4c 49 54 45 5f 4f 50 45 4e 5f 52 45 41 44 4f 4e  LITE_OPEN_READON
75a0: 4c 59 20 7c 20 53 51 4c 49 54 45 5f 4f 50 45 4e  LY | SQLITE_OPEN
75b0: 5f 4d 41 49 4e 5f 44 42 2c 20 26 6f 75 74 46 6c  _MAIN_DB, &outFl
75c0: 61 67 73 29 3b 0a 20 20 20 20 69 66 28 20 72 63  ags);.    if( rc
75d0: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
75e0: 20 20 20 20 20 66 64 2d 3e 70 4d 65 74 68 6f 64       fd->pMethod
75f0: 73 2d 3e 78 46 69 6c 65 53 69 7a 65 28 66 64 2c  s->xFileSize(fd,
7600: 20 26 69 53 69 7a 65 29 3b 0a 20 20 20 20 20 20   &iSize);.      
7610: 66 64 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43  fd->pMethods->xC
7620: 6c 6f 73 65 28 66 64 29 3b 0a 20 20 20 20 7d 65  lose(fd);.    }e
7630: 6c 73 65 20 69 66 28 20 72 63 3d 3d 53 51 4c 49  lse if( rc==SQLI
7640: 54 45 5f 43 41 4e 54 4f 50 45 4e 20 29 7b 0a 20  TE_CANTOPEN ){. 
7650: 20 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70 20       quotaGroup 
7660: 2a 70 47 72 6f 75 70 3b 0a 20 20 20 20 20 20 71  *pGroup;.      q
7670: 75 6f 74 61 46 69 6c 65 20 2a 70 46 69 6c 65 3b  uotaFile *pFile;
7680: 0a 20 20 20 20 20 20 71 75 6f 74 61 45 6e 74 65  .      quotaEnte
7690: 72 28 29 3b 0a 20 20 20 20 20 20 70 47 72 6f 75  r();.      pGrou
76a0: 70 20 3d 20 71 75 6f 74 61 47 72 6f 75 70 46 69  p = quotaGroupFi
76b0: 6e 64 28 7a 46 75 6c 6c 29 3b 0a 20 20 20 20 20  nd(zFull);.     
76c0: 20 69 66 28 20 70 47 72 6f 75 70 20 29 7b 0a 20   if( pGroup ){. 
76d0: 20 20 20 20 20 20 20 70 46 69 6c 65 20 3d 20 71         pFile = q
76e0: 75 6f 74 61 46 69 6e 64 46 69 6c 65 28 70 47 72  uotaFindFile(pGr
76f0: 6f 75 70 2c 20 7a 46 75 6c 6c 2c 20 30 29 3b 0a  oup, zFull, 0);.
7700: 20 20 20 20 20 20 20 20 69 66 28 20 70 46 69 6c          if( pFil
7710: 65 20 29 20 71 75 6f 74 61 52 65 6d 6f 76 65 46  e ) quotaRemoveF
7720: 69 6c 65 28 70 46 69 6c 65 29 3b 0a 20 20 20 20  ile(pFile);.    
7730: 20 20 7d 0a 20 20 20 20 20 20 71 75 6f 74 61 4c    }.      quotaL
7740: 65 61 76 65 28 29 3b 0a 20 20 20 20 7d 0a 20 20  eave();.    }.  
7750: 7d 0a 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  }..  sqlite3_fre
7760: 65 28 66 64 29 3b 0a 20 20 72 65 74 75 72 6e 20  e(fd);.  return 
7770: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4f 70 65  rc;.}../*.** Ope
7780: 6e 20 61 20 70 6f 74 65 6e 74 69 61 6c 6c 79 20  n a potentially 
7790: 71 75 6f 74 61 65 64 20 66 69 6c 65 20 66 6f 72  quotaed file for
77a0: 20 49 2f 4f 2e 0a 2a 2f 0a 71 75 6f 74 61 5f 46   I/O..*/.quota_F
77b0: 49 4c 45 20 2a 73 71 6c 69 74 65 33 5f 71 75 6f  ILE *sqlite3_quo
77c0: 74 61 5f 66 6f 70 65 6e 28 63 6f 6e 73 74 20 63  ta_fopen(const c
77d0: 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20  har *zFilename, 
77e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4d 6f 64  const char *zMod
77f0: 65 29 7b 0a 20 20 71 75 6f 74 61 5f 46 49 4c 45  e){.  quota_FILE
7800: 20 2a 70 20 3d 20 30 3b 0a 20 20 63 68 61 72 20   *p = 0;.  char 
7810: 2a 7a 46 75 6c 6c 20 3d 20 30 3b 0a 20 20 63 68  *zFull = 0;.  ch
7820: 61 72 20 2a 7a 46 75 6c 6c 54 72 61 6e 73 6c 61  ar *zFullTransla
7830: 74 65 64 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  ted = 0;.  int r
7840: 63 3b 0a 20 20 71 75 6f 74 61 47 72 6f 75 70 20  c;.  quotaGroup 
7850: 2a 70 47 72 6f 75 70 3b 0a 20 20 71 75 6f 74 61  *pGroup;.  quota
7860: 46 69 6c 65 20 2a 70 46 69 6c 65 3b 0a 0a 20 20  File *pFile;..  
7870: 7a 46 75 6c 6c 20 3d 20 28 63 68 61 72 2a 29 73  zFull = (char*)s
7880: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 67 51  qlite3_malloc(gQ
7890: 75 6f 74 61 2e 73 54 68 69 73 56 66 73 2e 6d 78  uota.sThisVfs.mx
78a0: 50 61 74 68 6e 61 6d 65 20 2b 20 31 29 3b 0a 20  Pathname + 1);. 
78b0: 20 69 66 28 20 7a 46 75 6c 6c 3d 3d 30 20 29 20   if( zFull==0 ) 
78c0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 72 63 20 3d  return 0;.  rc =
78d0: 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73   gQuota.pOrigVfs
78e0: 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  ->xFullPathname(
78f0: 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73 2c  gQuota.pOrigVfs,
7900: 20 7a 46 69 6c 65 6e 61 6d 65 2c 0a 20 20 20 20   zFilename,.    
7910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7920: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7930: 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66    gQuota.sThisVf
7940: 73 2e 6d 78 50 61 74 68 6e 61 6d 65 2b 31 2c 20  s.mxPathname+1, 
7950: 7a 46 75 6c 6c 29 3b 0a 20 20 69 66 28 20 72 63  zFull);.  if( rc
7960: 20 29 20 67 6f 74 6f 20 71 75 6f 74 61 5f 66 6f   ) goto quota_fo
7970: 70 65 6e 5f 65 72 72 6f 72 3b 0a 20 20 70 20 3d  pen_error;.  p =
7980: 20 28 71 75 6f 74 61 5f 46 49 4c 45 2a 29 73 71   (quota_FILE*)sq
7990: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73 69 7a  lite3_malloc(siz
79a0: 65 6f 66 28 2a 70 29 29 3b 0a 20 20 69 66 28 20  eof(*p));.  if( 
79b0: 70 3d 3d 30 20 29 20 67 6f 74 6f 20 71 75 6f 74  p==0 ) goto quot
79c0: 61 5f 66 6f 70 65 6e 5f 65 72 72 6f 72 3b 0a 20  a_fopen_error;. 
79d0: 20 6d 65 6d 73 65 74 28 70 2c 20 30 2c 20 73 69   memset(p, 0, si
79e0: 7a 65 6f 66 28 2a 70 29 29 3b 0a 20 20 7a 46 75  zeof(*p));.  zFu
79f0: 6c 6c 54 72 61 6e 73 6c 61 74 65 64 20 3d 20 71  llTranslated = q
7a00: 75 6f 74 61 5f 75 74 66 38 5f 74 6f 5f 6d 62 63  uota_utf8_to_mbc
7a10: 73 28 7a 46 75 6c 6c 29 3b 0a 20 20 69 66 28 20  s(zFull);.  if( 
7a20: 7a 46 75 6c 6c 54 72 61 6e 73 6c 61 74 65 64 3d  zFullTranslated=
7a30: 3d 30 20 29 20 67 6f 74 6f 20 71 75 6f 74 61 5f  =0 ) goto quota_
7a40: 66 6f 70 65 6e 5f 65 72 72 6f 72 3b 0a 20 20 70  fopen_error;.  p
7a50: 2d 3e 66 20 3d 20 66 6f 70 65 6e 28 7a 46 75 6c  ->f = fopen(zFul
7a60: 6c 54 72 61 6e 73 6c 61 74 65 64 2c 20 7a 4d 6f  lTranslated, zMo
7a70: 64 65 29 3b 0a 20 20 69 66 28 20 70 2d 3e 66 3d  de);.  if( p->f=
7a80: 3d 30 20 29 20 67 6f 74 6f 20 71 75 6f 74 61 5f  =0 ) goto quota_
7a90: 66 6f 70 65 6e 5f 65 72 72 6f 72 3b 0a 20 20 71  fopen_error;.  q
7aa0: 75 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 70  uotaEnter();.  p
7ab0: 47 72 6f 75 70 20 3d 20 71 75 6f 74 61 47 72 6f  Group = quotaGro
7ac0: 75 70 46 69 6e 64 28 7a 46 75 6c 6c 29 3b 0a 20  upFind(zFull);. 
7ad0: 20 69 66 28 20 70 47 72 6f 75 70 20 29 7b 0a 20   if( pGroup ){. 
7ae0: 20 20 20 70 46 69 6c 65 20 3d 20 71 75 6f 74 61     pFile = quota
7af0: 46 69 6e 64 46 69 6c 65 28 70 47 72 6f 75 70 2c  FindFile(pGroup,
7b00: 20 7a 46 75 6c 6c 2c 20 31 29 3b 0a 20 20 20 20   zFull, 1);.    
7b10: 69 66 28 20 70 46 69 6c 65 3d 3d 30 20 29 7b 0a  if( pFile==0 ){.
7b20: 20 20 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65        quotaLeave
7b30: 28 29 3b 0a 20 20 20 20 20 20 67 6f 74 6f 20 71  ();.      goto q
7b40: 75 6f 74 61 5f 66 6f 70 65 6e 5f 65 72 72 6f 72  uota_fopen_error
7b50: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 46 69 6c  ;.    }.    pFil
7b60: 65 2d 3e 6e 52 65 66 2b 2b 3b 0a 20 20 20 20 70  e->nRef++;.    p
7b70: 2d 3e 70 46 69 6c 65 20 3d 20 70 46 69 6c 65 3b  ->pFile = pFile;
7b80: 0a 20 20 7d 0a 20 20 71 75 6f 74 61 4c 65 61 76  .  }.  quotaLeav
7b90: 65 28 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  e();.  sqlite3_f
7ba0: 72 65 65 28 7a 46 75 6c 6c 29 3b 0a 23 69 66 20  ree(zFull);.#if 
7bb0: 53 51 4c 49 54 45 5f 4f 53 5f 57 49 4e 0a 20 20  SQLITE_OS_WIN.  
7bc0: 70 2d 3e 7a 4d 62 63 73 4e 61 6d 65 20 3d 20 7a  p->zMbcsName = z
7bd0: 46 75 6c 6c 54 72 61 6e 73 6c 61 74 65 64 3b 0a  FullTranslated;.
7be0: 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20  #endif.  return 
7bf0: 70 3b 0a 0a 71 75 6f 74 61 5f 66 6f 70 65 6e 5f  p;..quota_fopen_
7c00: 65 72 72 6f 72 3a 0a 20 20 71 75 6f 74 61 5f 6d  error:.  quota_m
7c10: 62 63 73 5f 66 72 65 65 28 7a 46 75 6c 6c 54 72  bcs_free(zFullTr
7c20: 61 6e 73 6c 61 74 65 64 29 3b 0a 20 20 73 71 6c  anslated);.  sql
7c30: 69 74 65 33 5f 66 72 65 65 28 7a 46 75 6c 6c 29  ite3_free(zFull)
7c40: 3b 0a 20 20 69 66 28 20 70 20 26 26 20 70 2d 3e  ;.  if( p && p->
7c50: 66 20 29 20 66 63 6c 6f 73 65 28 70 2d 3e 66 29  f ) fclose(p->f)
7c60: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
7c70: 28 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b  (p);.  return 0;
7c80: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61 64 20 63  .}../*.** Read c
7c90: 6f 6e 74 65 6e 74 20 66 72 6f 6d 20 61 20 71 75  ontent from a qu
7ca0: 6f 74 61 5f 46 49 4c 45 0a 2a 2f 0a 73 69 7a 65  ota_FILE.*/.size
7cb0: 5f 74 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61  _t sqlite3_quota
7cc0: 5f 66 72 65 61 64 28 0a 20 20 76 6f 69 64 20 2a  _fread(.  void *
7cd0: 70 42 75 66 2c 20 20 20 20 20 20 20 20 20 20 20  pBuf,           
7ce0: 20 2f 2a 20 53 74 6f 72 65 20 74 68 65 20 63 6f   /* Store the co
7cf0: 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a 20 20  ntent here */.  
7d00: 73 69 7a 65 5f 74 20 73 69 7a 65 2c 20 20 20 20  size_t size,    
7d10: 20 20 20 20 20 20 20 2f 2a 20 53 69 7a 65 20 6f         /* Size o
7d20: 66 20 65 61 63 68 20 65 6c 65 6d 65 6e 74 20 2a  f each element *
7d30: 2f 0a 20 20 73 69 7a 65 5f 74 20 6e 6d 65 6d 62  /.  size_t nmemb
7d40: 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75  ,          /* Nu
7d50: 6d 62 65 72 20 6f 66 20 65 6c 65 6d 65 6e 74 73  mber of elements
7d60: 20 74 6f 20 72 65 61 64 20 2a 2f 0a 20 20 71 75   to read */.  qu
7d70: 6f 74 61 5f 46 49 4c 45 20 2a 70 20 20 20 20 20  ota_FILE *p     
7d80: 20 20 20 20 20 2f 2a 20 52 65 61 64 20 66 72 6f       /* Read fro
7d90: 6d 20 74 68 69 73 20 71 75 6f 74 61 5f 46 49 4c  m this quota_FIL
7da0: 45 20 6f 62 6a 65 63 74 20 2a 2f 0a 29 7b 0a 20  E object */.){. 
7db0: 20 72 65 74 75 72 6e 20 66 72 65 61 64 28 70 42   return fread(pB
7dc0: 75 66 2c 20 73 69 7a 65 2c 20 6e 6d 65 6d 62 2c  uf, size, nmemb,
7dd0: 20 70 2d 3e 66 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   p->f);.}../*.**
7de0: 20 57 72 69 74 65 20 63 6f 6e 74 65 6e 74 20 69   Write content i
7df0: 6e 74 6f 20 61 20 71 75 6f 74 61 5f 46 49 4c 45  nto a quota_FILE
7e00: 2e 20 20 49 6e 76 6f 6b 65 20 74 68 65 20 71 75  .  Invoke the qu
7e10: 6f 74 61 20 63 61 6c 6c 62 61 63 6b 20 61 6e 64  ota callback and
7e20: 20 62 6c 6f 63 6b 0a 2a 2a 20 74 68 65 20 77 72   block.** the wr
7e30: 69 74 65 20 69 66 20 77 65 20 65 78 63 65 65 64  ite if we exceed
7e40: 20 71 75 6f 74 61 2e 0a 2a 2f 0a 73 69 7a 65 5f   quota..*/.size_
7e50: 74 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  t sqlite3_quota_
7e60: 66 77 72 69 74 65 28 0a 20 20 63 6f 6e 73 74 20  fwrite(.  const 
7e70: 76 6f 69 64 20 2a 70 42 75 66 2c 20 20 20 20 20  void *pBuf,     
7e80: 20 2f 2a 20 54 61 6b 65 20 63 6f 6e 74 65 6e 74   /* Take content
7e90: 20 74 6f 20 77 72 69 74 65 20 66 72 6f 6d 20 68   to write from h
7ea0: 65 72 65 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20  ere */.  size_t 
7eb0: 73 69 7a 65 2c 20 20 20 20 20 20 20 20 20 20 20  size,           
7ec0: 2f 2a 20 53 69 7a 65 20 6f 66 20 65 61 63 68 20  /* Size of each 
7ed0: 65 6c 65 6d 65 6e 74 20 2a 2f 0a 20 20 73 69 7a  element */.  siz
7ee0: 65 5f 74 20 6e 6d 65 6d 62 2c 20 20 20 20 20 20  e_t nmemb,      
7ef0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66      /* Number of
7f00: 20 65 6c 65 6d 65 6e 74 73 20 2a 2f 0a 20 20 71   elements */.  q
7f10: 75 6f 74 61 5f 46 49 4c 45 20 2a 70 20 20 20 20  uota_FILE *p    
7f20: 20 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74        /* Write t
7f30: 6f 20 74 68 69 73 20 71 75 6f 74 61 5f 46 49 4c  o this quota_FIL
7f40: 45 20 6f 62 6a 65 63 63 74 20 2a 2f 0a 29 7b 0a  E objecct */.){.
7f50: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
7f60: 69 4f 66 73 74 3b 0a 20 20 73 71 6c 69 74 65 33  iOfst;.  sqlite3
7f70: 5f 69 6e 74 36 34 20 69 45 6e 64 3b 0a 20 20 73  _int64 iEnd;.  s
7f80: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 7a 4e  qlite3_int64 szN
7f90: 65 77 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65 20  ew;.  quotaFile 
7fa0: 2a 70 46 69 6c 65 3b 0a 20 20 73 69 7a 65 5f 74  *pFile;.  size_t
7fb0: 20 72 63 3b 0a 0a 20 20 69 4f 66 73 74 20 3d 20   rc;..  iOfst = 
7fc0: 66 74 65 6c 6c 28 70 2d 3e 66 29 3b 0a 20 20 69  ftell(p->f);.  i
7fd0: 45 6e 64 20 3d 20 69 4f 66 73 74 20 2b 20 73 69  End = iOfst + si
7fe0: 7a 65 2a 6e 6d 65 6d 62 3b 0a 20 20 70 46 69 6c  ze*nmemb;.  pFil
7ff0: 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b 0a 20 20  e = p->pFile;.  
8000: 69 66 28 20 70 46 69 6c 65 20 26 26 20 70 46 69  if( pFile && pFi
8010: 6c 65 2d 3e 69 53 69 7a 65 3c 69 45 6e 64 20 29  le->iSize<iEnd )
8020: 7b 0a 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70  {.    quotaGroup
8030: 20 2a 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65   *pGroup = pFile
8040: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 71 75  ->pGroup;.    qu
8050: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 20 20  otaEnter();.    
8060: 73 7a 4e 65 77 20 3d 20 70 47 72 6f 75 70 2d 3e  szNew = pGroup->
8070: 69 53 69 7a 65 20 2d 20 70 46 69 6c 65 2d 3e 69  iSize - pFile->i
8080: 53 69 7a 65 20 2b 20 69 45 6e 64 3b 0a 20 20 20  Size + iEnd;.   
8090: 20 69 66 28 20 73 7a 4e 65 77 3e 70 47 72 6f 75   if( szNew>pGrou
80a0: 70 2d 3e 69 4c 69 6d 69 74 20 26 26 20 70 47 72  p->iLimit && pGr
80b0: 6f 75 70 2d 3e 69 4c 69 6d 69 74 3e 30 20 29 7b  oup->iLimit>0 ){
80c0: 0a 20 20 20 20 20 20 69 66 28 20 70 47 72 6f 75  .      if( pGrou
80d0: 70 2d 3e 78 43 61 6c 6c 62 61 63 6b 20 29 7b 0a  p->xCallback ){.
80e0: 20 20 20 20 20 20 20 20 70 47 72 6f 75 70 2d 3e          pGroup->
80f0: 78 43 61 6c 6c 62 61 63 6b 28 70 46 69 6c 65 2d  xCallback(pFile-
8100: 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 26 70 47 72  >zFilename, &pGr
8110: 6f 75 70 2d 3e 69 4c 69 6d 69 74 2c 20 73 7a 4e  oup->iLimit, szN
8120: 65 77 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20  ew,.            
8130: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 47                pG
8140: 72 6f 75 70 2d 3e 70 41 72 67 29 3b 0a 20 20 20  roup->pArg);.   
8150: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 73     }.      if( s
8160: 7a 4e 65 77 3e 70 47 72 6f 75 70 2d 3e 69 4c 69  zNew>pGroup->iLi
8170: 6d 69 74 20 26 26 20 70 47 72 6f 75 70 2d 3e 69  mit && pGroup->i
8180: 4c 69 6d 69 74 3e 30 20 29 7b 0a 20 20 20 20 20  Limit>0 ){.     
8190: 20 20 20 69 45 6e 64 20 3d 20 70 47 72 6f 75 70     iEnd = pGroup
81a0: 2d 3e 69 4c 69 6d 69 74 20 2d 20 70 47 72 6f 75  ->iLimit - pGrou
81b0: 70 2d 3e 69 53 69 7a 65 20 2b 20 70 46 69 6c 65  p->iSize + pFile
81c0: 2d 3e 69 53 69 7a 65 3b 0a 20 20 20 20 20 20 20  ->iSize;.       
81d0: 20 6e 6d 65 6d 62 20 3d 20 28 73 69 7a 65 5f 74   nmemb = (size_t
81e0: 29 28 28 69 45 6e 64 20 2d 20 69 4f 66 73 74 29  )((iEnd - iOfst)
81f0: 2f 73 69 7a 65 29 3b 0a 20 20 20 20 20 20 20 20  /size);.        
8200: 69 45 6e 64 20 3d 20 69 4f 66 73 74 20 2b 20 73  iEnd = iOfst + s
8210: 69 7a 65 2a 6e 6d 65 6d 62 3b 0a 20 20 20 20 20  ize*nmemb;.     
8220: 20 20 20 73 7a 4e 65 77 20 3d 20 70 47 72 6f 75     szNew = pGrou
8230: 70 2d 3e 69 53 69 7a 65 20 2d 20 70 46 69 6c 65  p->iSize - pFile
8240: 2d 3e 69 53 69 7a 65 20 2b 20 69 45 6e 64 3b 0a  ->iSize + iEnd;.
8250: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
8260: 20 20 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20    pGroup->iSize 
8270: 3d 20 73 7a 4e 65 77 3b 0a 20 20 20 20 70 46 69  = szNew;.    pFi
8280: 6c 65 2d 3e 69 53 69 7a 65 20 3d 20 69 45 6e 64  le->iSize = iEnd
8290: 3b 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65  ;.    quotaLeave
82a0: 28 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ();.  }else{.   
82b0: 20 70 46 69 6c 65 20 3d 20 30 3b 0a 20 20 7d 0a   pFile = 0;.  }.
82c0: 20 20 72 63 20 3d 20 66 77 72 69 74 65 28 70 42    rc = fwrite(pB
82d0: 75 66 2c 20 73 69 7a 65 2c 20 6e 6d 65 6d 62 2c  uf, size, nmemb,
82e0: 20 70 2d 3e 66 29 3b 0a 0a 20 20 2f 2a 20 49 66   p->f);..  /* If
82f0: 20 74 68 65 20 77 72 69 74 65 20 77 61 73 20 69   the write was i
8300: 6e 63 6f 6d 70 6c 65 74 65 2c 20 61 64 6a 75 73  ncomplete, adjus
8310: 74 20 74 68 65 20 66 69 6c 65 20 73 69 7a 65 20  t the file size 
8320: 61 6e 64 20 67 72 6f 75 70 20 73 69 7a 65 0a 20  and group size. 
8330: 20 2a 2a 20 64 6f 77 6e 77 61 72 64 20 2a 2f 0a   ** downward */.
8340: 20 20 69 66 28 20 72 63 3c 6e 6d 65 6d 62 20 26    if( rc<nmemb &
8350: 26 20 70 46 69 6c 65 20 29 7b 0a 20 20 20 20 73  & pFile ){.    s
8360: 69 7a 65 5f 74 20 6e 57 72 69 74 74 65 6e 20 3d  ize_t nWritten =
8370: 20 72 63 3b 0a 20 20 20 20 73 71 6c 69 74 65 33   rc;.    sqlite3
8380: 5f 69 6e 74 36 34 20 69 4e 65 77 45 6e 64 20 3d  _int64 iNewEnd =
8390: 20 69 4f 66 73 74 20 2b 20 73 69 7a 65 2a 6e 57   iOfst + size*nW
83a0: 72 69 74 74 65 6e 3b 0a 20 20 20 20 69 66 28 20  ritten;.    if( 
83b0: 69 4e 65 77 45 6e 64 3c 69 45 6e 64 20 29 20 69  iNewEnd<iEnd ) i
83c0: 4e 65 77 45 6e 64 20 3d 20 69 45 6e 64 3b 0a 20  NewEnd = iEnd;. 
83d0: 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29 3b     quotaEnter();
83e0: 0a 20 20 20 20 70 46 69 6c 65 2d 3e 70 47 72 6f  .    pFile->pGro
83f0: 75 70 2d 3e 69 53 69 7a 65 20 2b 3d 20 69 4e 65  up->iSize += iNe
8400: 77 45 6e 64 20 2d 20 70 46 69 6c 65 2d 3e 69 53  wEnd - pFile->iS
8410: 69 7a 65 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e  ize;.    pFile->
8420: 69 53 69 7a 65 20 3d 20 69 4e 65 77 45 6e 64 3b  iSize = iNewEnd;
8430: 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28  .    quotaLeave(
8440: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
8450: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6c 6f  rc;.}../*.** Clo
8460: 73 65 20 61 6e 20 6f 70 65 6e 20 71 75 6f 74 61  se an open quota
8470: 5f 46 49 4c 45 20 73 74 72 65 61 6d 2e 0a 2a 2f  _FILE stream..*/
8480: 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 71 75 6f  .int sqlite3_quo
8490: 74 61 5f 66 63 6c 6f 73 65 28 71 75 6f 74 61 5f  ta_fclose(quota_
84a0: 46 49 4c 45 20 2a 70 29 7b 0a 20 20 69 6e 74 20  FILE *p){.  int 
84b0: 72 63 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65 20  rc;.  quotaFile 
84c0: 2a 70 46 69 6c 65 3b 0a 20 20 72 63 20 3d 20 66  *pFile;.  rc = f
84d0: 63 6c 6f 73 65 28 70 2d 3e 66 29 3b 0a 20 20 70  close(p->f);.  p
84e0: 46 69 6c 65 20 3d 20 70 2d 3e 70 46 69 6c 65 3b  File = p->pFile;
84f0: 0a 20 20 69 66 28 20 70 46 69 6c 65 20 29 7b 0a  .  if( pFile ){.
8500: 20 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29      quotaEnter()
8510: 3b 0a 20 20 20 20 70 46 69 6c 65 2d 3e 6e 52 65  ;.    pFile->nRe
8520: 66 2d 2d 3b 0a 20 20 20 20 69 66 28 20 70 46 69  f--;.    if( pFi
8530: 6c 65 2d 3e 6e 52 65 66 3d 3d 30 20 29 7b 0a 20  le->nRef==0 ){. 
8540: 20 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70 20       quotaGroup 
8550: 2a 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65 2d  *pGroup = pFile-
8560: 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 20 20 69  >pGroup;.      i
8570: 66 28 20 70 46 69 6c 65 2d 3e 64 65 6c 65 74 65  f( pFile->delete
8580: 4f 6e 43 6c 6f 73 65 20 29 7b 0a 20 20 20 20 20  OnClose ){.     
8590: 20 20 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56     gQuota.pOrigV
85a0: 66 73 2d 3e 78 44 65 6c 65 74 65 28 67 51 75 6f  fs->xDelete(gQuo
85b0: 74 61 2e 70 4f 72 69 67 56 66 73 2c 20 70 46 69  ta.pOrigVfs, pFi
85c0: 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 30  le->zFilename, 0
85d0: 29 3b 0a 20 20 20 20 20 20 20 20 71 75 6f 74 61  );.        quota
85e0: 52 65 6d 6f 76 65 46 69 6c 65 28 70 46 69 6c 65  RemoveFile(pFile
85f0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
8600: 20 71 75 6f 74 61 47 72 6f 75 70 44 65 72 65 66   quotaGroupDeref
8610: 28 70 47 72 6f 75 70 29 3b 0a 20 20 20 20 7d 0a  (pGroup);.    }.
8620: 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29      quotaLeave()
8630: 3b 0a 20 20 7d 0a 23 69 66 20 53 51 4c 49 54 45  ;.  }.#if SQLITE
8640: 5f 4f 53 5f 57 49 4e 0a 20 20 71 75 6f 74 61 5f  _OS_WIN.  quota_
8650: 6d 62 63 73 5f 66 72 65 65 28 70 2d 3e 7a 4d 62  mbcs_free(p->zMb
8660: 63 73 4e 61 6d 65 29 3b 0a 23 65 6e 64 69 66 0a  csName);.#endif.
8670: 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70    sqlite3_free(p
8680: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
8690: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 6c 75 73 68 20 6d  }../*.** Flush m
86a0: 65 6d 6f 72 79 20 62 75 66 66 65 72 73 20 66 6f  emory buffers fo
86b0: 72 20 61 20 71 75 6f 74 61 5f 46 49 4c 45 20 74  r a quota_FILE t
86c0: 6f 20 64 69 73 6b 2e 0a 2a 2f 0a 69 6e 74 20 73  o disk..*/.int s
86d0: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 66 6c  qlite3_quota_ffl
86e0: 75 73 68 28 71 75 6f 74 61 5f 46 49 4c 45 20 2a  ush(quota_FILE *
86f0: 70 2c 20 69 6e 74 20 64 6f 46 73 79 6e 63 29 7b  p, int doFsync){
8700: 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 72 63 20  .  int rc;.  rc 
8710: 3d 20 66 66 6c 75 73 68 28 70 2d 3e 66 29 3b 0a  = fflush(p->f);.
8720: 20 20 69 66 28 20 72 63 3d 3d 30 20 26 26 20 64    if( rc==0 && d
8730: 6f 46 73 79 6e 63 20 29 7b 0a 23 69 66 20 53 51  oFsync ){.#if SQ
8740: 4c 49 54 45 5f 4f 53 5f 55 4e 49 58 0a 20 20 20  LITE_OS_UNIX.   
8750: 20 72 63 20 3d 20 66 73 79 6e 63 28 66 69 6c 65   rc = fsync(file
8760: 6e 6f 28 70 2d 3e 66 29 29 3b 0a 23 65 6e 64 69  no(p->f));.#endi
8770: 66 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53 5f  f.#if SQLITE_OS_
8780: 57 49 4e 0a 20 20 20 20 72 63 20 3d 20 5f 63 6f  WIN.    rc = _co
8790: 6d 6d 69 74 28 5f 66 69 6c 65 6e 6f 28 70 2d 3e  mmit(_fileno(p->
87a0: 66 29 29 3b 0a 23 65 6e 64 69 66 0a 20 20 7d 0a  f));.#endif.  }.
87b0: 20 20 72 65 74 75 72 6e 20 72 63 21 3d 30 3b 0a    return rc!=0;.
87c0: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 65 6b 20 6f 6e  }../*.** Seek on
87d0: 20 61 20 71 75 6f 74 61 5f 46 49 4c 45 20 73 74   a quota_FILE st
87e0: 72 65 61 6d 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c  ream..*/.int sql
87f0: 69 74 65 33 5f 71 75 6f 74 61 5f 66 73 65 65 6b  ite3_quota_fseek
8800: 28 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 2c 20  (quota_FILE *p, 
8810: 6c 6f 6e 67 20 6f 66 66 73 65 74 2c 20 69 6e 74  long offset, int
8820: 20 77 68 65 6e 63 65 29 7b 0a 20 20 72 65 74 75   whence){.  retu
8830: 72 6e 20 66 73 65 65 6b 28 70 2d 3e 66 2c 20 6f  rn fseek(p->f, o
8840: 66 66 73 65 74 2c 20 77 68 65 6e 63 65 29 3b 0a  ffset, whence);.
8850: 7d 0a 0a 2f 2a 0a 2a 2a 20 72 65 77 69 6e 64 20  }../*.** rewind 
8860: 61 20 71 75 6f 74 61 5f 46 49 4c 45 20 73 74 72  a quota_FILE str
8870: 65 61 6d 2e 0a 2a 2f 0a 76 6f 69 64 20 73 71 6c  eam..*/.void sql
8880: 69 74 65 33 5f 71 75 6f 74 61 5f 72 65 77 69 6e  ite3_quota_rewin
8890: 64 28 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 29  d(quota_FILE *p)
88a0: 7b 0a 20 20 72 65 77 69 6e 64 28 70 2d 3e 66 29  {.  rewind(p->f)
88b0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 65 6c 6c 20  ;.}../*.** Tell 
88c0: 74 68 65 20 63 75 72 72 65 6e 74 20 6c 6f 63 61  the current loca
88d0: 74 69 6f 6e 20 6f 66 20 61 20 71 75 6f 74 61 5f  tion of a quota_
88e0: 46 49 4c 45 20 73 74 72 65 61 6d 2e 0a 2a 2f 0a  FILE stream..*/.
88f0: 6c 6f 6e 67 20 73 71 6c 69 74 65 33 5f 71 75 6f  long sqlite3_quo
8900: 74 61 5f 66 74 65 6c 6c 28 71 75 6f 74 61 5f 46  ta_ftell(quota_F
8910: 49 4c 45 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  ILE *p){.  retur
8920: 6e 20 66 74 65 6c 6c 28 70 2d 3e 66 29 3b 0a 7d  n ftell(p->f);.}
8930: 0a 0a 2f 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65  ../*.** Test the
8940: 20 65 72 72 6f 72 20 69 6e 64 69 63 61 74 6f 72   error indicator
8950: 20 66 6f 72 20 74 68 65 20 67 69 76 65 6e 20 66   for the given f
8960: 69 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69  ile..*/.int sqli
8970: 74 65 33 5f 71 75 6f 74 61 5f 66 65 72 72 6f 72  te3_quota_ferror
8980: 28 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 29 7b  (quota_FILE *p){
8990: 0a 20 20 72 65 74 75 72 6e 20 66 65 72 72 6f 72  .  return ferror
89a0: 28 70 2d 3e 66 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  (p->f);.}../*.**
89b0: 20 54 72 75 6e 63 61 74 65 20 61 20 66 69 6c 65   Truncate a file
89c0: 20 74 6f 20 73 7a 4e 65 77 20 62 79 74 65 73 2e   to szNew bytes.
89d0: 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f  .*/.int sqlite3_
89e0: 71 75 6f 74 61 5f 66 74 72 75 6e 63 61 74 65 28  quota_ftruncate(
89f0: 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 2c 20 73  quota_FILE *p, s
8a00: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 7a 4e  qlite3_int64 szN
8a10: 65 77 29 7b 0a 20 20 71 75 6f 74 61 46 69 6c 65  ew){.  quotaFile
8a20: 20 2a 70 46 69 6c 65 20 3d 20 70 2d 3e 70 46 69   *pFile = p->pFi
8a30: 6c 65 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  le;.  int rc;.  
8a40: 69 66 28 20 28 70 46 69 6c 65 20 3d 20 70 2d 3e  if( (pFile = p->
8a50: 70 46 69 6c 65 29 21 3d 30 20 26 26 20 70 46 69  pFile)!=0 && pFi
8a60: 6c 65 2d 3e 69 53 69 7a 65 3c 73 7a 4e 65 77 20  le->iSize<szNew 
8a70: 29 7b 0a 20 20 20 20 71 75 6f 74 61 47 72 6f 75  ){.    quotaGrou
8a80: 70 20 2a 70 47 72 6f 75 70 3b 0a 20 20 20 20 69  p *pGroup;.    i
8a90: 66 28 20 70 46 69 6c 65 2d 3e 69 53 69 7a 65 3c  f( pFile->iSize<
8aa0: 73 7a 4e 65 77 20 29 7b 0a 20 20 20 20 20 20 2f  szNew ){.      /
8ab0: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 63  * This routine c
8ac0: 61 6e 6e 6f 74 20 62 65 20 75 73 65 64 20 74 6f  annot be used to
8ad0: 20 65 78 74 65 6e 64 20 61 20 66 69 6c 65 20 74   extend a file t
8ae0: 68 61 74 20 69 73 20 75 6e 64 65 72 0a 20 20 20  hat is under.   
8af0: 20 20 20 2a 2a 20 71 75 6f 74 61 20 6d 61 6e 61     ** quota mana
8b00: 67 65 6d 65 6e 74 2e 20 20 4f 6e 6c 79 20 74 72  gement.  Only tr
8b10: 75 65 20 74 72 75 6e 63 61 74 69 6f 6e 20 69 73  ue truncation is
8b20: 20 61 6c 6c 6f 77 65 64 2e 20 2a 2f 0a 20 20 20   allowed. */.   
8b30: 20 20 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20     return -1;.  
8b40: 20 20 7d 0a 20 20 20 20 70 47 72 6f 75 70 20 3d    }.    pGroup =
8b50: 20 70 46 69 6c 65 2d 3e 70 47 72 6f 75 70 3b 0a   pFile->pGroup;.
8b60: 20 20 20 20 71 75 6f 74 61 45 6e 74 65 72 28 29      quotaEnter()
8b70: 3b 0a 20 20 20 20 70 47 72 6f 75 70 2d 3e 69 53  ;.    pGroup->iS
8b80: 69 7a 65 20 2b 3d 20 73 7a 4e 65 77 20 2d 20 70  ize += szNew - p
8b90: 46 69 6c 65 2d 3e 69 53 69 7a 65 3b 0a 20 20 20  File->iSize;.   
8ba0: 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b 0a 20   quotaLeave();. 
8bb0: 20 7d 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53   }.#if SQLITE_OS
8bc0: 5f 55 4e 49 58 0a 20 20 72 63 20 3d 20 66 74 72  _UNIX.  rc = ftr
8bd0: 75 6e 63 61 74 65 28 66 69 6c 65 6e 6f 28 70 2d  uncate(fileno(p-
8be0: 3e 66 29 2c 20 73 7a 4e 65 77 29 3b 0a 23 65 6e  >f), szNew);.#en
8bf0: 64 69 66 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f  dif.#if SQLITE_O
8c00: 53 5f 57 49 4e 0a 23 20 20 69 66 20 64 65 66 69  S_WIN.#  if defi
8c10: 6e 65 64 28 5f 5f 4d 49 4e 47 57 33 32 5f 5f 29  ned(__MINGW32__)
8c20: 20 26 26 20 64 65 66 69 6e 65 64 28 53 51 4c 49   && defined(SQLI
8c30: 54 45 5f 54 45 53 54 29 0a 20 20 20 20 20 2f 2a  TE_TEST).     /*
8c40: 20 5f 63 68 73 69 7a 65 5f 73 28 29 20 69 73 20   _chsize_s() is 
8c50: 6d 69 73 73 69 6e 67 20 66 72 6f 6d 20 4d 69 6e  missing from Min
8c60: 67 57 20 28 61 73 20 6f 66 20 32 30 31 32 2d 31  gW (as of 2012-1
8c70: 31 2d 30 36 29 2e 20 20 55 73 65 0a 20 20 20 20  1-06).  Use.    
8c80: 20 2a 2a 20 5f 63 68 73 69 7a 65 28 29 20 61 73   ** _chsize() as
8c90: 20 61 20 77 6f 72 6b 2d 61 72 6f 75 6e 64 20 66   a work-around f
8ca0: 6f 72 20 74 65 73 74 69 6e 67 20 70 75 72 70 6f  or testing purpo
8cb0: 73 65 73 2e 20 2a 2f 0a 20 20 20 20 20 72 63 20  ses. */.     rc 
8cc0: 3d 20 5f 63 68 73 69 7a 65 28 5f 66 69 6c 65 6e  = _chsize(_filen
8cd0: 6f 28 70 2d 3e 66 29 2c 20 28 6c 6f 6e 67 29 73  o(p->f), (long)s
8ce0: 7a 4e 65 77 29 3b 0a 23 20 20 65 6c 73 65 0a 20  zNew);.#  else. 
8cf0: 20 20 20 20 72 63 20 3d 20 5f 63 68 73 69 7a 65      rc = _chsize
8d00: 5f 73 28 5f 66 69 6c 65 6e 6f 28 70 2d 3e 66 29  _s(_fileno(p->f)
8d10: 2c 20 73 7a 4e 65 77 29 3b 0a 23 20 20 65 6e 64  , szNew);.#  end
8d20: 69 66 0a 23 65 6e 64 69 66 0a 20 20 69 66 28 20  if.#endif.  if( 
8d30: 70 46 69 6c 65 20 26 26 20 72 63 3d 3d 30 20 29  pFile && rc==0 )
8d40: 7b 0a 20 20 20 20 71 75 6f 74 61 47 72 6f 75 70  {.    quotaGroup
8d50: 20 2a 70 47 72 6f 75 70 20 3d 20 70 46 69 6c 65   *pGroup = pFile
8d60: 2d 3e 70 47 72 6f 75 70 3b 0a 20 20 20 20 71 75  ->pGroup;.    qu
8d70: 6f 74 61 45 6e 74 65 72 28 29 3b 0a 20 20 20 20  otaEnter();.    
8d80: 70 47 72 6f 75 70 2d 3e 69 53 69 7a 65 20 2b 3d  pGroup->iSize +=
8d90: 20 73 7a 4e 65 77 20 2d 20 70 46 69 6c 65 2d 3e   szNew - pFile->
8da0: 69 53 69 7a 65 3b 0a 20 20 20 20 70 46 69 6c 65  iSize;.    pFile
8db0: 2d 3e 69 53 69 7a 65 20 3d 20 73 7a 4e 65 77 3b  ->iSize = szNew;
8dc0: 0a 20 20 20 20 71 75 6f 74 61 4c 65 61 76 65 28  .    quotaLeave(
8dd0: 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20  );.  }.  return 
8de0: 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 65 74  rc;.}../*.** Det
8df0: 65 72 6d 69 6e 65 20 74 68 65 20 74 69 6d 65 20  ermine the time 
8e00: 74 68 61 74 20 74 68 65 20 67 69 76 65 6e 20 66  that the given f
8e10: 69 6c 65 20 77 61 73 20 6c 61 73 74 20 6d 6f 64  ile was last mod
8e20: 69 66 69 65 64 2c 20 69 6e 0a 2a 2a 20 73 65 63  ified, in.** sec
8e30: 6f 6e 64 73 20 73 69 7a 65 20 31 39 37 30 2e 20  onds size 1970. 
8e40: 20 57 72 69 74 65 20 74 68 65 20 72 65 73 75 6c   Write the resul
8e50: 74 20 69 6e 74 6f 20 2a 70 54 69 6d 65 2e 20 20  t into *pTime.  
8e60: 52 65 74 75 72 6e 20 30 20 6f 6e 0a 2a 2a 20 73  Return 0 on.** s
8e70: 75 63 63 65 73 73 20 61 6e 64 20 6e 6f 6e 2d 7a  uccess and non-z
8e80: 65 72 6f 20 6f 6e 20 61 6e 79 20 6b 69 6e 64 20  ero on any kind 
8e90: 6f 66 20 65 72 72 6f 72 2e 0a 2a 2f 0a 69 6e 74  of error..*/.int
8ea0: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66   sqlite3_quota_f
8eb0: 69 6c 65 5f 6d 74 69 6d 65 28 71 75 6f 74 61 5f  ile_mtime(quota_
8ec0: 46 49 4c 45 20 2a 70 2c 20 74 69 6d 65 5f 74 20  FILE *p, time_t 
8ed0: 2a 70 54 69 6d 65 29 7b 0a 20 20 69 6e 74 20 72  *pTime){.  int r
8ee0: 63 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53  c;.#if SQLITE_OS
8ef0: 5f 55 4e 49 58 0a 20 20 73 74 72 75 63 74 20 73  _UNIX.  struct s
8f00: 74 61 74 20 62 75 66 3b 0a 20 20 72 63 20 3d 20  tat buf;.  rc = 
8f10: 66 73 74 61 74 28 66 69 6c 65 6e 6f 28 70 2d 3e  fstat(fileno(p->
8f20: 66 29 2c 20 26 62 75 66 29 3b 0a 23 65 6e 64 69  f), &buf);.#endi
8f30: 66 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53 5f  f.#if SQLITE_OS_
8f40: 57 49 4e 0a 20 20 73 74 72 75 63 74 20 5f 73 74  WIN.  struct _st
8f50: 61 74 69 36 34 20 62 75 66 3b 0a 20 20 72 63 20  ati64 buf;.  rc 
8f60: 3d 20 5f 73 74 61 74 69 36 34 28 70 2d 3e 7a 4d  = _stati64(p->zM
8f70: 62 63 73 4e 61 6d 65 2c 20 26 62 75 66 29 3b 0a  bcsName, &buf);.
8f80: 23 65 6e 64 69 66 0a 20 20 69 66 28 20 72 63 3d  #endif.  if( rc=
8f90: 3d 30 20 29 20 2a 70 54 69 6d 65 20 3d 20 62 75  =0 ) *pTime = bu
8fa0: 66 2e 73 74 5f 6d 74 69 6d 65 3b 0a 20 20 72 65  f.st_mtime;.  re
8fb0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
8fc0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 74 72 75  * Return the tru
8fd0: 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 66 69  e size of the fi
8fe0: 6c 65 2c 20 61 73 20 72 65 70 6f 72 74 65 64 20  le, as reported 
8ff0: 62 79 20 74 68 65 20 6f 70 65 72 61 74 69 6e 67  by the operating
9000: 0a 2a 2a 20 73 79 73 74 65 6d 2e 0a 2a 2f 0a 73  .** system..*/.s
9010: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 73 71 6c  qlite3_int64 sql
9020: 69 74 65 33 5f 71 75 6f 74 61 5f 66 69 6c 65 5f  ite3_quota_file_
9030: 74 72 75 65 73 69 7a 65 28 71 75 6f 74 61 5f 46  truesize(quota_F
9040: 49 4c 45 20 2a 70 29 7b 0a 20 20 69 6e 74 20 72  ILE *p){.  int r
9050: 63 3b 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53  c;.#if SQLITE_OS
9060: 5f 55 4e 49 58 0a 20 20 73 74 72 75 63 74 20 73  _UNIX.  struct s
9070: 74 61 74 20 62 75 66 3b 0a 20 20 72 63 20 3d 20  tat buf;.  rc = 
9080: 66 73 74 61 74 28 66 69 6c 65 6e 6f 28 70 2d 3e  fstat(fileno(p->
9090: 66 29 2c 20 26 62 75 66 29 3b 0a 23 65 6e 64 69  f), &buf);.#endi
90a0: 66 0a 23 69 66 20 53 51 4c 49 54 45 5f 4f 53 5f  f.#if SQLITE_OS_
90b0: 57 49 4e 0a 20 20 73 74 72 75 63 74 20 5f 73 74  WIN.  struct _st
90c0: 61 74 69 36 34 20 62 75 66 3b 0a 20 20 72 63 20  ati64 buf;.  rc 
90d0: 3d 20 5f 73 74 61 74 69 36 34 28 70 2d 3e 7a 4d  = _stati64(p->zM
90e0: 62 63 73 4e 61 6d 65 2c 20 26 62 75 66 29 3b 0a  bcsName, &buf);.
90f0: 23 65 6e 64 69 66 0a 20 20 72 65 74 75 72 6e 20  #endif.  return 
9100: 72 63 3d 3d 30 20 3f 20 62 75 66 2e 73 74 5f 73  rc==0 ? buf.st_s
9110: 69 7a 65 20 3a 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a  ize : -1;.}../*.
9120: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 73 69  ** Return the si
9130: 7a 65 20 6f 66 20 74 68 65 20 66 69 6c 65 2c 20  ze of the file, 
9140: 61 73 20 69 74 20 69 73 20 6b 6e 6f 77 6e 20 74  as it is known t
9150: 6f 20 74 68 65 20 71 75 6f 74 61 20 73 75 62 73  o the quota subs
9160: 79 73 74 65 6d 2e 0a 2a 2f 0a 73 71 6c 69 74 65  ystem..*/.sqlite
9170: 33 5f 69 6e 74 36 34 20 73 71 6c 69 74 65 33 5f  3_int64 sqlite3_
9180: 71 75 6f 74 61 5f 66 69 6c 65 5f 73 69 7a 65 28  quota_file_size(
9190: 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 29 7b 0a  quota_FILE *p){.
91a0: 20 20 72 65 74 75 72 6e 20 70 2d 3e 70 46 69 6c    return p->pFil
91b0: 65 20 3f 20 70 2d 3e 70 46 69 6c 65 2d 3e 69 53  e ? p->pFile->iS
91c0: 69 7a 65 20 3a 20 2d 31 3b 0a 7d 0a 0a 2f 2a 0a  ize : -1;.}../*.
91d0: 2a 2a 20 44 65 74 65 72 6d 69 6e 65 20 74 68 65  ** Determine the
91e0: 20 61 6d 6f 75 6e 74 20 6f 66 20 64 61 74 61 20   amount of data 
91f0: 69 6e 20 62 79 74 65 73 20 61 76 61 69 6c 61 62  in bytes availab
9200: 6c 65 20 66 6f 72 20 72 65 61 64 69 6e 67 0a 2a  le for reading.*
9210: 2a 20 69 6e 20 74 68 65 20 67 69 76 65 6e 20 66  * in the given f
9220: 69 6c 65 2e 0a 2a 2f 0a 6c 6f 6e 67 20 73 71 6c  ile..*/.long sql
9230: 69 74 65 33 5f 71 75 6f 74 61 5f 66 69 6c 65 5f  ite3_quota_file_
9240: 61 76 61 69 6c 61 62 6c 65 28 71 75 6f 74 61 5f  available(quota_
9250: 46 49 4c 45 20 2a 70 29 7b 0a 20 20 46 49 4c 45  FILE *p){.  FILE
9260: 2a 20 66 20 3d 20 70 2d 3e 66 3b 0a 20 20 6c 6f  * f = p->f;.  lo
9270: 6e 67 20 70 6f 73 31 2c 20 70 6f 73 32 3b 0a 20  ng pos1, pos2;. 
9280: 20 69 6e 74 20 72 63 3b 0a 20 20 70 6f 73 31 20   int rc;.  pos1 
9290: 3d 20 66 74 65 6c 6c 28 66 29 3b 0a 20 20 69 66  = ftell(f);.  if
92a0: 20 28 20 70 6f 73 31 20 3c 20 30 20 29 20 72 65   ( pos1 < 0 ) re
92b0: 74 75 72 6e 20 2d 31 3b 0a 20 20 72 63 20 3d 20  turn -1;.  rc = 
92c0: 66 73 65 65 6b 28 66 2c 20 30 2c 20 53 45 45 4b  fseek(f, 0, SEEK
92d0: 5f 45 4e 44 29 3b 0a 20 20 69 66 20 28 20 72 63  _END);.  if ( rc
92e0: 20 21 3d 20 30 20 29 20 72 65 74 75 72 6e 20 2d   != 0 ) return -
92f0: 31 3b 0a 20 20 70 6f 73 32 20 3d 20 66 74 65 6c  1;.  pos2 = ftel
9300: 6c 28 66 29 3b 0a 20 20 69 66 20 28 20 70 6f 73  l(f);.  if ( pos
9310: 32 20 3c 20 30 20 29 20 72 65 74 75 72 6e 20 2d  2 < 0 ) return -
9320: 31 3b 0a 20 20 72 63 20 3d 20 66 73 65 65 6b 28  1;.  rc = fseek(
9330: 66 2c 20 70 6f 73 31 2c 20 53 45 45 4b 5f 53 45  f, pos1, SEEK_SE
9340: 54 29 3b 0a 20 20 69 66 20 28 20 72 63 20 21 3d  T);.  if ( rc !=
9350: 20 30 20 29 20 72 65 74 75 72 6e 20 2d 31 3b 0a   0 ) return -1;.
9360: 20 20 72 65 74 75 72 6e 20 70 6f 73 32 20 2d 20    return pos2 - 
9370: 70 6f 73 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  pos1;.}../*.** R
9380: 65 6d 6f 76 65 20 61 20 6d 61 6e 61 67 65 64 20  emove a managed 
9390: 66 69 6c 65 2e 20 20 55 70 64 61 74 65 20 71 75  file.  Update qu
93a0: 6f 74 61 73 20 61 63 63 6f 72 64 69 6e 67 6c 79  otas accordingly
93b0: 2e 0a 2a 2f 0a 69 6e 74 20 73 71 6c 69 74 65 33  ..*/.int sqlite3
93c0: 5f 71 75 6f 74 61 5f 72 65 6d 6f 76 65 28 63 6f  _quota_remove(co
93d0: 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e  nst char *zFilen
93e0: 61 6d 65 29 7b 0a 20 20 63 68 61 72 20 2a 7a 46  ame){.  char *zF
93f0: 75 6c 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  ull;            
9400: 2f 2a 20 46 75 6c 6c 20 70 61 74 68 6e 61 6d 65  /* Full pathname
9410: 20 66 6f 72 20 7a 46 69 6c 65 6e 61 6d 65 20 2a   for zFilename *
9420: 2f 0a 20 20 73 69 7a 65 5f 74 20 6e 46 75 6c 6c  /.  size_t nFull
9430: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
9440: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 69  umber of bytes i
9450: 6e 20 7a 46 69 6c 65 6e 61 6d 65 20 2a 2f 0a 20  n zFilename */. 
9460: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
9470: 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 73 75           /* Resu
9480: 6c 74 20 63 6f 64 65 20 2a 2f 0a 20 20 71 75 6f  lt code */.  quo
9490: 74 61 47 72 6f 75 70 20 2a 70 47 72 6f 75 70 3b  taGroup *pGroup;
94a0: 20 20 20 20 20 2f 2a 20 47 72 6f 75 70 20 63 6f       /* Group co
94b0: 6e 74 61 69 6e 69 6e 67 20 7a 46 69 6c 65 6e 61  ntaining zFilena
94c0: 6d 65 20 2a 2f 0a 20 20 71 75 6f 74 61 46 69 6c  me */.  quotaFil
94d0: 65 20 2a 70 46 69 6c 65 3b 20 20 20 20 20 20 20  e *pFile;       
94e0: 2f 2a 20 41 20 66 69 6c 65 20 69 6e 20 74 68 65  /* A file in the
94f0: 20 67 72 6f 75 70 20 2a 2f 0a 20 20 71 75 6f 74   group */.  quot
9500: 61 46 69 6c 65 20 2a 70 4e 65 78 74 46 69 6c 65  aFile *pNextFile
9510: 3b 20 20 20 2f 2a 20 6e 65 78 74 20 66 69 6c 65  ;   /* next file
9520: 20 69 6e 20 74 68 65 20 67 72 6f 75 70 20 2a 2f   in the group */
9530: 0a 20 20 69 6e 74 20 64 69 66 66 3b 20 20 20 20  .  int diff;    
9540: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 44 69             /* Di
9550: 66 66 65 72 65 6e 63 65 20 62 65 74 77 65 65 6e  fference between
9560: 20 66 69 6c 65 6e 61 6d 65 73 20 2a 2f 0a 20 20   filenames */.  
9570: 63 68 61 72 20 63 3b 20 20 20 20 20 20 20 20 20  char c;         
9580: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74          /* First
9590: 20 63 68 61 72 61 63 74 65 72 20 70 61 73 74 20   character past 
95a0: 65 6e 64 20 6f 66 20 70 61 74 74 65 72 6e 20 2a  end of pattern *
95b0: 2f 0a 0a 20 20 7a 46 75 6c 6c 20 3d 20 28 63 68  /..  zFull = (ch
95c0: 61 72 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c  ar*)sqlite3_mall
95d0: 6f 63 28 67 51 75 6f 74 61 2e 73 54 68 69 73 56  oc(gQuota.sThisV
95e0: 66 73 2e 6d 78 50 61 74 68 6e 61 6d 65 20 2b 20  fs.mxPathname + 
95f0: 31 29 3b 0a 20 20 69 66 28 20 7a 46 75 6c 6c 3d  1);.  if( zFull=
9600: 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
9610: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 72 63 20 3d  TE_NOMEM;.  rc =
9620: 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73   gQuota.pOrigVfs
9630: 2d 3e 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28  ->xFullPathname(
9640: 67 51 75 6f 74 61 2e 70 4f 72 69 67 56 66 73 2c  gQuota.pOrigVfs,
9650: 20 7a 46 69 6c 65 6e 61 6d 65 2c 0a 20 20 20 20   zFilename,.    
9660: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9680: 20 20 67 51 75 6f 74 61 2e 73 54 68 69 73 56 66    gQuota.sThisVf
9690: 73 2e 6d 78 50 61 74 68 6e 61 6d 65 2b 31 2c 20  s.mxPathname+1, 
96a0: 7a 46 75 6c 6c 29 3b 0a 20 20 69 66 28 20 72 63  zFull);.  if( rc
96b0: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
96c0: 66 72 65 65 28 7a 46 75 6c 6c 29 3b 0a 20 20 20  free(zFull);.   
96d0: 20 72 65 74 75 72 6e 20 72 63 3b 0a 20 20 7d 0a   return rc;.  }.
96e0: 0a 20 20 2f 2a 20 46 69 67 75 72 65 20 6f 75 74  .  /* Figure out
96f0: 20 74 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74   the length of t
9700: 68 65 20 66 75 6c 6c 20 70 61 74 68 6e 61 6d 65  he full pathname
9710: 2e 20 20 49 66 20 74 68 65 20 6e 61 6d 65 20 65  .  If the name e
9720: 6e 64 73 20 77 69 74 68 0a 20 20 2a 2a 20 2f 20  nds with.  ** / 
9730: 28 6f 72 20 5c 20 6f 6e 20 77 69 6e 64 6f 77 73  (or \ on windows
9740: 29 20 74 68 65 6e 20 72 65 6d 6f 76 65 20 74 68  ) then remove th
9750: 65 20 74 72 61 69 6c 69 6e 67 20 2f 2e 0a 20 20  e trailing /..  
9760: 2a 2f 0a 20 20 6e 46 75 6c 6c 20 3d 20 73 74 72  */.  nFull = str
9770: 6c 65 6e 28 7a 46 75 6c 6c 29 3b 0a 20 20 69 66  len(zFull);.  if
9780: 28 20 6e 46 75 6c 6c 3e 30 20 26 26 20 28 7a 46  ( nFull>0 && (zF
9790: 75 6c 6c 5b 6e 46 75 6c 6c 2d 31 5d 3d 3d 27 2f  ull[nFull-1]=='/
97a0: 27 20 7c 7c 20 7a 46 75 6c 6c 5b 6e 46 75 6c 6c  ' || zFull[nFull
97b0: 2d 31 5d 3d 3d 27 5c 5c 27 29 20 29 7b 0a 20 20  -1]=='\\') ){.  
97c0: 20 20 6e 46 75 6c 6c 2d 2d 3b 0a 20 20 20 20 7a    nFull--;.    z
97d0: 46 75 6c 6c 5b 6e 46 75 6c 6c 5d 20 3d 20 30 3b  Full[nFull] = 0;
97e0: 0a 20 20 7d 0a 0a 20 20 71 75 6f 74 61 45 6e 74  .  }..  quotaEnt
97f0: 65 72 28 29 3b 0a 20 20 70 47 72 6f 75 70 20 3d  er();.  pGroup =
9800: 20 71 75 6f 74 61 47 72 6f 75 70 46 69 6e 64 28   quotaGroupFind(
9810: 7a 46 75 6c 6c 29 3b 0a 20 20 69 66 28 20 70 47  zFull);.  if( pG
9820: 72 6f 75 70 20 29 7b 0a 20 20 20 20 66 6f 72 28  roup ){.    for(
9830: 70 46 69 6c 65 3d 70 47 72 6f 75 70 2d 3e 70 46  pFile=pGroup->pF
9840: 69 6c 65 73 3b 20 70 46 69 6c 65 20 26 26 20 72  iles; pFile && r
9850: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 3b 20 70 46  c==SQLITE_OK; pF
9860: 69 6c 65 3d 70 4e 65 78 74 46 69 6c 65 29 7b 0a  ile=pNextFile){.
9870: 20 20 20 20 20 20 70 4e 65 78 74 46 69 6c 65 20        pNextFile 
9880: 3d 20 70 46 69 6c 65 2d 3e 70 4e 65 78 74 3b 0a  = pFile->pNext;.
9890: 20 20 20 20 20 20 64 69 66 66 20 3d 20 73 74 72        diff = str
98a0: 6e 63 6d 70 28 7a 46 75 6c 6c 2c 20 70 46 69 6c  ncmp(zFull, pFil
98b0: 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 6e 46  e->zFilename, nF
98c0: 75 6c 6c 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ull);.      if( 
98d0: 64 69 66 66 3d 3d 30 20 26 26 20 28 28 63 20 3d  diff==0 && ((c =
98e0: 20 70 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d   pFile->zFilenam
98f0: 65 5b 6e 46 75 6c 6c 5d 29 3d 3d 30 20 7c 7c 20  e[nFull])==0 || 
9900: 63 3d 3d 27 2f 27 20 7c 7c 20 63 3d 3d 27 5c 5c  c=='/' || c=='\\
9910: 27 29 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  ') ){.        if
9920: 28 20 70 46 69 6c 65 2d 3e 6e 52 65 66 20 29 7b  ( pFile->nRef ){
9930: 0a 20 20 20 20 20 20 20 20 20 20 70 46 69 6c 65  .          pFile
9940: 2d 3e 64 65 6c 65 74 65 4f 6e 43 6c 6f 73 65 20  ->deleteOnClose 
9950: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 1;.        }el
9960: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 72 63  se{.          rc
9970: 20 3d 20 67 51 75 6f 74 61 2e 70 4f 72 69 67 56   = gQuota.pOrigV
9980: 66 73 2d 3e 78 44 65 6c 65 74 65 28 67 51 75 6f  fs->xDelete(gQuo
9990: 74 61 2e 70 4f 72 69 67 56 66 73 2c 20 70 46 69  ta.pOrigVfs, pFi
99a0: 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d 65 2c 20 30  le->zFilename, 0
99b0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 71 75 6f  );.          quo
99c0: 74 61 52 65 6d 6f 76 65 46 69 6c 65 28 70 46 69  taRemoveFile(pFi
99d0: 6c 65 29 3b 0a 20 20 20 20 20 20 20 20 20 20 71  le);.          q
99e0: 75 6f 74 61 47 72 6f 75 70 44 65 72 65 66 28 70  uotaGroupDeref(p
99f0: 47 72 6f 75 70 29 3b 0a 20 20 20 20 20 20 20 20  Group);.        
9a00: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  }.      }.    }.
9a10: 20 20 7d 0a 20 20 71 75 6f 74 61 4c 65 61 76 65    }.  quotaLeave
9a20: 28 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  ();.  sqlite3_fr
9a30: 65 65 28 7a 46 75 6c 6c 29 3b 0a 20 20 72 65 74  ee(zFull);.  ret
9a40: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 2a 2a 2a  urn rc;.}../****
9a50: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9a60: 2a 2a 2a 2a 2a 2a 2a 2a 2a 20 54 65 73 74 20 43  ********* Test C
9a70: 6f 64 65 20 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ode ************
9a80: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
9a90: 2a 2a 2a 2a 2a 2a 2a 2f 0a 23 69 66 64 65 66 20  *******/.#ifdef 
9aa0: 53 51 4c 49 54 45 5f 54 45 53 54 0a 23 69 66 20  SQLITE_TEST.#if 
9ab0: 64 65 66 69 6e 65 64 28 49 4e 43 4c 55 44 45 5f  defined(INCLUDE_
9ac0: 53 51 4c 49 54 45 5f 54 43 4c 5f 48 29 0a 23 20  SQLITE_TCL_H).# 
9ad0: 20 69 6e 63 6c 75 64 65 20 22 73 71 6c 69 74 65   include "sqlite
9ae0: 5f 74 63 6c 2e 68 22 0a 23 65 6c 73 65 0a 23 20  _tcl.h".#else.# 
9af0: 20 69 6e 63 6c 75 64 65 20 22 74 63 6c 2e 68 22   include "tcl.h"
9b00: 0a 23 20 20 69 66 6e 64 65 66 20 53 51 4c 49 54  .#  ifndef SQLIT
9b10: 45 5f 54 43 4c 41 50 49 0a 23 20 20 20 20 64 65  E_TCLAPI.#    de
9b20: 66 69 6e 65 20 53 51 4c 49 54 45 5f 54 43 4c 41  fine SQLITE_TCLA
9b30: 50 49 0a 23 20 20 65 6e 64 69 66 0a 23 65 6e 64  PI.#  endif.#end
9b40: 69 66 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65  if../*.** Argume
9b50: 6e 74 20 70 61 73 73 65 64 20 74 6f 20 61 20 54  nt passed to a T
9b60: 43 4c 20 71 75 6f 74 61 2d 6f 76 65 72 2d 6c 69  CL quota-over-li
9b70: 6d 69 74 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2f  mit callback..*/
9b80: 0a 74 79 70 65 64 65 66 20 73 74 72 75 63 74 20  .typedef struct 
9b90: 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b  TclQuotaCallback
9ba0: 20 54 63 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63   TclQuotaCallbac
9bb0: 6b 3b 0a 73 74 72 75 63 74 20 54 63 6c 51 75 6f  k;.struct TclQuo
9bc0: 74 61 43 61 6c 6c 62 61 63 6b 20 7b 0a 20 20 54  taCallback {.  T
9bd0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
9be0: 70 3b 20 20 20 20 2f 2a 20 49 6e 74 65 72 70 72  p;    /* Interpr
9bf0: 65 74 65 72 20 69 6e 20 77 68 69 63 68 20 74 6f  eter in which to
9c00: 20 72 75 6e 20 74 68 65 20 73 63 72 69 70 74 20   run the script 
9c10: 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53  */.  Tcl_Obj *pS
9c20: 63 72 69 70 74 3b 20 20 20 20 20 20 2f 2a 20 53  cript;      /* S
9c30: 63 72 69 70 74 20 74 6f 20 62 65 20 72 75 6e 20  cript to be run 
9c40: 2a 2f 0a 7d 3b 0a 0a 65 78 74 65 72 6e 20 63 6f  */.};..extern co
9c50: 6e 73 74 20 63 68 61 72 20 2a 73 71 6c 69 74 65  nst char *sqlite
9c60: 33 45 72 72 4e 61 6d 65 28 69 6e 74 29 3b 0a 0a  3ErrName(int);..
9c70: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74  ./*.** This is t
9c80: 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 72 6f 6d  he callback from
9c90: 20 61 20 71 75 6f 74 61 2d 6f 76 65 72 2d 6c 69   a quota-over-li
9ca0: 6d 69 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  mit..*/.static v
9cb0: 6f 69 64 20 74 63 6c 51 75 6f 74 61 43 61 6c 6c  oid tclQuotaCall
9cc0: 62 61 63 6b 28 0a 20 20 63 6f 6e 73 74 20 63 68  back(.  const ch
9cd0: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 2c 20 20  ar *zFilename,  
9ce0: 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20          /* Name 
9cf0: 6f 66 20 66 69 6c 65 20 77 68 6f 73 65 20 73 69  of file whose si
9d00: 7a 65 20 69 6e 63 72 65 61 73 65 73 20 2a 2f 0a  ze increases */.
9d10: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
9d20: 2a 70 69 4c 69 6d 69 74 2c 20 20 20 20 20 20 20  *piLimit,       
9d30: 20 20 2f 2a 20 49 4e 2f 4f 55 54 3a 20 54 68 65    /* IN/OUT: The
9d40: 20 63 75 72 72 65 6e 74 20 6c 69 6d 69 74 20 2a   current limit *
9d50: 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  /.  sqlite3_int6
9d60: 34 20 69 53 69 7a 65 2c 20 20 20 20 20 20 20 20  4 iSize,        
9d70: 20 20 20 20 2f 2a 20 54 6f 74 61 6c 20 73 69 7a      /* Total siz
9d80: 65 20 6f 66 20 61 6c 6c 20 66 69 6c 65 73 20 69  e of all files i
9d90: 6e 20 74 68 65 20 67 72 6f 75 70 20 2a 2f 0a 20  n the group */. 
9da0: 20 76 6f 69 64 20 2a 70 41 72 67 20 20 20 20 20   void *pArg     
9db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9dc0: 20 2f 2a 20 43 6c 69 65 6e 74 20 64 61 74 61 20   /* Client data 
9dd0: 2a 2f 0a 29 7b 0a 20 20 54 63 6c 51 75 6f 74 61  */.){.  TclQuota
9de0: 43 61 6c 6c 62 61 63 6b 20 2a 70 3b 20 20 20 20  Callback *p;    
9df0: 20 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 62          /* Callb
9e00: 61 63 6b 20 73 63 72 69 70 74 20 6f 62 6a 65 63  ack script objec
9e10: 74 20 2a 2f 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a  t */.  Tcl_Obj *
9e20: 70 45 76 61 6c 3b 20 20 20 20 20 20 20 20 20 20  pEval;          
9e30: 20 20 20 20 20 20 20 2f 2a 20 53 63 72 69 70 74         /* Script
9e40: 20 74 6f 20 65 76 61 6c 75 61 74 65 20 2a 2f 0a   to evaluate */.
9e50: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 56 61 72 6e    Tcl_Obj *pVarn
9e60: 61 6d 65 3b 20 20 20 20 20 20 20 20 20 20 20 20  ame;            
9e70: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 76 61 72    /* Name of var
9e80: 69 61 62 6c 65 20 74 6f 20 70 61 73 73 20 61 73  iable to pass as
9e90: 20 32 6e 64 20 61 72 67 20 2a 2f 0a 20 20 75 6e   2nd arg */.  un
9ea0: 73 69 67 6e 65 64 20 69 6e 74 20 72 6e 64 3b 20  signed int rnd; 
9eb0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9ec0: 20 52 61 6e 64 6f 6d 20 70 61 72 74 20 6f 66 20   Random part of 
9ed0: 70 56 61 72 6e 61 6d 65 20 2a 2f 0a 20 20 69 6e  pVarname */.  in
9ee0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
9ef0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
9f00: 20 54 63 6c 20 65 72 72 6f 72 20 63 6f 64 65 20   Tcl error code 
9f10: 2a 2f 0a 0a 20 20 70 20 3d 20 28 54 63 6c 51 75  */..  p = (TclQu
9f20: 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 29 70 41  otaCallback *)pA
9f30: 72 67 3b 0a 20 20 69 66 28 20 70 3d 3d 30 20 29  rg;.  if( p==0 )
9f40: 20 72 65 74 75 72 6e 3b 0a 0a 20 20 70 56 61 72   return;..  pVar
9f50: 6e 61 6d 65 20 3d 20 54 63 6c 5f 4e 65 77 53 74  name = Tcl_NewSt
9f60: 72 69 6e 67 4f 62 6a 28 22 3a 3a 70 69 4c 69 6d  ringObj("::piLim
9f70: 69 74 5f 22 2c 20 2d 31 29 3b 0a 20 20 54 63 6c  it_", -1);.  Tcl
9f80: 5f 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 56  _IncrRefCount(pV
9f90: 61 72 6e 61 6d 65 29 3b 0a 20 20 73 71 6c 69 74  arname);.  sqlit
9fa0: 65 33 5f 72 61 6e 64 6f 6d 6e 65 73 73 28 73 69  e3_randomness(si
9fb0: 7a 65 6f 66 28 72 6e 64 29 2c 20 28 76 6f 69 64  zeof(rnd), (void
9fc0: 20 2a 29 26 72 6e 64 29 3b 0a 20 20 54 63 6c 5f   *)&rnd);.  Tcl_
9fd0: 41 70 70 65 6e 64 4f 62 6a 54 6f 4f 62 6a 28 70  AppendObjToObj(p
9fe0: 56 61 72 6e 61 6d 65 2c 20 54 63 6c 5f 4e 65 77  Varname, Tcl_New
9ff0: 49 6e 74 4f 62 6a 28 28 69 6e 74 29 28 72 6e 64  IntObj((int)(rnd
a000: 26 30 78 37 46 46 46 46 46 46 46 29 29 29 3b 0a  &0x7FFFFFFF)));.
a010: 20 20 54 63 6c 5f 4f 62 6a 53 65 74 56 61 72 32    Tcl_ObjSetVar2
a020: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 70 56 61 72  (p->interp, pVar
a030: 6e 61 6d 65 2c 20 30 2c 20 54 63 6c 5f 4e 65 77  name, 0, Tcl_New
a040: 57 69 64 65 49 6e 74 4f 62 6a 28 2a 70 69 4c 69  WideIntObj(*piLi
a050: 6d 69 74 29 2c 20 30 29 3b 0a 0a 20 20 70 45 76  mit), 0);..  pEv
a060: 61 6c 20 3d 20 54 63 6c 5f 44 75 70 6c 69 63 61  al = Tcl_Duplica
a070: 74 65 4f 62 6a 28 70 2d 3e 70 53 63 72 69 70 74  teObj(p->pScript
a080: 29 3b 0a 20 20 54 63 6c 5f 49 6e 63 72 52 65 66  );.  Tcl_IncrRef
a090: 43 6f 75 6e 74 28 70 45 76 61 6c 29 3b 0a 20 20  Count(pEval);.  
a0a0: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
a0b0: 64 45 6c 65 6d 65 6e 74 28 30 2c 20 70 45 76 61  dElement(0, pEva
a0c0: 6c 2c 20 54 63 6c 5f 4e 65 77 53 74 72 69 6e 67  l, Tcl_NewString
a0d0: 4f 62 6a 28 7a 46 69 6c 65 6e 61 6d 65 2c 20 2d  Obj(zFilename, -
a0e0: 31 29 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f  1));.  Tcl_ListO
a0f0: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
a100: 30 2c 20 70 45 76 61 6c 2c 20 70 56 61 72 6e 61  0, pEval, pVarna
a110: 6d 65 29 3b 0a 20 20 54 63 6c 5f 4c 69 73 74 4f  me);.  Tcl_ListO
a120: 62 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28  bjAppendElement(
a130: 30 2c 20 70 45 76 61 6c 2c 20 54 63 6c 5f 4e 65  0, pEval, Tcl_Ne
a140: 77 57 69 64 65 49 6e 74 4f 62 6a 28 69 53 69 7a  wWideIntObj(iSiz
a150: 65 29 29 3b 0a 20 20 72 63 20 3d 20 54 63 6c 5f  e));.  rc = Tcl_
a160: 45 76 61 6c 4f 62 6a 45 78 28 70 2d 3e 69 6e 74  EvalObjEx(p->int
a170: 65 72 70 2c 20 70 45 76 61 6c 2c 20 54 43 4c 5f  erp, pEval, TCL_
a180: 45 56 41 4c 5f 47 4c 4f 42 41 4c 29 3b 0a 0a 20  EVAL_GLOBAL);.. 
a190: 20 69 66 28 20 72 63 3d 3d 54 43 4c 5f 4f 4b 20   if( rc==TCL_OK 
a1a0: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 69 64 65 49  ){.    Tcl_WideI
a1b0: 6e 74 20 78 3b 0a 20 20 20 20 54 63 6c 5f 4f 62  nt x;.    Tcl_Ob
a1c0: 6a 20 2a 70 4c 69 6d 69 74 20 3d 20 54 63 6c 5f  j *pLimit = Tcl_
a1d0: 4f 62 6a 47 65 74 56 61 72 32 28 70 2d 3e 69 6e  ObjGetVar2(p->in
a1e0: 74 65 72 70 2c 20 70 56 61 72 6e 61 6d 65 2c 20  terp, pVarname, 
a1f0: 30 2c 20 30 29 3b 0a 20 20 20 20 72 63 20 3d 20  0, 0);.    rc = 
a200: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
a210: 6f 6d 4f 62 6a 28 70 2d 3e 69 6e 74 65 72 70 2c  omObj(p->interp,
a220: 20 70 4c 69 6d 69 74 2c 20 26 78 29 3b 0a 20 20   pLimit, &x);.  
a230: 20 20 2a 70 69 4c 69 6d 69 74 20 3d 20 78 3b 0a    *piLimit = x;.
a240: 20 20 20 20 54 63 6c 5f 55 6e 73 65 74 56 61 72      Tcl_UnsetVar
a250: 28 70 2d 3e 69 6e 74 65 72 70 2c 20 54 63 6c 5f  (p->interp, Tcl_
a260: 47 65 74 53 74 72 69 6e 67 28 70 56 61 72 6e 61  GetString(pVarna
a270: 6d 65 29 2c 20 30 29 3b 0a 20 20 7d 0a 0a 20 20  me), 0);.  }..  
a280: 54 63 6c 5f 44 65 63 72 52 65 66 43 6f 75 6e 74  Tcl_DecrRefCount
a290: 28 70 45 76 61 6c 29 3b 0a 20 20 54 63 6c 5f 44  (pEval);.  Tcl_D
a2a0: 65 63 72 52 65 66 43 6f 75 6e 74 28 70 56 61 72  ecrRefCount(pVar
a2b0: 6e 61 6d 65 29 3b 0a 20 20 69 66 28 20 72 63 21  name);.  if( rc!
a2c0: 3d 54 43 4c 5f 4f 4b 20 29 20 54 63 6c 5f 42 61  =TCL_OK ) Tcl_Ba
a2d0: 63 6b 67 72 6f 75 6e 64 45 72 72 6f 72 28 70 2d  ckgroundError(p-
a2e0: 3e 69 6e 74 65 72 70 29 3b 0a 7d 0a 0a 2f 2a 0a  >interp);.}../*.
a2f0: 2a 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66 6f  ** Destructor fo
a300: 72 20 61 20 54 43 4c 20 71 75 6f 74 61 2d 6f 76  r a TCL quota-ov
a310: 65 72 2d 6c 69 6d 69 74 20 63 61 6c 6c 62 61 63  er-limit callbac
a320: 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  k..*/.static voi
a330: 64 20 74 63 6c 43 61 6c 6c 62 61 63 6b 44 65 73  d tclCallbackDes
a340: 74 72 75 63 74 6f 72 28 76 6f 69 64 20 2a 70 4f  tructor(void *pO
a350: 62 6a 29 7b 0a 20 20 54 63 6c 51 75 6f 74 61 43  bj){.  TclQuotaC
a360: 61 6c 6c 62 61 63 6b 20 2a 70 20 3d 20 28 54 63  allback *p = (Tc
a370: 6c 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 2a 29  lQuotaCallback*)
a380: 70 4f 62 6a 3b 0a 20 20 69 66 28 20 70 20 29 7b  pObj;.  if( p ){
a390: 0a 20 20 20 20 54 63 6c 5f 44 65 63 72 52 65 66  .    Tcl_DecrRef
a3a0: 43 6f 75 6e 74 28 70 2d 3e 70 53 63 72 69 70 74  Count(p->pScript
a3b0: 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66  );.    sqlite3_f
a3c0: 72 65 65 28 28 63 68 61 72 20 2a 29 70 29 3b 0a  ree((char *)p);.
a3d0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c    }.}../*.** tcl
a3e0: 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f  cmd: sqlite3_quo
a3f0: 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65 20 4e 41  ta_initialize NA
a400: 4d 45 20 4d 41 4b 45 44 45 46 41 55 4c 54 0a 2a  ME MAKEDEFAULT.*
a410: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c  /.static int SQL
a420: 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f  ITE_TCLAPI test_
a430: 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65  quota_initialize
a440: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
a450: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
a460: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
a470: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
a480: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
a490: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
a4a0: 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20   *zName;        
a4b0: 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66        /* Name of
a4c0: 20 6e 65 77 20 71 75 6f 74 61 20 56 46 53 20 2a   new quota VFS *
a4d0: 2f 0a 20 20 69 6e 74 20 6d 61 6b 65 44 65 66 61  /.  int makeDefa
a4e0: 75 6c 74 3b 20 20 20 20 20 20 20 20 20 20 20 20  ult;            
a4f0: 20 20 20 20 2f 2a 20 54 72 75 65 20 74 6f 20 6d      /* True to m
a500: 61 6b 65 20 74 68 65 20 6e 65 77 20 56 46 53 20  ake the new VFS 
a510: 74 68 65 20 64 65 66 61 75 6c 74 20 2a 2f 0a 20  the default */. 
a520: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
a530: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
a540: 20 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e   /* Value return
a550: 65 64 20 62 79 20 71 75 6f 74 61 5f 69 6e 69 74  ed by quota_init
a560: 69 61 6c 69 7a 65 28 29 20 2a 2f 0a 0a 20 20 2f  ialize() */..  /
a570: 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d 65  * Process argume
a580: 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20 6f 62 6a  nts */.  if( obj
a590: 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f  c!=3 ){.    Tcl_
a5a0: 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74  WrongNumArgs(int
a5b0: 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 4e  erp, 1, objv, "N
a5c0: 41 4d 45 20 4d 41 4b 45 44 45 46 41 55 4c 54 22  AME MAKEDEFAULT"
a5d0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43  );.    return TC
a5e0: 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 7a  L_ERROR;.  }.  z
a5f0: 4e 61 6d 65 20 3d 20 54 63 6c 5f 47 65 74 53 74  Name = Tcl_GetSt
a600: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 20  ring(objv[1]);. 
a610: 20 69 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c   if( Tcl_GetBool
a620: 65 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72  eanFromObj(inter
a630: 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 6d 61 6b  p, objv[2], &mak
a640: 65 44 65 66 61 75 6c 74 29 20 29 20 72 65 74 75  eDefault) ) retu
a650: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
a660: 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 3d 3d 27 5c  if( zName[0]=='\
a670: 30 27 20 29 20 7a 4e 61 6d 65 20 3d 20 30 3b 0a  0' ) zName = 0;.
a680: 0a 20 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74  .  /* Call sqlit
a690: 65 33 5f 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c  e3_quota_initial
a6a0: 69 7a 65 28 29 20 2a 2f 0a 20 20 72 63 20 3d 20  ize() */.  rc = 
a6b0: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 69 6e  sqlite3_quota_in
a6c0: 69 74 69 61 6c 69 7a 65 28 7a 4e 61 6d 65 2c 20  itialize(zName, 
a6d0: 6d 61 6b 65 44 65 66 61 75 6c 74 29 3b 0a 20 20  makeDefault);.  
a6e0: 54 63 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e  Tcl_SetResult(in
a6f0: 74 65 72 70 2c 20 28 63 68 61 72 20 2a 29 73 71  terp, (char *)sq
a700: 6c 69 74 65 33 45 72 72 4e 61 6d 65 28 72 63 29  lite3ErrName(rc)
a710: 2c 20 54 43 4c 5f 53 54 41 54 49 43 29 3b 0a 0a  , TCL_STATIC);..
a720: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
a730: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64  .}../*.** tclcmd
a740: 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  : sqlite3_quota_
a750: 73 68 75 74 64 6f 77 6e 0a 2a 2f 0a 73 74 61 74  shutdown.*/.stat
a760: 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43  ic int SQLITE_TC
a770: 4c 41 50 49 20 74 65 73 74 5f 71 75 6f 74 61 5f  LAPI test_quota_
a780: 73 68 75 74 64 6f 77 6e 28 0a 20 20 76 6f 69 64  shutdown(.  void
a790: 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20   * clientData,. 
a7a0: 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74   Tcl_Interp *int
a7b0: 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c  erp,.  int objc,
a7c0: 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53  .  Tcl_Obj *CONS
a7d0: 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 69 6e  T objv[].){.  in
a7e0: 74 20 72 63 3b 20 20 20 20 20 20 20 20 20 20 20  t rc;           
a7f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
a800: 20 56 61 6c 75 65 20 72 65 74 75 72 6e 65 64 20   Value returned 
a810: 62 79 20 71 75 6f 74 61 5f 73 68 75 74 64 6f 77  by quota_shutdow
a820: 6e 28 29 20 2a 2f 0a 0a 20 20 69 66 28 20 6f 62  n() */..  if( ob
a830: 6a 63 21 3d 31 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=1 ){.    Tcl
a840: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
a850: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
a860: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54  ");.    return T
a870: 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20  CL_ERROR;.  }.. 
a880: 20 2f 2a 20 43 61 6c 6c 20 73 71 6c 69 74 65 33   /* Call sqlite3
a890: 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f 77 6e 28  _quota_shutdown(
a8a0: 29 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69  ) */.  rc = sqli
a8b0: 74 65 33 5f 71 75 6f 74 61 5f 73 68 75 74 64 6f  te3_quota_shutdo
a8c0: 77 6e 28 29 3b 0a 20 20 54 63 6c 5f 53 65 74 52  wn();.  Tcl_SetR
a8d0: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63  esult(interp, (c
a8e0: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 45 72 72  har *)sqlite3Err
a8f0: 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c 5f 53 54  Name(rc), TCL_ST
a900: 41 54 49 43 29 3b 0a 0a 20 20 72 65 74 75 72 6e  ATIC);..  return
a910: 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a   TCL_OK;.}../*.*
a920: 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65  * tclcmd: sqlite
a930: 33 5f 71 75 6f 74 61 5f 73 65 74 20 50 41 54 54  3_quota_set PATT
a940: 45 52 4e 20 4c 49 4d 49 54 20 53 43 52 49 50 54  ERN LIMIT SCRIPT
a950: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53  .*/.static int S
a960: 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73  QLITE_TCLAPI tes
a970: 74 5f 71 75 6f 74 61 5f 73 65 74 28 0a 20 20 76  t_quota_set(.  v
a980: 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61  oid * clientData
a990: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
a9a0: 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62  interp,.  int ob
a9b0: 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43  jc,.  Tcl_Obj *C
a9c0: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20  ONST objv[].){. 
a9d0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61   const char *zPa
a9e0: 74 74 65 72 6e 3b 20 20 20 20 20 20 20 20 20 20  ttern;          
a9f0: 20 2f 2a 20 46 69 6c 65 20 70 61 74 74 65 72 6e   /* File pattern
aa00: 20 74 6f 20 63 6f 6e 66 69 67 75 72 65 20 2a 2f   to configure */
aa10: 0a 20 20 54 63 6c 5f 57 69 64 65 49 6e 74 20 69  .  Tcl_WideInt i
aa20: 4c 69 6d 69 74 3b 20 20 20 20 20 20 20 20 20 20  Limit;          
aa30: 20 20 20 2f 2a 20 49 6e 69 74 69 61 6c 20 71 75     /* Initial qu
aa40: 6f 74 61 20 69 6e 20 62 79 74 65 73 20 2a 2f 0a  ota in bytes */.
aa50: 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 53 63 72 69    Tcl_Obj *pScri
aa60: 70 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  pt;             
aa70: 20 20 2f 2a 20 54 63 6c 20 73 63 72 69 70 74 20    /* Tcl script 
aa80: 74 6f 20 69 6e 76 6f 6b 65 20 74 6f 20 69 6e 63  to invoke to inc
aa90: 72 65 61 73 65 20 71 75 6f 74 61 20 2a 2f 0a 20  rease quota */. 
aaa0: 20 69 6e 74 20 72 63 3b 20 20 20 20 20 20 20 20   int rc;        
aab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
aac0: 20 2f 2a 20 56 61 6c 75 65 20 72 65 74 75 72 6e   /* Value return
aad0: 65 64 20 62 79 20 71 75 6f 74 61 5f 73 65 74 28  ed by quota_set(
aae0: 29 20 2a 2f 0a 20 20 54 63 6c 51 75 6f 74 61 43  ) */.  TclQuotaC
aaf0: 61 6c 6c 62 61 63 6b 20 2a 70 3b 20 20 20 20 20  allback *p;     
ab00: 20 20 20 20 20 20 20 2f 2a 20 43 61 6c 6c 62 61         /* Callba
ab10: 63 6b 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 69  ck object */.  i
ab20: 6e 74 20 6e 53 63 72 69 70 74 3b 20 20 20 20 20  nt nScript;     
ab30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
ab40: 2a 20 4c 65 6e 67 74 68 20 6f 66 20 63 61 6c 6c  * Length of call
ab50: 62 61 63 6b 20 73 63 72 69 70 74 20 2a 2f 0a 20  back script */. 
ab60: 20 76 6f 69 64 20 28 2a 78 44 65 73 74 72 6f 79   void (*xDestroy
ab70: 29 28 76 6f 69 64 2a 29 3b 20 20 20 20 20 20 20  )(void*);       
ab80: 20 2f 2a 20 4f 70 74 69 6f 6e 61 6c 20 64 65 73   /* Optional des
ab90: 74 72 75 63 74 6f 72 20 66 6f 72 20 70 41 72 67  tructor for pArg
aba0: 20 2a 2f 0a 20 20 76 6f 69 64 20 28 2a 78 43 61   */.  void (*xCa
abb0: 6c 6c 62 61 63 6b 29 28 63 6f 6e 73 74 20 63 68  llback)(const ch
abc0: 61 72 20 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e  ar *, sqlite3_in
abd0: 74 36 34 20 2a 2c 20 73 71 6c 69 74 65 33 5f 69  t64 *, sqlite3_i
abe0: 6e 74 36 34 2c 20 76 6f 69 64 20 2a 29 3b 0a 0a  nt64, void *);..
abf0: 20 20 2f 2a 20 50 72 6f 63 65 73 73 20 61 72 67    /* Process arg
ac00: 75 6d 65 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20  uments */.  if( 
ac10: 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20 20 54  objc!=4 ){.    T
ac20: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
ac30: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
ac40: 20 22 50 41 54 54 45 52 4e 20 4c 49 4d 49 54 20   "PATTERN LIMIT 
ac50: 53 43 52 49 50 54 22 29 3b 0a 20 20 20 20 72 65  SCRIPT");.    re
ac60: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
ac70: 20 20 7d 0a 20 20 7a 50 61 74 74 65 72 6e 20 3d    }.  zPattern =
ac80: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
ac90: 62 6a 76 5b 31 5d 29 3b 0a 20 20 69 66 28 20 54  bjv[1]);.  if( T
aca0: 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72 6f  cl_GetWideIntFro
acb0: 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a  mObj(interp, obj
acc0: 76 5b 32 5d 2c 20 26 69 4c 69 6d 69 74 29 20 29  v[2], &iLimit) )
acd0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
ace0: 52 3b 0a 20 20 70 53 63 72 69 70 74 20 3d 20 6f  R;.  pScript = o
acf0: 62 6a 76 5b 33 5d 3b 0a 20 20 54 63 6c 5f 47 65  bjv[3];.  Tcl_Ge
ad00: 74 53 74 72 69 6e 67 46 72 6f 6d 4f 62 6a 28 70  tStringFromObj(p
ad10: 53 63 72 69 70 74 2c 20 26 6e 53 63 72 69 70 74  Script, &nScript
ad20: 29 3b 0a 0a 20 20 69 66 28 20 6e 53 63 72 69 70  );..  if( nScrip
ad30: 74 3e 30 20 29 7b 0a 20 20 20 20 2f 2a 20 41 6c  t>0 ){.    /* Al
ad40: 6c 6f 63 61 74 65 20 61 20 54 63 6c 51 75 6f 74  locate a TclQuot
ad50: 61 43 61 6c 6c 62 61 63 6b 20 6f 62 6a 65 63 74  aCallback object
ad60: 20 2a 2f 0a 20 20 20 20 70 20 3d 20 28 54 63 6c   */.    p = (Tcl
ad70: 51 75 6f 74 61 43 61 6c 6c 62 61 63 6b 20 2a 29  QuotaCallback *)
ad80: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 73  sqlite3_malloc(s
ad90: 69 7a 65 6f 66 28 54 63 6c 51 75 6f 74 61 43 61  izeof(TclQuotaCa
ada0: 6c 6c 62 61 63 6b 29 29 3b 0a 20 20 20 20 69 66  llback));.    if
adb0: 28 20 21 70 20 29 7b 0a 20 20 20 20 20 20 54 63  ( !p ){.      Tc
adc0: 6c 5f 53 65 74 52 65 73 75 6c 74 28 69 6e 74 65  l_SetResult(inte
add0: 72 70 2c 20 28 63 68 61 72 20 2a 29 22 53 51 4c  rp, (char *)"SQL
ade0: 49 54 45 5f 4e 4f 4d 45 4d 22 2c 20 54 43 4c 5f  ITE_NOMEM", TCL_
adf0: 53 54 41 54 49 43 29 3b 0a 20 20 20 20 20 20 72  STATIC);.      r
ae00: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 20 20  eturn TCL_OK;.  
ae10: 20 20 7d 0a 20 20 20 20 6d 65 6d 73 65 74 28 70    }.    memset(p
ae20: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 54 63 6c 51  , 0, sizeof(TclQ
ae30: 75 6f 74 61 43 61 6c 6c 62 61 63 6b 29 29 3b 0a  uotaCallback));.
ae40: 20 20 20 20 70 2d 3e 69 6e 74 65 72 70 20 3d 20      p->interp = 
ae50: 69 6e 74 65 72 70 3b 0a 20 20 20 20 54 63 6c 5f  interp;.    Tcl_
ae60: 49 6e 63 72 52 65 66 43 6f 75 6e 74 28 70 53 63  IncrRefCount(pSc
ae70: 72 69 70 74 29 3b 0a 20 20 20 20 70 2d 3e 70 53  ript);.    p->pS
ae80: 63 72 69 70 74 20 3d 20 70 53 63 72 69 70 74 3b  cript = pScript;
ae90: 0a 20 20 20 20 78 44 65 73 74 72 6f 79 20 3d 20  .    xDestroy = 
aea0: 74 63 6c 43 61 6c 6c 62 61 63 6b 44 65 73 74 72  tclCallbackDestr
aeb0: 75 63 74 6f 72 3b 0a 20 20 20 20 78 43 61 6c 6c  uctor;.    xCall
aec0: 62 61 63 6b 20 3d 20 74 63 6c 51 75 6f 74 61 43  back = tclQuotaC
aed0: 61 6c 6c 62 61 63 6b 3b 0a 20 20 7d 65 6c 73 65  allback;.  }else
aee0: 7b 0a 20 20 20 20 70 20 3d 20 30 3b 0a 20 20 20  {.    p = 0;.   
aef0: 20 78 44 65 73 74 72 6f 79 20 3d 20 30 3b 0a 20   xDestroy = 0;. 
af00: 20 20 20 78 43 61 6c 6c 62 61 63 6b 20 3d 20 30     xCallback = 0
af10: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 6e 76 6f  ;.  }..  /* Invo
af20: 6b 65 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61  ke sqlite3_quota
af30: 5f 73 65 74 28 29 20 2a 2f 0a 20 20 72 63 20 3d  _set() */.  rc =
af40: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 73   sqlite3_quota_s
af50: 65 74 28 7a 50 61 74 74 65 72 6e 2c 20 69 4c 69  et(zPattern, iLi
af60: 6d 69 74 2c 20 78 43 61 6c 6c 62 61 63 6b 2c 20  mit, xCallback, 
af70: 28 76 6f 69 64 2a 29 70 2c 20 78 44 65 73 74 72  (void*)p, xDestr
af80: 6f 79 29 3b 0a 0a 20 20 54 63 6c 5f 53 65 74 52  oy);..  Tcl_SetR
af90: 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 28 63  esult(interp, (c
afa0: 68 61 72 20 2a 29 73 71 6c 69 74 65 33 45 72 72  har *)sqlite3Err
afb0: 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c 5f 53 54  Name(rc), TCL_ST
afc0: 41 54 49 43 29 3b 0a 20 20 72 65 74 75 72 6e 20  ATIC);.  return 
afd0: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  TCL_OK;.}../*.**
afe0: 20 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33   tclcmd: sqlite3
aff0: 5f 71 75 6f 74 61 5f 66 69 6c 65 20 46 49 4c 45  _quota_file FILE
b000: 4e 41 4d 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69  NAME.*/.static i
b010: 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49  nt SQLITE_TCLAPI
b020: 20 74 65 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65   test_quota_file
b030: 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e  (.  void * clien
b040: 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74  tData,.  Tcl_Int
b050: 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69  erp *interp,.  i
b060: 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f  nt objc,.  Tcl_O
b070: 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d  bj *CONST objv[]
b080: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
b090: 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20 20 20   *zFilename;    
b0a0: 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20 70 61        /* File pa
b0b0: 74 74 65 72 6e 20 74 6f 20 63 6f 6e 66 69 67 75  ttern to configu
b0c0: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63 3b 20  re */.  int rc; 
b0d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b0e0: 20 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65          /* Value
b0f0: 20 72 65 74 75 72 6e 65 64 20 62 79 20 71 75 6f   returned by quo
b100: 74 61 5f 66 69 6c 65 28 29 20 2a 2f 0a 0a 20 20  ta_file() */..  
b110: 2f 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d  /* Process argum
b120: 65 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20 6f 62  ents */.  if( ob
b130: 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=2 ){.    Tcl
b140: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
b150: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
b160: 46 49 4c 45 4e 41 4d 45 22 29 3b 0a 20 20 20 20  FILENAME");.    
b170: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
b180: 3b 0a 20 20 7d 0a 20 20 7a 46 69 6c 65 6e 61 6d  ;.  }.  zFilenam
b190: 65 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e  e = Tcl_GetStrin
b1a0: 67 28 6f 62 6a 76 5b 31 5d 29 3b 0a 0a 20 20 2f  g(objv[1]);..  /
b1b0: 2a 20 49 6e 76 6f 6b 65 20 73 71 6c 69 74 65 33  * Invoke sqlite3
b1c0: 5f 71 75 6f 74 61 5f 66 69 6c 65 28 29 20 2a 2f  _quota_file() */
b1d0: 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f  .  rc = sqlite3_
b1e0: 71 75 6f 74 61 5f 66 69 6c 65 28 7a 46 69 6c 65  quota_file(zFile
b1f0: 6e 61 6d 65 29 3b 0a 0a 20 20 54 63 6c 5f 53 65  name);..  Tcl_Se
b200: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  tResult(interp, 
b210: 28 63 68 61 72 20 2a 29 73 71 6c 69 74 65 33 45  (char *)sqlite3E
b220: 72 72 4e 61 6d 65 28 72 63 29 2c 20 54 43 4c 5f  rrName(rc), TCL_
b230: 53 54 41 54 49 43 29 3b 0a 20 20 72 65 74 75 72  STATIC);.  retur
b240: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
b250: 2a 2a 20 74 63 6c 63 6d 64 3a 20 20 73 71 6c 69  ** tclcmd:  sqli
b260: 74 65 33 5f 71 75 6f 74 61 5f 64 75 6d 70 0a 2a  te3_quota_dump.*
b270: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c  /.static int SQL
b280: 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f  ITE_TCLAPI test_
b290: 71 75 6f 74 61 5f 64 75 6d 70 28 0a 20 20 76 6f  quota_dump(.  vo
b2a0: 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c  id * clientData,
b2b0: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
b2c0: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
b2d0: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
b2e0: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
b2f0: 54 63 6c 5f 4f 62 6a 20 2a 70 52 65 73 75 6c 74  Tcl_Obj *pResult
b300: 3b 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 70 47 72  ;.  Tcl_Obj *pGr
b310: 6f 75 70 54 65 72 6d 3b 0a 20 20 54 63 6c 5f 4f  oupTerm;.  Tcl_O
b320: 62 6a 20 2a 70 46 69 6c 65 54 65 72 6d 3b 0a 20  bj *pFileTerm;. 
b330: 20 71 75 6f 74 61 47 72 6f 75 70 20 2a 70 47 72   quotaGroup *pGr
b340: 6f 75 70 3b 0a 20 20 71 75 6f 74 61 46 69 6c 65  oup;.  quotaFile
b350: 20 2a 70 46 69 6c 65 3b 0a 0a 20 20 70 52 65 73   *pFile;..  pRes
b360: 75 6c 74 20 3d 20 54 63 6c 5f 4e 65 77 4f 62 6a  ult = Tcl_NewObj
b370: 28 29 3b 0a 20 20 71 75 6f 74 61 45 6e 74 65 72  ();.  quotaEnter
b380: 28 29 3b 0a 20 20 66 6f 72 28 70 47 72 6f 75 70  ();.  for(pGroup
b390: 3d 67 51 75 6f 74 61 2e 70 47 72 6f 75 70 3b 20  =gQuota.pGroup; 
b3a0: 70 47 72 6f 75 70 3b 20 70 47 72 6f 75 70 3d 70  pGroup; pGroup=p
b3b0: 47 72 6f 75 70 2d 3e 70 4e 65 78 74 29 7b 0a 20  Group->pNext){. 
b3c0: 20 20 20 70 47 72 6f 75 70 54 65 72 6d 20 3d 20     pGroupTerm = 
b3d0: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
b3e0: 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70    Tcl_ListObjApp
b3f0: 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72  endElement(inter
b400: 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 0a 20  p, pGroupTerm,. 
b410: 20 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77           Tcl_New
b420: 53 74 72 69 6e 67 4f 62 6a 28 70 47 72 6f 75 70  StringObj(pGroup
b430: 2d 3e 7a 50 61 74 74 65 72 6e 2c 20 2d 31 29 29  ->zPattern, -1))
b440: 3b 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  ;.    Tcl_ListOb
b450: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
b460: 6e 74 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72  nterp, pGroupTer
b470: 6d 2c 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c  m,.          Tcl
b480: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 70  _NewWideIntObj(p
b490: 47 72 6f 75 70 2d 3e 69 4c 69 6d 69 74 29 29 3b  Group->iLimit));
b4a0: 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a  .    Tcl_ListObj
b4b0: 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e  AppendElement(in
b4c0: 74 65 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d  terp, pGroupTerm
b4d0: 2c 0a 20 20 20 20 20 20 20 20 20 20 54 63 6c 5f  ,.          Tcl_
b4e0: 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 70 47  NewWideIntObj(pG
b4f0: 72 6f 75 70 2d 3e 69 53 69 7a 65 29 29 3b 0a 20  roup->iSize));. 
b500: 20 20 20 66 6f 72 28 70 46 69 6c 65 3d 70 47 72     for(pFile=pGr
b510: 6f 75 70 2d 3e 70 46 69 6c 65 73 3b 20 70 46 69  oup->pFiles; pFi
b520: 6c 65 3b 20 70 46 69 6c 65 3d 70 46 69 6c 65 2d  le; pFile=pFile-
b530: 3e 70 4e 65 78 74 29 7b 0a 20 20 20 20 20 20 69  >pNext){.      i
b540: 6e 74 20 69 3b 0a 20 20 20 20 20 20 63 68 61 72  nt i;.      char
b550: 20 7a 54 65 6d 70 5b 31 30 30 30 5d 3b 0a 20 20   zTemp[1000];.  
b560: 20 20 20 20 70 46 69 6c 65 54 65 72 6d 20 3d 20      pFileTerm = 
b570: 54 63 6c 5f 4e 65 77 4f 62 6a 28 29 3b 0a 20 20  Tcl_NewObj();.  
b580: 20 20 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72      sqlite3_snpr
b590: 69 6e 74 66 28 73 69 7a 65 6f 66 28 7a 54 65 6d  intf(sizeof(zTem
b5a0: 70 29 2c 20 7a 54 65 6d 70 2c 20 22 25 73 22 2c  p), zTemp, "%s",
b5b0: 20 70 46 69 6c 65 2d 3e 7a 46 69 6c 65 6e 61 6d   pFile->zFilenam
b5c0: 65 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  e);.      for(i=
b5d0: 30 3b 20 7a 54 65 6d 70 5b 69 5d 3b 20 69 2b 2b  0; zTemp[i]; i++
b5e0: 29 7b 20 69 66 28 20 7a 54 65 6d 70 5b 69 5d 3d  ){ if( zTemp[i]=
b5f0: 3d 27 5c 5c 27 20 29 20 7a 54 65 6d 70 5b 69 5d  ='\\' ) zTemp[i]
b600: 20 3d 20 27 2f 27 3b 20 7d 0a 20 20 20 20 20 20   = '/'; }.      
b610: 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70 70 65 6e  Tcl_ListObjAppen
b620: 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65 72 70 2c  dElement(interp,
b630: 20 70 46 69 6c 65 54 65 72 6d 2c 0a 20 20 20 20   pFileTerm,.    
b640: 20 20 20 20 20 20 20 20 54 63 6c 5f 4e 65 77 53          Tcl_NewS
b650: 74 72 69 6e 67 4f 62 6a 28 7a 54 65 6d 70 2c 20  tringObj(zTemp, 
b660: 2d 31 29 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f  -1));.      Tcl_
b670: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
b680: 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46 69  ment(interp, pFi
b690: 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20  leTerm,.        
b6a0: 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49      Tcl_NewWideI
b6b0: 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 69 53 69  ntObj(pFile->iSi
b6c0: 7a 65 29 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f  ze));.      Tcl_
b6d0: 4c 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65  ListObjAppendEle
b6e0: 6d 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46 69  ment(interp, pFi
b6f0: 6c 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20  leTerm,.        
b700: 20 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49      Tcl_NewWideI
b710: 6e 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 6e 52 65  ntObj(pFile->nRe
b720: 66 29 29 3b 0a 20 20 20 20 20 20 54 63 6c 5f 4c  f));.      Tcl_L
b730: 69 73 74 4f 62 6a 41 70 70 65 6e 64 45 6c 65 6d  istObjAppendElem
b740: 65 6e 74 28 69 6e 74 65 72 70 2c 20 70 46 69 6c  ent(interp, pFil
b750: 65 54 65 72 6d 2c 0a 20 20 20 20 20 20 20 20 20  eTerm,.         
b760: 20 20 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e     Tcl_NewWideIn
b770: 74 4f 62 6a 28 70 46 69 6c 65 2d 3e 64 65 6c 65  tObj(pFile->dele
b780: 74 65 4f 6e 43 6c 6f 73 65 29 29 3b 0a 20 20 20  teOnClose));.   
b790: 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62 6a 41 70     Tcl_ListObjAp
b7a0: 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69 6e 74 65  pendElement(inte
b7b0: 72 70 2c 20 70 47 72 6f 75 70 54 65 72 6d 2c 20  rp, pGroupTerm, 
b7c0: 70 46 69 6c 65 54 65 72 6d 29 3b 0a 20 20 20 20  pFileTerm);.    
b7d0: 7d 0a 20 20 20 20 54 63 6c 5f 4c 69 73 74 4f 62  }.    Tcl_ListOb
b7e0: 6a 41 70 70 65 6e 64 45 6c 65 6d 65 6e 74 28 69  jAppendElement(i
b7f0: 6e 74 65 72 70 2c 20 70 52 65 73 75 6c 74 2c 20  nterp, pResult, 
b800: 70 47 72 6f 75 70 54 65 72 6d 29 3b 0a 20 20 7d  pGroupTerm);.  }
b810: 0a 20 20 71 75 6f 74 61 4c 65 61 76 65 28 29 3b  .  quotaLeave();
b820: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
b830: 75 6c 74 28 69 6e 74 65 72 70 2c 20 70 52 65 73  ult(interp, pRes
b840: 75 6c 74 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  ult);.  return T
b850: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  CL_OK;.}../*.** 
b860: 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f  tclcmd: sqlite3_
b870: 71 75 6f 74 61 5f 66 6f 70 65 6e 20 46 49 4c 45  quota_fopen FILE
b880: 4e 41 4d 45 20 4d 4f 44 45 0a 2a 2f 0a 73 74 61  NAME MODE.*/.sta
b890: 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54  tic int SQLITE_T
b8a0: 43 4c 41 50 49 20 74 65 73 74 5f 71 75 6f 74 61  CLAPI test_quota
b8b0: 5f 66 6f 70 65 6e 28 0a 20 20 76 6f 69 64 20 2a  _fopen(.  void *
b8c0: 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54   clientData,.  T
b8d0: 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72  cl_Interp *inter
b8e0: 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20  p,.  int objc,. 
b8f0: 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20   Tcl_Obj *CONST 
b900: 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73  objv[].){.  cons
b910: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
b920: 65 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46  e;          /* F
b930: 69 6c 65 20 70 61 74 74 65 72 6e 20 74 6f 20 63  ile pattern to c
b940: 6f 6e 66 69 67 75 72 65 20 2a 2f 0a 20 20 63 6f  onfigure */.  co
b950: 6e 73 74 20 63 68 61 72 20 2a 7a 4d 6f 64 65 3b  nst char *zMode;
b960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
b970: 20 4d 6f 64 65 20 73 74 72 69 6e 67 20 2a 2f 0a   Mode string */.
b980: 20 20 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 3b    quota_FILE *p;
b990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
b9a0: 20 20 2f 2a 20 4f 70 65 6e 20 73 74 72 69 6e 67    /* Open string
b9b0: 20 6f 62 6a 65 63 74 20 2a 2f 0a 20 20 63 68 61   object */.  cha
b9c0: 72 20 7a 52 65 74 75 72 6e 5b 35 30 5d 3b 20 20  r zReturn[50];  
b9d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
b9e0: 4e 61 6d 65 20 6f 66 20 70 6f 69 6e 74 65 72 20  Name of pointer 
b9f0: 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a 0a 20 20  to return */..  
ba00: 2f 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d  /* Process argum
ba10: 65 6e 74 73 20 2a 2f 0a 20 20 69 66 28 20 6f 62  ents */.  if( ob
ba20: 6a 63 21 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c  jc!=3 ){.    Tcl
ba30: 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e  _WrongNumArgs(in
ba40: 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22  terp, 1, objv, "
ba50: 46 49 4c 45 4e 41 4d 45 20 4d 4f 44 45 22 29 3b  FILENAME MODE");
ba60: 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  .    return TCL_
ba70: 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 7a 46 69  ERROR;.  }.  zFi
ba80: 6c 65 6e 61 6d 65 20 3d 20 54 63 6c 5f 47 65 74  lename = Tcl_Get
ba90: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 3b  String(objv[1]);
baa0: 0a 20 20 7a 4d 6f 64 65 20 3d 20 54 63 6c 5f 47  .  zMode = Tcl_G
bab0: 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 32 5d  etString(objv[2]
bac0: 29 3b 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33  );.  p = sqlite3
bad0: 5f 71 75 6f 74 61 5f 66 6f 70 65 6e 28 7a 46 69  _quota_fopen(zFi
bae0: 6c 65 6e 61 6d 65 2c 20 7a 4d 6f 64 65 29 3b 0a  lename, zMode);.
baf0: 20 20 73 71 6c 69 74 65 33 5f 73 6e 70 72 69 6e    sqlite3_snprin
bb00: 74 66 28 73 69 7a 65 6f 66 28 7a 52 65 74 75 72  tf(sizeof(zRetur
bb10: 6e 29 2c 20 7a 52 65 74 75 72 6e 2c 20 22 25 70  n), zReturn, "%p
bb20: 22 2c 20 70 29 3b 0a 20 20 54 63 6c 5f 53 65 74  ", p);.  Tcl_Set
bb30: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 7a  Result(interp, z
bb40: 52 65 74 75 72 6e 2c 20 54 43 4c 5f 56 4f 4c 41  Return, TCL_VOLA
bb50: 54 49 4c 45 29 3b 0a 20 20 72 65 74 75 72 6e 20  TILE);.  return 
bb60: 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 20 44 65  TCL_OK;.}../* De
bb70: 66 69 6e 65 64 20 69 6e 20 74 65 73 74 31 2e 63  fined in test1.c
bb80: 20 2a 2f 0a 65 78 74 65 72 6e 20 76 6f 69 64 20   */.extern void 
bb90: 2a 73 71 6c 69 74 65 33 54 65 73 74 54 65 78 74  *sqlite3TestText
bba0: 54 6f 50 74 72 28 63 6f 6e 73 74 20 63 68 61 72  ToPtr(const char
bbb0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d  *);../*.** tclcm
bbc0: 64 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61  d: sqlite3_quota
bbd0: 5f 66 72 65 61 64 20 48 41 4e 44 4c 45 20 53 49  _fread HANDLE SI
bbe0: 5a 45 20 4e 45 4c 45 4d 0a 2a 2f 0a 73 74 61 74  ZE NELEM.*/.stat
bbf0: 69 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43  ic int SQLITE_TC
bc00: 4c 41 50 49 20 74 65 73 74 5f 71 75 6f 74 61 5f  LAPI test_quota_
bc10: 66 72 65 61 64 28 0a 20 20 76 6f 69 64 20 2a 20  fread(.  void * 
bc20: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
bc30: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
bc40: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
bc50: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
bc60: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61  bjv[].){.  quota
bc70: 5f 46 49 4c 45 20 2a 70 3b 0a 20 20 63 68 61 72  _FILE *p;.  char
bc80: 20 2a 7a 42 75 66 3b 0a 20 20 69 6e 74 20 73 7a   *zBuf;.  int sz
bc90: 3b 0a 20 20 69 6e 74 20 6e 45 6c 65 6d 3b 0a 20  ;.  int nElem;. 
bca0: 20 73 69 7a 65 5f 74 20 67 6f 74 3b 0a 0a 20 20   size_t got;..  
bcb0: 69 66 28 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20  if( objc!=4 ){. 
bcc0: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
bcd0: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
bce0: 62 6a 76 2c 20 22 48 41 4e 44 4c 45 20 53 49 5a  bjv, "HANDLE SIZ
bcf0: 45 20 4e 45 4c 45 4d 22 29 3b 0a 20 20 20 20 72  E NELEM");.    r
bd00: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
bd10: 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69 74  .  }.  p = sqlit
bd20: 65 33 54 65 73 74 54 65 78 74 54 6f 50 74 72 28  e3TestTextToPtr(
bd30: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
bd40: 6a 76 5b 31 5d 29 29 3b 0a 20 20 69 66 28 20 54  jv[1]));.  if( T
bd50: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
bd60: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d  (interp, objv[2]
bd70: 2c 20 26 73 7a 29 20 29 20 72 65 74 75 72 6e 20  , &sz) ) return 
bd80: 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 69 66 28  TCL_ERROR;.  if(
bd90: 20 54 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f   Tcl_GetIntFromO
bda0: 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b  bj(interp, objv[
bdb0: 33 5d 2c 20 26 6e 45 6c 65 6d 29 20 29 20 72 65  3], &nElem) ) re
bdc0: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
bdd0: 20 20 7a 42 75 66 20 3d 20 28 63 68 61 72 2a 29    zBuf = (char*)
bde0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20  sqlite3_malloc( 
bdf0: 73 7a 2a 6e 45 6c 65 6d 20 2b 20 31 20 29 3b 0a  sz*nElem + 1 );.
be00: 20 20 69 66 28 20 7a 42 75 66 3d 3d 30 20 29 7b    if( zBuf==0 ){
be10: 0a 20 20 20 20 54 63 6c 5f 53 65 74 52 65 73 75  .    Tcl_SetResu
be20: 6c 74 28 69 6e 74 65 72 70 2c 20 22 6f 75 74 20  lt(interp, "out 
be30: 6f 66 20 6d 65 6d 6f 72 79 22 2c 20 54 43 4c 5f  of memory", TCL_
be40: 53 54 41 54 49 43 29 3b 0a 20 20 20 20 72 65 74  STATIC);.    ret
be50: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
be60: 20 7d 0a 20 20 67 6f 74 20 3d 20 73 71 6c 69 74   }.  got = sqlit
be70: 65 33 5f 71 75 6f 74 61 5f 66 72 65 61 64 28 7a  e3_quota_fread(z
be80: 42 75 66 2c 20 73 7a 2c 20 6e 45 6c 65 6d 2c 20  Buf, sz, nElem, 
be90: 70 29 3b 0a 20 20 7a 42 75 66 5b 67 6f 74 2a 73  p);.  zBuf[got*s
bea0: 7a 5d 20 3d 20 30 3b 0a 20 20 54 63 6c 5f 53 65  z] = 0;.  Tcl_Se
beb0: 74 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20  tResult(interp, 
bec0: 7a 42 75 66 2c 20 54 43 4c 5f 56 4f 4c 41 54 49  zBuf, TCL_VOLATI
bed0: 4c 45 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66  LE);.  sqlite3_f
bee0: 72 65 65 28 7a 42 75 66 29 3b 0a 20 20 72 65 74  ree(zBuf);.  ret
bef0: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
bf00: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
bf10: 69 74 65 33 5f 71 75 6f 74 61 5f 66 77 72 69 74  ite3_quota_fwrit
bf20: 65 20 48 41 4e 44 4c 45 20 53 49 5a 45 20 4e 45  e HANDLE SIZE NE
bf30: 4c 45 4d 20 43 4f 4e 54 45 4e 54 0a 2a 2f 0a 73  LEM CONTENT.*/.s
bf40: 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49 54 45  tatic int SQLITE
bf50: 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71 75 6f  _TCLAPI test_quo
bf60: 74 61 5f 66 77 72 69 74 65 28 0a 20 20 76 6f 69  ta_fwrite(.  voi
bf70: 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c 0a  d * clientData,.
bf80: 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69 6e    Tcl_Interp *in
bf90: 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a 63  terp,.  int objc
bfa0: 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e  ,.  Tcl_Obj *CON
bfb0: 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20 71  ST objv[].){.  q
bfc0: 75 6f 74 61 5f 46 49 4c 45 20 2a 70 3b 0a 20 20  uota_FILE *p;.  
bfd0: 63 68 61 72 20 2a 7a 42 75 66 3b 0a 20 20 69 6e  char *zBuf;.  in
bfe0: 74 20 73 7a 3b 0a 20 20 69 6e 74 20 6e 45 6c 65  t sz;.  int nEle
bff0: 6d 3b 0a 20 20 73 69 7a 65 5f 74 20 67 6f 74 3b  m;.  size_t got;
c000: 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 35 20  ..  if( objc!=5 
c010: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
c020: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
c030: 31 2c 20 6f 62 6a 76 2c 20 22 48 41 4e 44 4c 45  1, objv, "HANDLE
c040: 20 53 49 5a 45 20 4e 45 4c 45 4d 20 43 4f 4e 54   SIZE NELEM CONT
c050: 45 4e 54 22 29 3b 0a 20 20 20 20 72 65 74 75 72  ENT");.    retur
c060: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
c070: 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 54 65  .  p = sqlite3Te
c080: 73 74 54 65 78 74 54 6f 50 74 72 28 54 63 6c 5f  stTextToPtr(Tcl_
c090: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
c0a0: 5d 29 29 3b 0a 20 20 69 66 28 20 54 63 6c 5f 47  ]));.  if( Tcl_G
c0b0: 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69 6e 74  etIntFromObj(int
c0c0: 65 72 70 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 73  erp, objv[2], &s
c0d0: 7a 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c 5f  z) ) return TCL_
c0e0: 45 52 52 4f 52 3b 0a 20 20 69 66 28 20 54 63 6c  ERROR;.  if( Tcl
c0f0: 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a 28 69  _GetIntFromObj(i
c100: 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 33 5d 2c 20  nterp, objv[3], 
c110: 26 6e 45 6c 65 6d 29 20 29 20 72 65 74 75 72 6e  &nElem) ) return
c120: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7a 42   TCL_ERROR;.  zB
c130: 75 66 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69  uf = Tcl_GetStri
c140: 6e 67 28 6f 62 6a 76 5b 34 5d 29 3b 0a 20 20 67  ng(objv[4]);.  g
c150: 6f 74 20 3d 20 73 71 6c 69 74 65 33 5f 71 75 6f  ot = sqlite3_quo
c160: 74 61 5f 66 77 72 69 74 65 28 7a 42 75 66 2c 20  ta_fwrite(zBuf, 
c170: 73 7a 2c 20 6e 45 6c 65 6d 2c 20 70 29 3b 0a 20  sz, nElem, p);. 
c180: 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c   Tcl_SetObjResul
c190: 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65  t(interp, Tcl_Ne
c1a0: 77 57 69 64 65 49 6e 74 4f 62 6a 28 67 6f 74 29  wWideIntObj(got)
c1b0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
c1c0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c  OK;.}../*.** tcl
c1d0: 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f  cmd: sqlite3_quo
c1e0: 74 61 5f 66 63 6c 6f 73 65 20 48 41 4e 44 4c 45  ta_fclose HANDLE
c1f0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 53  .*/.static int S
c200: 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74 65 73  QLITE_TCLAPI tes
c210: 74 5f 71 75 6f 74 61 5f 66 63 6c 6f 73 65 28 0a  t_quota_fclose(.
c220: 20 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44    void * clientD
c230: 61 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72  ata,.  Tcl_Inter
c240: 70 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74  p *interp,.  int
c250: 20 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a   objc,.  Tcl_Obj
c260: 20 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29   *CONST objv[].)
c270: 7b 0a 20 20 71 75 6f 74 61 5f 46 49 4c 45 20 2a  {.  quota_FILE *
c280: 70 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20  p;.  int rc;..  
c290: 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20  if( objc!=2 ){. 
c2a0: 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41     Tcl_WrongNumA
c2b0: 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f  rgs(interp, 1, o
c2c0: 62 6a 76 2c 20 22 48 41 4e 44 4c 45 22 29 3b 0a  bjv, "HANDLE");.
c2d0: 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45      return TCL_E
c2e0: 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70 20 3d 20  RROR;.  }.  p = 
c2f0: 73 71 6c 69 74 65 33 54 65 73 74 54 65 78 74 54  sqlite3TestTextT
c300: 6f 50 74 72 28 54 63 6c 5f 47 65 74 53 74 72 69  oPtr(Tcl_GetStri
c310: 6e 67 28 6f 62 6a 76 5b 31 5d 29 29 3b 0a 20 20  ng(objv[1]));.  
c320: 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 71 75 6f  rc = sqlite3_quo
c330: 74 61 5f 66 63 6c 6f 73 65 28 70 29 3b 0a 20 20  ta_fclose(p);.  
c340: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
c350: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
c360: 49 6e 74 4f 62 6a 28 72 63 29 29 3b 0a 20 20 72  IntObj(rc));.  r
c370: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
c380: 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73  ./*.** tclcmd: s
c390: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 66 6c  qlite3_quota_ffl
c3a0: 75 73 68 20 48 41 4e 44 4c 45 20 3f 48 41 52 44  ush HANDLE ?HARD
c3b0: 53 59 4e 43 3f 0a 2a 2f 0a 73 74 61 74 69 63 20  SYNC?.*/.static 
c3c0: 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50  int SQLITE_TCLAP
c3d0: 49 20 74 65 73 74 5f 71 75 6f 74 61 5f 66 66 6c  I test_quota_ffl
c3e0: 75 73 68 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c  ush(.  void * cl
c3f0: 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f  ientData,.  Tcl_
c400: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
c410: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
c420: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
c430: 76 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61 5f 46  v[].){.  quota_F
c440: 49 4c 45 20 2a 70 3b 0a 20 20 69 6e 74 20 72 63  ILE *p;.  int rc
c450: 3b 0a 20 20 69 6e 74 20 64 6f 53 79 6e 63 20 3d  ;.  int doSync =
c460: 20 30 3b 0a 0a 20 20 69 66 28 20 6f 62 6a 63 21   0;..  if( objc!
c470: 3d 32 20 26 26 20 6f 62 6a 63 21 3d 33 20 29 7b  =2 && objc!=3 ){
c480: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
c490: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
c4a0: 20 6f 62 6a 76 2c 20 22 48 41 4e 44 4c 45 20 3f   objv, "HANDLE ?
c4b0: 48 41 52 44 53 59 4e 43 3f 22 29 3b 0a 20 20 20  HARDSYNC?");.   
c4c0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
c4d0: 52 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c  R;.  }.  p = sql
c4e0: 69 74 65 33 54 65 73 74 54 65 78 74 54 6f 50 74  ite3TestTextToPt
c4f0: 72 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  r(Tcl_GetString(
c500: 6f 62 6a 76 5b 31 5d 29 29 3b 0a 20 20 69 66 28  objv[1]));.  if(
c510: 20 6f 62 6a 63 3d 3d 33 20 29 7b 0a 20 20 20 20   objc==3 ){.    
c520: 69 66 28 20 54 63 6c 5f 47 65 74 42 6f 6f 6c 65  if( Tcl_GetBoole
c530: 61 6e 46 72 6f 6d 4f 62 6a 28 69 6e 74 65 72 70  anFromObj(interp
c540: 2c 20 6f 62 6a 76 5b 32 5d 2c 20 26 64 6f 53 79  , objv[2], &doSy
c550: 6e 63 29 20 29 20 72 65 74 75 72 6e 20 54 43 4c  nc) ) return TCL
c560: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 72 63  _ERROR;.  }.  rc
c570: 20 3d 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61   = sqlite3_quota
c580: 5f 66 66 6c 75 73 68 28 70 2c 20 64 6f 53 79 6e  _fflush(p, doSyn
c590: 63 29 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a  c);.  Tcl_SetObj
c5a0: 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54  Result(interp, T
c5b0: 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a 28 72 63 29  cl_NewIntObj(rc)
c5c0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f  );.  return TCL_
c5d0: 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c  OK;.}../*.** tcl
c5e0: 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f  cmd: sqlite3_quo
c5f0: 74 61 5f 66 73 65 65 6b 20 48 41 4e 44 4c 45 20  ta_fseek HANDLE 
c600: 4f 46 46 53 45 54 20 57 48 45 4e 43 45 0a 2a 2f  OFFSET WHENCE.*/
c610: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
c620: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71  TE_TCLAPI test_q
c630: 75 6f 74 61 5f 66 73 65 65 6b 28 0a 20 20 76 6f  uota_fseek(.  vo
c640: 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61 2c  id * clientData,
c650: 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a 69  .  Tcl_Interp *i
c660: 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62 6a  nterp,.  int obj
c670: 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43 4f  c,.  Tcl_Obj *CO
c680: 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20 20  NST objv[].){.  
c690: 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 3b 0a 20  quota_FILE *p;. 
c6a0: 20 69 6e 74 20 6f 66 73 74 3b 0a 20 20 63 6f 6e   int ofst;.  con
c6b0: 73 74 20 63 68 61 72 20 2a 7a 57 68 65 6e 63 65  st char *zWhence
c6c0: 3b 0a 20 20 69 6e 74 20 77 68 65 6e 63 65 3b 0a  ;.  int whence;.
c6d0: 20 20 69 6e 74 20 72 63 3b 0a 0a 20 20 69 66 28    int rc;..  if(
c6e0: 20 6f 62 6a 63 21 3d 34 20 29 7b 0a 20 20 20 20   objc!=4 ){.    
c6f0: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
c700: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
c710: 2c 20 22 48 41 4e 44 4c 45 20 4f 46 46 53 45 54  , "HANDLE OFFSET
c720: 20 57 48 45 4e 43 45 22 29 3b 0a 20 20 20 20 72   WHENCE");.    r
c730: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
c740: 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69 74  .  }.  p = sqlit
c750: 65 33 54 65 73 74 54 65 78 74 54 6f 50 74 72 28  e3TestTextToPtr(
c760: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
c770: 6a 76 5b 31 5d 29 29 3b 0a 20 20 69 66 28 20 54  jv[1]));.  if( T
c780: 63 6c 5f 47 65 74 49 6e 74 46 72 6f 6d 4f 62 6a  cl_GetIntFromObj
c790: 28 69 6e 74 65 72 70 2c 20 6f 62 6a 76 5b 32 5d  (interp, objv[2]
c7a0: 2c 20 26 6f 66 73 74 29 20 29 20 72 65 74 75 72  , &ofst) ) retur
c7b0: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7a  n TCL_ERROR;.  z
c7c0: 57 68 65 6e 63 65 20 3d 20 54 63 6c 5f 47 65 74  Whence = Tcl_Get
c7d0: 53 74 72 69 6e 67 28 6f 62 6a 76 5b 33 5d 29 3b  String(objv[3]);
c7e0: 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 57  .  if( strcmp(zW
c7f0: 68 65 6e 63 65 2c 20 22 53 45 45 4b 5f 53 45 54  hence, "SEEK_SET
c800: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 77 68 65  ")==0 ){.    whe
c810: 6e 63 65 20 3d 20 53 45 45 4b 5f 53 45 54 3b 0a  nce = SEEK_SET;.
c820: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63    }else if( strc
c830: 6d 70 28 7a 57 68 65 6e 63 65 2c 20 22 53 45 45  mp(zWhence, "SEE
c840: 4b 5f 43 55 52 22 29 3d 3d 30 20 29 7b 0a 20 20  K_CUR")==0 ){.  
c850: 20 20 77 68 65 6e 63 65 20 3d 20 53 45 45 4b 5f    whence = SEEK_
c860: 43 55 52 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  CUR;.  }else if(
c870: 20 73 74 72 63 6d 70 28 7a 57 68 65 6e 63 65 2c   strcmp(zWhence,
c880: 20 22 53 45 45 4b 5f 45 4e 44 22 29 3d 3d 30 20   "SEEK_END")==0 
c890: 29 7b 0a 20 20 20 20 77 68 65 6e 63 65 20 3d 20  ){.    whence = 
c8a0: 53 45 45 4b 5f 45 4e 44 3b 0a 20 20 7d 65 6c 73  SEEK_END;.  }els
c8b0: 65 7b 0a 20 20 20 20 54 63 6c 5f 41 70 70 65 6e  e{.    Tcl_Appen
c8c0: 64 52 65 73 75 6c 74 28 69 6e 74 65 72 70 2c 0a  dResult(interp,.
c8d0: 20 20 20 20 20 20 20 20 20 20 20 22 57 48 45 4e             "WHEN
c8e0: 43 45 20 73 68 6f 75 6c 64 20 62 65 20 53 45 45  CE should be SEE
c8f0: 4b 5f 53 45 54 2c 20 53 45 45 4b 5f 43 55 52 2c  K_SET, SEEK_CUR,
c900: 20 6f 72 20 53 45 45 4b 5f 45 4e 44 22 2c 20 28   or SEEK_END", (
c910: 63 68 61 72 2a 29 30 29 3b 0a 20 20 20 20 72 65  char*)0);.    re
c920: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
c930: 20 20 7d 0a 20 20 72 63 20 3d 20 73 71 6c 69 74    }.  rc = sqlit
c940: 65 33 5f 71 75 6f 74 61 5f 66 73 65 65 6b 28 70  e3_quota_fseek(p
c950: 2c 20 6f 66 73 74 2c 20 77 68 65 6e 63 65 29 3b  , ofst, whence);
c960: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
c970: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
c980: 4e 65 77 49 6e 74 4f 62 6a 28 72 63 29 29 3b 0a  NewIntObj(rc));.
c990: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
c9a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64  .}../*.** tclcmd
c9b0: 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  : sqlite3_quota_
c9c0: 72 65 77 69 6e 64 20 48 41 4e 44 4c 45 0a 2a 2f  rewind HANDLE.*/
c9d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
c9e0: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71  TE_TCLAPI test_q
c9f0: 75 6f 74 61 5f 72 65 77 69 6e 64 28 0a 20 20 76  uota_rewind(.  v
ca00: 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61  oid * clientData
ca10: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
ca20: 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62  interp,.  int ob
ca30: 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43  jc,.  Tcl_Obj *C
ca40: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20  ONST objv[].){. 
ca50: 20 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 3b 0a   quota_FILE *p;.
ca60: 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 20 29 7b    if( objc!=2 ){
ca70: 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67 4e 75  .    Tcl_WrongNu
ca80: 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20 31 2c  mArgs(interp, 1,
ca90: 20 6f 62 6a 76 2c 20 22 48 41 4e 44 4c 45 22 29   objv, "HANDLE")
caa0: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 54 43 4c  ;.    return TCL
cab0: 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 20 20 70 20  _ERROR;.  }.  p 
cac0: 3d 20 73 71 6c 69 74 65 33 54 65 73 74 54 65 78  = sqlite3TestTex
cad0: 74 54 6f 50 74 72 28 54 63 6c 5f 47 65 74 53 74  tToPtr(Tcl_GetSt
cae0: 72 69 6e 67 28 6f 62 6a 76 5b 31 5d 29 29 3b 0a  ring(objv[1]));.
caf0: 20 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f    sqlite3_quota_
cb00: 72 65 77 69 6e 64 28 70 29 3b 0a 20 20 72 65 74  rewind(p);.  ret
cb10: 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f  urn TCL_OK;.}../
cb20: 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c  *.** tclcmd: sql
cb30: 69 74 65 33 5f 71 75 6f 74 61 5f 66 74 65 6c 6c  ite3_quota_ftell
cb40: 20 48 41 4e 44 4c 45 0a 2a 2f 0a 73 74 61 74 69   HANDLE.*/.stati
cb50: 63 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c  c int SQLITE_TCL
cb60: 41 50 49 20 74 65 73 74 5f 71 75 6f 74 61 5f 66  API test_quota_f
cb70: 74 65 6c 6c 28 0a 20 20 76 6f 69 64 20 2a 20 63  tell(.  void * c
cb80: 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c  lientData,.  Tcl
cb90: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c  _Interp *interp,
cba0: 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54  .  int objc,.  T
cbb0: 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62  cl_Obj *CONST ob
cbc0: 6a 76 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61 5f  jv[].){.  quota_
cbd0: 46 49 4c 45 20 2a 70 3b 0a 20 20 73 71 6c 69 74  FILE *p;.  sqlit
cbe0: 65 33 5f 69 6e 74 36 34 20 78 3b 0a 20 20 69 66  e3_int64 x;.  if
cbf0: 28 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20  ( objc!=2 ){.   
cc00: 20 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67   Tcl_WrongNumArg
cc10: 73 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a  s(interp, 1, obj
cc20: 76 2c 20 22 48 41 4e 44 4c 45 22 29 3b 0a 20 20  v, "HANDLE");.  
cc30: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52    return TCL_ERR
cc40: 4f 52 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71  OR;.  }.  p = sq
cc50: 6c 69 74 65 33 54 65 73 74 54 65 78 74 54 6f 50  lite3TestTextToP
cc60: 74 72 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67  tr(Tcl_GetString
cc70: 28 6f 62 6a 76 5b 31 5d 29 29 3b 0a 20 20 78 20  (objv[1]));.  x 
cc80: 3d 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  = sqlite3_quota_
cc90: 66 74 65 6c 6c 28 70 29 3b 0a 20 20 54 63 6c 5f  ftell(p);.  Tcl_
cca0: 53 65 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74  SetObjResult(int
ccb0: 65 72 70 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65  erp, Tcl_NewWide
ccc0: 49 6e 74 4f 62 6a 28 78 29 29 3b 0a 20 20 72 65  IntObj(x));.  re
ccd0: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
cce0: 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71  /*.** tclcmd: sq
ccf0: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 74 72 75  lite3_quota_ftru
cd00: 6e 63 61 74 65 20 48 41 4e 44 4c 45 20 53 49 5a  ncate HANDLE SIZ
cd10: 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  E.*/.static int 
cd20: 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20 74 65  SQLITE_TCLAPI te
cd30: 73 74 5f 71 75 6f 74 61 5f 66 74 72 75 6e 63 61  st_quota_ftrunca
cd40: 74 65 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69  te(.  void * cli
cd50: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
cd60: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
cd70: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
cd80: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
cd90: 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61 5f 46 49  [].){.  quota_FI
cda0: 4c 45 20 2a 70 3b 0a 20 20 73 71 6c 69 74 65 33  LE *p;.  sqlite3
cdb0: 5f 69 6e 74 36 34 20 78 3b 0a 20 20 54 63 6c 5f  _int64 x;.  Tcl_
cdc0: 57 69 64 65 49 6e 74 20 77 3b 0a 20 20 69 6e 74  WideInt w;.  int
cdd0: 20 72 63 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21   rc;.  if( objc!
cde0: 3d 33 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =3 ){.    Tcl_Wr
cdf0: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
ce00: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 48 41 4e  p, 1, objv, "HAN
ce10: 44 4c 45 20 53 49 5a 45 22 29 3b 0a 20 20 20 20  DLE SIZE");.    
ce20: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
ce30: 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69  ;.  }.  p = sqli
ce40: 74 65 33 54 65 73 74 54 65 78 74 54 6f 50 74 72  te3TestTextToPtr
ce50: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f  (Tcl_GetString(o
ce60: 62 6a 76 5b 31 5d 29 29 3b 0a 20 20 69 66 28 20  bjv[1]));.  if( 
ce70: 54 63 6c 5f 47 65 74 57 69 64 65 49 6e 74 46 72  Tcl_GetWideIntFr
ce80: 6f 6d 4f 62 6a 28 69 6e 74 65 72 70 2c 20 6f 62  omObj(interp, ob
ce90: 6a 76 5b 32 5d 2c 20 26 77 29 20 29 20 72 65 74  jv[2], &w) ) ret
cea0: 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20  urn TCL_ERROR;. 
ceb0: 20 78 20 3d 20 28 73 71 6c 69 74 65 33 5f 69 6e   x = (sqlite3_in
cec0: 74 36 34 29 77 3b 0a 20 20 72 63 20 3d 20 73 71  t64)w;.  rc = sq
ced0: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 74 72 75  lite3_quota_ftru
cee0: 6e 63 61 74 65 28 70 2c 20 78 29 3b 0a 20 20 54  ncate(p, x);.  T
cef0: 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74 28  cl_SetObjResult(
cf00: 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77 49  interp, Tcl_NewI
cf10: 6e 74 4f 62 6a 28 72 63 29 29 3b 0a 20 20 72 65  ntObj(rc));.  re
cf20: 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a  turn TCL_OK;.}..
cf30: 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71  /*.** tclcmd: sq
cf40: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 69 6c 65  lite3_quota_file
cf50: 5f 73 69 7a 65 20 48 41 4e 44 4c 45 0a 2a 2f 0a  _size HANDLE.*/.
cf60: 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49 54  static int SQLIT
cf70: 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71 75  E_TCLAPI test_qu
cf80: 6f 74 61 5f 66 69 6c 65 5f 73 69 7a 65 28 0a 20  ota_file_size(. 
cf90: 20 76 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61   void * clientDa
cfa0: 74 61 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70  ta,.  Tcl_Interp
cfb0: 20 2a 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20   *interp,.  int 
cfc0: 6f 62 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20  objc,.  Tcl_Obj 
cfd0: 2a 43 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b  *CONST objv[].){
cfe0: 0a 20 20 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70  .  quota_FILE *p
cff0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  ;.  sqlite3_int6
d000: 34 20 78 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21  4 x;.  if( objc!
d010: 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72  =2 ){.    Tcl_Wr
d020: 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65 72  ongNumArgs(inter
d030: 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 48 41 4e  p, 1, objv, "HAN
d040: 44 4c 45 22 29 3b 0a 20 20 20 20 72 65 74 75 72  DLE");.    retur
d050: 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d  n TCL_ERROR;.  }
d060: 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 54 65  .  p = sqlite3Te
d070: 73 74 54 65 78 74 54 6f 50 74 72 28 54 63 6c 5f  stTextToPtr(Tcl_
d080: 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b 31  GetString(objv[1
d090: 5d 29 29 3b 0a 20 20 78 20 3d 20 73 71 6c 69 74  ]));.  x = sqlit
d0a0: 65 33 5f 71 75 6f 74 61 5f 66 69 6c 65 5f 73 69  e3_quota_file_si
d0b0: 7a 65 28 70 29 3b 0a 20 20 54 63 6c 5f 53 65 74  ze(p);.  Tcl_Set
d0c0: 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72 70  ObjResult(interp
d0d0: 2c 20 54 63 6c 5f 4e 65 77 57 69 64 65 49 6e 74  , Tcl_NewWideInt
d0e0: 4f 62 6a 28 78 29 29 3b 0a 20 20 72 65 74 75 72  Obj(x));.  retur
d0f0: 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  n TCL_OK;.}../*.
d100: 2a 2a 20 74 63 6c 63 6d 64 3a 20 73 71 6c 69 74  ** tclcmd: sqlit
d110: 65 33 5f 71 75 6f 74 61 5f 66 69 6c 65 5f 74 72  e3_quota_file_tr
d120: 75 65 73 69 7a 65 20 48 41 4e 44 4c 45 0a 2a 2f  uesize HANDLE.*/
d130: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
d140: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71  TE_TCLAPI test_q
d150: 75 6f 74 61 5f 66 69 6c 65 5f 74 72 75 65 73 69  uota_file_truesi
d160: 7a 65 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69  ze(.  void * cli
d170: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
d180: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
d190: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
d1a0: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
d1b0: 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61 5f 46 49  [].){.  quota_FI
d1c0: 4c 45 20 2a 70 3b 0a 20 20 73 71 6c 69 74 65 33  LE *p;.  sqlite3
d1d0: 5f 69 6e 74 36 34 20 78 3b 0a 20 20 69 66 28 20  _int64 x;.  if( 
d1e0: 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54  objc!=2 ){.    T
d1f0: 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28  cl_WrongNumArgs(
d200: 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c  interp, 1, objv,
d210: 20 22 48 41 4e 44 4c 45 22 29 3b 0a 20 20 20 20   "HANDLE");.    
d220: 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52  return TCL_ERROR
d230: 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69  ;.  }.  p = sqli
d240: 74 65 33 54 65 73 74 54 65 78 74 54 6f 50 74 72  te3TestTextToPtr
d250: 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f  (Tcl_GetString(o
d260: 62 6a 76 5b 31 5d 29 29 3b 0a 20 20 78 20 3d 20  bjv[1]));.  x = 
d270: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 69  sqlite3_quota_fi
d280: 6c 65 5f 74 72 75 65 73 69 7a 65 28 70 29 3b 0a  le_truesize(p);.
d290: 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75    Tcl_SetObjResu
d2a0: 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e  lt(interp, Tcl_N
d2b0: 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 78 29 29  ewWideIntObj(x))
d2c0: 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f  ;.  return TCL_O
d2d0: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63  K;.}../*.** tclc
d2e0: 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74  md: sqlite3_quot
d2f0: 61 5f 66 69 6c 65 5f 6d 74 69 6d 65 20 48 41 4e  a_file_mtime HAN
d300: 44 4c 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  DLE.*/.static in
d310: 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49 20  t SQLITE_TCLAPI 
d320: 74 65 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65 5f  test_quota_file_
d330: 6d 74 69 6d 65 28 0a 20 20 76 6f 69 64 20 2a 20  mtime(.  void * 
d340: 63 6c 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63  clientData,.  Tc
d350: 6c 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70  l_Interp *interp
d360: 2c 0a 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20  ,.  int objc,.  
d370: 54 63 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f  Tcl_Obj *CONST o
d380: 62 6a 76 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61  bjv[].){.  quota
d390: 5f 46 49 4c 45 20 2a 70 3b 0a 20 20 74 69 6d 65  _FILE *p;.  time
d3a0: 5f 74 20 74 3b 0a 20 20 69 66 28 20 6f 62 6a 63  _t t;.  if( objc
d3b0: 21 3d 32 20 29 7b 0a 20 20 20 20 54 63 6c 5f 57  !=2 ){.    Tcl_W
d3c0: 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69 6e 74 65  rongNumArgs(inte
d3d0: 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20 22 48 41  rp, 1, objv, "HA
d3e0: 4e 44 4c 45 22 29 3b 0a 20 20 20 20 72 65 74 75  NDLE");.    retu
d3f0: 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20  rn TCL_ERROR;.  
d400: 7d 0a 20 20 70 20 3d 20 73 71 6c 69 74 65 33 54  }.  p = sqlite3T
d410: 65 73 74 54 65 78 74 54 6f 50 74 72 28 54 63 6c  estTextToPtr(Tcl
d420: 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76 5b  _GetString(objv[
d430: 31 5d 29 29 3b 0a 20 20 74 20 3d 20 30 3b 0a 20  1]));.  t = 0;. 
d440: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66   sqlite3_quota_f
d450: 69 6c 65 5f 6d 74 69 6d 65 28 70 2c 20 26 74 29  ile_mtime(p, &t)
d460: 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65  ;.  Tcl_SetObjRe
d470: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
d480: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 74  _NewWideIntObj(t
d490: 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  ));.  return TCL
d4a0: 5f 4f 4b 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 74  _OK;.}.../*.** t
d4b0: 63 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71  clcmd: sqlite3_q
d4c0: 75 6f 74 61 5f 72 65 6d 6f 76 65 20 46 49 4c 45  uota_remove FILE
d4d0: 4e 41 4d 45 0a 2a 2f 0a 73 74 61 74 69 63 20 69  NAME.*/.static i
d4e0: 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41 50 49  nt SQLITE_TCLAPI
d4f0: 20 74 65 73 74 5f 71 75 6f 74 61 5f 72 65 6d 6f   test_quota_remo
d500: 76 65 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69  ve(.  void * cli
d510: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
d520: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
d530: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
d540: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
d550: 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  [].){.  const ch
d560: 61 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 3b 20 20  ar *zFilename;  
d570: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
d580: 70 61 74 74 65 72 6e 20 74 6f 20 63 6f 6e 66 69  pattern to confi
d590: 67 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 72 63  gure */.  int rc
d5a0: 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 32 20  ;.  if( objc!=2 
d5b0: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
d5c0: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
d5d0: 31 2c 20 6f 62 6a 76 2c 20 22 46 49 4c 45 4e 41  1, objv, "FILENA
d5e0: 4d 45 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  ME");.    return
d5f0: 20 54 43 4c 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a   TCL_ERROR;.  }.
d600: 20 20 7a 46 69 6c 65 6e 61 6d 65 20 3d 20 54 63    zFilename = Tc
d610: 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62 6a 76  l_GetString(objv
d620: 5b 31 5d 29 3b 0a 20 20 72 63 20 3d 20 73 71 6c  [1]);.  rc = sql
d630: 69 74 65 33 5f 71 75 6f 74 61 5f 72 65 6d 6f 76  ite3_quota_remov
d640: 65 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20  e(zFilename);.  
d650: 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73 75 6c 74  Tcl_SetObjResult
d660: 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f 4e 65 77  (interp, Tcl_New
d670: 49 6e 74 4f 62 6a 28 72 63 29 29 3b 0a 20 20 72  IntObj(rc));.  r
d680: 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b 0a 7d 0a  eturn TCL_OK;.}.
d690: 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64 3a 20 73  ./*.** tclcmd: s
d6a0: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 67 6c 6f  qlite3_quota_glo
d6b0: 62 20 50 41 54 54 45 52 4e 20 54 45 58 54 0a 2a  b PATTERN TEXT.*
d6c0: 2a 0a 2a 2a 20 54 65 73 74 20 74 68 65 20 67 6c  *.** Test the gl
d6d0: 6f 62 20 70 61 74 74 65 72 6e 20 6d 61 74 63 68  ob pattern match
d6e0: 69 6e 67 2e 20 20 52 65 74 75 72 6e 20 31 20 69  ing.  Return 1 i
d6f0: 66 20 54 45 58 54 20 6d 61 74 63 68 65 73 20 50  f TEXT matches P
d700: 41 54 54 45 52 4e 0a 2a 2a 20 61 6e 64 20 72 65  ATTERN.** and re
d710: 74 75 72 6e 20 30 20 69 66 20 69 74 20 64 6f 65  turn 0 if it doe
d720: 73 20 6e 6f 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  s not..*/.static
d730: 20 69 6e 74 20 53 51 4c 49 54 45 5f 54 43 4c 41   int SQLITE_TCLA
d740: 50 49 20 74 65 73 74 5f 71 75 6f 74 61 5f 67 6c  PI test_quota_gl
d750: 6f 62 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c 69  ob(.  void * cli
d760: 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f 49  entData,.  Tcl_I
d770: 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a 20  nterp *interp,. 
d780: 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63 6c   int objc,.  Tcl
d790: 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a 76  _Obj *CONST objv
d7a0: 5b 5d 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  [].){.  const ch
d7b0: 61 72 20 2a 7a 50 61 74 74 65 72 6e 3b 20 20 20  ar *zPattern;   
d7c0: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 67 6c         /* The gl
d7d0: 6f 62 20 70 61 74 74 65 72 6e 20 2a 2f 0a 20 20  ob pattern */.  
d7e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 65 78  const char *zTex
d7f0: 74 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f  t;             /
d800: 2a 20 54 65 78 74 20 74 6f 20 63 6f 6d 70 61 72  * Text to compar
d810: 65 20 61 67 61 69 6e 73 20 74 68 65 20 70 61 74  e agains the pat
d820: 74 65 72 6e 20 2a 2f 0a 20 20 69 6e 74 20 72 63  tern */.  int rc
d830: 3b 0a 20 20 69 66 28 20 6f 62 6a 63 21 3d 33 20  ;.  if( objc!=3 
d840: 29 7b 0a 20 20 20 20 54 63 6c 5f 57 72 6f 6e 67  ){.    Tcl_Wrong
d850: 4e 75 6d 41 72 67 73 28 69 6e 74 65 72 70 2c 20  NumArgs(interp, 
d860: 31 2c 20 6f 62 6a 76 2c 20 22 50 41 54 54 45 52  1, objv, "PATTER
d870: 4e 20 54 45 58 54 22 29 3b 0a 20 20 20 20 72 65  N TEXT");.    re
d880: 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b 0a  turn TCL_ERROR;.
d890: 20 20 7d 0a 20 20 7a 50 61 74 74 65 72 6e 20 3d    }.  zPattern =
d8a0: 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f   Tcl_GetString(o
d8b0: 62 6a 76 5b 31 5d 29 3b 0a 20 20 7a 54 65 78 74  bjv[1]);.  zText
d8c0: 20 3d 20 54 63 6c 5f 47 65 74 53 74 72 69 6e 67   = Tcl_GetString
d8d0: 28 6f 62 6a 76 5b 32 5d 29 3b 0a 20 20 72 63 20  (objv[2]);.  rc 
d8e0: 3d 20 71 75 6f 74 61 53 74 72 67 6c 6f 62 28 7a  = quotaStrglob(z
d8f0: 50 61 74 74 65 72 6e 2c 20 7a 54 65 78 74 29 3b  Pattern, zText);
d900: 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65 73  .  Tcl_SetObjRes
d910: 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c 5f  ult(interp, Tcl_
d920: 4e 65 77 49 6e 74 4f 62 6a 28 72 63 29 29 3b 0a  NewIntObj(rc));.
d930: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
d940: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63 6c 63 6d 64  .}../*.** tclcmd
d950: 3a 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f  : sqlite3_quota_
d960: 66 69 6c 65 5f 61 76 61 69 6c 61 62 6c 65 20 48  file_available H
d970: 41 4e 44 4c 45 0a 2a 2a 0a 2a 2a 20 52 65 74 75  ANDLE.**.** Retu
d980: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
d990: 20 62 79 74 65 73 20 66 72 6f 6d 20 74 68 65 20   bytes from the 
d9a0: 63 75 72 72 65 6e 74 20 66 69 6c 65 20 70 6f 69  current file poi
d9b0: 6e 74 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  nt to the end of
d9c0: 0a 2a 2a 20 74 68 65 20 66 69 6c 65 2e 0a 2a 2f  .** the file..*/
d9d0: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
d9e0: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71  TE_TCLAPI test_q
d9f0: 75 6f 74 61 5f 66 69 6c 65 5f 61 76 61 69 6c 61  uota_file_availa
da00: 62 6c 65 28 0a 20 20 76 6f 69 64 20 2a 20 63 6c  ble(.  void * cl
da10: 69 65 6e 74 44 61 74 61 2c 0a 20 20 54 63 6c 5f  ientData,.  Tcl_
da20: 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 2c 0a  Interp *interp,.
da30: 20 20 69 6e 74 20 6f 62 6a 63 2c 0a 20 20 54 63    int objc,.  Tc
da40: 6c 5f 4f 62 6a 20 2a 43 4f 4e 53 54 20 6f 62 6a  l_Obj *CONST obj
da50: 76 5b 5d 0a 29 7b 0a 20 20 71 75 6f 74 61 5f 46  v[].){.  quota_F
da60: 49 4c 45 20 2a 70 3b 0a 20 20 73 71 6c 69 74 65  ILE *p;.  sqlite
da70: 33 5f 69 6e 74 36 34 20 78 3b 0a 20 20 69 66 28  3_int64 x;.  if(
da80: 20 6f 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20   objc!=2 ){.    
da90: 54 63 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73  Tcl_WrongNumArgs
daa0: 28 69 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76  (interp, 1, objv
dab0: 2c 20 22 48 41 4e 44 4c 45 22 29 3b 0a 20 20 20  , "HANDLE");.   
dac0: 20 72 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f   return TCL_ERRO
dad0: 52 3b 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c  R;.  }.  p = sql
dae0: 69 74 65 33 54 65 73 74 54 65 78 74 54 6f 50 74  ite3TestTextToPt
daf0: 72 28 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28  r(Tcl_GetString(
db00: 6f 62 6a 76 5b 31 5d 29 29 3b 0a 20 20 78 20 3d  objv[1]));.  x =
db10: 20 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66   sqlite3_quota_f
db20: 69 6c 65 5f 61 76 61 69 6c 61 62 6c 65 28 70 29  ile_available(p)
db30: 3b 0a 20 20 54 63 6c 5f 53 65 74 4f 62 6a 52 65  ;.  Tcl_SetObjRe
db40: 73 75 6c 74 28 69 6e 74 65 72 70 2c 20 54 63 6c  sult(interp, Tcl
db50: 5f 4e 65 77 57 69 64 65 49 6e 74 4f 62 6a 28 78  _NewWideIntObj(x
db60: 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 54 43 4c  ));.  return TCL
db70: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 74 63  _OK;.}../*.** tc
db80: 6c 63 6d 64 3a 20 73 71 6c 69 74 65 33 5f 71 75  lcmd: sqlite3_qu
db90: 6f 74 61 5f 66 65 72 72 6f 72 20 48 41 4e 44 4c  ota_ferror HANDL
dba0: 45 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  E.**.** Return t
dbb0: 72 75 65 20 69 66 20 74 68 65 20 66 69 6c 65 20  rue if the file 
dbc0: 68 61 6e 64 6c 65 20 69 73 20 69 6e 20 74 68 65  handle is in the
dbd0: 20 65 72 72 6f 72 20 73 74 61 74 65 2e 0a 2a 2f   error state..*/
dbe0: 0a 73 74 61 74 69 63 20 69 6e 74 20 53 51 4c 49  .static int SQLI
dbf0: 54 45 5f 54 43 4c 41 50 49 20 74 65 73 74 5f 71  TE_TCLAPI test_q
dc00: 75 6f 74 61 5f 66 65 72 72 6f 72 28 0a 20 20 76  uota_ferror(.  v
dc10: 6f 69 64 20 2a 20 63 6c 69 65 6e 74 44 61 74 61  oid * clientData
dc20: 2c 0a 20 20 54 63 6c 5f 49 6e 74 65 72 70 20 2a  ,.  Tcl_Interp *
dc30: 69 6e 74 65 72 70 2c 0a 20 20 69 6e 74 20 6f 62  interp,.  int ob
dc40: 6a 63 2c 0a 20 20 54 63 6c 5f 4f 62 6a 20 2a 43  jc,.  Tcl_Obj *C
dc50: 4f 4e 53 54 20 6f 62 6a 76 5b 5d 0a 29 7b 0a 20  ONST objv[].){. 
dc60: 20 71 75 6f 74 61 5f 46 49 4c 45 20 2a 70 3b 0a   quota_FILE *p;.
dc70: 20 20 69 6e 74 20 78 3b 0a 20 20 69 66 28 20 6f    int x;.  if( o
dc80: 62 6a 63 21 3d 32 20 29 7b 0a 20 20 20 20 54 63  bjc!=2 ){.    Tc
dc90: 6c 5f 57 72 6f 6e 67 4e 75 6d 41 72 67 73 28 69  l_WrongNumArgs(i
dca0: 6e 74 65 72 70 2c 20 31 2c 20 6f 62 6a 76 2c 20  nterp, 1, objv, 
dcb0: 22 48 41 4e 44 4c 45 22 29 3b 0a 20 20 20 20 72  "HANDLE");.    r
dcc0: 65 74 75 72 6e 20 54 43 4c 5f 45 52 52 4f 52 3b  eturn TCL_ERROR;
dcd0: 0a 20 20 7d 0a 20 20 70 20 3d 20 73 71 6c 69 74  .  }.  p = sqlit
dce0: 65 33 54 65 73 74 54 65 78 74 54 6f 50 74 72 28  e3TestTextToPtr(
dcf0: 54 63 6c 5f 47 65 74 53 74 72 69 6e 67 28 6f 62  Tcl_GetString(ob
dd00: 6a 76 5b 31 5d 29 29 3b 0a 20 20 78 20 3d 20 73  jv[1]));.  x = s
dd10: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 65 72  qlite3_quota_fer
dd20: 72 6f 72 28 70 29 3b 0a 20 20 54 63 6c 5f 53 65  ror(p);.  Tcl_Se
dd30: 74 4f 62 6a 52 65 73 75 6c 74 28 69 6e 74 65 72  tObjResult(inter
dd40: 70 2c 20 54 63 6c 5f 4e 65 77 49 6e 74 4f 62 6a  p, Tcl_NewIntObj
dd50: 28 78 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 54  (x));.  return T
dd60: 43 4c 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  CL_OK;.}../*.** 
dd70: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 67  This routine reg
dd80: 69 73 74 65 72 73 20 74 68 65 20 63 75 73 74 6f  isters the custo
dd90: 6d 20 54 43 4c 20 63 6f 6d 6d 61 6e 64 73 20 64  m TCL commands d
dda0: 65 66 69 6e 65 64 20 69 6e 20 74 68 69 73 0a 2a  efined in this.*
ddb0: 2a 20 6d 6f 64 75 6c 65 2e 20 20 54 68 69 73 20  * module.  This 
ddc0: 73 68 6f 75 6c 64 20 62 65 20 74 68 65 20 6f 6e  should be the on
ddd0: 6c 79 20 70 72 6f 63 65 64 75 72 65 20 76 69 73  ly procedure vis
dde0: 69 62 6c 65 20 66 72 6f 6d 20 6f 75 74 73 69 64  ible from outsid
ddf0: 65 0a 2a 2a 20 6f 66 20 74 68 69 73 20 6d 6f 64  e.** of this mod
de00: 75 6c 65 2e 0a 2a 2f 0a 69 6e 74 20 53 71 6c 69  ule..*/.int Sqli
de10: 74 65 71 75 6f 74 61 5f 49 6e 69 74 28 54 63 6c  tequota_Init(Tcl
de20: 5f 49 6e 74 65 72 70 20 2a 69 6e 74 65 72 70 29  _Interp *interp)
de30: 7b 0a 20 20 73 74 61 74 69 63 20 73 74 72 75 63  {.  static struc
de40: 74 20 7b 0a 20 20 20 20 20 63 68 61 72 20 2a 7a  t {.     char *z
de50: 4e 61 6d 65 3b 0a 20 20 20 20 20 54 63 6c 5f 4f  Name;.     Tcl_O
de60: 62 6a 43 6d 64 50 72 6f 63 20 2a 78 50 72 6f 63  bjCmdProc *xProc
de70: 3b 0a 20 20 7d 20 61 43 6d 64 5b 5d 20 3d 20 7b  ;.  } aCmd[] = {
de80: 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f  .    { "sqlite3_
de90: 71 75 6f 74 61 5f 69 6e 69 74 69 61 6c 69 7a 65  quota_initialize
dea0: 22 2c 20 20 20 20 74 65 73 74 5f 71 75 6f 74 61  ",    test_quota
deb0: 5f 69 6e 69 74 69 61 6c 69 7a 65 20 7d 2c 0a 20  _initialize },. 
dec0: 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75     { "sqlite3_qu
ded0: 6f 74 61 5f 73 68 75 74 64 6f 77 6e 22 2c 20 20  ota_shutdown",  
dee0: 20 20 20 20 74 65 73 74 5f 71 75 6f 74 61 5f 73      test_quota_s
def0: 68 75 74 64 6f 77 6e 20 7d 2c 0a 20 20 20 20 7b  hutdown },.    {
df00: 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f   "sqlite3_quota_
df10: 73 65 74 22 2c 20 20 20 20 20 20 20 20 20 20 20  set",           
df20: 74 65 73 74 5f 71 75 6f 74 61 5f 73 65 74 20 7d  test_quota_set }
df30: 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  ,.    { "sqlite3
df40: 5f 71 75 6f 74 61 5f 66 69 6c 65 22 2c 20 20 20  _quota_file",   
df50: 20 20 20 20 20 20 20 74 65 73 74 5f 71 75 6f 74         test_quot
df60: 61 5f 66 69 6c 65 20 7d 2c 0a 20 20 20 20 7b 20  a_file },.    { 
df70: 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 64  "sqlite3_quota_d
df80: 75 6d 70 22 2c 20 20 20 20 20 20 20 20 20 20 74  ump",          t
df90: 65 73 74 5f 71 75 6f 74 61 5f 64 75 6d 70 20 7d  est_quota_dump }
dfa0: 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  ,.    { "sqlite3
dfb0: 5f 71 75 6f 74 61 5f 66 6f 70 65 6e 22 2c 20 20  _quota_fopen",  
dfc0: 20 20 20 20 20 20 20 74 65 73 74 5f 71 75 6f 74         test_quot
dfd0: 61 5f 66 6f 70 65 6e 20 7d 2c 0a 20 20 20 20 7b  a_fopen },.    {
dfe0: 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f   "sqlite3_quota_
dff0: 66 72 65 61 64 22 2c 20 20 20 20 20 20 20 20 20  fread",         
e000: 74 65 73 74 5f 71 75 6f 74 61 5f 66 72 65 61 64  test_quota_fread
e010: 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74   },.    { "sqlit
e020: 65 33 5f 71 75 6f 74 61 5f 66 77 72 69 74 65 22  e3_quota_fwrite"
e030: 2c 20 20 20 20 20 20 20 20 74 65 73 74 5f 71 75  ,        test_qu
e040: 6f 74 61 5f 66 77 72 69 74 65 20 7d 2c 0a 20 20  ota_fwrite },.  
e050: 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f    { "sqlite3_quo
e060: 74 61 5f 66 63 6c 6f 73 65 22 2c 20 20 20 20 20  ta_fclose",     
e070: 20 20 20 74 65 73 74 5f 71 75 6f 74 61 5f 66 63     test_quota_fc
e080: 6c 6f 73 65 20 7d 2c 0a 20 20 20 20 7b 20 22 73  lose },.    { "s
e090: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 66 6c  qlite3_quota_ffl
e0a0: 75 73 68 22 2c 20 20 20 20 20 20 20 20 74 65 73  ush",        tes
e0b0: 74 5f 71 75 6f 74 61 5f 66 66 6c 75 73 68 20 7d  t_quota_fflush }
e0c0: 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33  ,.    { "sqlite3
e0d0: 5f 71 75 6f 74 61 5f 66 73 65 65 6b 22 2c 20 20  _quota_fseek",  
e0e0: 20 20 20 20 20 20 20 74 65 73 74 5f 71 75 6f 74         test_quot
e0f0: 61 5f 66 73 65 65 6b 20 7d 2c 0a 20 20 20 20 7b  a_fseek },.    {
e100: 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f   "sqlite3_quota_
e110: 72 65 77 69 6e 64 22 2c 20 20 20 20 20 20 20 20  rewind",        
e120: 74 65 73 74 5f 71 75 6f 74 61 5f 72 65 77 69 6e  test_quota_rewin
e130: 64 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71 6c 69  d },.    { "sqli
e140: 74 65 33 5f 71 75 6f 74 61 5f 66 74 65 6c 6c 22  te3_quota_ftell"
e150: 2c 20 20 20 20 20 20 20 20 20 74 65 73 74 5f 71  ,         test_q
e160: 75 6f 74 61 5f 66 74 65 6c 6c 20 7d 2c 0a 20 20  uota_ftell },.  
e170: 20 20 7b 20 22 73 71 6c 69 74 65 33 5f 71 75 6f    { "sqlite3_quo
e180: 74 61 5f 66 74 72 75 6e 63 61 74 65 22 2c 20 20  ta_ftruncate",  
e190: 20 20 20 74 65 73 74 5f 71 75 6f 74 61 5f 66 74     test_quota_ft
e1a0: 72 75 6e 63 61 74 65 20 7d 2c 0a 20 20 20 20 7b  runcate },.    {
e1b0: 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f   "sqlite3_quota_
e1c0: 66 69 6c 65 5f 73 69 7a 65 22 2c 20 20 20 20 20  file_size",     
e1d0: 74 65 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65 5f  test_quota_file_
e1e0: 73 69 7a 65 20 7d 2c 0a 20 20 20 20 7b 20 22 73  size },.    { "s
e1f0: 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 69 6c  qlite3_quota_fil
e200: 65 5f 74 72 75 65 73 69 7a 65 22 2c 20 74 65 73  e_truesize", tes
e210: 74 5f 71 75 6f 74 61 5f 66 69 6c 65 5f 74 72 75  t_quota_file_tru
e220: 65 73 69 7a 65 20 7d 2c 0a 20 20 20 20 7b 20 22  esize },.    { "
e230: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 69  sqlite3_quota_fi
e240: 6c 65 5f 6d 74 69 6d 65 22 2c 20 20 20 20 74 65  le_mtime",    te
e250: 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65 5f 6d 74  st_quota_file_mt
e260: 69 6d 65 20 7d 2c 0a 20 20 20 20 7b 20 22 73 71  ime },.    { "sq
e270: 6c 69 74 65 33 5f 71 75 6f 74 61 5f 72 65 6d 6f  lite3_quota_remo
e280: 76 65 22 2c 20 20 20 20 20 20 20 20 74 65 73 74  ve",        test
e290: 5f 71 75 6f 74 61 5f 72 65 6d 6f 76 65 20 7d 2c  _quota_remove },
e2a0: 0a 20 20 20 20 7b 20 22 73 71 6c 69 74 65 33 5f  .    { "sqlite3_
e2b0: 71 75 6f 74 61 5f 67 6c 6f 62 22 2c 20 20 20 20  quota_glob",    
e2c0: 20 20 20 20 20 20 74 65 73 74 5f 71 75 6f 74 61        test_quota
e2d0: 5f 67 6c 6f 62 20 7d 2c 0a 20 20 20 20 7b 20 22  _glob },.    { "
e2e0: 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f 66 69  sqlite3_quota_fi
e2f0: 6c 65 5f 61 76 61 69 6c 61 62 6c 65 22 2c 74 65  le_available",te
e300: 73 74 5f 71 75 6f 74 61 5f 66 69 6c 65 5f 61 76  st_quota_file_av
e310: 61 69 6c 61 62 6c 65 20 7d 2c 0a 20 20 20 20 7b  ailable },.    {
e320: 20 22 73 71 6c 69 74 65 33 5f 71 75 6f 74 61 5f   "sqlite3_quota_
e330: 66 65 72 72 6f 72 22 2c 20 20 20 20 20 20 20 20  ferror",        
e340: 74 65 73 74 5f 71 75 6f 74 61 5f 66 65 72 72 6f  test_quota_ferro
e350: 72 20 7d 2c 0a 20 20 7d 3b 0a 20 20 69 6e 74 20  r },.  };.  int 
e360: 69 3b 0a 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69  i;..  for(i=0; i
e370: 3c 73 69 7a 65 6f 66 28 61 43 6d 64 29 2f 73 69  <sizeof(aCmd)/si
e380: 7a 65 6f 66 28 61 43 6d 64 5b 30 5d 29 3b 20 69  zeof(aCmd[0]); i
e390: 2b 2b 29 7b 0a 20 20 20 20 54 63 6c 5f 43 72 65  ++){.    Tcl_Cre
e3a0: 61 74 65 4f 62 6a 43 6f 6d 6d 61 6e 64 28 69 6e  ateObjCommand(in
e3b0: 74 65 72 70 2c 20 61 43 6d 64 5b 69 5d 2e 7a 4e  terp, aCmd[i].zN
e3c0: 61 6d 65 2c 20 61 43 6d 64 5b 69 5d 2e 78 50 72  ame, aCmd[i].xPr
e3d0: 6f 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a 0a  oc, 0, 0);.  }..
e3e0: 20 20 72 65 74 75 72 6e 20 54 43 4c 5f 4f 4b 3b    return TCL_OK;
e3f0: 0a 7d 0a 23 65 6e 64 69 66 0a                    .}.#endif.