/ Hex Artifact Content
Login

Artifact 592d6531d8413d81b25f5a47a45d7e310e455d33e03a64c6ae85724c6524a5d5:


0000: 2f 2a 0a 2a 2a 20 32 30 31 34 2d 30 36 2d 31 33  /*.** 2014-06-13
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
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 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 53 51 4c 69 74 65 20 65 78 74 65 6e 73 69 6f 6e  SQLite extension
0190: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 53 51 4c 20   implements SQL 
01a0: 66 75 6e 63 74 69 6f 6e 73 20 72 65 61 64 66 69  functions readfi
01b0: 6c 65 28 29 20 61 6e 64 0a 2a 2a 20 77 72 69 74  le() and.** writ
01c0: 65 66 69 6c 65 28 29 2c 20 61 6e 64 20 65 70 6f  efile(), and epo
01d0: 6e 79 6d 6f 75 73 20 76 69 72 74 75 61 6c 20 74  nymous virtual t
01e0: 79 70 65 20 22 66 73 64 69 72 22 2e 0a 2a 2a 0a  ype "fsdir"..**.
01f0: 2a 2a 20 57 52 49 54 45 46 49 4c 45 28 46 49 4c  ** WRITEFILE(FIL
0200: 45 2c 20 44 41 54 41 20 5b 2c 20 4d 4f 44 45 20  E, DATA [, MODE 
0210: 5b 2c 20 4d 54 49 4d 45 5d 5d 29 3a 0a 2a 2a 0a  [, MTIME]]):.**.
0220: 2a 2a 20 20 20 49 66 20 6e 65 69 74 68 65 72 20  **   If neither 
0230: 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20  of the optional 
0240: 61 72 67 75 6d 65 6e 74 73 20 69 73 20 70 72 65  arguments is pre
0250: 73 65 6e 74 2c 20 74 68 65 6e 20 74 68 69 73 20  sent, then this 
0260: 55 44 46 0a 2a 2a 20 20 20 66 75 6e 63 74 69 6f  UDF.**   functio
0270: 6e 20 77 72 69 74 65 73 20 62 6c 6f 62 20 44 41  n writes blob DA
0280: 54 41 20 74 6f 20 66 69 6c 65 20 46 49 4c 45 2e  TA to file FILE.
0290: 20 49 66 20 73 75 63 63 65 73 73 66 75 6c 2c 20   If successful, 
02a0: 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 20 20  the number.**   
02b0: 6f 66 20 62 79 74 65 73 20 77 72 69 74 74 65 6e  of bytes written
02c0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 49 66   is returned. If
02d0: 20 61 6e 20 65 72 72 6f 72 20 6f 63 63 75 72 73   an error occurs
02e0: 2c 20 4e 55 4c 4c 20 69 73 20 72 65 74 75 72 6e  , NULL is return
02f0: 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 74  ed..**.**   If t
0300: 68 65 20 66 69 72 73 74 20 6f 70 74 69 6f 6e 20  he first option 
0310: 61 72 67 75 6d 65 6e 74 20 2d 20 4d 4f 44 45 20  argument - MODE 
0320: 2d 20 69 73 20 70 72 65 73 65 6e 74 2c 20 74 68  - is present, th
0330: 65 6e 20 69 74 20 6d 75 73 74 0a 2a 2a 20 20 20  en it must.**   
0340: 62 65 20 70 61 73 73 65 64 20 61 6e 20 69 6e 74  be passed an int
0350: 65 67 65 72 20 76 61 6c 75 65 20 74 68 61 74 20  eger value that 
0360: 63 6f 72 72 65 73 70 6f 6e 64 73 20 74 6f 20 61  corresponds to a
0370: 20 50 4f 53 49 58 20 6d 6f 64 65 0a 2a 2a 20 20   POSIX mode.**  
0380: 20 76 61 6c 75 65 20 28 66 69 6c 65 20 74 79 70   value (file typ
0390: 65 20 2b 20 70 65 72 6d 69 73 73 69 6f 6e 73 2c  e + permissions,
03a0: 20 61 73 20 72 65 74 75 72 6e 65 64 20 69 6e 20   as returned in 
03b0: 74 68 65 20 73 74 61 74 2e 73 74 5f 6d 6f 64 65  the stat.st_mode
03c0: 0a 2a 2a 20 20 20 66 69 65 6c 64 20 62 79 20 74  .**   field by t
03d0: 68 65 20 73 74 61 74 28 29 20 73 79 73 74 65 6d  he stat() system
03e0: 20 63 61 6c 6c 29 2e 20 54 68 72 65 65 20 74 79   call). Three ty
03f0: 70 65 73 20 6f 66 20 66 69 6c 65 73 20 6d 61 79  pes of files may
0400: 0a 2a 2a 20 20 20 62 65 20 77 72 69 74 74 65 6e  .**   be written
0410: 2f 63 72 65 61 74 65 64 3a 0a 2a 2a 0a 2a 2a 20  /created:.**.** 
0420: 20 20 20 20 72 65 67 75 6c 61 72 20 66 69 6c 65      regular file
0430: 73 3a 20 20 28 6d 6f 64 65 20 26 20 30 31 37 30  s:  (mode & 0170
0440: 30 30 30 29 3d 3d 30 31 30 30 30 30 30 0a 2a 2a  000)==0100000.**
0450: 20 20 20 20 20 73 79 6d 62 6f 6c 69 63 20 6c 69       symbolic li
0460: 6e 6b 73 3a 20 28 6d 6f 64 65 20 26 20 30 31 37  nks: (mode & 017
0470: 30 30 30 30 29 3d 3d 30 31 32 30 30 30 30 0a 2a  0000)==0120000.*
0480: 2a 20 20 20 20 20 64 69 72 65 63 74 6f 72 69 65  *     directorie
0490: 73 3a 20 20 20 20 28 6d 6f 64 65 20 26 20 30 31  s:    (mode & 01
04a0: 37 30 30 30 30 29 3d 3d 30 30 34 30 30 30 30 0a  70000)==0040000.
04b0: 2a 2a 0a 2a 2a 20 20 20 46 6f 72 20 61 20 64 69  **.**   For a di
04c0: 72 65 63 74 6f 72 79 2c 20 74 68 65 20 44 41 54  rectory, the DAT
04d0: 41 20 69 73 20 69 67 6e 6f 72 65 64 2e 20 46 6f  A is ignored. Fo
04e0: 72 20 61 20 73 79 6d 62 6f 6c 69 63 20 6c 69 6e  r a symbolic lin
04f0: 6b 2c 20 69 74 20 69 73 0a 2a 2a 20 20 20 69 6e  k, it is.**   in
0500: 74 65 72 70 72 65 74 65 64 20 61 73 20 74 65 78  terpreted as tex
0510: 74 20 61 6e 64 20 75 73 65 64 20 61 73 20 74 68  t and used as th
0520: 65 20 74 61 72 67 65 74 20 6f 66 20 74 68 65 20  e target of the 
0530: 6c 69 6e 6b 2e 20 46 6f 72 20 61 0a 2a 2a 20 20  link. For a.**  
0540: 20 72 65 67 75 6c 61 72 20 66 69 6c 65 2c 20 69   regular file, i
0550: 74 20 69 73 20 69 6e 74 65 72 70 72 65 74 65 64  t is interpreted
0560: 20 61 73 20 61 20 62 6c 6f 62 20 61 6e 64 20 77   as a blob and w
0570: 72 69 74 74 65 6e 20 69 6e 74 6f 20 74 68 65 0a  ritten into the.
0580: 2a 2a 20 20 20 6e 61 6d 65 64 20 66 69 6c 65 2e  **   named file.
0590: 20 52 65 67 61 72 64 6c 65 73 73 20 6f 66 20 74   Regardless of t
05a0: 68 65 20 74 79 70 65 20 6f 66 20 66 69 6c 65 2c  he type of file,
05b0: 20 69 74 73 20 70 65 72 6d 69 73 73 69 6f 6e 73   its permissions
05c0: 20 61 72 65 0a 2a 2a 20 20 20 73 65 74 20 74 6f   are.**   set to
05d0: 20 28 6d 6f 64 65 20 26 20 30 37 37 37 29 20 62   (mode & 0777) b
05e0: 65 66 6f 72 65 20 72 65 74 75 72 6e 69 6e 67 2e  efore returning.
05f0: 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 74 68 65 20  .**.**   If the 
0600: 6f 70 74 69 6f 6e 61 6c 20 4d 54 49 4d 45 20 61  optional MTIME a
0610: 72 67 75 6d 65 6e 74 20 69 73 20 70 72 65 73 65  rgument is prese
0620: 6e 74 2c 20 74 68 65 6e 20 69 74 20 69 73 20 69  nt, then it is i
0630: 6e 74 65 72 70 72 65 74 65 64 0a 2a 2a 20 20 20  nterpreted.**   
0640: 61 73 20 61 6e 20 69 6e 74 65 67 65 72 20 2d 20  as an integer - 
0650: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 73 65  the number of se
0660: 63 6f 6e 64 73 20 73 69 6e 63 65 20 74 68 65 20  conds since the 
0670: 75 6e 69 78 20 65 70 6f 63 68 2e 20 54 68 65 0a  unix epoch. The.
0680: 2a 2a 20 20 20 6d 6f 64 69 66 69 63 61 74 69 6f  **   modificatio
0690: 6e 2d 74 69 6d 65 20 6f 66 20 74 68 65 20 74 61  n-time of the ta
06a0: 72 67 65 74 20 66 69 6c 65 20 69 73 20 73 65 74  rget file is set
06b0: 20 74 6f 20 74 68 69 73 20 76 61 6c 75 65 20 62   to this value b
06c0: 65 66 6f 72 65 0a 2a 2a 20 20 20 72 65 74 75 72  efore.**   retur
06d0: 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66  ning..**.**   If
06e0: 20 74 68 72 65 65 20 6f 72 20 6d 6f 72 65 20 61   three or more a
06f0: 72 67 75 6d 65 6e 74 73 20 61 72 65 20 70 61 73  rguments are pas
0700: 73 65 64 20 74 6f 20 74 68 69 73 20 66 75 6e 63  sed to this func
0710: 74 69 6f 6e 20 61 6e 64 20 61 6e 0a 2a 2a 20 20  tion and an.**  
0720: 20 65 72 72 6f 72 20 69 73 20 65 6e 63 6f 75 6e   error is encoun
0730: 74 65 72 65 64 2c 20 61 6e 20 65 78 63 65 70 74  tered, an except
0740: 69 6f 6e 20 69 73 20 72 61 69 73 65 64 2e 0a 2a  ion is raised..*
0750: 2a 0a 2a 2a 20 52 45 41 44 46 49 4c 45 28 46 49  *.** READFILE(FI
0760: 4c 45 29 3a 0a 2a 2a 0a 2a 2a 20 20 20 52 65 61  LE):.**.**   Rea
0770: 64 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65  d and return the
0780: 20 63 6f 6e 74 65 6e 74 73 20 6f 66 20 66 69 6c   contents of fil
0790: 65 20 46 49 4c 45 20 28 74 79 70 65 20 62 6c 6f  e FILE (type blo
07a0: 62 29 20 66 72 6f 6d 20 64 69 73 6b 2e 0a 2a 2a  b) from disk..**
07b0: 0a 2a 2a 20 46 53 44 49 52 3a 0a 2a 2a 0a 2a 2a  .** FSDIR:.**.**
07c0: 20 20 20 55 73 65 64 20 61 73 20 66 6f 6c 6c 6f     Used as follo
07d0: 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 53 45  ws:.**.**     SE
07e0: 4c 45 43 54 20 2a 20 46 52 4f 4d 20 66 73 64 69  LECT * FROM fsdi
07f0: 72 28 24 70 61 74 68 20 5b 2c 20 24 64 69 72 5d  r($path [, $dir]
0800: 29 3b 0a 2a 2a 0a 2a 2a 20 20 20 50 61 72 61 6d  );.**.**   Param
0810: 65 74 65 72 20 24 70 61 74 68 20 69 73 20 61 6e  eter $path is an
0820: 20 61 62 73 6f 6c 75 74 65 20 6f 72 20 72 65 6c   absolute or rel
0830: 61 74 69 76 65 20 70 61 74 68 6e 61 6d 65 2e 20  ative pathname. 
0840: 49 66 20 74 68 65 20 66 69 6c 65 20 74 68 61 74  If the file that
0850: 20 69 74 0a 2a 2a 20 20 20 72 65 66 65 72 73 20   it.**   refers 
0860: 74 6f 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73  to does not exis
0870: 74 2c 20 69 74 20 69 73 20 61 6e 20 65 72 72 6f  t, it is an erro
0880: 72 2e 20 49 66 20 74 68 65 20 70 61 74 68 20 72  r. If the path r
0890: 65 66 65 72 73 20 74 6f 20 61 20 72 65 67 75 6c  efers to a regul
08a0: 61 72 0a 2a 2a 20 20 20 66 69 6c 65 20 6f 72 20  ar.**   file or 
08b0: 73 79 6d 62 6f 6c 69 63 20 6c 69 6e 6b 2c 20 69  symbolic link, i
08c0: 74 20 72 65 74 75 72 6e 73 20 61 20 73 69 6e 67  t returns a sing
08d0: 6c 65 20 72 6f 77 2e 20 4f 72 2c 20 69 66 20 74  le row. Or, if t
08e0: 68 65 20 70 61 74 68 20 72 65 66 65 72 73 0a 2a  he path refers.*
08f0: 2a 20 20 20 74 6f 20 61 20 64 69 72 65 63 74 6f  *   to a directo
0900: 72 79 2c 20 69 74 20 72 65 74 75 72 6e 73 20 6f  ry, it returns o
0910: 6e 65 20 72 6f 77 20 66 6f 72 20 74 68 65 20 64  ne row for the d
0920: 69 72 65 63 74 6f 72 79 2c 20 61 6e 64 20 6f 6e  irectory, and on
0930: 65 20 72 6f 77 20 66 6f 72 20 65 61 63 68 0a 2a  e row for each.*
0940: 2a 20 20 20 66 69 6c 65 20 77 69 74 68 69 6e 20  *   file within 
0950: 74 68 65 20 68 69 65 72 61 72 63 68 79 20 72 6f  the hierarchy ro
0960: 6f 74 65 64 20 61 74 20 24 70 61 74 68 2e 0a 2a  oted at $path..*
0970: 2a 0a 2a 2a 20 20 20 45 61 63 68 20 72 6f 77 20  *.**   Each row 
0980: 68 61 73 20 74 68 65 20 66 6f 6c 6c 6f 77 69 6e  has the followin
0990: 67 20 63 6f 6c 75 6d 6e 73 3a 0a 2a 2a 0a 2a 2a  g columns:.**.**
09a0: 20 20 20 20 20 6e 61 6d 65 3a 20 20 50 61 74 68       name:  Path
09b0: 20 74 6f 20 66 69 6c 65 20 6f 72 20 64 69 72 65   to file or dire
09c0: 63 74 6f 72 79 20 28 74 65 78 74 20 76 61 6c 75  ctory (text valu
09d0: 65 29 2e 0a 2a 2a 20 20 20 20 20 6d 6f 64 65 3a  e)..**     mode:
09e0: 20 20 56 61 6c 75 65 20 6f 66 20 73 74 61 74 2e    Value of stat.
09f0: 73 74 5f 6d 6f 64 65 20 66 6f 72 20 64 69 72 65  st_mode for dire
0a00: 63 74 6f 72 79 20 65 6e 74 72 79 20 28 61 6e 20  ctory entry (an 
0a10: 69 6e 74 65 67 65 72 29 2e 0a 2a 2a 20 20 20 20  integer)..**    
0a20: 20 6d 74 69 6d 65 3a 20 56 61 6c 75 65 20 6f 66   mtime: Value of
0a30: 20 73 74 61 74 2e 73 74 5f 6d 74 69 6d 65 20 66   stat.st_mtime f
0a40: 6f 72 20 64 69 72 65 63 74 6f 72 79 20 65 6e 74  or directory ent
0a50: 72 79 20 28 61 6e 20 69 6e 74 65 67 65 72 29 2e  ry (an integer).
0a60: 0a 2a 2a 20 20 20 20 20 64 61 74 61 3a 20 20 46  .**     data:  F
0a70: 6f 72 20 61 20 72 65 67 75 6c 61 72 20 66 69 6c  or a regular fil
0a80: 65 2c 20 61 20 62 6c 6f 62 20 63 6f 6e 74 61 69  e, a blob contai
0a90: 6e 69 6e 67 20 74 68 65 20 66 69 6c 65 20 64 61  ning the file da
0aa0: 74 61 2e 20 46 6f 72 20 61 0a 2a 2a 20 20 20 20  ta. For a.**    
0ab0: 20 20 20 20 20 20 20 20 73 79 6d 6c 69 6e 6b 2c          symlink,
0ac0: 20 61 20 74 65 78 74 20 76 61 6c 75 65 20 63 6f   a text value co
0ad0: 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 74 65 78  ntaining the tex
0ae0: 74 20 6f 66 20 74 68 65 20 6c 69 6e 6b 2e 20 46  t of the link. F
0af0: 6f 72 20 61 0a 2a 2a 20 20 20 20 20 20 20 20 20  or a.**         
0b00: 20 20 20 64 69 72 65 63 74 6f 72 79 2c 20 4e 55     directory, NU
0b10: 4c 4c 2e 0a 2a 2a 0a 2a 2a 20 20 20 49 66 20 61  LL..**.**   If a
0b20: 20 6e 6f 6e 2d 4e 55 4c 4c 20 76 61 6c 75 65 20   non-NULL value 
0b30: 69 73 20 73 70 65 63 69 66 69 65 64 20 66 6f 72  is specified for
0b40: 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20 24 64   the optional $d
0b50: 69 72 20 70 61 72 61 6d 65 74 65 72 20 61 6e 64  ir parameter and
0b60: 0a 2a 2a 20 20 20 24 70 61 74 68 20 69 73 20 61  .**   $path is a
0b70: 20 72 65 6c 61 74 69 76 65 20 70 61 74 68 2c 20   relative path, 
0b80: 74 68 65 6e 20 24 70 61 74 68 20 69 73 20 69 6e  then $path is in
0b90: 74 65 72 70 72 65 74 65 64 20 72 65 6c 61 74 69  terpreted relati
0ba0: 76 65 20 74 6f 20 24 64 69 72 2e 20 0a 2a 2a 20  ve to $dir. .** 
0bb0: 20 20 41 6e 64 20 74 68 65 20 70 61 74 68 73 20    And the paths 
0bc0: 72 65 74 75 72 6e 65 64 20 69 6e 20 74 68 65 20  returned in the 
0bd0: 22 6e 61 6d 65 22 20 63 6f 6c 75 6d 6e 20 6f 66  "name" column of
0be0: 20 74 68 65 20 74 61 62 6c 65 20 61 72 65 20 61   the table are a
0bf0: 6c 73 6f 20 0a 2a 2a 20 20 20 72 65 6c 61 74 69  lso .**   relati
0c00: 76 65 20 74 6f 20 64 69 72 65 63 74 6f 72 79 20  ve to directory 
0c10: 24 64 69 72 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64  $dir..*/.#includ
0c20: 65 20 22 73 71 6c 69 74 65 33 65 78 74 2e 68 22  e "sqlite3ext.h"
0c30: 0a 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f  .SQLITE_EXTENSIO
0c40: 4e 5f 49 4e 49 54 31 0a 23 69 6e 63 6c 75 64 65  N_INIT1.#include
0c50: 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c   <stdio.h>.#incl
0c60: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0c70: 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e  include <assert.
0c80: 68 3e 0a 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79  h>..#include <sy
0c90: 73 2f 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c  s/types.h>.#incl
0ca0: 75 64 65 20 3c 73 79 73 2f 73 74 61 74 2e 68 3e  ude <sys/stat.h>
0cb0: 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e 74 6c  .#include <fcntl
0cc0: 2e 68 3e 0a 23 69 66 20 21 64 65 66 69 6e 65 64  .h>.#if !defined
0cd0: 28 5f 57 49 4e 33 32 29 20 26 26 20 21 64 65 66  (_WIN32) && !def
0ce0: 69 6e 65 64 28 57 49 4e 33 32 29 0a 23 20 20 69  ined(WIN32).#  i
0cf0: 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68  nclude <unistd.h
0d00: 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 64 69  >.#  include <di
0d10: 72 65 6e 74 2e 68 3e 0a 23 20 20 69 6e 63 6c 75  rent.h>.#  inclu
0d20: 64 65 20 3c 75 74 69 6d 65 2e 68 3e 0a 23 20 20  de <utime.h>.#  
0d30: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d  include <sys/tim
0d40: 65 2e 68 3e 0a 23 65 6c 73 65 0a 23 20 20 69 6e  e.h>.#else.#  in
0d50: 63 6c 75 64 65 20 22 77 69 6e 64 6f 77 73 2e 68  clude "windows.h
0d60: 22 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 69 6f  ".#  include <io
0d70: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c  .h>.#  include <
0d80: 64 69 72 65 63 74 2e 68 3e 0a 23 20 20 69 6e 63  direct.h>.#  inc
0d90: 6c 75 64 65 20 22 74 65 73 74 5f 77 69 6e 64 69  lude "test_windi
0da0: 72 65 6e 74 2e 68 22 0a 23 20 20 64 65 66 69 6e  rent.h".#  defin
0db0: 65 20 64 69 72 65 6e 74 20 44 49 52 45 4e 54 0a  e dirent DIRENT.
0dc0: 23 20 20 69 66 6e 64 65 66 20 63 68 6d 6f 64 0a  #  ifndef chmod.
0dd0: 23 20 20 20 20 64 65 66 69 6e 65 20 63 68 6d 6f  #    define chmo
0de0: 64 20 5f 63 68 6d 6f 64 0a 23 20 20 65 6e 64 69  d _chmod.#  endi
0df0: 66 0a 23 20 20 69 66 6e 64 65 66 20 73 74 61 74  f.#  ifndef stat
0e00: 0a 23 20 20 20 20 64 65 66 69 6e 65 20 73 74 61  .#    define sta
0e10: 74 20 5f 73 74 61 74 0a 23 20 20 65 6e 64 69 66  t _stat.#  endif
0e20: 0a 23 20 20 64 65 66 69 6e 65 20 6d 6b 64 69 72  .#  define mkdir
0e30: 28 70 61 74 68 2c 6d 6f 64 65 29 20 5f 6d 6b 64  (path,mode) _mkd
0e40: 69 72 28 70 61 74 68 29 0a 23 20 20 64 65 66 69  ir(path).#  defi
0e50: 6e 65 20 6c 73 74 61 74 28 70 61 74 68 2c 62 75  ne lstat(path,bu
0e60: 66 29 20 73 74 61 74 28 70 61 74 68 2c 62 75 66  f) stat(path,buf
0e70: 29 0a 23 65 6e 64 69 66 0a 23 69 6e 63 6c 75 64  ).#endif.#includ
0e80: 65 20 3c 74 69 6d 65 2e 68 3e 0a 23 69 6e 63 6c  e <time.h>.#incl
0e90: 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 0a 0a  ude <errno.h>...
0ea0: 2f 2a 0a 2a 2a 20 53 74 72 75 63 74 75 72 65 20  /*.** Structure 
0eb0: 6f 66 20 74 68 65 20 66 73 64 69 72 28 29 20 74  of the fsdir() t
0ec0: 61 62 6c 65 2d 76 61 6c 75 65 64 20 66 75 6e 63  able-valued func
0ed0: 74 69 6f 6e 0a 2a 2f 0a 20 20 20 20 20 20 20 20  tion.*/.        
0ee0: 20 20 20 20 20 20 20 20 20 2f 2a 20 20 20 20 30           /*    0
0ef0: 20 20 20 20 31 20 20 20 20 32 20 20 20 20 20 33      1    2     3
0f00: 20 20 20 20 34 20 20 20 20 20 20 20 20 20 20 20      4           
0f10: 35 20 20 20 20 20 20 20 20 20 20 20 20 20 2a 2f  5             */
0f20: 0a 23 64 65 66 69 6e 65 20 46 53 44 49 52 5f 53  .#define FSDIR_S
0f30: 43 48 45 4d 41 20 22 28 6e 61 6d 65 2c 6d 6f 64  CHEMA "(name,mod
0f40: 65 2c 6d 74 69 6d 65 2c 64 61 74 61 2c 70 61 74  e,mtime,data,pat
0f50: 68 20 48 49 44 44 45 4e 2c 64 69 72 20 48 49 44  h HIDDEN,dir HID
0f60: 44 45 4e 29 22 0a 23 64 65 66 69 6e 65 20 46 53  DEN)".#define FS
0f70: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4e 41 4d 45 20  DIR_COLUMN_NAME 
0f80: 20 20 20 20 30 20 20 20 20 20 2f 2a 20 4e 61 6d      0     /* Nam
0f90: 65 20 6f 66 20 74 68 65 20 66 69 6c 65 20 2a 2f  e of the file */
0fa0: 0a 23 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43  .#define FSDIR_C
0fb0: 4f 4c 55 4d 4e 5f 4d 4f 44 45 20 20 20 20 20 31  OLUMN_MODE     1
0fc0: 20 20 20 20 20 2f 2a 20 41 63 63 65 73 73 20 6d       /* Access m
0fd0: 6f 64 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46  ode */.#define F
0fe0: 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 54 49 4d  SDIR_COLUMN_MTIM
0ff0: 45 20 20 20 20 32 20 20 20 20 20 2f 2a 20 4c 61  E    2     /* La
1000: 73 74 20 6d 6f 64 69 66 69 63 61 74 69 6f 6e 20  st modification 
1010: 74 69 6d 65 20 2a 2f 0a 23 64 65 66 69 6e 65 20  time */.#define 
1020: 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 41 54  FSDIR_COLUMN_DAT
1030: 41 20 20 20 20 20 33 20 20 20 20 20 2f 2a 20 46  A     3     /* F
1040: 69 6c 65 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 23  ile content */.#
1050: 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43 4f 4c  define FSDIR_COL
1060: 55 4d 4e 5f 50 41 54 48 20 20 20 20 20 34 20 20  UMN_PATH     4  
1070: 20 20 20 2f 2a 20 50 61 74 68 20 74 6f 20 74 6f     /* Path to to
1080: 70 20 6f 66 20 73 65 61 72 63 68 20 2a 2f 0a 23  p of search */.#
1090: 64 65 66 69 6e 65 20 46 53 44 49 52 5f 43 4f 4c  define FSDIR_COL
10a0: 55 4d 4e 5f 44 49 52 20 20 20 20 20 20 35 20 20  UMN_DIR      5  
10b0: 20 20 20 2f 2a 20 50 61 74 68 20 69 73 20 72 65     /* Path is re
10c0: 6c 61 74 69 76 65 20 74 6f 20 74 68 69 73 20 64  lative to this d
10d0: 69 72 65 63 74 6f 72 79 20 2a 2f 0a 0a 0a 2f 2a  irectory */.../*
10e0: 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 73 75  .** Set the resu
10f0: 6c 74 20 73 74 6f 72 65 64 20 62 79 20 63 6f 6e  lt stored by con
1100: 74 65 78 74 20 63 74 78 20 74 6f 20 61 20 62 6c  text ctx to a bl
1110: 6f 62 20 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68  ob containing th
1120: 65 20 0a 2a 2a 20 63 6f 6e 74 65 6e 74 73 20 6f  e .** contents o
1130: 66 20 66 69 6c 65 20 7a 4e 61 6d 65 2e 20 20 4f  f file zName.  O
1140: 72 2c 20 6c 65 61 76 65 20 74 68 65 20 72 65 73  r, leave the res
1150: 75 6c 74 20 75 6e 63 68 61 6e 67 65 64 20 28 4e  ult unchanged (N
1160: 55 4c 4c 29 0a 2a 2a 20 69 66 20 74 68 65 20 66  ULL).** if the f
1170: 69 6c 65 20 64 6f 65 73 20 6e 6f 74 20 65 78 69  ile does not exi
1180: 73 74 20 6f 72 20 69 73 20 75 6e 72 65 61 64 61  st or is unreada
1190: 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68  ble..**.** If th
11a0: 65 20 66 69 6c 65 20 65 78 63 65 65 64 73 20 74  e file exceeds t
11b0: 68 65 20 53 51 4c 69 74 65 20 62 6c 6f 62 20 73  he SQLite blob s
11c0: 69 7a 65 20 6c 69 6d 69 74 2c 20 74 68 72 6f 75  ize limit, throu
11d0: 67 68 20 61 6e 0a 2a 2a 20 53 51 4c 49 54 45 5f  gh an.** SQLITE_
11e0: 54 4f 4f 42 49 47 20 65 72 72 6f 72 2e 0a 2a 2a  TOOBIG error..**
11f0: 0a 2a 2a 20 54 68 72 6f 77 20 61 6e 20 53 51 4c  .** Throw an SQL
1200: 49 54 45 5f 49 4f 45 52 52 20 69 66 20 74 68 65  ITE_IOERR if the
1210: 72 65 20 61 72 65 20 64 69 66 66 69 63 75 6c 74  re are difficult
1220: 69 65 73 20 70 75 6c 6c 69 6e 67 20 74 68 65 20  ies pulling the 
1230: 66 69 6c 65 0a 2a 2a 20 6f 66 66 20 6f 66 20 64  file.** off of d
1240: 69 73 6b 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  isk..*/.static v
1250: 6f 69 64 20 72 65 61 64 46 69 6c 65 43 6f 6e 74  oid readFileCont
1260: 65 6e 74 73 28 73 71 6c 69 74 65 33 5f 63 6f 6e  ents(sqlite3_con
1270: 74 65 78 74 20 2a 63 74 78 2c 20 63 6f 6e 73 74  text *ctx, const
1280: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a 20   char *zName){. 
1290: 20 46 49 4c 45 20 2a 69 6e 3b 0a 20 20 73 71 6c   FILE *in;.  sql
12a0: 69 74 65 33 5f 69 6e 74 36 34 20 6e 49 6e 3b 0a  ite3_int64 nIn;.
12b0: 20 20 76 6f 69 64 20 2a 70 42 75 66 3b 0a 20 20    void *pBuf;.  
12c0: 73 71 6c 69 74 65 33 20 2a 64 62 3b 0a 20 20 69  sqlite3 *db;.  i
12d0: 6e 74 20 6d 78 42 6c 6f 62 3b 0a 0a 20 20 69 6e  nt mxBlob;..  in
12e0: 20 3d 20 66 6f 70 65 6e 28 7a 4e 61 6d 65 2c 20   = fopen(zName, 
12f0: 22 72 62 22 29 3b 0a 20 20 69 66 28 20 69 6e 3d  "rb");.  if( in=
1300: 3d 30 20 29 7b 0a 20 20 20 20 2f 2a 20 46 69 6c  =0 ){.    /* Fil
1310: 65 20 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74  e does not exist
1320: 20 6f 72 20 69 73 20 75 6e 72 65 61 64 61 62 6c   or is unreadabl
1330: 65 2e 20 4c 65 61 76 65 20 74 68 65 20 72 65 73  e. Leave the res
1340: 75 6c 74 20 73 65 74 20 74 6f 20 4e 55 4c 4c 2e  ult set to NULL.
1350: 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a   */.    return;.
1360: 20 20 7d 0a 20 20 66 73 65 65 6b 28 69 6e 2c 20    }.  fseek(in, 
1370: 30 2c 20 53 45 45 4b 5f 45 4e 44 29 3b 0a 20 20  0, SEEK_END);.  
1380: 6e 49 6e 20 3d 20 66 74 65 6c 6c 28 69 6e 29 3b  nIn = ftell(in);
1390: 0a 20 20 72 65 77 69 6e 64 28 69 6e 29 3b 0a 20  .  rewind(in);. 
13a0: 20 64 62 20 3d 20 73 71 6c 69 74 65 33 5f 63 6f   db = sqlite3_co
13b0: 6e 74 65 78 74 5f 64 62 5f 68 61 6e 64 6c 65 28  ntext_db_handle(
13c0: 63 74 78 29 3b 0a 20 20 6d 78 42 6c 6f 62 20 3d  ctx);.  mxBlob =
13d0: 20 73 71 6c 69 74 65 33 5f 6c 69 6d 69 74 28 64   sqlite3_limit(d
13e0: 62 2c 20 53 51 4c 49 54 45 5f 4c 49 4d 49 54 5f  b, SQLITE_LIMIT_
13f0: 4c 45 4e 47 54 48 2c 20 2d 31 29 3b 0a 20 20 69  LENGTH, -1);.  i
1400: 66 28 20 6e 49 6e 3e 6d 78 42 6c 6f 62 20 29 7b  f( nIn>mxBlob ){
1410: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
1420: 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65 28 63  ult_error_code(c
1430: 74 78 2c 20 53 51 4c 49 54 45 5f 54 4f 4f 42 49  tx, SQLITE_TOOBI
1440: 47 29 3b 0a 20 20 20 20 66 63 6c 6f 73 65 28 69  G);.    fclose(i
1450: 6e 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b 0a  n);.    return;.
1460: 20 20 7d 0a 20 20 70 42 75 66 20 3d 20 73 71 6c    }.  pBuf = sql
1470: 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28 20 6e  ite3_malloc64( n
1480: 49 6e 20 29 3b 0a 20 20 69 66 28 20 70 42 75 66  In );.  if( pBuf
1490: 3d 3d 30 20 29 7b 0a 20 20 20 20 73 71 6c 69 74  ==0 ){.    sqlit
14a0: 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f  e3_result_error_
14b0: 6e 6f 6d 65 6d 28 63 74 78 29 3b 0a 20 20 20 20  nomem(ctx);.    
14c0: 66 63 6c 6f 73 65 28 69 6e 29 3b 0a 20 20 20 20  fclose(in);.    
14d0: 72 65 74 75 72 6e 3b 0a 20 20 7d 0a 20 20 69 66  return;.  }.  if
14e0: 28 20 31 3d 3d 66 72 65 61 64 28 70 42 75 66 2c  ( 1==fread(pBuf,
14f0: 20 6e 49 6e 2c 20 31 2c 20 69 6e 29 20 29 7b 0a   nIn, 1, in) ){.
1500: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
1510: 6c 74 5f 62 6c 6f 62 36 34 28 63 74 78 2c 20 70  lt_blob64(ctx, p
1520: 42 75 66 2c 20 6e 49 6e 2c 20 73 71 6c 69 74 65  Buf, nIn, sqlite
1530: 33 5f 66 72 65 65 29 3b 0a 20 20 7d 65 6c 73 65  3_free);.  }else
1540: 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65  {.    sqlite3_re
1550: 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f 64 65 28  sult_error_code(
1560: 63 74 78 2c 20 53 51 4c 49 54 45 5f 49 4f 45 52  ctx, SQLITE_IOER
1570: 52 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f  R);.    sqlite3_
1580: 66 72 65 65 28 70 42 75 66 29 3b 0a 20 20 7d 0a  free(pBuf);.  }.
1590: 20 20 66 63 6c 6f 73 65 28 69 6e 29 3b 0a 7d 0a    fclose(in);.}.
15a0: 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74  ./*.** Implement
15b0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 22 72 65  ation of the "re
15c0: 61 64 66 69 6c 65 28 58 29 22 20 53 51 4c 20 66  adfile(X)" SQL f
15d0: 75 6e 63 74 69 6f 6e 2e 20 20 54 68 65 20 65 6e  unction.  The en
15e0: 74 69 72 65 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20  tire content.** 
15f0: 6f 66 20 74 68 65 20 66 69 6c 65 20 6e 61 6d 65  of the file name
1600: 64 20 58 20 69 73 20 72 65 61 64 20 61 6e 64 20  d X is read and 
1610: 72 65 74 75 72 6e 65 64 20 61 73 20 61 20 42 4c  returned as a BL
1620: 4f 42 2e 20 20 4e 55 4c 4c 20 69 73 20 72 65 74  OB.  NULL is ret
1630: 75 72 6e 65 64 0a 2a 2a 20 69 66 20 74 68 65 20  urned.** if the 
1640: 66 69 6c 65 20 64 6f 65 73 20 6e 6f 74 20 65 78  file does not ex
1650: 69 73 74 20 6f 72 20 69 73 20 75 6e 72 65 61 64  ist or is unread
1660: 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  able..*/.static 
1670: 76 6f 69 64 20 72 65 61 64 66 69 6c 65 46 75 6e  void readfileFun
1680: 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  c(.  sqlite3_con
1690: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20  text *context,. 
16a0: 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c   int argc,.  sql
16b0: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67  ite3_value **arg
16c0: 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  v.){.  const cha
16d0: 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 28 76 6f 69  r *zName;.  (voi
16e0: 64 29 28 61 72 67 63 29 3b 20 20 2f 2a 20 55 6e  d)(argc);  /* Un
16f0: 75 73 65 64 20 70 61 72 61 6d 65 74 65 72 20 2a  used parameter *
1700: 2f 0a 20 20 7a 4e 61 6d 65 20 3d 20 28 63 6f 6e  /.  zName = (con
1710: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
1720: 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76  _value_text(argv
1730: 5b 30 5d 29 3b 0a 20 20 69 66 28 20 7a 4e 61 6d  [0]);.  if( zNam
1740: 65 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  e==0 ) return;. 
1750: 20 72 65 61 64 46 69 6c 65 43 6f 6e 74 65 6e 74   readFileContent
1760: 73 28 63 6f 6e 74 65 78 74 2c 20 7a 4e 61 6d 65  s(context, zName
1770: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  );.}../*.** Set 
1780: 74 68 65 20 65 72 72 6f 72 20 6d 65 73 73 61 67  the error messag
1790: 65 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 63  e contained in c
17a0: 6f 6e 74 65 78 74 20 63 74 78 20 74 6f 20 74 68  ontext ctx to th
17b0: 65 20 72 65 73 75 6c 74 73 20 6f 66 0a 2a 2a 20  e results of.** 
17c0: 76 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20 2e 2e  vprintf(zFmt, ..
17d0: 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  .)..*/.static vo
17e0: 69 64 20 63 74 78 45 72 72 6f 72 4d 73 67 28 73  id ctxErrorMsg(s
17f0: 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a  qlite3_context *
1800: 63 74 78 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ctx, const char 
1810: 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 20 63  *zFmt, ...){.  c
1820: 68 61 72 20 2a 7a 4d 73 67 20 3d 20 30 3b 0a 20  har *zMsg = 0;. 
1830: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76   va_list ap;.  v
1840: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6d 74  a_start(ap, zFmt
1850: 29 3b 0a 20 20 7a 4d 73 67 20 3d 20 73 71 6c 69  );.  zMsg = sqli
1860: 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6d  te3_vmprintf(zFm
1870: 74 2c 20 61 70 29 3b 0a 20 20 73 71 6c 69 74 65  t, ap);.  sqlite
1880: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63  3_result_error(c
1890: 74 78 2c 20 7a 4d 73 67 2c 20 2d 31 29 3b 0a 20  tx, zMsg, -1);. 
18a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 4d   sqlite3_free(zM
18b0: 73 67 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  sg);.  va_end(ap
18c0: 29 3b 0a 7d 0a 0a 23 69 66 20 64 65 66 69 6e 65  );.}..#if define
18d0: 64 28 5f 57 49 4e 33 32 29 0a 2f 2a 0a 2a 2a 20  d(_WIN32)./*.** 
18e0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 69 73  This function is
18f0: 20 64 65 73 69 67 6e 65 64 20 74 6f 20 63 6f 6e   designed to con
1900: 76 65 72 74 20 61 20 57 69 6e 33 32 20 46 49 4c  vert a Win32 FIL
1910: 45 54 49 4d 45 20 73 74 72 75 63 74 75 72 65 20  ETIME structure 
1920: 69 6e 74 6f 20 74 68 65 0a 2a 2a 20 6e 75 6d 62  into the.** numb
1930: 65 72 20 6f 66 20 73 65 63 6f 6e 64 73 20 73 69  er of seconds si
1940: 6e 63 65 20 74 68 65 20 55 6e 69 78 20 45 70 6f  nce the Unix Epo
1950: 63 68 20 28 31 39 37 30 2d 30 31 2d 30 31 20 30  ch (1970-01-01 0
1960: 30 3a 30 30 3a 30 30 20 55 54 43 29 2e 0a 2a 2f  0:00:00 UTC)..*/
1970: 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f  .static sqlite3_
1980: 75 69 6e 74 36 34 20 66 69 6c 65 54 69 6d 65 54  uint64 fileTimeT
1990: 6f 55 6e 69 78 54 69 6d 65 28 0a 20 20 4c 50 46  oUnixTime(.  LPF
19a0: 49 4c 45 54 49 4d 45 20 70 46 69 6c 65 54 69 6d  ILETIME pFileTim
19b0: 65 0a 29 7b 0a 20 20 53 59 53 54 45 4d 54 49 4d  e.){.  SYSTEMTIM
19c0: 45 20 65 70 6f 63 68 53 79 73 74 65 6d 54 69 6d  E epochSystemTim
19d0: 65 3b 0a 20 20 55 4c 41 52 47 45 5f 49 4e 54 45  e;.  ULARGE_INTE
19e0: 47 45 52 20 65 70 6f 63 68 49 6e 74 65 72 76 61  GER epochInterva
19f0: 6c 73 3b 0a 20 20 46 49 4c 45 54 49 4d 45 20 65  ls;.  FILETIME e
1a00: 70 6f 63 68 46 69 6c 65 54 69 6d 65 3b 0a 20 20  pochFileTime;.  
1a10: 55 4c 41 52 47 45 5f 49 4e 54 45 47 45 52 20 66  ULARGE_INTEGER f
1a20: 69 6c 65 49 6e 74 65 72 76 61 6c 73 3b 0a 0a 20  ileIntervals;.. 
1a30: 20 6d 65 6d 73 65 74 28 26 65 70 6f 63 68 53 79   memset(&epochSy
1a40: 73 74 65 6d 54 69 6d 65 2c 20 30 2c 20 73 69 7a  stemTime, 0, siz
1a50: 65 6f 66 28 53 59 53 54 45 4d 54 49 4d 45 29 29  eof(SYSTEMTIME))
1a60: 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 65 6d 54  ;.  epochSystemT
1a70: 69 6d 65 2e 77 59 65 61 72 20 3d 20 31 39 37 30  ime.wYear = 1970
1a80: 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 65 6d 54  ;.  epochSystemT
1a90: 69 6d 65 2e 77 4d 6f 6e 74 68 20 3d 20 31 3b 0a  ime.wMonth = 1;.
1aa0: 20 20 65 70 6f 63 68 53 79 73 74 65 6d 54 69 6d    epochSystemTim
1ab0: 65 2e 77 44 61 79 20 3d 20 31 3b 0a 20 20 53 79  e.wDay = 1;.  Sy
1ac0: 73 74 65 6d 54 69 6d 65 54 6f 46 69 6c 65 54 69  stemTimeToFileTi
1ad0: 6d 65 28 26 65 70 6f 63 68 53 79 73 74 65 6d 54  me(&epochSystemT
1ae0: 69 6d 65 2c 20 26 65 70 6f 63 68 46 69 6c 65 54  ime, &epochFileT
1af0: 69 6d 65 29 3b 0a 20 20 65 70 6f 63 68 49 6e 74  ime);.  epochInt
1b00: 65 72 76 61 6c 73 2e 4c 6f 77 50 61 72 74 20 3d  ervals.LowPart =
1b10: 20 65 70 6f 63 68 46 69 6c 65 54 69 6d 65 2e 64   epochFileTime.d
1b20: 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b 0a 20 20  wLowDateTime;.  
1b30: 65 70 6f 63 68 49 6e 74 65 72 76 61 6c 73 2e 48  epochIntervals.H
1b40: 69 67 68 50 61 72 74 20 3d 20 65 70 6f 63 68 46  ighPart = epochF
1b50: 69 6c 65 54 69 6d 65 2e 64 77 48 69 67 68 44 61  ileTime.dwHighDa
1b60: 74 65 54 69 6d 65 3b 0a 0a 20 20 66 69 6c 65 49  teTime;..  fileI
1b70: 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50 61 72 74  ntervals.LowPart
1b80: 20 3d 20 70 46 69 6c 65 54 69 6d 65 2d 3e 64 77   = pFileTime->dw
1b90: 4c 6f 77 44 61 74 65 54 69 6d 65 3b 0a 20 20 66  LowDateTime;.  f
1ba0: 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e 48 69 67  ileIntervals.Hig
1bb0: 68 50 61 72 74 20 3d 20 70 46 69 6c 65 54 69 6d  hPart = pFileTim
1bc0: 65 2d 3e 64 77 48 69 67 68 44 61 74 65 54 69 6d  e->dwHighDateTim
1bd0: 65 3b 0a 0a 20 20 72 65 74 75 72 6e 20 28 66 69  e;..  return (fi
1be0: 6c 65 49 6e 74 65 72 76 61 6c 73 2e 51 75 61 64  leIntervals.Quad
1bf0: 50 61 72 74 20 2d 20 65 70 6f 63 68 49 6e 74 65  Part - epochInte
1c00: 72 76 61 6c 73 2e 51 75 61 64 50 61 72 74 29 20  rvals.QuadPart) 
1c10: 2f 20 31 30 30 30 30 30 30 30 3b 0a 7d 0a 0a 2f  / 10000000;.}../
1c20: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
1c30: 6f 6e 20 61 74 74 65 6d 70 74 73 20 74 6f 20 6e  on attempts to n
1c40: 6f 72 6d 61 6c 69 7a 65 20 74 68 65 20 74 69 6d  ormalize the tim
1c50: 65 20 76 61 6c 75 65 73 20 66 6f 75 6e 64 20 69  e values found i
1c60: 6e 20 74 68 65 20 73 74 61 74 28 29 0a 2a 2a 20  n the stat().** 
1c70: 62 75 66 66 65 72 20 74 6f 20 55 54 43 2e 20 20  buffer to UTC.  
1c80: 54 68 69 73 20 69 73 20 6e 65 63 65 73 73 61 72  This is necessar
1c90: 79 20 6f 6e 20 57 69 6e 33 32 2c 20 77 68 65 72  y on Win32, wher
1ca0: 65 20 74 68 65 20 72 75 6e 74 69 6d 65 20 6c 69  e the runtime li
1cb0: 62 72 61 72 79 0a 2a 2a 20 61 70 70 65 61 72 73  brary.** appears
1cc0: 20 74 6f 20 72 65 74 75 72 6e 20 74 68 65 73 65   to return these
1cd0: 20 76 61 6c 75 65 73 20 61 73 20 6c 6f 63 61 6c   values as local
1ce0: 20 74 69 6d 65 73 2e 0a 2a 2f 0a 73 74 61 74 69   times..*/.stati
1cf0: 63 20 76 6f 69 64 20 73 74 61 74 54 69 6d 65 73  c void statTimes
1d00: 54 6f 55 74 63 28 0a 20 20 63 6f 6e 73 74 20 63  ToUtc(.  const c
1d10: 68 61 72 20 2a 7a 50 61 74 68 2c 0a 20 20 73 74  har *zPath,.  st
1d20: 72 75 63 74 20 73 74 61 74 20 2a 70 53 74 61 74  ruct stat *pStat
1d30: 42 75 66 0a 29 7b 0a 20 20 48 41 4e 44 4c 45 20  Buf.){.  HANDLE 
1d40: 68 46 69 6e 64 46 69 6c 65 3b 0a 20 20 57 49 4e  hFindFile;.  WIN
1d50: 33 32 5f 46 49 4e 44 5f 44 41 54 41 57 20 66 64  32_FIND_DATAW fd
1d60: 3b 0a 20 20 4c 50 57 53 54 52 20 7a 55 6e 69 63  ;.  LPWSTR zUnic
1d70: 6f 64 65 4e 61 6d 65 3b 0a 20 20 65 78 74 65 72  odeName;.  exter
1d80: 6e 20 4c 50 57 53 54 52 20 73 71 6c 69 74 65 33  n LPWSTR sqlite3
1d90: 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75  _win32_utf8_to_u
1da0: 6e 69 63 6f 64 65 28 63 6f 6e 73 74 20 63 68 61  nicode(const cha
1db0: 72 2a 29 3b 0a 20 20 7a 55 6e 69 63 6f 64 65 4e  r*);.  zUnicodeN
1dc0: 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f 77 69  ame = sqlite3_wi
1dd0: 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 63  n32_utf8_to_unic
1de0: 6f 64 65 28 7a 50 61 74 68 29 3b 0a 20 20 69 66  ode(zPath);.  if
1df0: 28 20 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 20 29  ( zUnicodeName )
1e00: 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 66 64  {.    memset(&fd
1e10: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57 49 4e 33  , 0, sizeof(WIN3
1e20: 32 5f 46 49 4e 44 5f 44 41 54 41 57 29 29 3b 0a  2_FIND_DATAW));.
1e30: 20 20 20 20 68 46 69 6e 64 46 69 6c 65 20 3d 20      hFindFile = 
1e40: 46 69 6e 64 46 69 72 73 74 46 69 6c 65 57 28 7a  FindFirstFileW(z
1e50: 55 6e 69 63 6f 64 65 4e 61 6d 65 2c 20 26 66 64  UnicodeName, &fd
1e60: 29 3b 0a 20 20 20 20 69 66 28 20 68 46 69 6e 64  );.    if( hFind
1e70: 46 69 6c 65 21 3d 4e 55 4c 4c 20 29 7b 0a 20 20  File!=NULL ){.  
1e80: 20 20 20 20 70 53 74 61 74 42 75 66 2d 3e 73 74      pStatBuf->st
1e90: 5f 63 74 69 6d 65 20 3d 20 28 74 69 6d 65 5f 74  _ctime = (time_t
1ea0: 29 66 69 6c 65 54 69 6d 65 54 6f 55 6e 69 78 54  )fileTimeToUnixT
1eb0: 69 6d 65 28 26 66 64 2e 66 74 43 72 65 61 74 69  ime(&fd.ftCreati
1ec0: 6f 6e 54 69 6d 65 29 3b 0a 20 20 20 20 20 20 70  onTime);.      p
1ed0: 53 74 61 74 42 75 66 2d 3e 73 74 5f 61 74 69 6d  StatBuf->st_atim
1ee0: 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 69 6c 65  e = (time_t)file
1ef0: 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 26  TimeToUnixTime(&
1f00: 66 64 2e 66 74 4c 61 73 74 41 63 63 65 73 73 54  fd.ftLastAccessT
1f10: 69 6d 65 29 3b 0a 20 20 20 20 20 20 70 53 74 61  ime);.      pSta
1f20: 74 42 75 66 2d 3e 73 74 5f 6d 74 69 6d 65 20 3d  tBuf->st_mtime =
1f30: 20 28 74 69 6d 65 5f 74 29 66 69 6c 65 54 69 6d   (time_t)fileTim
1f40: 65 54 6f 55 6e 69 78 54 69 6d 65 28 26 66 64 2e  eToUnixTime(&fd.
1f50: 66 74 4c 61 73 74 57 72 69 74 65 54 69 6d 65 29  ftLastWriteTime)
1f60: 3b 0a 20 20 20 20 20 20 46 69 6e 64 43 6c 6f 73  ;.      FindClos
1f70: 65 28 68 46 69 6e 64 46 69 6c 65 29 3b 0a 20 20  e(hFindFile);.  
1f80: 20 20 7d 0a 20 20 20 20 73 71 6c 69 74 65 33 5f    }.    sqlite3_
1f90: 66 72 65 65 28 7a 55 6e 69 63 6f 64 65 4e 61 6d  free(zUnicodeNam
1fa0: 65 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66  e);.  }.}.#endif
1fb0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
1fc0: 63 74 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e  ction is used in
1fd0: 20 70 6c 61 63 65 20 6f 66 20 73 74 61 74 28 29   place of stat()
1fe0: 2e 20 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 73  .  On Windows, s
1ff0: 70 65 63 69 61 6c 20 68 61 6e 64 6c 69 6e 67 0a  pecial handling.
2000: 2a 2a 20 69 73 20 72 65 71 75 69 72 65 64 20 69  ** is required i
2010: 6e 20 6f 72 64 65 72 20 66 6f 72 20 74 68 65 20  n order for the 
2020: 69 6e 63 6c 75 64 65 64 20 74 69 6d 65 20 74 6f  included time to
2030: 20 62 65 20 72 65 74 75 72 6e 65 64 20 61 73 20   be returned as 
2040: 55 54 43 2e 20 20 4f 6e 20 61 6c 6c 0a 2a 2a 20  UTC.  On all.** 
2050: 6f 74 68 65 72 20 73 79 73 74 65 6d 73 2c 20 74  other systems, t
2060: 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 73 69 6d  his function sim
2070: 70 6c 79 20 63 61 6c 6c 73 20 73 74 61 74 28 29  ply calls stat()
2080: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2090: 66 69 6c 65 53 74 61 74 28 0a 20 20 63 6f 6e 73  fileStat(.  cons
20a0: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 0a 20  t char *zPath,. 
20b0: 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 70 53   struct stat *pS
20c0: 74 61 74 42 75 66 0a 29 7b 0a 23 69 66 20 64 65  tatBuf.){.#if de
20d0: 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20  fined(_WIN32).  
20e0: 69 6e 74 20 72 63 20 3d 20 73 74 61 74 28 7a 50  int rc = stat(zP
20f0: 61 74 68 2c 20 70 53 74 61 74 42 75 66 29 3b 0a  ath, pStatBuf);.
2100: 20 20 69 66 28 20 72 63 3d 3d 30 20 29 20 73 74    if( rc==0 ) st
2110: 61 74 54 69 6d 65 73 54 6f 55 74 63 28 7a 50 61  atTimesToUtc(zPa
2120: 74 68 2c 20 70 53 74 61 74 42 75 66 29 3b 0a 20  th, pStatBuf);. 
2130: 20 72 65 74 75 72 6e 20 72 63 3b 0a 23 65 6c 73   return rc;.#els
2140: 65 0a 20 20 72 65 74 75 72 6e 20 73 74 61 74 28  e.  return stat(
2150: 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 29  zPath, pStatBuf)
2160: 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a  ;.#endif.}../*.*
2170: 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  * This function 
2180: 69 73 20 75 73 65 64 20 69 6e 20 70 6c 61 63 65  is used in place
2190: 20 6f 66 20 6c 73 74 61 74 28 29 2e 20 20 4f 6e   of lstat().  On
21a0: 20 57 69 6e 64 6f 77 73 2c 20 73 70 65 63 69 61   Windows, specia
21b0: 6c 20 68 61 6e 64 6c 69 6e 67 0a 2a 2a 20 69 73  l handling.** is
21c0: 20 72 65 71 75 69 72 65 64 20 69 6e 20 6f 72 64   required in ord
21d0: 65 72 20 66 6f 72 20 74 68 65 20 69 6e 63 6c 75  er for the inclu
21e0: 64 65 64 20 74 69 6d 65 20 74 6f 20 62 65 20 72  ded time to be r
21f0: 65 74 75 72 6e 65 64 20 61 73 20 55 54 43 2e 20  eturned as UTC. 
2200: 20 4f 6e 20 61 6c 6c 0a 2a 2a 20 6f 74 68 65 72   On all.** other
2210: 20 73 79 73 74 65 6d 73 2c 20 74 68 69 73 20 66   systems, this f
2220: 75 6e 63 74 69 6f 6e 20 73 69 6d 70 6c 79 20 63  unction simply c
2230: 61 6c 6c 73 20 6c 73 74 61 74 28 29 2e 0a 2a 2f  alls lstat()..*/
2240: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65  .static int file
2250: 4c 69 6e 6b 53 74 61 74 28 0a 20 20 63 6f 6e 73  LinkStat(.  cons
2260: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 0a 20  t char *zPath,. 
2270: 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 70 53   struct stat *pS
2280: 74 61 74 42 75 66 0a 29 7b 0a 23 69 66 20 64 65  tatBuf.){.#if de
2290: 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20  fined(_WIN32).  
22a0: 69 6e 74 20 72 63 20 3d 20 6c 73 74 61 74 28 7a  int rc = lstat(z
22b0: 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 29 3b  Path, pStatBuf);
22c0: 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 29 20 73  .  if( rc==0 ) s
22d0: 74 61 74 54 69 6d 65 73 54 6f 55 74 63 28 7a 50  tatTimesToUtc(zP
22e0: 61 74 68 2c 20 70 53 74 61 74 42 75 66 29 3b 0a  ath, pStatBuf);.
22f0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 23 65 6c    return rc;.#el
2300: 73 65 0a 20 20 72 65 74 75 72 6e 20 6c 73 74 61  se.  return lsta
2310: 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75  t(zPath, pStatBu
2320: 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a  f);.#endif.}../*
2330: 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20 7a 46 69  .** Argument zFi
2340: 6c 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f  le is the name o
2350: 66 20 61 20 66 69 6c 65 20 74 68 61 74 20 77 69  f a file that wi
2360: 6c 6c 20 62 65 20 63 72 65 61 74 65 64 20 61 6e  ll be created an
2370: 64 2f 6f 72 20 77 72 69 74 74 65 6e 0a 2a 2a 20  d/or written.** 
2380: 62 79 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 20  by SQL function 
2390: 77 72 69 74 65 66 69 6c 65 28 29 2e 20 54 68 69  writefile(). Thi
23a0: 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e 73 75 72  s function ensur
23b0: 65 73 20 74 68 61 74 20 74 68 65 20 64 69 72 65  es that the dire
23c0: 63 74 6f 72 79 0a 2a 2a 20 7a 46 69 6c 65 20 77  ctory.** zFile w
23d0: 69 6c 6c 20 62 65 20 77 72 69 74 74 65 6e 20 74  ill be written t
23e0: 6f 20 65 78 69 73 74 73 2c 20 63 72 65 61 74 69  o exists, creati
23f0: 6e 67 20 69 74 20 69 66 20 72 65 71 75 69 72 65  ng it if require
2400: 64 2e 20 54 68 65 20 70 65 72 6d 69 73 73 69 6f  d. The permissio
2410: 6e 73 0a 2a 2a 20 66 6f 72 20 61 6e 79 20 70 61  ns.** for any pa
2420: 74 68 20 63 6f 6d 70 6f 6e 65 6e 74 73 20 63 72  th components cr
2430: 65 61 74 65 64 20 62 79 20 74 68 69 73 20 66 75  eated by this fu
2440: 6e 63 74 69 6f 6e 20 61 72 65 20 73 65 74 20 74  nction are set t
2450: 6f 20 28 6d 6f 64 65 26 30 37 37 37 29 2e 0a 2a  o (mode&0777)..*
2460: 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f 4f 4d 20 63  *.** If an OOM c
2470: 6f 6e 64 69 74 69 6f 6e 20 69 73 20 65 6e 63 6f  ondition is enco
2480: 75 6e 74 65 72 65 64 2c 20 53 51 4c 49 54 45 5f  untered, SQLITE_
2490: 4e 4f 4d 45 4d 20 69 73 20 72 65 74 75 72 6e 65  NOMEM is returne
24a0: 64 2e 20 4f 74 68 65 72 77 69 73 65 2c 0a 2a 2a  d. Otherwise,.**
24b0: 20 53 51 4c 49 54 45 5f 4f 4b 20 69 73 20 72 65   SQLITE_OK is re
24c0: 74 75 72 6e 65 64 20 69 66 20 74 68 65 20 64 69  turned if the di
24d0: 72 65 63 74 6f 72 79 20 69 73 20 73 75 63 63 65  rectory is succe
24e0: 73 73 66 75 6c 6c 79 20 63 72 65 61 74 65 64 2c  ssfully created,
24f0: 20 6f 72 0a 2a 2a 20 53 51 4c 49 54 45 5f 45 52   or.** SQLITE_ER
2500: 52 4f 52 20 6f 74 68 65 72 77 69 73 65 2e 0a 2a  ROR otherwise..*
2510: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6d 61 6b  /.static int mak
2520: 65 44 69 72 65 63 74 6f 72 79 28 0a 20 20 63 6f  eDirectory(.  co
2530: 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 2c  nst char *zFile,
2540: 0a 20 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 0a 29  .  mode_t mode.)
2550: 7b 0a 20 20 63 68 61 72 20 2a 7a 43 6f 70 79 20  {.  char *zCopy 
2560: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
2570: 66 28 22 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a  f("%s", zFile);.
2580: 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c 49 54    int rc = SQLIT
2590: 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28 20 7a 43 6f  E_OK;..  if( zCo
25a0: 70 79 3d 3d 30 20 29 7b 0a 20 20 20 20 72 63 20  py==0 ){.    rc 
25b0: 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  = SQLITE_NOMEM;.
25c0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74    }else{.    int
25d0: 20 6e 43 6f 70 79 20 3d 20 28 69 6e 74 29 73 74   nCopy = (int)st
25e0: 72 6c 65 6e 28 7a 43 6f 70 79 29 3b 0a 20 20 20  rlen(zCopy);.   
25f0: 20 69 6e 74 20 69 20 3d 20 31 3b 0a 0a 20 20 20   int i = 1;..   
2600: 20 77 68 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49   while( rc==SQLI
2610: 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73  TE_OK ){.      s
2620: 74 72 75 63 74 20 73 74 61 74 20 73 53 74 61 74  truct stat sStat
2630: 3b 0a 20 20 20 20 20 20 69 6e 74 20 72 63 32 3b  ;.      int rc2;
2640: 0a 0a 20 20 20 20 20 20 66 6f 72 28 3b 20 7a 43  ..      for(; zC
2650: 6f 70 79 5b 69 5d 21 3d 27 2f 27 20 26 26 20 69  opy[i]!='/' && i
2660: 3c 6e 43 6f 70 79 3b 20 69 2b 2b 29 3b 0a 20 20  <nCopy; i++);.  
2670: 20 20 20 20 69 66 28 20 69 3d 3d 6e 43 6f 70 79      if( i==nCopy
2680: 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20   ) break;.      
2690: 7a 43 6f 70 79 5b 69 5d 20 3d 20 27 5c 30 27 3b  zCopy[i] = '\0';
26a0: 0a 0a 20 20 20 20 20 20 72 63 32 20 3d 20 66 69  ..      rc2 = fi
26b0: 6c 65 53 74 61 74 28 7a 43 6f 70 79 2c 20 26 73  leStat(zCopy, &s
26c0: 53 74 61 74 29 3b 0a 20 20 20 20 20 20 69 66 28  Stat);.      if(
26d0: 20 72 63 32 21 3d 30 20 29 7b 0a 20 20 20 20 20   rc2!=0 ){.     
26e0: 20 20 20 69 66 28 20 6d 6b 64 69 72 28 7a 43 6f     if( mkdir(zCo
26f0: 70 79 2c 20 6d 6f 64 65 20 26 20 30 37 37 37 29  py, mode & 0777)
2700: 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 45   ) rc = SQLITE_E
2710: 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 65 6c 73  RROR;.      }els
2720: 65 7b 0a 20 20 20 20 20 20 20 20 69 66 28 20 21  e{.        if( !
2730: 53 5f 49 53 44 49 52 28 73 53 74 61 74 2e 73 74  S_ISDIR(sStat.st
2740: 5f 6d 6f 64 65 29 20 29 20 72 63 20 3d 20 53 51  _mode) ) rc = SQ
2750: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
2760: 20 20 7d 0a 20 20 20 20 20 20 7a 43 6f 70 79 5b    }.      zCopy[
2770: 69 5d 20 3d 20 27 2f 27 3b 0a 20 20 20 20 20 20  i] = '/';.      
2780: 69 2b 2b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20  i++;.    }..    
2790: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 43 6f  sqlite3_free(zCo
27a0: 70 79 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75  py);.  }..  retu
27b0: 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  rn rc;.}../*.** 
27c0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 64 6f  This function do
27d0: 65 73 20 74 68 65 20 77 6f 72 6b 20 66 6f 72 20  es the work for 
27e0: 74 68 65 20 77 72 69 74 65 66 69 6c 65 28 29 20  the writefile() 
27f0: 55 44 46 2e 20 52 65 66 65 72 20 74 6f 20 0a 2a  UDF. Refer to .*
2800: 2a 20 68 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74  * header comment
2810: 73 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 20  s at the top of 
2820: 74 68 69 73 20 66 69 6c 65 20 66 6f 72 20 64 65  this file for de
2830: 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  tails..*/.static
2840: 20 69 6e 74 20 77 72 69 74 65 46 69 6c 65 28 0a   int writeFile(.
2850: 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78    sqlite3_contex
2860: 74 20 2a 70 43 74 78 2c 20 20 20 20 20 20 20 20  t *pCtx,        
2870: 20 20 2f 2a 20 43 6f 6e 74 65 78 74 20 74 6f 20    /* Context to 
2880: 72 65 74 75 72 6e 20 62 79 74 65 73 20 77 72 69  return bytes wri
2890: 74 74 65 6e 20 69 6e 20 2a 2f 0a 20 20 63 6f 6e  tten in */.  con
28a0: 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 2c 20  st char *zFile, 
28b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
28c0: 46 69 6c 65 20 74 6f 20 77 72 69 74 65 20 2a 2f  File to write */
28d0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
28e0: 20 2a 70 44 61 74 61 2c 20 20 20 20 20 20 20 20   *pData,        
28f0: 20 20 20 2f 2a 20 44 61 74 61 20 74 6f 20 77 72     /* Data to wr
2900: 69 74 65 20 2a 2f 0a 20 20 6d 6f 64 65 5f 74 20  ite */.  mode_t 
2910: 6d 6f 64 65 2c 20 20 20 20 20 20 20 20 20 20 20  mode,           
2920: 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 4f 44 45           /* MODE
2930: 20 70 61 72 61 6d 65 74 65 72 20 70 61 73 73 65   parameter passe
2940: 64 20 74 6f 20 77 72 69 74 65 66 69 6c 65 28 29  d to writefile()
2950: 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e   */.  sqlite3_in
2960: 74 36 34 20 6d 74 69 6d 65 20 20 20 20 20 20 20  t64 mtime       
2970: 20 20 20 20 20 20 2f 2a 20 4d 54 49 4d 45 20 70        /* MTIME p
2980: 61 72 61 6d 65 74 65 72 20 28 6f 72 20 2d 31 20  arameter (or -1 
2990: 74 6f 20 6e 6f 74 20 73 65 74 20 74 69 6d 65 29  to not set time)
29a0: 20 2a 2f 0a 29 7b 0a 23 69 66 20 21 64 65 66 69   */.){.#if !defi
29b0: 6e 65 64 28 5f 57 49 4e 33 32 29 20 26 26 20 21  ned(_WIN32) && !
29c0: 64 65 66 69 6e 65 64 28 57 49 4e 33 32 29 0a 20  defined(WIN32). 
29d0: 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 6d 6f 64   if( S_ISLNK(mod
29e0: 65 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  e) ){.    const 
29f0: 63 68 61 72 20 2a 7a 54 6f 20 3d 20 28 63 6f 6e  char *zTo = (con
2a00: 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33  st char*)sqlite3
2a10: 5f 76 61 6c 75 65 5f 74 65 78 74 28 70 44 61 74  _value_text(pDat
2a20: 61 29 3b 0a 20 20 20 20 69 66 28 20 73 79 6d 6c  a);.    if( syml
2a30: 69 6e 6b 28 7a 54 6f 2c 20 7a 46 69 6c 65 29 3c  ink(zTo, zFile)<
2a40: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  0 ) return 1;.  
2a50: 7d 65 6c 73 65 0a 23 65 6e 64 69 66 0a 20 20 7b  }else.#endif.  {
2a60: 0a 20 20 20 20 69 66 28 20 53 5f 49 53 44 49 52  .    if( S_ISDIR
2a70: 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20 20 20  (mode) ){.      
2a80: 69 66 28 20 6d 6b 64 69 72 28 7a 46 69 6c 65 2c  if( mkdir(zFile,
2a90: 20 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20 20 20   mode) ){.      
2aa0: 20 20 2f 2a 20 54 68 65 20 6d 6b 64 69 72 28 29    /* The mkdir()
2ab0: 20 63 61 6c 6c 20 74 6f 20 63 72 65 61 74 65 20   call to create 
2ac0: 74 68 65 20 64 69 72 65 63 74 6f 72 79 20 66 61  the directory fa
2ad0: 69 6c 65 64 2e 20 54 68 69 73 20 6d 69 67 68 74  iled. This might
2ae0: 20 6e 6f 74 0a 20 20 20 20 20 20 20 20 2a 2a 20   not.        ** 
2af0: 62 65 20 61 6e 20 65 72 72 6f 72 20 74 68 6f 75  be an error thou
2b00: 67 68 20 2d 20 69 66 20 74 68 65 72 65 20 69 73  gh - if there is
2b10: 20 61 6c 72 65 61 64 79 20 61 20 64 69 72 65 63   already a direc
2b20: 74 6f 72 79 20 61 74 20 74 68 65 20 73 61 6d 65  tory at the same
2b30: 0a 20 20 20 20 20 20 20 20 2a 2a 20 70 61 74 68  .        ** path
2b40: 20 61 6e 64 20 65 69 74 68 65 72 20 74 68 65 20   and either the 
2b50: 70 65 72 6d 69 73 73 69 6f 6e 73 20 61 6c 72 65  permissions alre
2b60: 61 64 79 20 6d 61 74 63 68 20 6f 72 20 63 61 6e  ady match or can
2b70: 20 62 65 20 63 68 61 6e 67 65 64 0a 20 20 20 20   be changed.    
2b80: 20 20 20 20 2a 2a 20 74 6f 20 64 6f 20 73 6f 20      ** to do so 
2b90: 75 73 69 6e 67 20 63 68 6d 6f 64 28 29 2c 20 69  using chmod(), i
2ba0: 74 20 69 73 20 6e 6f 74 20 61 6e 20 65 72 72 6f  t is not an erro
2bb0: 72 2e 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 73  r.  */.        s
2bc0: 74 72 75 63 74 20 73 74 61 74 20 73 53 74 61 74  truct stat sStat
2bd0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 65 72  ;.        if( er
2be0: 72 6e 6f 21 3d 45 45 58 49 53 54 0a 20 20 20 20  rno!=EEXIST.    
2bf0: 20 20 20 20 20 7c 7c 20 30 21 3d 66 69 6c 65 53       || 0!=fileS
2c00: 74 61 74 28 7a 46 69 6c 65 2c 20 26 73 53 74 61  tat(zFile, &sSta
2c10: 74 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 21  t).         || !
2c20: 53 5f 49 53 44 49 52 28 73 53 74 61 74 2e 73 74  S_ISDIR(sStat.st
2c30: 5f 6d 6f 64 65 29 0a 20 20 20 20 20 20 20 20 20  _mode).         
2c40: 7c 7c 20 28 28 73 53 74 61 74 2e 73 74 5f 6d 6f  || ((sStat.st_mo
2c50: 64 65 26 30 37 37 37 29 21 3d 28 6d 6f 64 65 26  de&0777)!=(mode&
2c60: 30 37 37 37 29 20 26 26 20 30 21 3d 63 68 6d 6f  0777) && 0!=chmo
2c70: 64 28 7a 46 69 6c 65 2c 20 6d 6f 64 65 26 30 37  d(zFile, mode&07
2c80: 37 37 29 29 0a 20 20 20 20 20 20 20 20 29 7b 0a  77)).        ){.
2c90: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e            return
2ca0: 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20   1;.        }.  
2cb0: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 7b      }.    }else{
2cc0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69  .      sqlite3_i
2cd0: 6e 74 36 34 20 6e 57 72 69 74 65 20 3d 20 30 3b  nt64 nWrite = 0;
2ce0: 0a 20 20 20 20 20 20 63 6f 6e 73 74 20 63 68 61  .      const cha
2cf0: 72 20 2a 7a 3b 0a 20 20 20 20 20 20 69 6e 74 20  r *z;.      int 
2d00: 72 63 20 3d 20 30 3b 0a 20 20 20 20 20 20 46 49  rc = 0;.      FI
2d10: 4c 45 20 2a 6f 75 74 20 3d 20 66 6f 70 65 6e 28  LE *out = fopen(
2d20: 7a 46 69 6c 65 2c 20 22 77 62 22 29 3b 0a 20 20  zFile, "wb");.  
2d30: 20 20 20 20 69 66 28 20 6f 75 74 3d 3d 30 20 29      if( out==0 )
2d40: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20   return 1;.     
2d50: 20 7a 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72   z = (const char
2d60: 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  *)sqlite3_value_
2d70: 62 6c 6f 62 28 70 44 61 74 61 29 3b 0a 20 20 20  blob(pData);.   
2d80: 20 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20     if( z ){.    
2d90: 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36      sqlite3_int6
2da0: 34 20 6e 20 3d 20 66 77 72 69 74 65 28 7a 2c 20  4 n = fwrite(z, 
2db0: 31 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  1, sqlite3_value
2dc0: 5f 62 79 74 65 73 28 70 44 61 74 61 29 2c 20 6f  _bytes(pData), o
2dd0: 75 74 29 3b 0a 20 20 20 20 20 20 20 20 6e 57 72  ut);.        nWr
2de0: 69 74 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 61  ite = sqlite3_va
2df0: 6c 75 65 5f 62 79 74 65 73 28 70 44 61 74 61 29  lue_bytes(pData)
2e00: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 6e 57  ;.        if( nW
2e10: 72 69 74 65 21 3d 6e 20 29 7b 0a 20 20 20 20 20  rite!=n ){.     
2e20: 20 20 20 20 20 72 63 20 3d 20 31 3b 0a 20 20 20       rc = 1;.   
2e30: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
2e40: 20 20 20 20 20 66 63 6c 6f 73 65 28 6f 75 74 29       fclose(out)
2e50: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 3d 3d  ;.      if( rc==
2e60: 30 20 26 26 20 6d 6f 64 65 20 26 26 20 63 68 6d  0 && mode && chm
2e70: 6f 64 28 7a 46 69 6c 65 2c 20 6d 6f 64 65 20 26  od(zFile, mode &
2e80: 20 30 37 37 37 29 20 29 7b 0a 20 20 20 20 20 20   0777) ){.      
2e90: 20 20 72 63 20 3d 20 31 3b 0a 20 20 20 20 20 20    rc = 1;.      
2ea0: 7d 0a 20 20 20 20 20 20 69 66 28 20 72 63 20 29  }.      if( rc )
2eb0: 20 72 65 74 75 72 6e 20 32 3b 0a 20 20 20 20 20   return 2;.     
2ec0: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
2ed0: 69 6e 74 36 34 28 70 43 74 78 2c 20 6e 57 72 69  int64(pCtx, nWri
2ee0: 74 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  te);.    }.  }..
2ef0: 20 20 69 66 28 20 6d 74 69 6d 65 3e 3d 30 20 29    if( mtime>=0 )
2f00: 7b 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57  {.#if defined(_W
2f10: 49 4e 33 32 29 0a 20 20 20 20 2f 2a 20 57 69 6e  IN32).    /* Win
2f20: 64 6f 77 73 20 2a 2f 0a 20 20 20 20 46 49 4c 45  dows */.    FILE
2f30: 54 49 4d 45 20 6c 61 73 74 41 63 63 65 73 73 3b  TIME lastAccess;
2f40: 0a 20 20 20 20 46 49 4c 45 54 49 4d 45 20 6c 61  .    FILETIME la
2f50: 73 74 57 72 69 74 65 3b 0a 20 20 20 20 53 59 53  stWrite;.    SYS
2f60: 54 45 4d 54 49 4d 45 20 63 75 72 72 65 6e 74 54  TEMTIME currentT
2f70: 69 6d 65 3b 0a 20 20 20 20 4c 4f 4e 47 4c 4f 4e  ime;.    LONGLON
2f80: 47 20 69 6e 74 65 72 76 61 6c 73 3b 0a 20 20 20  G intervals;.   
2f90: 20 48 41 4e 44 4c 45 20 68 46 69 6c 65 3b 0a 20   HANDLE hFile;. 
2fa0: 20 20 20 4c 50 57 53 54 52 20 7a 55 6e 69 63 6f     LPWSTR zUnico
2fb0: 64 65 4e 61 6d 65 3b 0a 20 20 20 20 65 78 74 65  deName;.    exte
2fc0: 72 6e 20 4c 50 57 53 54 52 20 73 71 6c 69 74 65  rn LPWSTR sqlite
2fd0: 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f  3_win32_utf8_to_
2fe0: 75 6e 69 63 6f 64 65 28 63 6f 6e 73 74 20 63 68  unicode(const ch
2ff0: 61 72 2a 29 3b 0a 0a 20 20 20 20 47 65 74 53 79  ar*);..    GetSy
3000: 73 74 65 6d 54 69 6d 65 28 26 63 75 72 72 65 6e  stemTime(&curren
3010: 74 54 69 6d 65 29 3b 0a 20 20 20 20 53 79 73 74  tTime);.    Syst
3020: 65 6d 54 69 6d 65 54 6f 46 69 6c 65 54 69 6d 65  emTimeToFileTime
3030: 28 26 63 75 72 72 65 6e 74 54 69 6d 65 2c 20 26  (&currentTime, &
3040: 6c 61 73 74 41 63 63 65 73 73 29 3b 0a 20 20 20  lastAccess);.   
3050: 20 69 6e 74 65 72 76 61 6c 73 20 3d 20 49 6e 74   intervals = Int
3060: 33 32 78 33 32 54 6f 36 34 28 6d 74 69 6d 65 2c  32x32To64(mtime,
3070: 20 31 30 30 30 30 30 30 30 29 20 2b 20 31 31 36   10000000) + 116
3080: 34 34 34 37 33 36 30 30 30 30 30 30 30 30 30 3b  444736000000000;
3090: 0a 20 20 20 20 6c 61 73 74 57 72 69 74 65 2e 64  .    lastWrite.d
30a0: 77 4c 6f 77 44 61 74 65 54 69 6d 65 20 3d 20 28  wLowDateTime = (
30b0: 44 57 4f 52 44 29 69 6e 74 65 72 76 61 6c 73 3b  DWORD)intervals;
30c0: 0a 20 20 20 20 6c 61 73 74 57 72 69 74 65 2e 64  .    lastWrite.d
30d0: 77 48 69 67 68 44 61 74 65 54 69 6d 65 20 3d 20  wHighDateTime = 
30e0: 69 6e 74 65 72 76 61 6c 73 20 3e 3e 20 33 32 3b  intervals >> 32;
30f0: 0a 20 20 20 20 7a 55 6e 69 63 6f 64 65 4e 61 6d  .    zUnicodeNam
3100: 65 20 3d 20 73 71 6c 69 74 65 33 5f 77 69 6e 33  e = sqlite3_win3
3110: 32 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 63 6f 64  2_utf8_to_unicod
3120: 65 28 7a 46 69 6c 65 29 3b 0a 20 20 20 20 69 66  e(zFile);.    if
3130: 28 20 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 3d 3d  ( zUnicodeName==
3140: 30 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  0 ){.      retur
3150: 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 20 20 68  n 1;.    }.    h
3160: 46 69 6c 65 20 3d 20 43 72 65 61 74 65 46 69 6c  File = CreateFil
3170: 65 57 28 0a 20 20 20 20 20 20 7a 55 6e 69 63 6f  eW(.      zUnico
3180: 64 65 4e 61 6d 65 2c 20 46 49 4c 45 5f 57 52 49  deName, FILE_WRI
3190: 54 45 5f 41 54 54 52 49 42 55 54 45 53 2c 20 30  TE_ATTRIBUTES, 0
31a0: 2c 20 4e 55 4c 4c 2c 20 4f 50 45 4e 5f 45 58 49  , NULL, OPEN_EXI
31b0: 53 54 49 4e 47 2c 0a 20 20 20 20 20 20 46 49 4c  STING,.      FIL
31c0: 45 5f 46 4c 41 47 5f 42 41 43 4b 55 50 5f 53 45  E_FLAG_BACKUP_SE
31d0: 4d 41 4e 54 49 43 53 2c 20 4e 55 4c 4c 0a 20 20  MANTICS, NULL.  
31e0: 20 20 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33    );.    sqlite3
31f0: 5f 66 72 65 65 28 7a 55 6e 69 63 6f 64 65 4e 61  _free(zUnicodeNa
3200: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 68 46 69  me);.    if( hFi
3210: 6c 65 21 3d 49 4e 56 41 4c 49 44 5f 48 41 4e 44  le!=INVALID_HAND
3220: 4c 45 5f 56 41 4c 55 45 20 29 7b 0a 20 20 20 20  LE_VALUE ){.    
3230: 20 20 42 4f 4f 4c 20 62 52 65 73 75 6c 74 20 3d    BOOL bResult =
3240: 20 53 65 74 46 69 6c 65 54 69 6d 65 28 68 46 69   SetFileTime(hFi
3250: 6c 65 2c 20 4e 55 4c 4c 2c 20 26 6c 61 73 74 41  le, NULL, &lastA
3260: 63 63 65 73 73 2c 20 26 6c 61 73 74 57 72 69 74  ccess, &lastWrit
3270: 65 29 3b 0a 20 20 20 20 20 20 43 6c 6f 73 65 48  e);.      CloseH
3280: 61 6e 64 6c 65 28 68 46 69 6c 65 29 3b 0a 20 20  andle(hFile);.  
3290: 20 20 20 20 72 65 74 75 72 6e 20 21 62 52 65 73      return !bRes
32a0: 75 6c 74 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  ult;.    }else{.
32b0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a        return 1;.
32c0: 20 20 20 20 7d 0a 23 65 6c 69 66 20 64 65 66 69      }.#elif defi
32d0: 6e 65 64 28 41 54 5f 46 44 43 57 44 29 20 26 26  ned(AT_FDCWD) &&
32e0: 20 30 20 2f 2a 20 75 74 69 6d 65 6e 73 61 74 28   0 /* utimensat(
32f0: 29 20 69 73 20 6e 6f 74 20 75 6e 69 76 65 72 73  ) is not univers
3300: 61 6c 6c 79 20 61 76 61 69 6c 61 62 6c 65 20 2a  ally available *
3310: 2f 0a 20 20 20 20 2f 2a 20 52 65 63 65 6e 74 20  /.    /* Recent 
3320: 75 6e 69 78 20 2a 2f 0a 20 20 20 20 73 74 72 75  unix */.    stru
3330: 63 74 20 74 69 6d 65 73 70 65 63 20 74 69 6d 65  ct timespec time
3340: 73 5b 32 5d 3b 0a 20 20 20 20 74 69 6d 65 73 5b  s[2];.    times[
3350: 30 5d 2e 74 76 5f 6e 73 65 63 20 3d 20 74 69 6d  0].tv_nsec = tim
3360: 65 73 5b 31 5d 2e 74 76 5f 6e 73 65 63 20 3d 20  es[1].tv_nsec = 
3370: 30 3b 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e  0;.    times[0].
3380: 74 76 5f 73 65 63 20 3d 20 74 69 6d 65 28 30 29  tv_sec = time(0)
3390: 3b 0a 20 20 20 20 74 69 6d 65 73 5b 31 5d 2e 74  ;.    times[1].t
33a0: 76 5f 73 65 63 20 3d 20 6d 74 69 6d 65 3b 0a 20  v_sec = mtime;. 
33b0: 20 20 20 69 66 28 20 75 74 69 6d 65 6e 73 61 74     if( utimensat
33c0: 28 41 54 5f 46 44 43 57 44 2c 20 7a 46 69 6c 65  (AT_FDCWD, zFile
33d0: 2c 20 74 69 6d 65 73 2c 20 41 54 5f 53 59 4d 4c  , times, AT_SYML
33e0: 49 4e 4b 5f 4e 4f 46 4f 4c 4c 4f 57 29 20 29 7b  INK_NOFOLLOW) ){
33f0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b  .      return 1;
3400: 0a 20 20 20 20 7d 0a 23 65 6c 73 65 0a 20 20 20  .    }.#else.   
3410: 20 2f 2a 20 4c 65 67 61 63 79 20 75 6e 69 78 20   /* Legacy unix 
3420: 2a 2f 0a 20 20 20 20 73 74 72 75 63 74 20 74 69  */.    struct ti
3430: 6d 65 76 61 6c 20 74 69 6d 65 73 5b 32 5d 3b 0a  meval times[2];.
3440: 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e 74 76 5f      times[0].tv_
3450: 75 73 65 63 20 3d 20 74 69 6d 65 73 5b 31 5d 2e  usec = times[1].
3460: 74 76 5f 75 73 65 63 20 3d 20 30 3b 0a 20 20 20  tv_usec = 0;.   
3470: 20 74 69 6d 65 73 5b 30 5d 2e 74 76 5f 73 65 63   times[0].tv_sec
3480: 20 3d 20 74 69 6d 65 28 30 29 3b 0a 20 20 20 20   = time(0);.    
3490: 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 73 65 63 20  times[1].tv_sec 
34a0: 3d 20 6d 74 69 6d 65 3b 0a 20 20 20 20 69 66 28  = mtime;.    if(
34b0: 20 75 74 69 6d 65 73 28 7a 46 69 6c 65 2c 20 74   utimes(zFile, t
34c0: 69 6d 65 73 29 20 29 7b 0a 20 20 20 20 20 20 72  imes) ){.      r
34d0: 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 23  eturn 1;.    }.#
34e0: 65 6e 64 69 66 0a 20 20 7d 0a 0a 20 20 72 65 74  endif.  }..  ret
34f0: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
3500: 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 6f  Implementation o
3510: 66 20 74 68 65 20 22 77 72 69 74 65 66 69 6c 65  f the "writefile
3520: 28 57 2c 58 5b 2c 59 5b 2c 5a 5d 5d 5d 29 22 20  (W,X[,Y[,Z]]])" 
3530: 53 51 4c 20 66 75 6e 63 74 69 6f 6e 2e 20 20 0a  SQL function.  .
3540: 2a 2a 20 52 65 66 65 72 20 74 6f 20 68 65 61 64  ** Refer to head
3550: 65 72 20 63 6f 6d 6d 65 6e 74 73 20 61 74 20 74  er comments at t
3560: 68 65 20 74 6f 70 20 6f 66 20 74 68 69 73 20 66  he top of this f
3570: 69 6c 65 20 66 6f 72 20 64 65 74 61 69 6c 73 2e  ile for details.
3580: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3590: 77 72 69 74 65 66 69 6c 65 46 75 6e 63 28 0a 20  writefileFunc(. 
35a0: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
35b0: 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74   *context,.  int
35c0: 20 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33   argc,.  sqlite3
35d0: 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b  _value **argv.){
35e0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
35f0: 46 69 6c 65 3b 0a 20 20 6d 6f 64 65 5f 74 20 6d  File;.  mode_t m
3600: 6f 64 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72  ode = 0;.  int r
3610: 65 73 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e  es;.  sqlite3_in
3620: 74 36 34 20 6d 74 69 6d 65 20 3d 20 2d 31 3b 0a  t64 mtime = -1;.
3630: 0a 20 20 69 66 28 20 61 72 67 63 3c 32 20 7c 7c  .  if( argc<2 ||
3640: 20 61 72 67 63 3e 34 20 29 7b 0a 20 20 20 20 73   argc>4 ){.    s
3650: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72  qlite3_result_er
3660: 72 6f 72 28 63 6f 6e 74 65 78 74 2c 20 0a 20 20  ror(context, .  
3670: 20 20 20 20 20 20 22 77 72 6f 6e 67 20 6e 75 6d        "wrong num
3680: 62 65 72 20 6f 66 20 61 72 67 75 6d 65 6e 74 73  ber of arguments
3690: 20 74 6f 20 66 75 6e 63 74 69 6f 6e 20 77 72 69   to function wri
36a0: 74 65 66 69 6c 65 28 29 22 2c 20 2d 31 0a 20 20  tefile()", -1.  
36b0: 20 20 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 3b    );.    return;
36c0: 0a 20 20 7d 0a 0a 20 20 7a 46 69 6c 65 20 3d 20  .  }..  zFile = 
36d0: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
36e0: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
36f0: 61 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20  argv[0]);.  if( 
3700: 7a 46 69 6c 65 3d 3d 30 20 29 20 72 65 74 75 72  zFile==0 ) retur
3710: 6e 3b 0a 20 20 69 66 28 20 61 72 67 63 3e 3d 33  n;.  if( argc>=3
3720: 20 29 7b 0a 20 20 20 20 6d 6f 64 65 20 3d 20 28   ){.    mode = (
3730: 6d 6f 64 65 5f 74 29 73 71 6c 69 74 65 33 5f 76  mode_t)sqlite3_v
3740: 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 32 5d  alue_int(argv[2]
3750: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 72 67  );.  }.  if( arg
3760: 63 3d 3d 34 20 29 7b 0a 20 20 20 20 6d 74 69 6d  c==4 ){.    mtim
3770: 65 20 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  e = sqlite3_valu
3780: 65 5f 69 6e 74 36 34 28 61 72 67 76 5b 33 5d 29  e_int64(argv[3])
3790: 3b 0a 20 20 7d 0a 0a 20 20 72 65 73 20 3d 20 77  ;.  }..  res = w
37a0: 72 69 74 65 46 69 6c 65 28 63 6f 6e 74 65 78 74  riteFile(context
37b0: 2c 20 7a 46 69 6c 65 2c 20 61 72 67 76 5b 31 5d  , zFile, argv[1]
37c0: 2c 20 6d 6f 64 65 2c 20 6d 74 69 6d 65 29 3b 0a  , mode, mtime);.
37d0: 20 20 69 66 28 20 72 65 73 3d 3d 31 20 26 26 20    if( res==1 && 
37e0: 65 72 72 6e 6f 3d 3d 45 4e 4f 45 4e 54 20 29 7b  errno==ENOENT ){
37f0: 0a 20 20 20 20 69 66 28 20 6d 61 6b 65 44 69 72  .    if( makeDir
3800: 65 63 74 6f 72 79 28 7a 46 69 6c 65 2c 20 6d 6f  ectory(zFile, mo
3810: 64 65 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  de)==SQLITE_OK )
3820: 7b 0a 20 20 20 20 20 20 72 65 73 20 3d 20 77 72  {.      res = wr
3830: 69 74 65 46 69 6c 65 28 63 6f 6e 74 65 78 74 2c  iteFile(context,
3840: 20 7a 46 69 6c 65 2c 20 61 72 67 76 5b 31 5d 2c   zFile, argv[1],
3850: 20 6d 6f 64 65 2c 20 6d 74 69 6d 65 29 3b 0a 20   mode, mtime);. 
3860: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
3870: 61 72 67 63 3e 32 20 26 26 20 72 65 73 21 3d 30  argc>2 && res!=0
3880: 20 29 7b 0a 20 20 20 20 69 66 28 20 53 5f 49 53   ){.    if( S_IS
3890: 4c 4e 4b 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20  LNK(mode) ){.   
38a0: 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67 28 63     ctxErrorMsg(c
38b0: 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65 64 20  ontext, "failed 
38c0: 74 6f 20 63 72 65 61 74 65 20 73 79 6d 6c 69 6e  to create symlin
38d0: 6b 3a 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a  k: %s", zFile);.
38e0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53 5f      }else if( S_
38f0: 49 53 44 49 52 28 6d 6f 64 65 29 20 29 7b 0a 20  ISDIR(mode) ){. 
3900: 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67       ctxErrorMsg
3910: 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65  (context, "faile
3920: 64 20 74 6f 20 63 72 65 61 74 65 20 64 69 72 65  d to create dire
3930: 63 74 6f 72 79 3a 20 25 73 22 2c 20 7a 46 69 6c  ctory: %s", zFil
3940: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  e);.    }else{. 
3950: 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67       ctxErrorMsg
3960: 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65  (context, "faile
3970: 64 20 74 6f 20 77 72 69 74 65 20 66 69 6c 65 3a  d to write file:
3980: 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20   %s", zFile);.  
3990: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
39a0: 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 3a 20 20   SQL function:  
39b0: 20 6c 73 6d 6f 64 65 28 4d 4f 44 45 29 0a 2a 2a   lsmode(MODE).**
39c0: 0a 2a 2a 20 47 69 76 65 6e 20 61 20 6e 75 6d 62  .** Given a numb
39d0: 65 72 69 63 20 73 74 5f 6d 6f 64 65 20 66 72 6f  eric st_mode fro
39e0: 6d 20 73 74 61 74 28 29 2c 20 63 6f 6e 76 65 72  m stat(), conver
39f0: 74 20 69 74 20 69 6e 74 6f 20 61 20 68 75 6d 61  t it into a huma
3a00: 6e 2d 72 65 61 64 61 62 6c 65 0a 2a 2a 20 74 65  n-readable.** te
3a10: 78 74 20 73 74 72 69 6e 67 20 69 6e 20 74 68 65  xt string in the
3a20: 20 73 74 79 6c 65 20 6f 66 20 22 6c 73 20 2d 6c   style of "ls -l
3a30: 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  "..*/.static voi
3a40: 64 20 6c 73 4d 6f 64 65 46 75 6e 63 28 0a 20 20  d lsModeFunc(.  
3a50: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
3a60: 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  *context,.  int 
3a70: 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
3a80: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
3a90: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69    int i;.  int i
3aa0: 4d 6f 64 65 20 3d 20 73 71 6c 69 74 65 33 5f 76  Mode = sqlite3_v
3ab0: 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 30 5d  alue_int(argv[0]
3ac0: 29 3b 0a 20 20 63 68 61 72 20 7a 5b 31 36 5d 3b  );.  char z[16];
3ad0: 0a 20 20 28 76 6f 69 64 29 61 72 67 63 3b 0a 20  .  (void)argc;. 
3ae0: 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 69 4d 6f   if( S_ISLNK(iMo
3af0: 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20  de) ){.    z[0] 
3b00: 3d 20 27 6c 27 3b 0a 20 20 7d 65 6c 73 65 20 69  = 'l';.  }else i
3b10: 66 28 20 53 5f 49 53 52 45 47 28 69 4d 6f 64 65  f( S_ISREG(iMode
3b20: 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d 20  ) ){.    z[0] = 
3b30: 27 2d 27 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  '-';.  }else if(
3b40: 20 53 5f 49 53 44 49 52 28 69 4d 6f 64 65 29 20   S_ISDIR(iMode) 
3b50: 29 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d 20 27 64  ){.    z[0] = 'd
3b60: 27 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  ';.  }else{.    
3b70: 7a 5b 30 5d 20 3d 20 27 3f 27 3b 0a 20 20 7d 0a  z[0] = '?';.  }.
3b80: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 33 3b 20    for(i=0; i<3; 
3b90: 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6d 20  i++){.    int m 
3ba0: 3d 20 28 69 4d 6f 64 65 20 3e 3e 20 28 28 32 2d  = (iMode >> ((2-
3bb0: 69 29 2a 33 29 29 3b 0a 20 20 20 20 63 68 61 72  i)*3));.    char
3bc0: 20 2a 61 20 3d 20 26 7a 5b 31 20 2b 20 69 2a 33   *a = &z[1 + i*3
3bd0: 5d 3b 0a 20 20 20 20 61 5b 30 5d 20 3d 20 28 6d  ];.    a[0] = (m
3be0: 20 26 20 30 78 34 29 20 3f 20 27 72 27 20 3a 20   & 0x4) ? 'r' : 
3bf0: 27 2d 27 3b 0a 20 20 20 20 61 5b 31 5d 20 3d 20  '-';.    a[1] = 
3c00: 28 6d 20 26 20 30 78 32 29 20 3f 20 27 77 27 20  (m & 0x2) ? 'w' 
3c10: 3a 20 27 2d 27 3b 0a 20 20 20 20 61 5b 32 5d 20  : '-';.    a[2] 
3c20: 3d 20 28 6d 20 26 20 30 78 31 29 20 3f 20 27 78  = (m & 0x1) ? 'x
3c30: 27 20 3a 20 27 2d 27 3b 0a 20 20 7d 0a 20 20 7a  ' : '-';.  }.  z
3c40: 5b 31 30 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 73  [10] = '\0';.  s
3c50: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
3c60: 78 74 28 63 6f 6e 74 65 78 74 2c 20 7a 2c 20 2d  xt(context, z, -
3c70: 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  1, SQLITE_TRANSI
3c80: 45 4e 54 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66  ENT);.}..#ifndef
3c90: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
3ca0: 54 55 41 4c 54 41 42 4c 45 0a 0a 2f 2a 20 0a 2a  TUALTABLE../* .*
3cb0: 2a 20 43 75 72 73 6f 72 20 74 79 70 65 20 66 6f  * Cursor type fo
3cc0: 72 20 72 65 63 75 72 73 69 76 65 6c 79 20 69 74  r recursively it
3cd0: 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68 20  erating through 
3ce0: 61 20 64 69 72 65 63 74 6f 72 79 20 73 74 72 75  a directory stru
3cf0: 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65 64 65  cture..*/.typede
3d00: 66 20 73 74 72 75 63 74 20 66 73 64 69 72 5f 63  f struct fsdir_c
3d10: 75 72 73 6f 72 20 66 73 64 69 72 5f 63 75 72 73  ursor fsdir_curs
3d20: 6f 72 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  or;.typedef stru
3d30: 63 74 20 46 73 64 69 72 4c 65 76 65 6c 20 46 73  ct FsdirLevel Fs
3d40: 64 69 72 4c 65 76 65 6c 3b 0a 0a 73 74 72 75 63  dirLevel;..struc
3d50: 74 20 46 73 64 69 72 4c 65 76 65 6c 20 7b 0a 20  t FsdirLevel {. 
3d60: 20 44 49 52 20 2a 70 44 69 72 3b 20 20 20 20 20   DIR *pDir;     
3d70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
3d80: 72 6f 6d 20 6f 70 65 6e 64 69 72 28 29 20 2a 2f  rom opendir() */
3d90: 0a 20 20 63 68 61 72 20 2a 7a 44 69 72 3b 20 20  .  char *zDir;  
3da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3db0: 20 4e 61 6d 65 20 6f 66 20 64 69 72 65 63 74 6f   Name of directo
3dc0: 72 79 20 28 6e 75 6c 2d 74 65 72 6d 69 6e 61 74  ry (nul-terminat
3dd0: 65 64 29 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63  ed) */.};..struc
3de0: 74 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 7b  t fsdir_cursor {
3df0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
3e00: 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a  cursor base;  /*
3e10: 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75   Base class - mu
3e20: 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 0a  st be first */..
3e30: 20 20 69 6e 74 20 6e 4c 76 6c 3b 20 20 20 20 20    int nLvl;     
3e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3e50: 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  Number of entrie
3e60: 73 20 69 6e 20 61 4c 76 6c 5b 5d 20 61 72 72 61  s in aLvl[] arra
3e70: 79 20 2a 2f 0a 20 20 69 6e 74 20 69 4c 76 6c 3b  y */.  int iLvl;
3e80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e90: 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 75    /* Index of cu
3ea0: 72 72 65 6e 74 20 65 6e 74 72 79 20 2a 2f 0a 20  rrent entry */. 
3eb0: 20 46 73 64 69 72 4c 65 76 65 6c 20 2a 61 4c 76   FsdirLevel *aLv
3ec0: 6c 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48  l;          /* H
3ed0: 69 65 72 61 72 63 68 79 20 6f 66 20 64 69 72 65  ierarchy of dire
3ee0: 63 74 6f 72 69 65 73 20 62 65 69 6e 67 20 74 72  ctories being tr
3ef0: 61 76 65 72 73 65 64 20 2a 2f 0a 0a 20 20 63 6f  aversed */..  co
3f00: 6e 73 74 20 63 68 61 72 20 2a 7a 42 61 73 65 3b  nst char *zBase;
3f10: 0a 20 20 69 6e 74 20 6e 42 61 73 65 3b 0a 0a 20  .  int nBase;.. 
3f20: 20 73 74 72 75 63 74 20 73 74 61 74 20 73 53 74   struct stat sSt
3f30: 61 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 43  at;         /* C
3f40: 75 72 72 65 6e 74 20 6c 73 74 61 74 28 29 20 72  urrent lstat() r
3f50: 65 73 75 6c 74 73 20 2a 2f 0a 20 20 63 68 61 72  esults */.  char
3f60: 20 2a 7a 50 61 74 68 3b 20 20 20 20 20 20 20 20   *zPath;        
3f70: 20 20 20 20 20 20 20 2f 2a 20 50 61 74 68 20 74         /* Path t
3f80: 6f 20 63 75 72 72 65 6e 74 20 65 6e 74 72 79 20  o current entry 
3f90: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
3fa0: 36 34 20 69 52 6f 77 69 64 3b 20 20 20 20 20 20  64 iRowid;      
3fb0: 2f 2a 20 43 75 72 72 65 6e 74 20 72 6f 77 69 64  /* Current rowid
3fc0: 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65 64 65 66 20   */.};..typedef 
3fd0: 73 74 72 75 63 74 20 66 73 64 69 72 5f 74 61 62  struct fsdir_tab
3fe0: 20 66 73 64 69 72 5f 74 61 62 3b 0a 73 74 72 75   fsdir_tab;.stru
3ff0: 63 74 20 66 73 64 69 72 5f 74 61 62 20 7b 0a 20  ct fsdir_tab {. 
4000: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61   sqlite3_vtab ba
4010: 73 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42  se;         /* B
4020: 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75 73 74  ase class - must
4030: 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 7d 3b 0a   be first */.};.
4040: 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63 74  ./*.** Construct
4050: 20 61 20 6e 65 77 20 66 73 64 69 72 20 76 69 72   a new fsdir vir
4060: 74 75 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63  tual table objec
4070: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
4080: 20 66 73 64 69 72 43 6f 6e 6e 65 63 74 28 0a 20   fsdirConnect(. 
4090: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
40a0: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
40b0: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
40c0: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
40d0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
40e0: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
40f0: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 66 73 64  **pzErr.){.  fsd
4100: 69 72 5f 74 61 62 20 2a 70 4e 65 77 20 3d 20 30  ir_tab *pNew = 0
4110: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 28 76  ;.  int rc;.  (v
4120: 6f 69 64 29 70 41 75 78 3b 0a 20 20 28 76 6f 69  oid)pAux;.  (voi
4130: 64 29 61 72 67 63 3b 0a 20 20 28 76 6f 69 64 29  d)argc;.  (void)
4140: 61 72 67 76 3b 0a 20 20 28 76 6f 69 64 29 70 7a  argv;.  (void)pz
4150: 45 72 72 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  Err;.  rc = sqli
4160: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
4170: 28 64 62 2c 20 22 43 52 45 41 54 45 20 54 41 42  (db, "CREATE TAB
4180: 4c 45 20 78 22 20 46 53 44 49 52 5f 53 43 48 45  LE x" FSDIR_SCHE
4190: 4d 41 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  MA);.  if( rc==S
41a0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
41b0: 70 4e 65 77 20 3d 20 28 66 73 64 69 72 5f 74 61  pNew = (fsdir_ta
41c0: 62 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  b*)sqlite3_mallo
41d0: 63 28 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29  c( sizeof(*pNew)
41e0: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77   );.    if( pNew
41f0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
4200: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 6d  ITE_NOMEM;.    m
4210: 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 73  emset(pNew, 0, s
4220: 69 7a 65 6f 66 28 2a 70 4e 65 77 29 29 3b 0a 20  izeof(*pNew));. 
4230: 20 7d 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 28   }.  *ppVtab = (
4240: 73 71 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 4e  sqlite3_vtab*)pN
4250: 65 77 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ew;.  return rc;
4260: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 6d  .}../*.** This m
4270: 65 74 68 6f 64 20 69 73 20 74 68 65 20 64 65 73  ethod is the des
4280: 74 72 75 63 74 6f 72 20 66 6f 72 20 66 73 64 69  tructor for fsdi
4290: 72 20 76 74 61 62 20 6f 62 6a 65 63 74 73 2e 0a  r vtab objects..
42a0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
42b0: 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  dirDisconnect(sq
42c0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
42d0: 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  b){.  sqlite3_fr
42e0: 65 65 28 70 56 74 61 62 29 3b 0a 20 20 72 65 74  ee(pVtab);.  ret
42f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4300: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63  ../*.** Construc
4310: 74 6f 72 20 66 6f 72 20 61 20 6e 65 77 20 66 73  tor for a new fs
4320: 64 69 72 5f 63 75 72 73 6f 72 20 6f 62 6a 65 63  dir_cursor objec
4330: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
4340: 20 66 73 64 69 72 4f 70 65 6e 28 73 71 6c 69 74   fsdirOpen(sqlit
4350: 65 33 5f 76 74 61 62 20 2a 70 2c 20 73 71 6c 69  e3_vtab *p, sqli
4360: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
4370: 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66  **ppCursor){.  f
4380: 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75  sdir_cursor *pCu
4390: 72 3b 0a 20 20 28 76 6f 69 64 29 70 3b 0a 20 20  r;.  (void)p;.  
43a0: 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pCur = sqlite3_m
43b0: 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70  alloc( sizeof(*p
43c0: 43 75 72 29 20 29 3b 0a 20 20 69 66 28 20 70 43  Cur) );.  if( pC
43d0: 75 72 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ur==0 ) return S
43e0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d  QLITE_NOMEM;.  m
43f0: 65 6d 73 65 74 28 70 43 75 72 2c 20 30 2c 20 73  emset(pCur, 0, s
4400: 69 7a 65 6f 66 28 2a 70 43 75 72 29 29 3b 0a 20  izeof(*pCur));. 
4410: 20 70 43 75 72 2d 3e 69 4c 76 6c 20 3d 20 2d 31   pCur->iLvl = -1
4420: 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20  ;.  *ppCursor = 
4430: 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a 20 20 72  &pCur->base;.  r
4440: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4450: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20  .}../*.** Reset 
4460: 61 20 63 75 72 73 6f 72 20 62 61 63 6b 20 74 6f  a cursor back to
4470: 20 74 68 65 20 73 74 61 74 65 20 69 74 20 77 61   the state it wa
4480: 73 20 69 6e 20 77 68 65 6e 20 66 69 72 73 74 20  s in when first 
4490: 72 65 74 75 72 6e 65 64 0a 2a 2a 20 62 79 20 66  returned.** by f
44a0: 73 64 69 72 4f 70 65 6e 28 29 2e 0a 2a 2f 0a 73  sdirOpen()..*/.s
44b0: 74 61 74 69 63 20 76 6f 69 64 20 66 73 64 69 72  tatic void fsdir
44c0: 52 65 73 65 74 43 75 72 73 6f 72 28 66 73 64 69  ResetCursor(fsdi
44d0: 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 29 7b  r_cursor *pCur){
44e0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
44f0: 69 3d 30 3b 20 69 3c 3d 70 43 75 72 2d 3e 69 4c  i=0; i<=pCur->iL
4500: 76 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 46 73  vl; i++){.    Fs
4510: 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d  dirLevel *pLvl =
4520: 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 69 5d 3b   &pCur->aLvl[i];
4530: 0a 20 20 20 20 69 66 28 20 70 4c 76 6c 2d 3e 70  .    if( pLvl->p
4540: 44 69 72 20 29 20 63 6c 6f 73 65 64 69 72 28 70  Dir ) closedir(p
4550: 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20  Lvl->pDir);.    
4560: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 4c 76  sqlite3_free(pLv
4570: 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 7d 0a 20 20  l->zDir);.  }.  
4580: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75  sqlite3_free(pCu
4590: 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 73 71 6c  r->zPath);.  sql
45a0: 69 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e  ite3_free(pCur->
45b0: 61 4c 76 6c 29 3b 0a 20 20 70 43 75 72 2d 3e 61  aLvl);.  pCur->a
45c0: 4c 76 6c 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d  Lvl = 0;.  pCur-
45d0: 3e 7a 50 61 74 68 20 3d 20 30 3b 0a 20 20 70 43  >zPath = 0;.  pC
45e0: 75 72 2d 3e 7a 42 61 73 65 20 3d 20 30 3b 0a 20  ur->zBase = 0;. 
45f0: 20 70 43 75 72 2d 3e 6e 42 61 73 65 20 3d 20 30   pCur->nBase = 0
4600: 3b 0a 20 20 70 43 75 72 2d 3e 6e 4c 76 6c 20 3d  ;.  pCur->nLvl =
4610: 20 30 3b 0a 20 20 70 43 75 72 2d 3e 69 4c 76 6c   0;.  pCur->iLvl
4620: 20 3d 20 2d 31 3b 0a 20 20 70 43 75 72 2d 3e 69   = -1;.  pCur->i
4630: 52 6f 77 69 64 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a  Rowid = 1;.}../*
4640: 0a 2a 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66  .** Destructor f
4650: 6f 72 20 61 6e 20 66 73 64 69 72 5f 63 75 72 73  or an fsdir_curs
4660: 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or..*/.static in
4670: 74 20 66 73 64 69 72 43 6c 6f 73 65 28 73 71 6c  t fsdirClose(sql
4680: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
4690: 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72 5f   *cur){.  fsdir_
46a0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
46b0: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
46c0: 72 3b 0a 0a 20 20 66 73 64 69 72 52 65 73 65 74  r;..  fsdirReset
46d0: 43 75 72 73 6f 72 28 70 43 75 72 29 3b 0a 20 20  Cursor(pCur);.  
46e0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75  sqlite3_free(pCu
46f0: 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  r);.  return SQL
4700: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4710: 20 53 65 74 20 74 68 65 20 65 72 72 6f 72 20 6d   Set the error m
4720: 65 73 73 61 67 65 20 66 6f 72 20 74 68 65 20 76  essage for the v
4730: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 61 73 73  irtual table ass
4740: 6f 63 69 61 74 65 64 20 77 69 74 68 20 63 75 72  ociated with cur
4750: 73 6f 72 0a 2a 2a 20 70 43 75 72 20 74 6f 20 74  sor.** pCur to t
4760: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 76 70  he results of vp
4770: 72 69 6e 74 66 28 7a 46 6d 74 2c 20 2e 2e 2e 29  rintf(zFmt, ...)
4780: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
4790: 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28   fsdirSetErrmsg(
47a0: 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43  fsdir_cursor *pC
47b0: 75 72 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ur, const char *
47c0: 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61  zFmt, ...){.  va
47d0: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73  _list ap;.  va_s
47e0: 74 61 72 74 28 61 70 2c 20 7a 46 6d 74 29 3b 0a  tart(ap, zFmt);.
47f0: 20 20 70 43 75 72 2d 3e 62 61 73 65 2e 70 56 74    pCur->base.pVt
4800: 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71  ab->zErrMsg = sq
4810: 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a  lite3_vmprintf(z
4820: 46 6d 74 2c 20 61 70 29 3b 0a 20 20 76 61 5f 65  Fmt, ap);.  va_e
4830: 6e 64 28 61 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  nd(ap);.}.../*.*
4840: 2a 20 41 64 76 61 6e 63 65 20 61 6e 20 66 73 64  * Advance an fsd
4850: 69 72 5f 63 75 72 73 6f 72 20 74 6f 20 69 74 73  ir_cursor to its
4860: 20 6e 65 78 74 20 72 6f 77 20 6f 66 20 6f 75 74   next row of out
4870: 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  put..*/.static i
4880: 6e 74 20 66 73 64 69 72 4e 65 78 74 28 73 71 6c  nt fsdirNext(sql
4890: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
48a0: 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72 5f   *cur){.  fsdir_
48b0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
48c0: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
48d0: 72 3b 0a 20 20 6d 6f 64 65 5f 74 20 6d 20 3d 20  r;.  mode_t m = 
48e0: 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d  pCur->sStat.st_m
48f0: 6f 64 65 3b 0a 0a 20 20 70 43 75 72 2d 3e 69 52  ode;..  pCur->iR
4900: 6f 77 69 64 2b 2b 3b 0a 20 20 69 66 28 20 53 5f  owid++;.  if( S_
4910: 49 53 44 49 52 28 6d 29 20 29 7b 0a 20 20 20 20  ISDIR(m) ){.    
4920: 2f 2a 20 44 65 73 63 65 6e 64 20 69 6e 74 6f 20  /* Descend into 
4930: 74 68 69 73 20 64 69 72 65 63 74 6f 72 79 20 2a  this directory *
4940: 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 77 20 3d  /.    int iNew =
4950: 20 70 43 75 72 2d 3e 69 4c 76 6c 20 2b 20 31 3b   pCur->iLvl + 1;
4960: 0a 20 20 20 20 46 73 64 69 72 4c 65 76 65 6c 20  .    FsdirLevel 
4970: 2a 70 4c 76 6c 3b 0a 20 20 20 20 69 66 28 20 69  *pLvl;.    if( i
4980: 4e 65 77 3e 3d 70 43 75 72 2d 3e 6e 4c 76 6c 20  New>=pCur->nLvl 
4990: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  ){.      int nNe
49a0: 77 20 3d 20 69 4e 65 77 2b 31 3b 0a 20 20 20 20  w = iNew+1;.    
49b0: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
49c0: 6e 42 79 74 65 20 3d 20 6e 4e 65 77 2a 73 69 7a  nByte = nNew*siz
49d0: 65 6f 66 28 46 73 64 69 72 4c 65 76 65 6c 29 3b  eof(FsdirLevel);
49e0: 0a 20 20 20 20 20 20 46 73 64 69 72 4c 65 76 65  .      FsdirLeve
49f0: 6c 20 2a 61 4e 65 77 20 3d 20 28 46 73 64 69 72  l *aNew = (Fsdir
4a00: 4c 65 76 65 6c 2a 29 73 71 6c 69 74 65 33 5f 72  Level*)sqlite3_r
4a10: 65 61 6c 6c 6f 63 36 34 28 70 43 75 72 2d 3e 61  ealloc64(pCur->a
4a20: 4c 76 6c 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  Lvl, nByte);.   
4a30: 20 20 20 69 66 28 20 61 4e 65 77 3d 3d 30 20 29     if( aNew==0 )
4a40: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
4a50: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 6d 65 6d 73  OMEM;.      mems
4a60: 65 74 28 26 61 4e 65 77 5b 70 43 75 72 2d 3e 6e  et(&aNew[pCur->n
4a70: 4c 76 6c 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28  Lvl], 0, sizeof(
4a80: 46 73 64 69 72 4c 65 76 65 6c 29 2a 28 6e 4e 65  FsdirLevel)*(nNe
4a90: 77 2d 70 43 75 72 2d 3e 6e 4c 76 6c 29 29 3b 0a  w-pCur->nLvl));.
4aa0: 20 20 20 20 20 20 70 43 75 72 2d 3e 61 4c 76 6c        pCur->aLvl
4ab0: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70   = aNew;.      p
4ac0: 43 75 72 2d 3e 6e 4c 76 6c 20 3d 20 6e 4e 65 77  Cur->nLvl = nNew
4ad0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 75 72  ;.    }.    pCur
4ae0: 2d 3e 69 4c 76 6c 20 3d 20 69 4e 65 77 3b 0a 20  ->iLvl = iNew;. 
4af0: 20 20 20 70 4c 76 6c 20 3d 20 26 70 43 75 72 2d     pLvl = &pCur-
4b00: 3e 61 4c 76 6c 5b 69 4e 65 77 5d 3b 0a 20 20 20  >aLvl[iNew];.   
4b10: 20 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69 72   .    pLvl->zDir
4b20: 20 3d 20 70 43 75 72 2d 3e 7a 50 61 74 68 3b 0a   = pCur->zPath;.
4b30: 20 20 20 20 70 43 75 72 2d 3e 7a 50 61 74 68 20      pCur->zPath 
4b40: 3d 20 30 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 70  = 0;.    pLvl->p
4b50: 44 69 72 20 3d 20 6f 70 65 6e 64 69 72 28 70 4c  Dir = opendir(pL
4b60: 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 20 20 69  vl->zDir);.    i
4b70: 66 28 20 70 4c 76 6c 2d 3e 70 44 69 72 3d 3d 30  f( pLvl->pDir==0
4b80: 20 29 7b 0a 20 20 20 20 20 20 66 73 64 69 72 53   ){.      fsdirS
4b90: 65 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22  etErrmsg(pCur, "
4ba0: 63 61 6e 6e 6f 74 20 72 65 61 64 20 64 69 72 65  cannot read dire
4bb0: 63 74 6f 72 79 3a 20 25 73 22 2c 20 70 43 75 72  ctory: %s", pCur
4bc0: 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20  ->zPath);.      
4bd0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
4be0: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ROR;.    }.  }..
4bf0: 20 20 77 68 69 6c 65 28 20 70 43 75 72 2d 3e 69    while( pCur->i
4c00: 4c 76 6c 3e 3d 30 20 29 7b 0a 20 20 20 20 46 73  Lvl>=0 ){.    Fs
4c10: 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d  dirLevel *pLvl =
4c20: 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 70 43 75   &pCur->aLvl[pCu
4c30: 72 2d 3e 69 4c 76 6c 5d 3b 0a 20 20 20 20 73 74  r->iLvl];.    st
4c40: 72 75 63 74 20 64 69 72 65 6e 74 20 2a 70 45 6e  ruct dirent *pEn
4c50: 74 72 79 20 3d 20 72 65 61 64 64 69 72 28 70 4c  try = readdir(pL
4c60: 76 6c 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20 69  vl->pDir);.    i
4c70: 66 28 20 70 45 6e 74 72 79 20 29 7b 0a 20 20 20  f( pEntry ){.   
4c80: 20 20 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 64     if( pEntry->d
4c90: 5f 6e 61 6d 65 5b 30 5d 3d 3d 27 2e 27 20 29 7b  _name[0]=='.' ){
4ca0: 0a 20 20 20 20 20 20 20 69 66 28 20 70 45 6e 74  .       if( pEnt
4cb0: 72 79 2d 3e 64 5f 6e 61 6d 65 5b 31 5d 3d 3d 27  ry->d_name[1]=='
4cc0: 2e 27 20 26 26 20 70 45 6e 74 72 79 2d 3e 64 5f  .' && pEntry->d_
4cd0: 6e 61 6d 65 5b 32 5d 3d 3d 27 5c 30 27 20 29 20  name[2]=='\0' ) 
4ce0: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
4cf0: 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 64 5f 6e   if( pEntry->d_n
4d00: 61 6d 65 5b 31 5d 3d 3d 27 5c 30 27 20 29 20 63  ame[1]=='\0' ) c
4d10: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d  ontinue;.      }
4d20: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
4d30: 72 65 65 28 70 43 75 72 2d 3e 7a 50 61 74 68 29  ree(pCur->zPath)
4d40: 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 7a 50  ;.      pCur->zP
4d50: 61 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ath = sqlite3_mp
4d60: 72 69 6e 74 66 28 22 25 73 2f 25 73 22 2c 20 70  rintf("%s/%s", p
4d70: 4c 76 6c 2d 3e 7a 44 69 72 2c 20 70 45 6e 74 72  Lvl->zDir, pEntr
4d80: 79 2d 3e 64 5f 6e 61 6d 65 29 3b 0a 20 20 20 20  y->d_name);.    
4d90: 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 50 61 74    if( pCur->zPat
4da0: 68 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  h==0 ) return SQ
4db0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
4dc0: 20 20 69 66 28 20 66 69 6c 65 4c 69 6e 6b 53 74    if( fileLinkSt
4dd0: 61 74 28 70 43 75 72 2d 3e 7a 50 61 74 68 2c 20  at(pCur->zPath, 
4de0: 26 70 43 75 72 2d 3e 73 53 74 61 74 29 20 29 7b  &pCur->sStat) ){
4df0: 0a 20 20 20 20 20 20 20 20 66 73 64 69 72 53 65  .        fsdirSe
4e00: 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 63  tErrmsg(pCur, "c
4e10: 61 6e 6e 6f 74 20 73 74 61 74 20 66 69 6c 65 3a  annot stat file:
4e20: 20 25 73 22 2c 20 70 43 75 72 2d 3e 7a 50 61 74   %s", pCur->zPat
4e30: 68 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  h);.        retu
4e40: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
4e50: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
4e60: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4e70: 0a 20 20 20 20 7d 0a 20 20 20 20 63 6c 6f 73 65  .    }.    close
4e80: 64 69 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b  dir(pLvl->pDir);
4e90: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4ea0: 65 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20  e(pLvl->zDir);. 
4eb0: 20 20 20 70 4c 76 6c 2d 3e 70 44 69 72 20 3d 20     pLvl->pDir = 
4ec0: 30 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69  0;.    pLvl->zDi
4ed0: 72 20 3d 20 30 3b 0a 20 20 20 20 70 43 75 72 2d  r = 0;.    pCur-
4ee0: 3e 69 4c 76 6c 2d 2d 3b 0a 20 20 7d 0a 0a 20 20  >iLvl--;.  }..  
4ef0: 2f 2a 20 45 4f 46 20 2a 2f 0a 20 20 73 71 6c 69  /* EOF */.  sqli
4f00: 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a  te3_free(pCur->z
4f10: 50 61 74 68 29 3b 0a 20 20 70 43 75 72 2d 3e 7a  Path);.  pCur->z
4f20: 50 61 74 68 20 3d 20 30 3b 0a 20 20 72 65 74 75  Path = 0;.  retu
4f30: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
4f40: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 76 61  ./*.** Return va
4f50: 6c 75 65 73 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  lues of columns 
4f60: 66 6f 72 20 74 68 65 20 72 6f 77 20 61 74 20 77  for the row at w
4f70: 68 69 63 68 20 74 68 65 20 73 65 72 69 65 73 5f  hich the series_
4f80: 63 75 72 73 6f 72 0a 2a 2a 20 69 73 20 63 75 72  cursor.** is cur
4f90: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 69 6e 67 2e  rently pointing.
4fa0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
4fb0: 73 64 69 72 43 6f 6c 75 6d 6e 28 0a 20 20 73 71  sdirColumn(.  sq
4fc0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4fd0: 72 20 2a 63 75 72 2c 20 20 20 2f 2a 20 54 68 65  r *cur,   /* The
4fe0: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 73 71 6c   cursor */.  sql
4ff0: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74  ite3_context *ct
5000: 78 2c 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73  x,       /* Firs
5010: 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 71  t argument to sq
5020: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 2e 2e 2e  lite3_result_...
5030: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 69 20 20 20  () */.  int i   
5040: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5050: 20 20 20 20 2f 2a 20 57 68 69 63 68 20 63 6f 6c      /* Which col
5060: 75 6d 6e 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  umn to return */
5070: 0a 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73  .){.  fsdir_curs
5080: 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69  or *pCur = (fsdi
5090: 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20  r_cursor*)cur;. 
50a0: 20 73 77 69 74 63 68 28 20 69 20 29 7b 0a 20 20   switch( i ){.  
50b0: 20 20 63 61 73 65 20 46 53 44 49 52 5f 43 4f 4c    case FSDIR_COL
50c0: 55 4d 4e 5f 4e 41 4d 45 3a 20 7b 0a 20 20 20 20  UMN_NAME: {.    
50d0: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
50e0: 5f 74 65 78 74 28 63 74 78 2c 20 26 70 43 75 72  _text(ctx, &pCur
50f0: 2d 3e 7a 50 61 74 68 5b 70 43 75 72 2d 3e 6e 42  ->zPath[pCur->nB
5100: 61 73 65 5d 2c 20 2d 31 2c 20 53 51 4c 49 54 45  ase], -1, SQLITE
5110: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20  _TRANSIENT);.   
5120: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
5130: 0a 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f  .    case FSDIR_
5140: 43 4f 4c 55 4d 4e 5f 4d 4f 44 45 3a 0a 20 20 20  COLUMN_MODE:.   
5150: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
5160: 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43 75  t_int64(ctx, pCu
5170: 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65  r->sStat.st_mode
5180: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
5190: 0a 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f  .    case FSDIR_
51a0: 43 4f 4c 55 4d 4e 5f 4d 54 49 4d 45 3a 0a 20 20  COLUMN_MTIME:.  
51b0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
51c0: 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43  lt_int64(ctx, pC
51d0: 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 74 69  ur->sStat.st_mti
51e0: 6d 65 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  me);.      break
51f0: 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 53 44 49  ;..    case FSDI
5200: 52 5f 43 4f 4c 55 4d 4e 5f 44 41 54 41 3a 20 7b  R_COLUMN_DATA: {
5210: 0a 20 20 20 20 20 20 6d 6f 64 65 5f 74 20 6d 20  .      mode_t m 
5220: 3d 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74  = pCur->sStat.st
5230: 5f 6d 6f 64 65 3b 0a 20 20 20 20 20 20 69 66 28  _mode;.      if(
5240: 20 53 5f 49 53 44 49 52 28 6d 29 20 29 7b 0a 20   S_ISDIR(m) ){. 
5250: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72         sqlite3_r
5260: 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b  esult_null(ctx);
5270: 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f 57  .#if !defined(_W
5280: 49 4e 33 32 29 20 26 26 20 21 64 65 66 69 6e 65  IN32) && !define
5290: 64 28 57 49 4e 33 32 29 0a 20 20 20 20 20 20 7d  d(WIN32).      }
52a0: 65 6c 73 65 20 69 66 28 20 53 5f 49 53 4c 4e 4b  else if( S_ISLNK
52b0: 28 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63  (m) ){.        c
52c0: 68 61 72 20 61 53 74 61 74 69 63 5b 36 34 5d 3b  har aStatic[64];
52d0: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 61  .        char *a
52e0: 42 75 66 20 3d 20 61 53 74 61 74 69 63 3b 0a 20  Buf = aStatic;. 
52f0: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69         sqlite3_i
5300: 6e 74 36 34 20 6e 42 75 66 20 3d 20 36 34 3b 0a  nt64 nBuf = 64;.
5310: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 0a          int n;..
5320: 20 20 20 20 20 20 20 20 77 68 69 6c 65 28 20 31          while( 1
5330: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 20   ){.          n 
5340: 3d 20 72 65 61 64 6c 69 6e 6b 28 70 43 75 72 2d  = readlink(pCur-
5350: 3e 7a 50 61 74 68 2c 20 61 42 75 66 2c 20 6e 42  >zPath, aBuf, nB
5360: 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  uf);.          i
5370: 66 28 20 6e 3c 6e 42 75 66 20 29 20 62 72 65 61  f( n<nBuf ) brea
5380: 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  k;.          if(
5390: 20 61 42 75 66 21 3d 61 53 74 61 74 69 63 20 29   aBuf!=aStatic )
53a0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 42   sqlite3_free(aB
53b0: 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6e  uf);.          n
53c0: 42 75 66 20 3d 20 6e 42 75 66 2a 32 3b 0a 20 20  Buf = nBuf*2;.  
53d0: 20 20 20 20 20 20 20 20 61 42 75 66 20 3d 20 73          aBuf = s
53e0: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28  qlite3_malloc64(
53f0: 6e 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20  nBuf);.         
5400: 20 69 66 28 20 61 42 75 66 3d 3d 30 20 29 7b 0a   if( aBuf==0 ){.
5410: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
5420: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
5430: 5f 6e 6f 6d 65 6d 28 63 74 78 29 3b 0a 20 20 20  _nomem(ctx);.   
5440: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
5450: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
5460: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
5470: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 73 71 6c    }..        sql
5480: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
5490: 28 63 74 78 2c 20 61 42 75 66 2c 20 6e 2c 20 53  (ctx, aBuf, n, S
54a0: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
54b0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 42  ;.        if( aB
54c0: 75 66 21 3d 61 53 74 61 74 69 63 20 29 20 73 71  uf!=aStatic ) sq
54d0: 6c 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29  lite3_free(aBuf)
54e0: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 7d  ;.#endif.      }
54f0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65  else{.        re
5500: 61 64 46 69 6c 65 43 6f 6e 74 65 6e 74 73 28 63  adFileContents(c
5510: 74 78 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68 29  tx, pCur->zPath)
5520: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
5530: 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f 43      case FSDIR_C
5540: 4f 4c 55 4d 4e 5f 50 41 54 48 3a 0a 20 20 20 20  OLUMN_PATH:.    
5550: 64 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20  default: {.     
5560: 20 2f 2a 20 54 68 65 20 46 53 44 49 52 5f 43 4f   /* The FSDIR_CO
5570: 4c 55 4d 4e 5f 50 41 54 48 20 61 6e 64 20 46 53  LUMN_PATH and FS
5580: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 49 52 20 61  DIR_COLUMN_DIR a
5590: 72 65 20 69 6e 70 75 74 20 70 61 72 61 6d 65 74  re input paramet
55a0: 65 72 73 2e 0a 20 20 20 20 20 20 2a 2a 20 61 6c  ers..      ** al
55b0: 77 61 79 73 20 72 65 74 75 72 6e 20 74 68 65 69  ways return thei
55c0: 72 20 76 61 6c 75 65 73 20 61 73 20 4e 55 4c 4c  r values as NULL
55d0: 20 2a 2f 0a 20 20 20 20 20 20 62 72 65 61 6b 3b   */.      break;
55e0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
55f0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5600: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
5610: 68 65 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65  he rowid for the
5620: 20 63 75 72 72 65 6e 74 20 72 6f 77 2e 20 49 6e   current row. In
5630: 20 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61   this implementa
5640: 74 69 6f 6e 2c 20 74 68 65 0a 2a 2a 20 66 69 72  tion, the.** fir
5650: 73 74 20 72 6f 77 20 72 65 74 75 72 6e 65 64 20  st row returned 
5660: 69 73 20 61 73 73 69 67 6e 65 64 20 72 6f 77 69  is assigned rowi
5670: 64 20 76 61 6c 75 65 20 31 2c 20 61 6e 64 20 65  d value 1, and e
5680: 61 63 68 20 73 75 62 73 65 71 75 65 6e 74 0a 2a  ach subsequent.*
5690: 2a 20 72 6f 77 20 61 20 76 61 6c 75 65 20 31 20  * row a value 1 
56a0: 6d 6f 72 65 20 74 68 61 6e 20 74 68 61 74 20 6f  more than that o
56b0: 66 20 74 68 65 20 70 72 65 76 69 6f 75 73 2e 0a  f the previous..
56c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
56d0: 64 69 72 52 6f 77 69 64 28 73 71 6c 69 74 65 33  dirRowid(sqlite3
56e0: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
56f0: 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  r, sqlite_int64 
5700: 2a 70 52 6f 77 69 64 29 7b 0a 20 20 66 73 64 69  *pRowid){.  fsdi
5710: 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  r_cursor *pCur =
5720: 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29   (fsdir_cursor*)
5730: 63 75 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d  cur;.  *pRowid =
5740: 20 70 43 75 72 2d 3e 69 52 6f 77 69 64 3b 0a 20   pCur->iRowid;. 
5750: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
5760: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  K;.}../*.** Retu
5770: 72 6e 20 54 52 55 45 20 69 66 20 74 68 65 20 63  rn TRUE if the c
5780: 75 72 73 6f 72 20 68 61 73 20 62 65 65 6e 20 6d  ursor has been m
5790: 6f 76 65 64 20 6f 66 66 20 6f 66 20 74 68 65 20  oved off of the 
57a0: 6c 61 73 74 0a 2a 2a 20 72 6f 77 20 6f 66 20 6f  last.** row of o
57b0: 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  utput..*/.static
57c0: 20 69 6e 74 20 66 73 64 69 72 45 6f 66 28 73 71   int fsdirEof(sq
57d0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
57e0: 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72  r *cur){.  fsdir
57f0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  _cursor *pCur = 
5800: 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63  (fsdir_cursor*)c
5810: 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 43  ur;.  return (pC
5820: 75 72 2d 3e 7a 50 61 74 68 3d 3d 30 29 3b 0a 7d  ur->zPath==0);.}
5830: 0a 0a 2f 2a 0a 2a 2a 20 78 46 69 6c 74 65 72 20  ../*.** xFilter 
5840: 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a 0a 2a 2a 20  callback..**.** 
5850: 69 64 78 4e 75 6d 3d 3d 31 20 20 20 50 41 54 48  idxNum==1   PATH
5860: 20 70 61 72 61 6d 65 74 65 72 20 6f 6e 6c 79 0a   parameter only.
5870: 2a 2a 20 69 64 78 4e 75 6d 3d 3d 32 20 20 20 42  ** idxNum==2   B
5880: 6f 74 68 20 50 41 54 48 20 61 6e 64 20 44 49 52  oth PATH and DIR
5890: 20 73 75 70 70 6c 69 65 64 0a 2a 2f 0a 73 74 61   supplied.*/.sta
58a0: 74 69 63 20 69 6e 74 20 66 73 64 69 72 46 69 6c  tic int fsdirFil
58b0: 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ter(.  sqlite3_v
58c0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c  tab_cursor *cur,
58d0: 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20   .  int idxNum, 
58e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53  const char *idxS
58f0: 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  tr,.  int argc, 
5900: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
5910: 61 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20  argv.){.  const 
5920: 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 30 3b 0a  char *zDir = 0;.
5930: 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a    fsdir_cursor *
5940: 70 43 75 72 20 3d 20 28 66 73 64 69 72 5f 63 75  pCur = (fsdir_cu
5950: 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 28 76 6f  rsor*)cur;.  (vo
5960: 69 64 29 69 64 78 53 74 72 3b 0a 20 20 66 73 64  id)idxStr;.  fsd
5970: 69 72 52 65 73 65 74 43 75 72 73 6f 72 28 70 43  irResetCursor(pC
5980: 75 72 29 3b 0a 0a 20 20 69 66 28 20 69 64 78 4e  ur);..  if( idxN
5990: 75 6d 3d 3d 30 20 29 7b 0a 20 20 20 20 66 73 64  um==0 ){.    fsd
59a0: 69 72 53 65 74 45 72 72 6d 73 67 28 70 43 75 72  irSetErrmsg(pCur
59b0: 2c 20 22 74 61 62 6c 65 20 66 75 6e 63 74 69 6f  , "table functio
59c0: 6e 20 66 73 64 69 72 20 72 65 71 75 69 72 65 73  n fsdir requires
59d0: 20 61 6e 20 61 72 67 75 6d 65 6e 74 22 29 3b 0a   an argument");.
59e0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
59f0: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
5a00: 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 69 64  assert( argc==id
5a10: 78 4e 75 6d 20 26 26 20 28 61 72 67 63 3d 3d 31  xNum && (argc==1
5a20: 20 7c 7c 20 61 72 67 63 3d 3d 32 29 20 29 3b 0a   || argc==2) );.
5a30: 20 20 7a 44 69 72 20 3d 20 28 63 6f 6e 73 74 20    zDir = (const 
5a40: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
5a50: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d  lue_text(argv[0]
5a60: 29 3b 0a 20 20 69 66 28 20 7a 44 69 72 3d 3d 30  );.  if( zDir==0
5a70: 20 29 7b 0a 20 20 20 20 66 73 64 69 72 53 65 74   ){.    fsdirSet
5a80: 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 74 61  Errmsg(pCur, "ta
5a90: 62 6c 65 20 66 75 6e 63 74 69 6f 6e 20 66 73 64  ble function fsd
5aa0: 69 72 20 72 65 71 75 69 72 65 73 20 61 20 6e 6f  ir requires a no
5ab0: 6e 2d 4e 55 4c 4c 20 61 72 67 75 6d 65 6e 74 22  n-NULL argument"
5ac0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  );.    return SQ
5ad0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
5ae0: 20 20 69 66 28 20 61 72 67 63 3d 3d 32 20 29 7b    if( argc==2 ){
5af0: 0a 20 20 20 20 70 43 75 72 2d 3e 7a 42 61 73 65  .    pCur->zBase
5b00: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
5b10: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
5b20: 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 7d  xt(argv[1]);.  }
5b30: 0a 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 42 61  .  if( pCur->zBa
5b40: 73 65 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e  se ){.    pCur->
5b50: 6e 42 61 73 65 20 3d 20 28 69 6e 74 29 73 74 72  nBase = (int)str
5b60: 6c 65 6e 28 70 43 75 72 2d 3e 7a 42 61 73 65 29  len(pCur->zBase)
5b70: 2b 31 3b 0a 20 20 20 20 70 43 75 72 2d 3e 7a 50  +1;.    pCur->zP
5b80: 61 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ath = sqlite3_mp
5b90: 72 69 6e 74 66 28 22 25 73 2f 25 73 22 2c 20 70  rintf("%s/%s", p
5ba0: 43 75 72 2d 3e 7a 42 61 73 65 2c 20 7a 44 69 72  Cur->zBase, zDir
5bb0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
5bc0: 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 73 71  pCur->zPath = sq
5bd0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
5be0: 73 22 2c 20 7a 44 69 72 29 3b 0a 20 20 7d 0a 0a  s", zDir);.  }..
5bf0: 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 50 61 74    if( pCur->zPat
5c00: 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  h==0 ){.    retu
5c10: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
5c20: 0a 20 20 7d 0a 20 20 69 66 28 20 66 69 6c 65 4c  .  }.  if( fileL
5c30: 69 6e 6b 53 74 61 74 28 70 43 75 72 2d 3e 7a 50  inkStat(pCur->zP
5c40: 61 74 68 2c 20 26 70 43 75 72 2d 3e 73 53 74 61  ath, &pCur->sSta
5c50: 74 29 20 29 7b 0a 20 20 20 20 66 73 64 69 72 53  t) ){.    fsdirS
5c60: 65 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22  etErrmsg(pCur, "
5c70: 63 61 6e 6e 6f 74 20 73 74 61 74 20 66 69 6c 65  cannot stat file
5c80: 3a 20 25 73 22 2c 20 70 43 75 72 2d 3e 7a 50 61  : %s", pCur->zPa
5c90: 74 68 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  th);.    return 
5ca0: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
5cb0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
5cc0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
5cd0: 53 51 4c 69 74 65 20 77 69 6c 6c 20 69 6e 76 6f  SQLite will invo
5ce0: 6b 65 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f  ke this method o
5cf0: 6e 65 20 6f 72 20 6d 6f 72 65 20 74 69 6d 65 73  ne or more times
5d00: 20 77 68 69 6c 65 20 70 6c 61 6e 6e 69 6e 67 20   while planning 
5d10: 61 20 71 75 65 72 79 0a 2a 2a 20 74 68 61 74 20  a query.** that 
5d20: 75 73 65 73 20 74 68 65 20 67 65 6e 65 72 61 74  uses the generat
5d30: 65 5f 73 65 72 69 65 73 20 76 69 72 74 75 61 6c  e_series virtual
5d40: 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 72 6f   table.  This ro
5d50: 75 74 69 6e 65 20 6e 65 65 64 73 20 74 6f 20 63  utine needs to c
5d60: 72 65 61 74 65 0a 2a 2a 20 61 20 71 75 65 72 79  reate.** a query
5d70: 20 70 6c 61 6e 20 66 6f 72 20 65 61 63 68 20 69   plan for each i
5d80: 6e 76 6f 63 61 74 69 6f 6e 20 61 6e 64 20 63 6f  nvocation and co
5d90: 6d 70 75 74 65 20 61 6e 20 65 73 74 69 6d 61 74  mpute an estimat
5da0: 65 64 20 63 6f 73 74 20 66 6f 72 20 74 68 61 74  ed cost for that
5db0: 0a 2a 2a 20 70 6c 61 6e 2e 0a 2a 2a 0a 2a 2a 20  .** plan..**.** 
5dc0: 49 6e 20 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e  In this implemen
5dd0: 74 61 74 69 6f 6e 20 69 64 78 4e 75 6d 20 69 73  tation idxNum is
5de0: 20 75 73 65 64 20 74 6f 20 72 65 70 72 65 73 65   used to represe
5df0: 6e 74 20 74 68 65 0a 2a 2a 20 71 75 65 72 79 20  nt the.** query 
5e00: 70 6c 61 6e 2e 20 20 69 64 78 53 74 72 20 69 73  plan.  idxStr is
5e10: 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   unused..**.** T
5e20: 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 69 73  he query plan is
5e30: 20 72 65 70 72 65 73 65 6e 74 65 64 20 62 79 20   represented by 
5e40: 76 61 6c 75 65 73 20 6f 66 20 69 64 78 4e 75 6d  values of idxNum
5e50: 3a 0a 2a 2a 0a 2a 2a 20 20 28 31 29 20 20 54 68  :.**.**  (1)  Th
5e60: 65 20 70 61 74 68 20 76 61 6c 75 65 20 69 73 20  e path value is 
5e70: 73 75 70 70 6c 69 65 64 20 62 79 20 61 72 67 76  supplied by argv
5e80: 5b 30 5d 0a 2a 2a 20 20 28 32 29 20 20 50 61 74  [0].**  (2)  Pat
5e90: 68 20 69 73 20 69 6e 20 61 72 67 76 5b 30 5d 20  h is in argv[0] 
5ea0: 61 6e 64 20 64 69 72 20 69 73 20 69 6e 20 61 72  and dir is in ar
5eb0: 67 76 5b 31 5d 0a 2a 2f 0a 73 74 61 74 69 63 20  gv[1].*/.static 
5ec0: 69 6e 74 20 66 73 64 69 72 42 65 73 74 49 6e 64  int fsdirBestInd
5ed0: 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  ex(.  sqlite3_vt
5ee0: 61 62 20 2a 74 61 62 2c 0a 20 20 73 71 6c 69 74  ab *tab,.  sqlit
5ef0: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70  e3_index_info *p
5f00: 49 64 78 49 6e 66 6f 0a 29 7b 0a 20 20 69 6e 74  IdxInfo.){.  int
5f10: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
5f20: 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 6f 76 65 72      /* Loop over
5f30: 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a   constraints */.
5f40: 20 20 69 6e 74 20 69 64 78 50 61 74 68 20 3d 20    int idxPath = 
5f50: 2d 31 3b 20 20 20 20 20 20 2f 2a 20 49 6e 64 65  -1;      /* Inde
5f60: 78 20 69 6e 20 70 49 64 78 49 6e 66 6f 2d 3e 61  x in pIdxInfo->a
5f70: 43 6f 6e 73 74 72 61 69 6e 74 20 6f 66 20 50 41  Constraint of PA
5f80: 54 48 3d 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78  TH= */.  int idx
5f90: 44 69 72 20 3d 20 2d 31 3b 20 20 20 20 20 20 20  Dir = -1;       
5fa0: 2f 2a 20 49 6e 64 65 78 20 69 6e 20 70 49 64 78  /* Index in pIdx
5fb0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
5fc0: 74 20 6f 66 20 44 49 52 3d 20 2a 2f 0a 20 20 69  t of DIR= */.  i
5fd0: 6e 74 20 73 65 65 6e 50 61 74 68 20 3d 20 30 3b  nt seenPath = 0;
5fe0: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
5ff0: 20 61 6e 20 75 6e 75 73 61 62 6c 65 20 50 41 54   an unusable PAT
6000: 48 3d 20 63 6f 6e 73 74 72 61 69 6e 74 20 69 73  H= constraint is
6010: 20 73 65 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 73   seen */.  int s
6020: 65 65 6e 44 69 72 20 3d 20 30 3b 20 20 20 20 20  eenDir = 0;     
6030: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 6e 20    /* True if an 
6040: 75 6e 75 73 61 62 6c 65 20 44 49 52 3d 20 63 6f  unusable DIR= co
6050: 6e 73 74 72 61 69 6e 74 20 69 73 20 73 65 65 6e  nstraint is seen
6060: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 73 74 72 75   */.  const stru
6070: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
6080: 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f  _constraint *pCo
6090: 6e 73 74 72 61 69 6e 74 3b 0a 0a 20 20 28 76 6f  nstraint;..  (vo
60a0: 69 64 29 74 61 62 3b 0a 20 20 70 43 6f 6e 73 74  id)tab;.  pConst
60b0: 72 61 69 6e 74 20 3d 20 70 49 64 78 49 6e 66 6f  raint = pIdxInfo
60c0: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20  ->aConstraint;. 
60d0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 64 78   for(i=0; i<pIdx
60e0: 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e  Info->nConstrain
60f0: 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e 73 74 72 61  t; i++, pConstra
6100: 69 6e 74 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  int++){.    if( 
6110: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 21  pConstraint->op!
6120: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
6130: 4e 53 54 52 41 49 4e 54 5f 45 51 20 29 20 63 6f  NSTRAINT_EQ ) co
6140: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 73 77 69 74  ntinue;.    swit
6150: 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  ch( pConstraint-
6160: 3e 69 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20  >iColumn ){.    
6170: 20 20 63 61 73 65 20 46 53 44 49 52 5f 43 4f 4c    case FSDIR_COL
6180: 55 4d 4e 5f 50 41 54 48 3a 20 7b 0a 20 20 20 20  UMN_PATH: {.    
6190: 20 20 20 20 69 66 28 20 70 43 6f 6e 73 74 72 61      if( pConstra
61a0: 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29 7b 0a 20  int->usable ){. 
61b0: 20 20 20 20 20 20 20 20 20 69 64 78 50 61 74 68           idxPath
61c0: 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20   = i;.          
61d0: 73 65 65 6e 50 61 74 68 20 3d 20 30 3b 0a 20 20  seenPath = 0;.  
61e0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
61f0: 69 64 78 50 61 74 68 3c 30 20 29 7b 0a 20 20 20  idxPath<0 ){.   
6200: 20 20 20 20 20 20 20 73 65 65 6e 50 61 74 68 20         seenPath 
6210: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  = 1;.        }. 
6220: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
6230: 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65      }.      case
6240: 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 49   FSDIR_COLUMN_DI
6250: 52 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 66 28  R: {.        if(
6260: 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75 73   pConstraint->us
6270: 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20  able ){.        
6280: 20 20 69 64 78 44 69 72 20 3d 20 69 3b 0a 20 20    idxDir = i;.  
6290: 20 20 20 20 20 20 20 20 73 65 65 6e 44 69 72 20          seenDir 
62a0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 0;.        }el
62b0: 73 65 20 69 66 28 20 69 64 78 44 69 72 3c 30 20  se if( idxDir<0 
62c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 65  ){.          see
62d0: 6e 44 69 72 20 3d 20 31 3b 0a 20 20 20 20 20 20  nDir = 1;.      
62e0: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61    }.        brea
62f0: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
6300: 20 0a 20 20 7d 0a 20 20 69 66 28 20 73 65 65 6e   .  }.  if( seen
6310: 50 61 74 68 20 7c 7c 20 73 65 65 6e 44 69 72 20  Path || seenDir 
6320: 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 69 6e 70  ){.    /* If inp
6330: 75 74 20 70 61 72 61 6d 65 74 65 72 73 20 61 72  ut parameters ar
6340: 65 20 75 6e 75 73 61 62 6c 65 2c 20 64 69 73 61  e unusable, disa
6350: 6c 6c 6f 77 20 74 68 69 73 20 70 6c 61 6e 20 2a  llow this plan *
6360: 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  /.    return SQL
6370: 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a  ITE_CONSTRAINT;.
6380: 20 20 7d 0a 0a 20 20 69 66 28 20 69 64 78 50 61    }..  if( idxPa
6390: 74 68 3c 30 20 29 7b 0a 20 20 20 20 70 49 64 78  th<0 ){.    pIdx
63a0: 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 30  Info->idxNum = 0
63b0: 3b 0a 20 20 20 20 2f 2a 20 54 68 65 20 70 49 64  ;.    /* The pId
63c0: 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  xInfo->estimated
63d0: 43 6f 73 74 20 73 68 6f 75 6c 64 20 68 61 76 65  Cost should have
63e0: 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   been initialize
63f0: 64 20 74 6f 20 61 20 68 75 67 65 0a 20 20 20 20  d to a huge.    
6400: 2a 2a 20 6e 75 6d 62 65 72 2e 20 20 4c 65 61 76  ** number.  Leav
6410: 65 20 69 74 20 75 6e 63 68 61 6e 67 65 64 2e 20  e it unchanged. 
6420: 2a 2f 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  */.    pIdxInfo-
6430: 3e 65 73 74 69 6d 61 74 65 64 52 6f 77 73 20 3d  >estimatedRows =
6440: 20 30 78 37 66 66 66 66 66 66 66 3b 0a 20 20 7d   0x7fffffff;.  }
6450: 65 6c 73 65 7b 0a 20 20 20 20 70 49 64 78 49 6e  else{.    pIdxIn
6460: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
6470: 73 61 67 65 5b 69 64 78 50 61 74 68 5d 2e 6f 6d  sage[idxPath].om
6480: 69 74 20 3d 20 31 3b 0a 20 20 20 20 70 49 64 78  it = 1;.    pIdx
6490: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
64a0: 74 55 73 61 67 65 5b 69 64 78 50 61 74 68 5d 2e  tUsage[idxPath].
64b0: 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20  argvIndex = 1;. 
64c0: 20 20 20 69 66 28 20 69 64 78 44 69 72 3e 3d 30     if( idxDir>=0
64d0: 20 29 7b 0a 20 20 20 20 20 20 70 49 64 78 49 6e   ){.      pIdxIn
64e0: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
64f0: 73 61 67 65 5b 69 64 78 44 69 72 5d 2e 6f 6d 69  sage[idxDir].omi
6500: 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49 64  t = 1;.      pId
6510: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
6520: 6e 74 55 73 61 67 65 5b 69 64 78 44 69 72 5d 2e  ntUsage[idxDir].
6530: 61 72 67 76 49 6e 64 65 78 20 3d 20 32 3b 0a 20  argvIndex = 2;. 
6540: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69       pIdxInfo->i
6550: 64 78 4e 75 6d 20 3d 20 32 3b 0a 20 20 20 20 20  dxNum = 2;.     
6560: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
6570: 61 74 65 64 43 6f 73 74 20 3d 20 31 30 2e 30 3b  atedCost = 10.0;
6580: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
6590: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e    pIdxInfo->idxN
65a0: 75 6d 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49  um = 1;.      pI
65b0: 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65  dxInfo->estimate
65c0: 64 43 6f 73 74 20 3d 20 31 30 30 2e 30 3b 0a 20  dCost = 100.0;. 
65d0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
65e0: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
65f0: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
6600: 74 68 65 20 22 66 73 64 69 72 22 20 76 69 72 74  the "fsdir" virt
6610: 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74  ual table..*/.st
6620: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 52 65  atic int fsdirRe
6630: 67 69 73 74 65 72 28 73 71 6c 69 74 65 33 20 2a  gister(sqlite3 *
6640: 64 62 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71  db){.  static sq
6650: 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66 73 64  lite3_module fsd
6660: 69 72 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 20  irModule = {.   
6670: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
6680: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
6690: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30  Version */.    0
66a0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
66b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72            /* xCr
66c0: 65 61 74 65 20 2a 2f 0a 20 20 20 20 66 73 64 69  eate */.    fsdi
66d0: 72 43 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20 20  rConnect,       
66e0: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e 65         /* xConne
66f0: 63 74 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 42  ct */.    fsdirB
6700: 65 73 74 49 6e 64 65 78 2c 20 20 20 20 20 20 20  estIndex,       
6710: 20 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64       /* xBestInd
6720: 65 78 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 44  ex */.    fsdirD
6730: 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20  isconnect,      
6740: 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e       /* xDisconn
6750: 65 63 74 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ect */.    0,   
6760: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6770: 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f        /* xDestro
6780: 79 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 4f 70  y */.    fsdirOp
6790: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
67a0: 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f      /* xOpen - o
67b0: 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  pen a cursor */.
67c0: 20 20 20 20 66 73 64 69 72 43 6c 6f 73 65 2c 20      fsdirClose, 
67d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
67e0: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
67f0: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 20   a cursor */.   
6800: 20 66 73 64 69 72 46 69 6c 74 65 72 2c 20 20 20   fsdirFilter,   
6810: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6820: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
6830: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
6840: 6e 74 73 20 2a 2f 0a 20 20 20 20 66 73 64 69 72  nts */.    fsdir
6850: 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20  Next,           
6860: 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d        /* xNext -
6870: 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f   advance a curso
6880: 72 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 45 6f  r */.    fsdirEo
6890: 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
68a0: 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63 68      /* xEof - ch
68b0: 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20 73  eck for end of s
68c0: 63 61 6e 20 2a 2f 0a 20 20 20 20 66 73 64 69 72  can */.    fsdir
68d0: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
68e0: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e        /* xColumn
68f0: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
6900: 20 20 20 20 66 73 64 69 72 52 6f 77 69 64 2c 20      fsdirRowid, 
6910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6920: 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20  * xRowid - read 
6930: 64 61 74 61 20 2a 2f 0a 20 20 20 20 30 2c 20 20  data */.    0,  
6940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6950: 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74         /* xUpdat
6960: 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  e */.    0,     
6970: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6980: 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f      /* xBegin */
6990: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
69a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69b0: 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 20 20  /* xSync */.    
69c0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
69d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
69e0: 6f 6d 6d 69 74 20 2a 2f 0a 20 20 20 20 30 2c 20  ommit */.    0, 
69f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a00: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c          /* xRoll
6a10: 62 61 63 6b 20 2a 2f 0a 20 20 20 20 30 2c 20 20  back */.    0,  
6a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a30: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 4d         /* xFindM
6a40: 65 74 68 6f 64 20 2a 2f 0a 20 20 20 20 30 2c 20  ethod */.    0, 
6a50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a60: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61          /* xRena
6a70: 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  me */.    0,    
6a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a90: 20 20 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69       /* xSavepoi
6aa0: 6e 74 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  nt */.    0,    
6ab0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ac0: 20 20 20 20 20 2f 2a 20 78 52 65 6c 65 61 73 65       /* xRelease
6ad0: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
6ae0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6af0: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 54     /* xRollbackT
6b00: 6f 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  o */.    0,     
6b10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b20: 20 20 20 20 2f 2a 20 78 53 68 61 64 6f 77 4e 61      /* xShadowNa
6b30: 6d 65 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 69 6e  me */.  };..  in
6b40: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63  t rc = sqlite3_c
6b50: 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c  reate_module(db,
6b60: 20 22 66 73 64 69 72 22 2c 20 26 66 73 64 69 72   "fsdir", &fsdir
6b70: 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 20 20 72 65  Module, 0);.  re
6b80: 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65  turn rc;.}.#else
6b90: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49           /* SQLI
6ba0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
6bb0: 41 42 4c 45 20 2a 2f 0a 23 20 64 65 66 69 6e 65  ABLE */.# define
6bc0: 20 66 73 64 69 72 52 65 67 69 73 74 65 72 28 78   fsdirRegister(x
6bd0: 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64  ) SQLITE_OK.#end
6be0: 69 66 0a 0a 23 69 66 64 65 66 20 5f 57 49 4e 33  if..#ifdef _WIN3
6bf0: 32 0a 5f 5f 64 65 63 6c 73 70 65 63 28 64 6c 6c  2.__declspec(dll
6c00: 65 78 70 6f 72 74 29 0a 23 65 6e 64 69 66 0a 69  export).#endif.i
6c10: 6e 74 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 69  nt sqlite3_filei
6c20: 6f 5f 69 6e 69 74 28 0a 20 20 73 71 6c 69 74 65  o_init(.  sqlite
6c30: 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20 2a  3 *db, .  char *
6c40: 2a 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20 63 6f  *pzErrMsg, .  co
6c50: 6e 73 74 20 73 71 6c 69 74 65 33 5f 61 70 69 5f  nst sqlite3_api_
6c60: 72 6f 75 74 69 6e 65 73 20 2a 70 41 70 69 0a 29  routines *pApi.)
6c70: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
6c80: 49 54 45 5f 4f 4b 3b 0a 20 20 53 51 4c 49 54 45  ITE_OK;.  SQLITE
6c90: 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49 54 32  _EXTENSION_INIT2
6ca0: 28 70 41 70 69 29 3b 0a 20 20 28 76 6f 69 64 29  (pApi);.  (void)
6cb0: 70 7a 45 72 72 4d 73 67 3b 20 20 2f 2a 20 55 6e  pzErrMsg;  /* Un
6cc0: 75 73 65 64 20 70 61 72 61 6d 65 74 65 72 20 2a  used parameter *
6cd0: 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  /.  rc = sqlite3
6ce0: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
6cf0: 28 64 62 2c 20 22 72 65 61 64 66 69 6c 65 22 2c  (db, "readfile",
6d00: 20 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c   1, SQLITE_UTF8,
6d10: 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   0,.            
6d20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d30: 20 20 20 72 65 61 64 66 69 6c 65 46 75 6e 63 2c     readfileFunc,
6d40: 20 30 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63   0, 0);.  if( rc
6d50: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
6d60: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
6d70: 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28  create_function(
6d80: 64 62 2c 20 22 77 72 69 74 65 66 69 6c 65 22 2c  db, "writefile",
6d90: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38   -1, SQLITE_UTF8
6da0: 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , 0,.           
6db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dc0: 20 20 20 20 20 20 77 72 69 74 65 66 69 6c 65 46        writefileF
6dd0: 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a  unc, 0, 0);.  }.
6de0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6df0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
6e00: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 66  sqlite3_create_f
6e10: 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 6c 73 6d  unction(db, "lsm
6e20: 6f 64 65 22 2c 20 31 2c 20 53 51 4c 49 54 45 5f  ode", 1, SQLITE_
6e30: 55 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20  UTF8, 0,.       
6e40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e50: 20 20 20 20 20 20 20 20 20 20 6c 73 4d 6f 64 65            lsMode
6e60: 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  Func, 0, 0);.  }
6e70: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6e80: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
6e90: 20 66 73 64 69 72 52 65 67 69 73 74 65 72 28 64   fsdirRegister(d
6ea0: 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  b);.  }.  return
6eb0: 20 72 63 3b 0a 7d 0a                              rc;.}.