/ Hex Artifact Content
Login

Artifact b8e9421ea5bc10d300230c06f26baff2dc0fc04dcfe007c1258e1411144bda8b:


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 3f 20 6e 49 6e 20 3a 20 31 20 29 3b 0a  In ? nIn : 1 );.
1490: 20 20 69 66 28 20 70 42 75 66 3d 3d 30 20 29 7b    if( pBuf==0 ){
14a0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
14b0: 75 6c 74 5f 65 72 72 6f 72 5f 6e 6f 6d 65 6d 28  ult_error_nomem(
14c0: 63 74 78 29 3b 0a 20 20 20 20 66 63 6c 6f 73 65  ctx);.    fclose
14d0: 28 69 6e 29 3b 0a 20 20 20 20 72 65 74 75 72 6e  (in);.    return
14e0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 6e 49 6e 3d  ;.  }.  if( nIn=
14f0: 3d 66 72 65 61 64 28 70 42 75 66 2c 20 31 2c 20  =fread(pBuf, 1, 
1500: 28 73 69 7a 65 5f 74 29 6e 49 6e 2c 20 69 6e 29  (size_t)nIn, in)
1510: 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f   ){.    sqlite3_
1520: 72 65 73 75 6c 74 5f 62 6c 6f 62 36 34 28 63 74  result_blob64(ct
1530: 78 2c 20 70 42 75 66 2c 20 6e 49 6e 2c 20 73 71  x, pBuf, nIn, sq
1540: 6c 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 7d  lite3_free);.  }
1550: 65 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65  else{.    sqlite
1560: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63  3_result_error_c
1570: 6f 64 65 28 63 74 78 2c 20 53 51 4c 49 54 45 5f  ode(ctx, SQLITE_
1580: 49 4f 45 52 52 29 3b 0a 20 20 20 20 73 71 6c 69  IOERR);.    sqli
1590: 74 65 33 5f 66 72 65 65 28 70 42 75 66 29 3b 0a  te3_free(pBuf);.
15a0: 20 20 7d 0a 20 20 66 63 6c 6f 73 65 28 69 6e 29    }.  fclose(in)
15b0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
15c0: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
15d0: 20 22 72 65 61 64 66 69 6c 65 28 58 29 22 20 53   "readfile(X)" S
15e0: 51 4c 20 66 75 6e 63 74 69 6f 6e 2e 20 20 54 68  QL function.  Th
15f0: 65 20 65 6e 74 69 72 65 20 63 6f 6e 74 65 6e 74  e entire content
1600: 0a 2a 2a 20 6f 66 20 74 68 65 20 66 69 6c 65 20  .** of the file 
1610: 6e 61 6d 65 64 20 58 20 69 73 20 72 65 61 64 20  named X is read 
1620: 61 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20  and returned as 
1630: 61 20 42 4c 4f 42 2e 20 20 4e 55 4c 4c 20 69 73  a BLOB.  NULL is
1640: 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 66 20   returned.** if 
1650: 74 68 65 20 66 69 6c 65 20 64 6f 65 73 20 6e 6f  the file does no
1660: 74 20 65 78 69 73 74 20 6f 72 20 69 73 20 75 6e  t exist or is un
1670: 72 65 61 64 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61  readable..*/.sta
1680: 74 69 63 20 76 6f 69 64 20 72 65 61 64 66 69 6c  tic void readfil
1690: 65 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33  eFunc(.  sqlite3
16a0: 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78  _context *contex
16b0: 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20  t,.  int argc,. 
16c0: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a   sqlite3_value *
16d0: 2a 61 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74  *argv.){.  const
16e0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20   char *zName;.  
16f0: 28 76 6f 69 64 29 28 61 72 67 63 29 3b 20 20 2f  (void)(argc);  /
1700: 2a 20 55 6e 75 73 65 64 20 70 61 72 61 6d 65 74  * Unused paramet
1710: 65 72 20 2a 2f 0a 20 20 7a 4e 61 6d 65 20 3d 20  er */.  zName = 
1720: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
1730: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
1740: 61 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20  argv[0]);.  if( 
1750: 7a 4e 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72  zName==0 ) retur
1760: 6e 3b 0a 20 20 72 65 61 64 46 69 6c 65 43 6f 6e  n;.  readFileCon
1770: 74 65 6e 74 73 28 63 6f 6e 74 65 78 74 2c 20 7a  tents(context, z
1780: 4e 61 6d 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  Name);.}../*.** 
1790: 53 65 74 20 74 68 65 20 65 72 72 6f 72 20 6d 65  Set the error me
17a0: 73 73 61 67 65 20 63 6f 6e 74 61 69 6e 65 64 20  ssage contained 
17b0: 69 6e 20 63 6f 6e 74 65 78 74 20 63 74 78 20 74  in context ctx t
17c0: 6f 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66  o the results of
17d0: 0a 2a 2a 20 76 70 72 69 6e 74 66 28 7a 46 6d 74  .** vprintf(zFmt
17e0: 2c 20 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69  , ...)..*/.stati
17f0: 63 20 76 6f 69 64 20 63 74 78 45 72 72 6f 72 4d  c void ctxErrorM
1800: 73 67 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65  sg(sqlite3_conte
1810: 78 74 20 2a 63 74 78 2c 20 63 6f 6e 73 74 20 63  xt *ctx, const c
1820: 68 61 72 20 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b  har *zFmt, ...){
1830: 0a 20 20 63 68 61 72 20 2a 7a 4d 73 67 20 3d 20  .  char *zMsg = 
1840: 30 3b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b  0;.  va_list ap;
1850: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
1860: 7a 46 6d 74 29 3b 0a 20 20 7a 4d 73 67 20 3d 20  zFmt);.  zMsg = 
1870: 73 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66  sqlite3_vmprintf
1880: 28 7a 46 6d 74 2c 20 61 70 29 3b 0a 20 20 73 71  (zFmt, ap);.  sq
1890: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72  lite3_result_err
18a0: 6f 72 28 63 74 78 2c 20 7a 4d 73 67 2c 20 2d 31  or(ctx, zMsg, -1
18b0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65  );.  sqlite3_fre
18c0: 65 28 7a 4d 73 67 29 3b 0a 20 20 76 61 5f 65 6e  e(zMsg);.  va_en
18d0: 64 28 61 70 29 3b 0a 7d 0a 0a 23 69 66 20 64 65  d(ap);.}..#if de
18e0: 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 2f 2a  fined(_WIN32)./*
18f0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
1900: 6e 20 69 73 20 64 65 73 69 67 6e 65 64 20 74 6f  n is designed to
1910: 20 63 6f 6e 76 65 72 74 20 61 20 57 69 6e 33 32   convert a Win32
1920: 20 46 49 4c 45 54 49 4d 45 20 73 74 72 75 63 74   FILETIME struct
1930: 75 72 65 20 69 6e 74 6f 20 74 68 65 0a 2a 2a 20  ure into the.** 
1940: 6e 75 6d 62 65 72 20 6f 66 20 73 65 63 6f 6e 64  number of second
1950: 73 20 73 69 6e 63 65 20 74 68 65 20 55 6e 69 78  s since the Unix
1960: 20 45 70 6f 63 68 20 28 31 39 37 30 2d 30 31 2d   Epoch (1970-01-
1970: 30 31 20 30 30 3a 30 30 3a 30 30 20 55 54 43 29  01 00:00:00 UTC)
1980: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69  ..*/.static sqli
1990: 74 65 33 5f 75 69 6e 74 36 34 20 66 69 6c 65 54  te3_uint64 fileT
19a0: 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 0a 20  imeToUnixTime(. 
19b0: 20 4c 50 46 49 4c 45 54 49 4d 45 20 70 46 69 6c   LPFILETIME pFil
19c0: 65 54 69 6d 65 0a 29 7b 0a 20 20 53 59 53 54 45  eTime.){.  SYSTE
19d0: 4d 54 49 4d 45 20 65 70 6f 63 68 53 79 73 74 65  MTIME epochSyste
19e0: 6d 54 69 6d 65 3b 0a 20 20 55 4c 41 52 47 45 5f  mTime;.  ULARGE_
19f0: 49 4e 54 45 47 45 52 20 65 70 6f 63 68 49 6e 74  INTEGER epochInt
1a00: 65 72 76 61 6c 73 3b 0a 20 20 46 49 4c 45 54 49  ervals;.  FILETI
1a10: 4d 45 20 65 70 6f 63 68 46 69 6c 65 54 69 6d 65  ME epochFileTime
1a20: 3b 0a 20 20 55 4c 41 52 47 45 5f 49 4e 54 45 47  ;.  ULARGE_INTEG
1a30: 45 52 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73  ER fileIntervals
1a40: 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 65 70 6f  ;..  memset(&epo
1a50: 63 68 53 79 73 74 65 6d 54 69 6d 65 2c 20 30 2c  chSystemTime, 0,
1a60: 20 73 69 7a 65 6f 66 28 53 59 53 54 45 4d 54 49   sizeof(SYSTEMTI
1a70: 4d 45 29 29 3b 0a 20 20 65 70 6f 63 68 53 79 73  ME));.  epochSys
1a80: 74 65 6d 54 69 6d 65 2e 77 59 65 61 72 20 3d 20  temTime.wYear = 
1a90: 31 39 37 30 3b 0a 20 20 65 70 6f 63 68 53 79 73  1970;.  epochSys
1aa0: 74 65 6d 54 69 6d 65 2e 77 4d 6f 6e 74 68 20 3d  temTime.wMonth =
1ab0: 20 31 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 65   1;.  epochSyste
1ac0: 6d 54 69 6d 65 2e 77 44 61 79 20 3d 20 31 3b 0a  mTime.wDay = 1;.
1ad0: 20 20 53 79 73 74 65 6d 54 69 6d 65 54 6f 46 69    SystemTimeToFi
1ae0: 6c 65 54 69 6d 65 28 26 65 70 6f 63 68 53 79 73  leTime(&epochSys
1af0: 74 65 6d 54 69 6d 65 2c 20 26 65 70 6f 63 68 46  temTime, &epochF
1b00: 69 6c 65 54 69 6d 65 29 3b 0a 20 20 65 70 6f 63  ileTime);.  epoc
1b10: 68 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50 61  hIntervals.LowPa
1b20: 72 74 20 3d 20 65 70 6f 63 68 46 69 6c 65 54 69  rt = epochFileTi
1b30: 6d 65 2e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65  me.dwLowDateTime
1b40: 3b 0a 20 20 65 70 6f 63 68 49 6e 74 65 72 76 61  ;.  epochInterva
1b50: 6c 73 2e 48 69 67 68 50 61 72 74 20 3d 20 65 70  ls.HighPart = ep
1b60: 6f 63 68 46 69 6c 65 54 69 6d 65 2e 64 77 48 69  ochFileTime.dwHi
1b70: 67 68 44 61 74 65 54 69 6d 65 3b 0a 0a 20 20 66  ghDateTime;..  f
1b80: 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77  ileIntervals.Low
1b90: 50 61 72 74 20 3d 20 70 46 69 6c 65 54 69 6d 65  Part = pFileTime
1ba0: 2d 3e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b  ->dwLowDateTime;
1bb0: 0a 20 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73  .  fileIntervals
1bc0: 2e 48 69 67 68 50 61 72 74 20 3d 20 70 46 69 6c  .HighPart = pFil
1bd0: 65 54 69 6d 65 2d 3e 64 77 48 69 67 68 44 61 74  eTime->dwHighDat
1be0: 65 54 69 6d 65 3b 0a 0a 20 20 72 65 74 75 72 6e  eTime;..  return
1bf0: 20 28 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e   (fileIntervals.
1c00: 51 75 61 64 50 61 72 74 20 2d 20 65 70 6f 63 68  QuadPart - epoch
1c10: 49 6e 74 65 72 76 61 6c 73 2e 51 75 61 64 50 61  Intervals.QuadPa
1c20: 72 74 29 20 2f 20 31 30 30 30 30 30 30 30 3b 0a  rt) / 10000000;.
1c30: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75  }../*.** This fu
1c40: 6e 63 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20  nction attempts 
1c50: 74 6f 20 6e 6f 72 6d 61 6c 69 7a 65 20 74 68 65  to normalize the
1c60: 20 74 69 6d 65 20 76 61 6c 75 65 73 20 66 6f 75   time values fou
1c70: 6e 64 20 69 6e 20 74 68 65 20 73 74 61 74 28 29  nd in the stat()
1c80: 0a 2a 2a 20 62 75 66 66 65 72 20 74 6f 20 55 54  .** buffer to UT
1c90: 43 2e 20 20 54 68 69 73 20 69 73 20 6e 65 63 65  C.  This is nece
1ca0: 73 73 61 72 79 20 6f 6e 20 57 69 6e 33 32 2c 20  ssary on Win32, 
1cb0: 77 68 65 72 65 20 74 68 65 20 72 75 6e 74 69 6d  where the runtim
1cc0: 65 20 6c 69 62 72 61 72 79 0a 2a 2a 20 61 70 70  e library.** app
1cd0: 65 61 72 73 20 74 6f 20 72 65 74 75 72 6e 20 74  ears to return t
1ce0: 68 65 73 65 20 76 61 6c 75 65 73 20 61 73 20 6c  hese values as l
1cf0: 6f 63 61 6c 20 74 69 6d 65 73 2e 0a 2a 2f 0a 73  ocal times..*/.s
1d00: 74 61 74 69 63 20 76 6f 69 64 20 73 74 61 74 54  tatic void statT
1d10: 69 6d 65 73 54 6f 55 74 63 28 0a 20 20 63 6f 6e  imesToUtc(.  con
1d20: 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 0a  st char *zPath,.
1d30: 20 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 70    struct stat *p
1d40: 53 74 61 74 42 75 66 0a 29 7b 0a 20 20 48 41 4e  StatBuf.){.  HAN
1d50: 44 4c 45 20 68 46 69 6e 64 46 69 6c 65 3b 0a 20  DLE hFindFile;. 
1d60: 20 57 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41   WIN32_FIND_DATA
1d70: 57 20 66 64 3b 0a 20 20 4c 50 57 53 54 52 20 7a  W fd;.  LPWSTR z
1d80: 55 6e 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20 65  UnicodeName;.  e
1d90: 78 74 65 72 6e 20 4c 50 57 53 54 52 20 73 71 6c  xtern LPWSTR sql
1da0: 69 74 65 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f  ite3_win32_utf8_
1db0: 74 6f 5f 75 6e 69 63 6f 64 65 28 63 6f 6e 73 74  to_unicode(const
1dc0: 20 63 68 61 72 2a 29 3b 0a 20 20 7a 55 6e 69 63   char*);.  zUnic
1dd0: 6f 64 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65  odeName = sqlite
1de0: 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f  3_win32_utf8_to_
1df0: 75 6e 69 63 6f 64 65 28 7a 50 61 74 68 29 3b 0a  unicode(zPath);.
1e00: 20 20 69 66 28 20 7a 55 6e 69 63 6f 64 65 4e 61    if( zUnicodeNa
1e10: 6d 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74  me ){.    memset
1e20: 28 26 66 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28  (&fd, 0, sizeof(
1e30: 57 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41 57  WIN32_FIND_DATAW
1e40: 29 29 3b 0a 20 20 20 20 68 46 69 6e 64 46 69 6c  ));.    hFindFil
1e50: 65 20 3d 20 46 69 6e 64 46 69 72 73 74 46 69 6c  e = FindFirstFil
1e60: 65 57 28 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 2c  eW(zUnicodeName,
1e70: 20 26 66 64 29 3b 0a 20 20 20 20 69 66 28 20 68   &fd);.    if( h
1e80: 46 69 6e 64 46 69 6c 65 21 3d 4e 55 4c 4c 20 29  FindFile!=NULL )
1e90: 7b 0a 20 20 20 20 20 20 70 53 74 61 74 42 75 66  {.      pStatBuf
1ea0: 2d 3e 73 74 5f 63 74 69 6d 65 20 3d 20 28 74 69  ->st_ctime = (ti
1eb0: 6d 65 5f 74 29 66 69 6c 65 54 69 6d 65 54 6f 55  me_t)fileTimeToU
1ec0: 6e 69 78 54 69 6d 65 28 26 66 64 2e 66 74 43 72  nixTime(&fd.ftCr
1ed0: 65 61 74 69 6f 6e 54 69 6d 65 29 3b 0a 20 20 20  eationTime);.   
1ee0: 20 20 20 70 53 74 61 74 42 75 66 2d 3e 73 74 5f     pStatBuf->st_
1ef0: 61 74 69 6d 65 20 3d 20 28 74 69 6d 65 5f 74 29  atime = (time_t)
1f00: 66 69 6c 65 54 69 6d 65 54 6f 55 6e 69 78 54 69  fileTimeToUnixTi
1f10: 6d 65 28 26 66 64 2e 66 74 4c 61 73 74 41 63 63  me(&fd.ftLastAcc
1f20: 65 73 73 54 69 6d 65 29 3b 0a 20 20 20 20 20 20  essTime);.      
1f30: 70 53 74 61 74 42 75 66 2d 3e 73 74 5f 6d 74 69  pStatBuf->st_mti
1f40: 6d 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 69 6c  me = (time_t)fil
1f50: 65 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28  eTimeToUnixTime(
1f60: 26 66 64 2e 66 74 4c 61 73 74 57 72 69 74 65 54  &fd.ftLastWriteT
1f70: 69 6d 65 29 3b 0a 20 20 20 20 20 20 46 69 6e 64  ime);.      Find
1f80: 43 6c 6f 73 65 28 68 46 69 6e 64 46 69 6c 65 29  Close(hFindFile)
1f90: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69  ;.    }.    sqli
1fa0: 74 65 33 5f 66 72 65 65 28 7a 55 6e 69 63 6f 64  te3_free(zUnicod
1fb0: 65 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 23 65  eName);.  }.}.#e
1fc0: 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  ndif../*.** This
1fd0: 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65   function is use
1fe0: 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 73 74  d in place of st
1ff0: 61 74 28 29 2e 20 20 4f 6e 20 57 69 6e 64 6f 77  at().  On Window
2000: 73 2c 20 73 70 65 63 69 61 6c 20 68 61 6e 64 6c  s, special handl
2010: 69 6e 67 0a 2a 2a 20 69 73 20 72 65 71 75 69 72  ing.** is requir
2020: 65 64 20 69 6e 20 6f 72 64 65 72 20 66 6f 72 20  ed in order for 
2030: 74 68 65 20 69 6e 63 6c 75 64 65 64 20 74 69 6d  the included tim
2040: 65 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64  e to be returned
2050: 20 61 73 20 55 54 43 2e 20 20 4f 6e 20 61 6c 6c   as UTC.  On all
2060: 0a 2a 2a 20 6f 74 68 65 72 20 73 79 73 74 65 6d  .** other system
2070: 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e  s, this function
2080: 20 73 69 6d 70 6c 79 20 63 61 6c 6c 73 20 73 74   simply calls st
2090: 61 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  at()..*/.static 
20a0: 69 6e 74 20 66 69 6c 65 53 74 61 74 28 0a 20 20  int fileStat(.  
20b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74  const char *zPat
20c0: 68 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74  h,.  struct stat
20d0: 20 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69   *pStatBuf.){.#i
20e0: 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32  f defined(_WIN32
20f0: 29 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 74 61  ).  int rc = sta
2100: 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75  t(zPath, pStatBu
2110: 66 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30 20  f);.  if( rc==0 
2120: 29 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63  ) statTimesToUtc
2130: 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66  (zPath, pStatBuf
2140: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
2150: 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20 73  #else.  return s
2160: 74 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74  tat(zPath, pStat
2170: 42 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a  Buf);.#endif.}..
2180: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
2190: 69 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 20 70  ion is used in p
21a0: 6c 61 63 65 20 6f 66 20 6c 73 74 61 74 28 29 2e  lace of lstat().
21b0: 20 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 73 70    On Windows, sp
21c0: 65 63 69 61 6c 20 68 61 6e 64 6c 69 6e 67 0a 2a  ecial handling.*
21d0: 2a 20 69 73 20 72 65 71 75 69 72 65 64 20 69 6e  * is required in
21e0: 20 6f 72 64 65 72 20 66 6f 72 20 74 68 65 20 69   order for the i
21f0: 6e 63 6c 75 64 65 64 20 74 69 6d 65 20 74 6f 20  ncluded time to 
2200: 62 65 20 72 65 74 75 72 6e 65 64 20 61 73 20 55  be returned as U
2210: 54 43 2e 20 20 4f 6e 20 61 6c 6c 0a 2a 2a 20 6f  TC.  On all.** o
2220: 74 68 65 72 20 73 79 73 74 65 6d 73 2c 20 74 68  ther systems, th
2230: 69 73 20 66 75 6e 63 74 69 6f 6e 20 73 69 6d 70  is function simp
2240: 6c 79 20 63 61 6c 6c 73 20 6c 73 74 61 74 28 29  ly calls lstat()
2250: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2260: 66 69 6c 65 4c 69 6e 6b 53 74 61 74 28 0a 20 20  fileLinkStat(.  
2270: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74  const char *zPat
2280: 68 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74  h,.  struct stat
2290: 20 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69   *pStatBuf.){.#i
22a0: 66 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32  f defined(_WIN32
22b0: 29 0a 20 20 69 6e 74 20 72 63 20 3d 20 6c 73 74  ).  int rc = lst
22c0: 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42  at(zPath, pStatB
22d0: 75 66 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30  uf);.  if( rc==0
22e0: 20 29 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74   ) statTimesToUt
22f0: 63 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75  c(zPath, pStatBu
2300: 66 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  f);.  return rc;
2310: 0a 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20  .#else.  return 
2320: 6c 73 74 61 74 28 7a 50 61 74 68 2c 20 70 53 74  lstat(zPath, pSt
2330: 61 74 42 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d  atBuf);.#endif.}
2340: 0a 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74  ../*.** Argument
2350: 20 7a 46 69 6c 65 20 69 73 20 74 68 65 20 6e 61   zFile is the na
2360: 6d 65 20 6f 66 20 61 20 66 69 6c 65 20 74 68 61  me of a file tha
2370: 74 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65  t will be create
2380: 64 20 61 6e 64 2f 6f 72 20 77 72 69 74 74 65 6e  d and/or written
2390: 0a 2a 2a 20 62 79 20 53 51 4c 20 66 75 6e 63 74  .** by SQL funct
23a0: 69 6f 6e 20 77 72 69 74 65 66 69 6c 65 28 29 2e  ion writefile().
23b0: 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65   This function e
23c0: 6e 73 75 72 65 73 20 74 68 61 74 20 74 68 65 20  nsures that the 
23d0: 64 69 72 65 63 74 6f 72 79 0a 2a 2a 20 7a 46 69  directory.** zFi
23e0: 6c 65 20 77 69 6c 6c 20 62 65 20 77 72 69 74 74  le will be writt
23f0: 65 6e 20 74 6f 20 65 78 69 73 74 73 2c 20 63 72  en to exists, cr
2400: 65 61 74 69 6e 67 20 69 74 20 69 66 20 72 65 71  eating it if req
2410: 75 69 72 65 64 2e 20 54 68 65 20 70 65 72 6d 69  uired. The permi
2420: 73 73 69 6f 6e 73 0a 2a 2a 20 66 6f 72 20 61 6e  ssions.** for an
2430: 79 20 70 61 74 68 20 63 6f 6d 70 6f 6e 65 6e 74  y path component
2440: 73 20 63 72 65 61 74 65 64 20 62 79 20 74 68 69  s created by thi
2450: 73 20 66 75 6e 63 74 69 6f 6e 20 61 72 65 20 73  s function are s
2460: 65 74 20 74 6f 20 28 6d 6f 64 65 26 30 37 37 37  et to (mode&0777
2470: 29 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 61 6e 20 4f  )..**.** If an O
2480: 4f 4d 20 63 6f 6e 64 69 74 69 6f 6e 20 69 73 20  OM condition is 
2490: 65 6e 63 6f 75 6e 74 65 72 65 64 2c 20 53 51 4c  encountered, SQL
24a0: 49 54 45 5f 4e 4f 4d 45 4d 20 69 73 20 72 65 74  ITE_NOMEM is ret
24b0: 75 72 6e 65 64 2e 20 4f 74 68 65 72 77 69 73 65  urned. Otherwise
24c0: 2c 0a 2a 2a 20 53 51 4c 49 54 45 5f 4f 4b 20 69  ,.** SQLITE_OK i
24d0: 73 20 72 65 74 75 72 6e 65 64 20 69 66 20 74 68  s returned if th
24e0: 65 20 64 69 72 65 63 74 6f 72 79 20 69 73 20 73  e directory is s
24f0: 75 63 63 65 73 73 66 75 6c 6c 79 20 63 72 65 61  uccessfully crea
2500: 74 65 64 2c 20 6f 72 0a 2a 2a 20 53 51 4c 49 54  ted, or.** SQLIT
2510: 45 5f 45 52 52 4f 52 20 6f 74 68 65 72 77 69 73  E_ERROR otherwis
2520: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
2530: 20 6d 61 6b 65 44 69 72 65 63 74 6f 72 79 28 0a   makeDirectory(.
2540: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46    const char *zF
2550: 69 6c 65 2c 0a 20 20 6d 6f 64 65 5f 74 20 6d 6f  ile,.  mode_t mo
2560: 64 65 0a 29 7b 0a 20 20 63 68 61 72 20 2a 7a 43  de.){.  char *zC
2570: 6f 70 79 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  opy = sqlite3_mp
2580: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 46 69 6c  rintf("%s", zFil
2590: 65 29 3b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53  e);.  int rc = S
25a0: 51 4c 49 54 45 5f 4f 4b 3b 0a 0a 20 20 69 66 28  QLITE_OK;..  if(
25b0: 20 7a 43 6f 70 79 3d 3d 30 20 29 7b 0a 20 20 20   zCopy==0 ){.   
25c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4e 4f 4d   rc = SQLITE_NOM
25d0: 45 4d 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  EM;.  }else{.   
25e0: 20 69 6e 74 20 6e 43 6f 70 79 20 3d 20 28 69 6e   int nCopy = (in
25f0: 74 29 73 74 72 6c 65 6e 28 7a 43 6f 70 79 29 3b  t)strlen(zCopy);
2600: 0a 20 20 20 20 69 6e 74 20 69 20 3d 20 31 3b 0a  .    int i = 1;.
2610: 0a 20 20 20 20 77 68 69 6c 65 28 20 72 63 3d 3d  .    while( rc==
2620: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
2630: 20 20 20 73 74 72 75 63 74 20 73 74 61 74 20 73     struct stat s
2640: 53 74 61 74 3b 0a 20 20 20 20 20 20 69 6e 74 20  Stat;.      int 
2650: 72 63 32 3b 0a 0a 20 20 20 20 20 20 66 6f 72 28  rc2;..      for(
2660: 3b 20 7a 43 6f 70 79 5b 69 5d 21 3d 27 2f 27 20  ; zCopy[i]!='/' 
2670: 26 26 20 69 3c 6e 43 6f 70 79 3b 20 69 2b 2b 29  && i<nCopy; i++)
2680: 3b 0a 20 20 20 20 20 20 69 66 28 20 69 3d 3d 6e  ;.      if( i==n
2690: 43 6f 70 79 20 29 20 62 72 65 61 6b 3b 0a 20 20  Copy ) break;.  
26a0: 20 20 20 20 7a 43 6f 70 79 5b 69 5d 20 3d 20 27      zCopy[i] = '
26b0: 5c 30 27 3b 0a 0a 20 20 20 20 20 20 72 63 32 20  \0';..      rc2 
26c0: 3d 20 66 69 6c 65 53 74 61 74 28 7a 43 6f 70 79  = fileStat(zCopy
26d0: 2c 20 26 73 53 74 61 74 29 3b 0a 20 20 20 20 20  , &sStat);.     
26e0: 20 69 66 28 20 72 63 32 21 3d 30 20 29 7b 0a 20   if( rc2!=0 ){. 
26f0: 20 20 20 20 20 20 20 69 66 28 20 6d 6b 64 69 72         if( mkdir
2700: 28 7a 43 6f 70 79 2c 20 6d 6f 64 65 20 26 20 30  (zCopy, mode & 0
2710: 37 37 37 29 20 29 20 72 63 20 3d 20 53 51 4c 49  777) ) rc = SQLI
2720: 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 20 20  TE_ERROR;.      
2730: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 69  }else{.        i
2740: 66 28 20 21 53 5f 49 53 44 49 52 28 73 53 74 61  f( !S_ISDIR(sSta
2750: 74 2e 73 74 5f 6d 6f 64 65 29 20 29 20 72 63 20  t.st_mode) ) rc 
2760: 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  = SQLITE_ERROR;.
2770: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 43        }.      zC
2780: 6f 70 79 5b 69 5d 20 3d 20 27 2f 27 3b 0a 20 20  opy[i] = '/';.  
2790: 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d 0a 0a      i++;.    }..
27a0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
27b0: 28 7a 43 6f 70 79 29 3b 0a 20 20 7d 0a 0a 20 20  (zCopy);.  }..  
27c0: 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a  return rc;.}../*
27d0: 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f  .** This functio
27e0: 6e 20 64 6f 65 73 20 74 68 65 20 77 6f 72 6b 20  n does the work 
27f0: 66 6f 72 20 74 68 65 20 77 72 69 74 65 66 69 6c  for the writefil
2800: 65 28 29 20 55 44 46 2e 20 52 65 66 65 72 20 74  e() UDF. Refer t
2810: 6f 20 0a 2a 2a 20 68 65 61 64 65 72 20 63 6f 6d  o .** header com
2820: 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f 70  ments at the top
2830: 20 6f 66 20 74 68 69 73 20 66 69 6c 65 20 66 6f   of this file fo
2840: 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74  r details..*/.st
2850: 61 74 69 63 20 69 6e 74 20 77 72 69 74 65 46 69  atic int writeFi
2860: 6c 65 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f  le(.  sqlite3_co
2870: 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20 20 20  ntext *pCtx,    
2880: 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 78 74        /* Context
2890: 20 74 6f 20 72 65 74 75 72 6e 20 62 79 74 65 73   to return bytes
28a0: 20 77 72 69 74 74 65 6e 20 69 6e 20 2a 2f 0a 20   written in */. 
28b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69   const char *zFi
28c0: 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  le,             
28d0: 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72 69 74   /* File to writ
28e0: 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 76  e */.  sqlite3_v
28f0: 61 6c 75 65 20 2a 70 44 61 74 61 2c 20 20 20 20  alue *pData,    
2900: 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61 20 74         /* Data t
2910: 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 6d 6f 64  o write */.  mod
2920: 65 5f 74 20 6d 6f 64 65 2c 20 20 20 20 20 20 20  e_t mode,       
2930: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
2940: 4d 4f 44 45 20 70 61 72 61 6d 65 74 65 72 20 70  MODE parameter p
2950: 61 73 73 65 64 20 74 6f 20 77 72 69 74 65 66 69  assed to writefi
2960: 6c 65 28 29 20 2a 2f 0a 20 20 73 71 6c 69 74 65  le() */.  sqlite
2970: 33 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20 20 20  3_int64 mtime   
2980: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d 54 49            /* MTI
2990: 4d 45 20 70 61 72 61 6d 65 74 65 72 20 28 6f 72  ME parameter (or
29a0: 20 2d 31 20 74 6f 20 6e 6f 74 20 73 65 74 20 74   -1 to not set t
29b0: 69 6d 65 29 20 2a 2f 0a 29 7b 0a 23 69 66 20 21  ime) */.){.#if !
29c0: 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29 20  defined(_WIN32) 
29d0: 26 26 20 21 64 65 66 69 6e 65 64 28 57 49 4e 33  && !defined(WIN3
29e0: 32 29 0a 20 20 69 66 28 20 53 5f 49 53 4c 4e 4b  2).  if( S_ISLNK
29f0: 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20 63 6f  (mode) ){.    co
2a00: 6e 73 74 20 63 68 61 72 20 2a 7a 54 6f 20 3d 20  nst char *zTo = 
2a10: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
2a20: 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28  ite3_value_text(
2a30: 70 44 61 74 61 29 3b 0a 20 20 20 20 69 66 28 20  pData);.    if( 
2a40: 73 79 6d 6c 69 6e 6b 28 7a 54 6f 2c 20 7a 46 69  symlink(zTo, zFi
2a50: 6c 65 29 3c 30 20 29 20 72 65 74 75 72 6e 20 31  le)<0 ) return 1
2a60: 3b 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64 69 66  ;.  }else.#endif
2a70: 0a 20 20 7b 0a 20 20 20 20 69 66 28 20 53 5f 49  .  {.    if( S_I
2a80: 53 44 49 52 28 6d 6f 64 65 29 20 29 7b 0a 20 20  SDIR(mode) ){.  
2a90: 20 20 20 20 69 66 28 20 6d 6b 64 69 72 28 7a 46      if( mkdir(zF
2aa0: 69 6c 65 2c 20 6d 6f 64 65 29 20 29 7b 0a 20 20  ile, mode) ){.  
2ab0: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6d 6b 64        /* The mkd
2ac0: 69 72 28 29 20 63 61 6c 6c 20 74 6f 20 63 72 65  ir() call to cre
2ad0: 61 74 65 20 74 68 65 20 64 69 72 65 63 74 6f 72  ate the director
2ae0: 79 20 66 61 69 6c 65 64 2e 20 54 68 69 73 20 6d  y failed. This m
2af0: 69 67 68 74 20 6e 6f 74 0a 20 20 20 20 20 20 20  ight not.       
2b00: 20 2a 2a 20 62 65 20 61 6e 20 65 72 72 6f 72 20   ** be an error 
2b10: 74 68 6f 75 67 68 20 2d 20 69 66 20 74 68 65 72  though - if ther
2b20: 65 20 69 73 20 61 6c 72 65 61 64 79 20 61 20 64  e is already a d
2b30: 69 72 65 63 74 6f 72 79 20 61 74 20 74 68 65 20  irectory at the 
2b40: 73 61 6d 65 0a 20 20 20 20 20 20 20 20 2a 2a 20  same.        ** 
2b50: 70 61 74 68 20 61 6e 64 20 65 69 74 68 65 72 20  path and either 
2b60: 74 68 65 20 70 65 72 6d 69 73 73 69 6f 6e 73 20  the permissions 
2b70: 61 6c 72 65 61 64 79 20 6d 61 74 63 68 20 6f 72  already match or
2b80: 20 63 61 6e 20 62 65 20 63 68 61 6e 67 65 64 0a   can be changed.
2b90: 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 20 64 6f          ** to do
2ba0: 20 73 6f 20 75 73 69 6e 67 20 63 68 6d 6f 64 28   so using chmod(
2bb0: 29 2c 20 69 74 20 69 73 20 6e 6f 74 20 61 6e 20  ), it is not an 
2bc0: 65 72 72 6f 72 2e 20 20 2a 2f 0a 20 20 20 20 20  error.  */.     
2bd0: 20 20 20 73 74 72 75 63 74 20 73 74 61 74 20 73     struct stat s
2be0: 53 74 61 74 3b 0a 20 20 20 20 20 20 20 20 69 66  Stat;.        if
2bf0: 28 20 65 72 72 6e 6f 21 3d 45 45 58 49 53 54 0a  ( errno!=EEXIST.
2c00: 20 20 20 20 20 20 20 20 20 7c 7c 20 30 21 3d 66           || 0!=f
2c10: 69 6c 65 53 74 61 74 28 7a 46 69 6c 65 2c 20 26  ileStat(zFile, &
2c20: 73 53 74 61 74 29 0a 20 20 20 20 20 20 20 20 20  sStat).         
2c30: 7c 7c 20 21 53 5f 49 53 44 49 52 28 73 53 74 61  || !S_ISDIR(sSta
2c40: 74 2e 73 74 5f 6d 6f 64 65 29 0a 20 20 20 20 20  t.st_mode).     
2c50: 20 20 20 20 7c 7c 20 28 28 73 53 74 61 74 2e 73      || ((sStat.s
2c60: 74 5f 6d 6f 64 65 26 30 37 37 37 29 21 3d 28 6d  t_mode&0777)!=(m
2c70: 6f 64 65 26 30 37 37 37 29 20 26 26 20 30 21 3d  ode&0777) && 0!=
2c80: 63 68 6d 6f 64 28 7a 46 69 6c 65 2c 20 6d 6f 64  chmod(zFile, mod
2c90: 65 26 30 37 37 37 29 29 0a 20 20 20 20 20 20 20  e&0777)).       
2ca0: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 72 65   ){.          re
2cb0: 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20 20 20  turn 1;.        
2cc0: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65  }.      }.    }e
2cd0: 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c 69 74  lse{.      sqlit
2ce0: 65 33 5f 69 6e 74 36 34 20 6e 57 72 69 74 65 20  e3_int64 nWrite 
2cf0: 3d 20 30 3b 0a 20 20 20 20 20 20 63 6f 6e 73 74  = 0;.      const
2d00: 20 63 68 61 72 20 2a 7a 3b 0a 20 20 20 20 20 20   char *z;.      
2d10: 69 6e 74 20 72 63 20 3d 20 30 3b 0a 20 20 20 20  int rc = 0;.    
2d20: 20 20 46 49 4c 45 20 2a 6f 75 74 20 3d 20 66 6f    FILE *out = fo
2d30: 70 65 6e 28 7a 46 69 6c 65 2c 20 22 77 62 22 29  pen(zFile, "wb")
2d40: 3b 0a 20 20 20 20 20 20 69 66 28 20 6f 75 74 3d  ;.      if( out=
2d50: 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  =0 ) return 1;. 
2d60: 20 20 20 20 20 7a 20 3d 20 28 63 6f 6e 73 74 20       z = (const 
2d70: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
2d80: 6c 75 65 5f 62 6c 6f 62 28 70 44 61 74 61 29 3b  lue_blob(pData);
2d90: 0a 20 20 20 20 20 20 69 66 28 20 7a 20 29 7b 0a  .      if( z ){.
2da0: 20 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f          sqlite3_
2db0: 69 6e 74 36 34 20 6e 20 3d 20 66 77 72 69 74 65  int64 n = fwrite
2dc0: 28 7a 2c 20 31 2c 20 73 71 6c 69 74 65 33 5f 76  (z, 1, sqlite3_v
2dd0: 61 6c 75 65 5f 62 79 74 65 73 28 70 44 61 74 61  alue_bytes(pData
2de0: 29 2c 20 6f 75 74 29 3b 0a 20 20 20 20 20 20 20  ), out);.       
2df0: 20 6e 57 72 69 74 65 20 3d 20 73 71 6c 69 74 65   nWrite = sqlite
2e00: 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 44  3_value_bytes(pD
2e10: 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ata);.        if
2e20: 28 20 6e 57 72 69 74 65 21 3d 6e 20 29 7b 0a 20  ( nWrite!=n ){. 
2e30: 20 20 20 20 20 20 20 20 20 72 63 20 3d 20 31 3b           rc = 1;
2e40: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
2e50: 20 7d 0a 20 20 20 20 20 20 66 63 6c 6f 73 65 28   }.      fclose(
2e60: 6f 75 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  out);.      if( 
2e70: 72 63 3d 3d 30 20 26 26 20 6d 6f 64 65 20 26 26  rc==0 && mode &&
2e80: 20 63 68 6d 6f 64 28 7a 46 69 6c 65 2c 20 6d 6f   chmod(zFile, mo
2e90: 64 65 20 26 20 30 37 37 37 29 20 29 7b 0a 20 20  de & 0777) ){.  
2ea0: 20 20 20 20 20 20 72 63 20 3d 20 31 3b 0a 20 20        rc = 1;.  
2eb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
2ec0: 72 63 20 29 20 72 65 74 75 72 6e 20 32 3b 0a 20  rc ) return 2;. 
2ed0: 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73       sqlite3_res
2ee0: 75 6c 74 5f 69 6e 74 36 34 28 70 43 74 78 2c 20  ult_int64(pCtx, 
2ef0: 6e 57 72 69 74 65 29 3b 0a 20 20 20 20 7d 0a 20  nWrite);.    }. 
2f00: 20 7d 0a 0a 20 20 69 66 28 20 6d 74 69 6d 65 3e   }..  if( mtime>
2f10: 3d 30 20 29 7b 0a 23 69 66 20 64 65 66 69 6e 65  =0 ){.#if define
2f20: 64 28 5f 57 49 4e 33 32 29 0a 20 20 20 20 2f 2a  d(_WIN32).    /*
2f30: 20 57 69 6e 64 6f 77 73 20 2a 2f 0a 20 20 20 20   Windows */.    
2f40: 46 49 4c 45 54 49 4d 45 20 6c 61 73 74 41 63 63  FILETIME lastAcc
2f50: 65 73 73 3b 0a 20 20 20 20 46 49 4c 45 54 49 4d  ess;.    FILETIM
2f60: 45 20 6c 61 73 74 57 72 69 74 65 3b 0a 20 20 20  E lastWrite;.   
2f70: 20 53 59 53 54 45 4d 54 49 4d 45 20 63 75 72 72   SYSTEMTIME curr
2f80: 65 6e 74 54 69 6d 65 3b 0a 20 20 20 20 4c 4f 4e  entTime;.    LON
2f90: 47 4c 4f 4e 47 20 69 6e 74 65 72 76 61 6c 73 3b  GLONG intervals;
2fa0: 0a 20 20 20 20 48 41 4e 44 4c 45 20 68 46 69 6c  .    HANDLE hFil
2fb0: 65 3b 0a 20 20 20 20 4c 50 57 53 54 52 20 7a 55  e;.    LPWSTR zU
2fc0: 6e 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20 20 20  nicodeName;.    
2fd0: 65 78 74 65 72 6e 20 4c 50 57 53 54 52 20 73 71  extern LPWSTR sq
2fe0: 6c 69 74 65 33 5f 77 69 6e 33 32 5f 75 74 66 38  lite3_win32_utf8
2ff0: 5f 74 6f 5f 75 6e 69 63 6f 64 65 28 63 6f 6e 73  _to_unicode(cons
3000: 74 20 63 68 61 72 2a 29 3b 0a 0a 20 20 20 20 47  t char*);..    G
3010: 65 74 53 79 73 74 65 6d 54 69 6d 65 28 26 63 75  etSystemTime(&cu
3020: 72 72 65 6e 74 54 69 6d 65 29 3b 0a 20 20 20 20  rrentTime);.    
3030: 53 79 73 74 65 6d 54 69 6d 65 54 6f 46 69 6c 65  SystemTimeToFile
3040: 54 69 6d 65 28 26 63 75 72 72 65 6e 74 54 69 6d  Time(&currentTim
3050: 65 2c 20 26 6c 61 73 74 41 63 63 65 73 73 29 3b  e, &lastAccess);
3060: 0a 20 20 20 20 69 6e 74 65 72 76 61 6c 73 20 3d  .    intervals =
3070: 20 49 6e 74 33 32 78 33 32 54 6f 36 34 28 6d 74   Int32x32To64(mt
3080: 69 6d 65 2c 20 31 30 30 30 30 30 30 30 29 20 2b  ime, 10000000) +
3090: 20 31 31 36 34 34 34 37 33 36 30 30 30 30 30 30   116444736000000
30a0: 30 30 30 3b 0a 20 20 20 20 6c 61 73 74 57 72 69  000;.    lastWri
30b0: 74 65 2e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65  te.dwLowDateTime
30c0: 20 3d 20 28 44 57 4f 52 44 29 69 6e 74 65 72 76   = (DWORD)interv
30d0: 61 6c 73 3b 0a 20 20 20 20 6c 61 73 74 57 72 69  als;.    lastWri
30e0: 74 65 2e 64 77 48 69 67 68 44 61 74 65 54 69 6d  te.dwHighDateTim
30f0: 65 20 3d 20 69 6e 74 65 72 76 61 6c 73 20 3e 3e  e = intervals >>
3100: 20 33 32 3b 0a 20 20 20 20 7a 55 6e 69 63 6f 64   32;.    zUnicod
3110: 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f  eName = sqlite3_
3120: 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75 6e  win32_utf8_to_un
3130: 69 63 6f 64 65 28 7a 46 69 6c 65 29 3b 0a 20 20  icode(zFile);.  
3140: 20 20 69 66 28 20 7a 55 6e 69 63 6f 64 65 4e 61    if( zUnicodeNa
3150: 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 72  me==0 ){.      r
3160: 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 20  eturn 1;.    }. 
3170: 20 20 20 68 46 69 6c 65 20 3d 20 43 72 65 61 74     hFile = Creat
3180: 65 46 69 6c 65 57 28 0a 20 20 20 20 20 20 7a 55  eFileW(.      zU
3190: 6e 69 63 6f 64 65 4e 61 6d 65 2c 20 46 49 4c 45  nicodeName, FILE
31a0: 5f 57 52 49 54 45 5f 41 54 54 52 49 42 55 54 45  _WRITE_ATTRIBUTE
31b0: 53 2c 20 30 2c 20 4e 55 4c 4c 2c 20 4f 50 45 4e  S, 0, NULL, OPEN
31c0: 5f 45 58 49 53 54 49 4e 47 2c 0a 20 20 20 20 20  _EXISTING,.     
31d0: 20 46 49 4c 45 5f 46 4c 41 47 5f 42 41 43 4b 55   FILE_FLAG_BACKU
31e0: 50 5f 53 45 4d 41 4e 54 49 43 53 2c 20 4e 55 4c  P_SEMANTICS, NUL
31f0: 4c 0a 20 20 20 20 29 3b 0a 20 20 20 20 73 71 6c  L.    );.    sql
3200: 69 74 65 33 5f 66 72 65 65 28 7a 55 6e 69 63 6f  ite3_free(zUnico
3210: 64 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28  deName);.    if(
3220: 20 68 46 69 6c 65 21 3d 49 4e 56 41 4c 49 44 5f   hFile!=INVALID_
3230: 48 41 4e 44 4c 45 5f 56 41 4c 55 45 20 29 7b 0a  HANDLE_VALUE ){.
3240: 20 20 20 20 20 20 42 4f 4f 4c 20 62 52 65 73 75        BOOL bResu
3250: 6c 74 20 3d 20 53 65 74 46 69 6c 65 54 69 6d 65  lt = SetFileTime
3260: 28 68 46 69 6c 65 2c 20 4e 55 4c 4c 2c 20 26 6c  (hFile, NULL, &l
3270: 61 73 74 41 63 63 65 73 73 2c 20 26 6c 61 73 74  astAccess, &last
3280: 57 72 69 74 65 29 3b 0a 20 20 20 20 20 20 43 6c  Write);.      Cl
3290: 6f 73 65 48 61 6e 64 6c 65 28 68 46 69 6c 65 29  oseHandle(hFile)
32a0: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 21  ;.      return !
32b0: 62 52 65 73 75 6c 74 3b 0a 20 20 20 20 7d 65 6c  bResult;.    }el
32c0: 73 65 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  se{.      return
32d0: 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6c 69 66 20   1;.    }.#elif 
32e0: 64 65 66 69 6e 65 64 28 41 54 5f 46 44 43 57 44  defined(AT_FDCWD
32f0: 29 20 26 26 20 30 20 2f 2a 20 75 74 69 6d 65 6e  ) && 0 /* utimen
3300: 73 61 74 28 29 20 69 73 20 6e 6f 74 20 75 6e 69  sat() is not uni
3310: 76 65 72 73 61 6c 6c 79 20 61 76 61 69 6c 61 62  versally availab
3320: 6c 65 20 2a 2f 0a 20 20 20 20 2f 2a 20 52 65 63  le */.    /* Rec
3330: 65 6e 74 20 75 6e 69 78 20 2a 2f 0a 20 20 20 20  ent unix */.    
3340: 73 74 72 75 63 74 20 74 69 6d 65 73 70 65 63 20  struct timespec 
3350: 74 69 6d 65 73 5b 32 5d 3b 0a 20 20 20 20 74 69  times[2];.    ti
3360: 6d 65 73 5b 30 5d 2e 74 76 5f 6e 73 65 63 20 3d  mes[0].tv_nsec =
3370: 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 6e 73 65   times[1].tv_nse
3380: 63 20 3d 20 30 3b 0a 20 20 20 20 74 69 6d 65 73  c = 0;.    times
3390: 5b 30 5d 2e 74 76 5f 73 65 63 20 3d 20 74 69 6d  [0].tv_sec = tim
33a0: 65 28 30 29 3b 0a 20 20 20 20 74 69 6d 65 73 5b  e(0);.    times[
33b0: 31 5d 2e 74 76 5f 73 65 63 20 3d 20 6d 74 69 6d  1].tv_sec = mtim
33c0: 65 3b 0a 20 20 20 20 69 66 28 20 75 74 69 6d 65  e;.    if( utime
33d0: 6e 73 61 74 28 41 54 5f 46 44 43 57 44 2c 20 7a  nsat(AT_FDCWD, z
33e0: 46 69 6c 65 2c 20 74 69 6d 65 73 2c 20 41 54 5f  File, times, AT_
33f0: 53 59 4d 4c 49 4e 4b 5f 4e 4f 46 4f 4c 4c 4f 57  SYMLINK_NOFOLLOW
3400: 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72  ) ){.      retur
3410: 6e 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6c 73 65  n 1;.    }.#else
3420: 0a 20 20 20 20 2f 2a 20 4c 65 67 61 63 79 20 75  .    /* Legacy u
3430: 6e 69 78 20 2a 2f 0a 20 20 20 20 73 74 72 75 63  nix */.    struc
3440: 74 20 74 69 6d 65 76 61 6c 20 74 69 6d 65 73 5b  t timeval times[
3450: 32 5d 3b 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d  2];.    times[0]
3460: 2e 74 76 5f 75 73 65 63 20 3d 20 74 69 6d 65 73  .tv_usec = times
3470: 5b 31 5d 2e 74 76 5f 75 73 65 63 20 3d 20 30 3b  [1].tv_usec = 0;
3480: 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e 74 76  .    times[0].tv
3490: 5f 73 65 63 20 3d 20 74 69 6d 65 28 30 29 3b 0a  _sec = time(0);.
34a0: 20 20 20 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f      times[1].tv_
34b0: 73 65 63 20 3d 20 6d 74 69 6d 65 3b 0a 20 20 20  sec = mtime;.   
34c0: 20 69 66 28 20 75 74 69 6d 65 73 28 7a 46 69 6c   if( utimes(zFil
34d0: 65 2c 20 74 69 6d 65 73 29 20 29 7b 0a 20 20 20  e, times) ){.   
34e0: 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20     return 1;.   
34f0: 20 7d 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 0a 20   }.#endif.  }.. 
3500: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a   return 0;.}../*
3510: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69  .** Implementati
3520: 6f 6e 20 6f 66 20 74 68 65 20 22 77 72 69 74 65  on of the "write
3530: 66 69 6c 65 28 57 2c 58 5b 2c 59 5b 2c 5a 5d 5d  file(W,X[,Y[,Z]]
3540: 5d 29 22 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e  ])" SQL function
3550: 2e 20 20 0a 2a 2a 20 52 65 66 65 72 20 74 6f 20  .  .** Refer to 
3560: 68 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74 73 20  header comments 
3570: 61 74 20 74 68 65 20 74 6f 70 20 6f 66 20 74 68  at the top of th
3580: 69 73 20 66 69 6c 65 20 66 6f 72 20 64 65 74 61  is file for deta
3590: 69 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ils..*/.static v
35a0: 6f 69 64 20 77 72 69 74 65 66 69 6c 65 46 75 6e  oid writefileFun
35b0: 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e  c(.  sqlite3_con
35c0: 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20  text *context,. 
35d0: 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c   int argc,.  sql
35e0: 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67  ite3_value **arg
35f0: 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  v.){.  const cha
3600: 72 20 2a 7a 46 69 6c 65 3b 0a 20 20 6d 6f 64 65  r *zFile;.  mode
3610: 5f 74 20 6d 6f 64 65 20 3d 20 30 3b 0a 20 20 69  _t mode = 0;.  i
3620: 6e 74 20 72 65 73 3b 0a 20 20 73 71 6c 69 74 65  nt res;.  sqlite
3630: 33 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20 3d 20  3_int64 mtime = 
3640: 2d 31 3b 0a 0a 20 20 69 66 28 20 61 72 67 63 3c  -1;..  if( argc<
3650: 32 20 7c 7c 20 61 72 67 63 3e 34 20 29 7b 0a 20  2 || argc>4 ){. 
3660: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
3670: 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78 74 2c  t_error(context,
3680: 20 0a 20 20 20 20 20 20 20 20 22 77 72 6f 6e 67   .        "wrong
3690: 20 6e 75 6d 62 65 72 20 6f 66 20 61 72 67 75 6d   number of argum
36a0: 65 6e 74 73 20 74 6f 20 66 75 6e 63 74 69 6f 6e  ents to function
36b0: 20 77 72 69 74 65 66 69 6c 65 28 29 22 2c 20 2d   writefile()", -
36c0: 31 0a 20 20 20 20 29 3b 0a 20 20 20 20 72 65 74  1.    );.    ret
36d0: 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 7a 46 69 6c  urn;.  }..  zFil
36e0: 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a  e = (const char*
36f0: 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74  )sqlite3_value_t
3700: 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  ext(argv[0]);.  
3710: 69 66 28 20 7a 46 69 6c 65 3d 3d 30 20 29 20 72  if( zFile==0 ) r
3720: 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 61 72 67  eturn;.  if( arg
3730: 63 3e 3d 33 20 29 7b 0a 20 20 20 20 6d 6f 64 65  c>=3 ){.    mode
3740: 20 3d 20 28 6d 6f 64 65 5f 74 29 73 71 6c 69 74   = (mode_t)sqlit
3750: 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67  e3_value_int(arg
3760: 76 5b 32 5d 29 3b 0a 20 20 7d 0a 20 20 69 66 28  v[2]);.  }.  if(
3770: 20 61 72 67 63 3d 3d 34 20 29 7b 0a 20 20 20 20   argc==4 ){.    
3780: 6d 74 69 6d 65 20 3d 20 73 71 6c 69 74 65 33 5f  mtime = sqlite3_
3790: 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 72 67 76  value_int64(argv
37a0: 5b 33 5d 29 3b 0a 20 20 7d 0a 0a 20 20 72 65 73  [3]);.  }..  res
37b0: 20 3d 20 77 72 69 74 65 46 69 6c 65 28 63 6f 6e   = writeFile(con
37c0: 74 65 78 74 2c 20 7a 46 69 6c 65 2c 20 61 72 67  text, zFile, arg
37d0: 76 5b 31 5d 2c 20 6d 6f 64 65 2c 20 6d 74 69 6d  v[1], mode, mtim
37e0: 65 29 3b 0a 20 20 69 66 28 20 72 65 73 3d 3d 31  e);.  if( res==1
37f0: 20 26 26 20 65 72 72 6e 6f 3d 3d 45 4e 4f 45 4e   && errno==ENOEN
3800: 54 20 29 7b 0a 20 20 20 20 69 66 28 20 6d 61 6b  T ){.    if( mak
3810: 65 44 69 72 65 63 74 6f 72 79 28 7a 46 69 6c 65  eDirectory(zFile
3820: 2c 20 6d 6f 64 65 29 3d 3d 53 51 4c 49 54 45 5f  , mode)==SQLITE_
3830: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 72 65 73 20  OK ){.      res 
3840: 3d 20 77 72 69 74 65 46 69 6c 65 28 63 6f 6e 74  = writeFile(cont
3850: 65 78 74 2c 20 7a 46 69 6c 65 2c 20 61 72 67 76  ext, zFile, argv
3860: 5b 31 5d 2c 20 6d 6f 64 65 2c 20 6d 74 69 6d 65  [1], mode, mtime
3870: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  );.    }.  }..  
3880: 69 66 28 20 61 72 67 63 3e 32 20 26 26 20 72 65  if( argc>2 && re
3890: 73 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  s!=0 ){.    if( 
38a0: 53 5f 49 53 4c 4e 4b 28 6d 6f 64 65 29 20 29 7b  S_ISLNK(mode) ){
38b0: 0a 20 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d  .      ctxErrorM
38c0: 73 67 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69  sg(context, "fai
38d0: 6c 65 64 20 74 6f 20 63 72 65 61 74 65 20 73 79  led to create sy
38e0: 6d 6c 69 6e 6b 3a 20 25 73 22 2c 20 7a 46 69 6c  mlink: %s", zFil
38f0: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  e);.    }else if
3900: 28 20 53 5f 49 53 44 49 52 28 6d 6f 64 65 29 20  ( S_ISDIR(mode) 
3910: 29 7b 0a 20 20 20 20 20 20 63 74 78 45 72 72 6f  ){.      ctxErro
3920: 72 4d 73 67 28 63 6f 6e 74 65 78 74 2c 20 22 66  rMsg(context, "f
3930: 61 69 6c 65 64 20 74 6f 20 63 72 65 61 74 65 20  ailed to create 
3940: 64 69 72 65 63 74 6f 72 79 3a 20 25 73 22 2c 20  directory: %s", 
3950: 7a 46 69 6c 65 29 3b 0a 20 20 20 20 7d 65 6c 73  zFile);.    }els
3960: 65 7b 0a 20 20 20 20 20 20 63 74 78 45 72 72 6f  e{.      ctxErro
3970: 72 4d 73 67 28 63 6f 6e 74 65 78 74 2c 20 22 66  rMsg(context, "f
3980: 61 69 6c 65 64 20 74 6f 20 77 72 69 74 65 20 66  ailed to write f
3990: 69 6c 65 3a 20 25 73 22 2c 20 7a 46 69 6c 65 29  ile: %s", zFile)
39a0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f  ;.    }.  }.}../
39b0: 2a 0a 2a 2a 20 53 51 4c 20 66 75 6e 63 74 69 6f  *.** SQL functio
39c0: 6e 3a 20 20 20 6c 73 6d 6f 64 65 28 4d 4f 44 45  n:   lsmode(MODE
39d0: 29 0a 2a 2a 0a 2a 2a 20 47 69 76 65 6e 20 61 20  ).**.** Given a 
39e0: 6e 75 6d 62 65 72 69 63 20 73 74 5f 6d 6f 64 65  numberic st_mode
39f0: 20 66 72 6f 6d 20 73 74 61 74 28 29 2c 20 63 6f   from stat(), co
3a00: 6e 76 65 72 74 20 69 74 20 69 6e 74 6f 20 61 20  nvert it into a 
3a10: 68 75 6d 61 6e 2d 72 65 61 64 61 62 6c 65 0a 2a  human-readable.*
3a20: 2a 20 74 65 78 74 20 73 74 72 69 6e 67 20 69 6e  * text string in
3a30: 20 74 68 65 20 73 74 79 6c 65 20 6f 66 20 22 6c   the style of "l
3a40: 73 20 2d 6c 22 2e 0a 2a 2f 0a 73 74 61 74 69 63  s -l"..*/.static
3a50: 20 76 6f 69 64 20 6c 73 4d 6f 64 65 46 75 6e 63   void lsModeFunc
3a60: 28 0a 20 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74  (.  sqlite3_cont
3a70: 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c 0a 20 20  ext *context,.  
3a80: 69 6e 74 20 61 72 67 63 2c 0a 20 20 73 71 6c 69  int argc,.  sqli
3a90: 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61 72 67 76  te3_value **argv
3aa0: 0a 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69  .){.  int i;.  i
3ab0: 6e 74 20 69 4d 6f 64 65 20 3d 20 73 71 6c 69 74  nt iMode = sqlit
3ac0: 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61 72 67  e3_value_int(arg
3ad0: 76 5b 30 5d 29 3b 0a 20 20 63 68 61 72 20 7a 5b  v[0]);.  char z[
3ae0: 31 36 5d 3b 0a 20 20 28 76 6f 69 64 29 61 72 67  16];.  (void)arg
3af0: 63 3b 0a 20 20 69 66 28 20 53 5f 49 53 4c 4e 4b  c;.  if( S_ISLNK
3b00: 28 69 4d 6f 64 65 29 20 29 7b 0a 20 20 20 20 7a  (iMode) ){.    z
3b10: 5b 30 5d 20 3d 20 27 6c 27 3b 0a 20 20 7d 65 6c  [0] = 'l';.  }el
3b20: 73 65 20 69 66 28 20 53 5f 49 53 52 45 47 28 69  se if( S_ISREG(i
3b30: 4d 6f 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30  Mode) ){.    z[0
3b40: 5d 20 3d 20 27 2d 27 3b 0a 20 20 7d 65 6c 73 65  ] = '-';.  }else
3b50: 20 69 66 28 20 53 5f 49 53 44 49 52 28 69 4d 6f   if( S_ISDIR(iMo
3b60: 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20  de) ){.    z[0] 
3b70: 3d 20 27 64 27 3b 0a 20 20 7d 65 6c 73 65 7b 0a  = 'd';.  }else{.
3b80: 20 20 20 20 7a 5b 30 5d 20 3d 20 27 3f 27 3b 0a      z[0] = '?';.
3b90: 20 20 7d 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69    }.  for(i=0; i
3ba0: 3c 33 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 6e  <3; i++){.    in
3bb0: 74 20 6d 20 3d 20 28 69 4d 6f 64 65 20 3e 3e 20  t m = (iMode >> 
3bc0: 28 28 32 2d 69 29 2a 33 29 29 3b 0a 20 20 20 20  ((2-i)*3));.    
3bd0: 63 68 61 72 20 2a 61 20 3d 20 26 7a 5b 31 20 2b  char *a = &z[1 +
3be0: 20 69 2a 33 5d 3b 0a 20 20 20 20 61 5b 30 5d 20   i*3];.    a[0] 
3bf0: 3d 20 28 6d 20 26 20 30 78 34 29 20 3f 20 27 72  = (m & 0x4) ? 'r
3c00: 27 20 3a 20 27 2d 27 3b 0a 20 20 20 20 61 5b 31  ' : '-';.    a[1
3c10: 5d 20 3d 20 28 6d 20 26 20 30 78 32 29 20 3f 20  ] = (m & 0x2) ? 
3c20: 27 77 27 20 3a 20 27 2d 27 3b 0a 20 20 20 20 61  'w' : '-';.    a
3c30: 5b 32 5d 20 3d 20 28 6d 20 26 20 30 78 31 29 20  [2] = (m & 0x1) 
3c40: 3f 20 27 78 27 20 3a 20 27 2d 27 3b 0a 20 20 7d  ? 'x' : '-';.  }
3c50: 0a 20 20 7a 5b 31 30 5d 20 3d 20 27 5c 30 27 3b  .  z[10] = '\0';
3c60: 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c  .  sqlite3_resul
3c70: 74 5f 74 65 78 74 28 63 6f 6e 74 65 78 74 2c 20  t_text(context, 
3c80: 7a 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52  z, -1, SQLITE_TR
3c90: 41 4e 53 49 45 4e 54 29 3b 0a 7d 0a 0a 23 69 66  ANSIENT);.}..#if
3ca0: 6e 64 65 66 20 53 51 4c 49 54 45 5f 4f 4d 49 54  ndef SQLITE_OMIT
3cb0: 5f 56 49 52 54 55 41 4c 54 41 42 4c 45 0a 0a 2f  _VIRTUALTABLE../
3cc0: 2a 20 0a 2a 2a 20 43 75 72 73 6f 72 20 74 79 70  * .** Cursor typ
3cd0: 65 20 66 6f 72 20 72 65 63 75 72 73 69 76 65 6c  e for recursivel
3ce0: 79 20 69 74 65 72 61 74 69 6e 67 20 74 68 72 6f  y iterating thro
3cf0: 75 67 68 20 61 20 64 69 72 65 63 74 6f 72 79 20  ugh a directory 
3d00: 73 74 72 75 63 74 75 72 65 2e 0a 2a 2f 0a 74 79  structure..*/.ty
3d10: 70 65 64 65 66 20 73 74 72 75 63 74 20 66 73 64  pedef struct fsd
3d20: 69 72 5f 63 75 72 73 6f 72 20 66 73 64 69 72 5f  ir_cursor fsdir_
3d30: 63 75 72 73 6f 72 3b 0a 74 79 70 65 64 65 66 20  cursor;.typedef 
3d40: 73 74 72 75 63 74 20 46 73 64 69 72 4c 65 76 65  struct FsdirLeve
3d50: 6c 20 46 73 64 69 72 4c 65 76 65 6c 3b 0a 0a 73  l FsdirLevel;..s
3d60: 74 72 75 63 74 20 46 73 64 69 72 4c 65 76 65 6c  truct FsdirLevel
3d70: 20 7b 0a 20 20 44 49 52 20 2a 70 44 69 72 3b 20   {.  DIR *pDir; 
3d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3d90: 2f 2a 20 46 72 6f 6d 20 6f 70 65 6e 64 69 72 28  /* From opendir(
3da0: 29 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 44 69  ) */.  char *zDi
3db0: 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  r;              
3dc0: 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 64 69 72    /* Name of dir
3dd0: 65 63 74 6f 72 79 20 28 6e 75 6c 2d 74 65 72 6d  ectory (nul-term
3de0: 69 6e 61 74 65 64 29 20 2a 2f 0a 7d 3b 0a 0a 73  inated) */.};..s
3df0: 74 72 75 63 74 20 66 73 64 69 72 5f 63 75 72 73  truct fsdir_curs
3e00: 6f 72 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76  or {.  sqlite3_v
3e10: 74 61 62 5f 63 75 72 73 6f 72 20 62 61 73 65 3b  tab_cursor base;
3e20: 20 20 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20    /* Base class 
3e30: 2d 20 6d 75 73 74 20 62 65 20 66 69 72 73 74 20  - must be first 
3e40: 2a 2f 0a 0a 20 20 69 6e 74 20 6e 4c 76 6c 3b 20  */..  int nLvl; 
3e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3e60: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 65 6e   /* Number of en
3e70: 74 72 69 65 73 20 69 6e 20 61 4c 76 6c 5b 5d 20  tries in aLvl[] 
3e80: 61 72 72 61 79 20 2a 2f 0a 20 20 69 6e 74 20 69  array */.  int i
3e90: 4c 76 6c 3b 20 20 20 20 20 20 20 20 20 20 20 20  Lvl;            
3ea0: 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 6f        /* Index o
3eb0: 66 20 63 75 72 72 65 6e 74 20 65 6e 74 72 79 20  f current entry 
3ec0: 2a 2f 0a 20 20 46 73 64 69 72 4c 65 76 65 6c 20  */.  FsdirLevel 
3ed0: 2a 61 4c 76 6c 3b 20 20 20 20 20 20 20 20 20 20  *aLvl;          
3ee0: 2f 2a 20 48 69 65 72 61 72 63 68 79 20 6f 66 20  /* Hierarchy of 
3ef0: 64 69 72 65 63 74 6f 72 69 65 73 20 62 65 69 6e  directories bein
3f00: 67 20 74 72 61 76 65 72 73 65 64 20 2a 2f 0a 0a  g traversed */..
3f10: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 42    const char *zB
3f20: 61 73 65 3b 0a 20 20 69 6e 74 20 6e 42 61 73 65  ase;.  int nBase
3f30: 3b 0a 0a 20 20 73 74 72 75 63 74 20 73 74 61 74  ;..  struct stat
3f40: 20 73 53 74 61 74 3b 20 20 20 20 20 20 20 20 20   sStat;         
3f50: 2f 2a 20 43 75 72 72 65 6e 74 20 6c 73 74 61 74  /* Current lstat
3f60: 28 29 20 72 65 73 75 6c 74 73 20 2a 2f 0a 20 20  () results */.  
3f70: 63 68 61 72 20 2a 7a 50 61 74 68 3b 20 20 20 20  char *zPath;    
3f80: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 61             /* Pa
3f90: 74 68 20 74 6f 20 63 75 72 72 65 6e 74 20 65 6e  th to current en
3fa0: 74 72 79 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  try */.  sqlite3
3fb0: 5f 69 6e 74 36 34 20 69 52 6f 77 69 64 3b 20 20  _int64 iRowid;  
3fc0: 20 20 20 20 2f 2a 20 43 75 72 72 65 6e 74 20 72      /* Current r
3fd0: 6f 77 69 64 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65  owid */.};..type
3fe0: 64 65 66 20 73 74 72 75 63 74 20 66 73 64 69 72  def struct fsdir
3ff0: 5f 74 61 62 20 66 73 64 69 72 5f 74 61 62 3b 0a  _tab fsdir_tab;.
4000: 73 74 72 75 63 74 20 66 73 64 69 72 5f 74 61 62  struct fsdir_tab
4010: 20 7b 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61   {.  sqlite3_vta
4020: 62 20 62 61 73 65 3b 20 20 20 20 20 20 20 20 20  b base;         
4030: 2f 2a 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20  /* Base class - 
4040: 6d 75 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f  must be first */
4050: 0a 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74  .};../*.** Const
4060: 72 75 63 74 20 61 20 6e 65 77 20 66 73 64 69 72  ruct a new fsdir
4070: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 20 6f   virtual table o
4080: 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  bject..*/.static
4090: 20 69 6e 74 20 66 73 64 69 72 43 6f 6e 6e 65 63   int fsdirConnec
40a0: 74 28 0a 20 20 73 71 6c 69 74 65 33 20 2a 64 62  t(.  sqlite3 *db
40b0: 2c 0a 20 20 76 6f 69 64 20 2a 70 41 75 78 2c 0a  ,.  void *pAux,.
40c0: 20 20 69 6e 74 20 61 72 67 63 2c 20 63 6f 6e 73    int argc, cons
40d0: 74 20 63 68 61 72 20 2a 63 6f 6e 73 74 2a 61 72  t char *const*ar
40e0: 67 76 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  gv,.  sqlite3_vt
40f0: 61 62 20 2a 2a 70 70 56 74 61 62 2c 0a 20 20 63  ab **ppVtab,.  c
4100: 68 61 72 20 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20  har **pzErr.){. 
4110: 20 66 73 64 69 72 5f 74 61 62 20 2a 70 4e 65 77   fsdir_tab *pNew
4120: 20 3d 20 30 3b 0a 20 20 69 6e 74 20 72 63 3b 0a   = 0;.  int rc;.
4130: 20 20 28 76 6f 69 64 29 70 41 75 78 3b 0a 20 20    (void)pAux;.  
4140: 28 76 6f 69 64 29 61 72 67 63 3b 0a 20 20 28 76  (void)argc;.  (v
4150: 6f 69 64 29 61 72 67 76 3b 0a 20 20 28 76 6f 69  oid)argv;.  (voi
4160: 64 29 70 7a 45 72 72 3b 0a 20 20 72 63 20 3d 20  d)pzErr;.  rc = 
4170: 73 71 6c 69 74 65 33 5f 64 65 63 6c 61 72 65 5f  sqlite3_declare_
4180: 76 74 61 62 28 64 62 2c 20 22 43 52 45 41 54 45  vtab(db, "CREATE
4190: 20 54 41 42 4c 45 20 78 22 20 46 53 44 49 52 5f   TABLE x" FSDIR_
41a0: 53 43 48 45 4d 41 29 3b 0a 20 20 69 66 28 20 72  SCHEMA);.  if( r
41b0: 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a  c==SQLITE_OK ){.
41c0: 20 20 20 20 70 4e 65 77 20 3d 20 28 66 73 64 69      pNew = (fsdi
41d0: 72 5f 74 61 62 2a 29 73 71 6c 69 74 65 33 5f 6d  r_tab*)sqlite3_m
41e0: 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70  alloc( sizeof(*p
41f0: 4e 65 77 29 20 29 3b 0a 20 20 20 20 69 66 28 20  New) );.    if( 
4200: 70 4e 65 77 3d 3d 30 20 29 20 72 65 74 75 72 6e  pNew==0 ) return
4210: 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20   SQLITE_NOMEM;. 
4220: 20 20 20 6d 65 6d 73 65 74 28 70 4e 65 77 2c 20     memset(pNew, 
4230: 30 2c 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29  0, sizeof(*pNew)
4240: 29 3b 0a 20 20 7d 0a 20 20 2a 70 70 56 74 61 62  );.  }.  *ppVtab
4250: 20 3d 20 28 73 71 6c 69 74 65 33 5f 76 74 61 62   = (sqlite3_vtab
4260: 2a 29 70 4e 65 77 3b 0a 20 20 72 65 74 75 72 6e  *)pNew;.  return
4270: 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68   rc;.}../*.** Th
4280: 69 73 20 6d 65 74 68 6f 64 20 69 73 20 74 68 65  is method is the
4290: 20 64 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20   destructor for 
42a0: 66 73 64 69 72 20 76 74 61 62 20 6f 62 6a 65 63  fsdir vtab objec
42b0: 74 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ts..*/.static in
42c0: 74 20 66 73 64 69 72 44 69 73 63 6f 6e 6e 65 63  t fsdirDisconnec
42d0: 74 28 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a  t(sqlite3_vtab *
42e0: 70 56 74 61 62 29 7b 0a 20 20 73 71 6c 69 74 65  pVtab){.  sqlite
42f0: 33 5f 66 72 65 65 28 70 56 74 61 62 29 3b 0a 20  3_free(pVtab);. 
4300: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4310: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73  K;.}../*.** Cons
4320: 74 72 75 63 74 6f 72 20 66 6f 72 20 61 20 6e 65  tructor for a ne
4330: 77 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 6f  w fsdir_cursor o
4340: 62 6a 65 63 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  bject..*/.static
4350: 20 69 6e 74 20 66 73 64 69 72 4f 70 65 6e 28 73   int fsdirOpen(s
4360: 71 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 2c 20  qlite3_vtab *p, 
4370: 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72  sqlite3_vtab_cur
4380: 73 6f 72 20 2a 2a 70 70 43 75 72 73 6f 72 29 7b  sor **ppCursor){
4390: 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20  .  fsdir_cursor 
43a0: 2a 70 43 75 72 3b 0a 20 20 28 76 6f 69 64 29 70  *pCur;.  (void)p
43b0: 3b 0a 20 20 70 43 75 72 20 3d 20 73 71 6c 69 74  ;.  pCur = sqlit
43c0: 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69 7a 65 6f  e3_malloc( sizeo
43d0: 66 28 2a 70 43 75 72 29 20 29 3b 0a 20 20 69 66  f(*pCur) );.  if
43e0: 28 20 70 43 75 72 3d 3d 30 20 29 20 72 65 74 75  ( pCur==0 ) retu
43f0: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
4400: 0a 20 20 6d 65 6d 73 65 74 28 70 43 75 72 2c 20  .  memset(pCur, 
4410: 30 2c 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29  0, sizeof(*pCur)
4420: 29 3b 0a 20 20 70 43 75 72 2d 3e 69 4c 76 6c 20  );.  pCur->iLvl 
4430: 3d 20 2d 31 3b 0a 20 20 2a 70 70 43 75 72 73 6f  = -1;.  *ppCurso
4440: 72 20 3d 20 26 70 43 75 72 2d 3e 62 61 73 65 3b  r = &pCur->base;
4450: 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45  .  return SQLITE
4460: 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  _OK;.}../*.** Re
4470: 73 65 74 20 61 20 63 75 72 73 6f 72 20 62 61 63  set a cursor bac
4480: 6b 20 74 6f 20 74 68 65 20 73 74 61 74 65 20 69  k to the state i
4490: 74 20 77 61 73 20 69 6e 20 77 68 65 6e 20 66 69  t was in when fi
44a0: 72 73 74 20 72 65 74 75 72 6e 65 64 0a 2a 2a 20  rst returned.** 
44b0: 62 79 20 66 73 64 69 72 4f 70 65 6e 28 29 2e 0a  by fsdirOpen()..
44c0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66  */.static void f
44d0: 73 64 69 72 52 65 73 65 74 43 75 72 73 6f 72 28  sdirResetCursor(
44e0: 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43  fsdir_cursor *pC
44f0: 75 72 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  ur){.  int i;.  
4500: 66 6f 72 28 69 3d 30 3b 20 69 3c 3d 70 43 75 72  for(i=0; i<=pCur
4510: 2d 3e 69 4c 76 6c 3b 20 69 2b 2b 29 7b 0a 20 20  ->iLvl; i++){.  
4520: 20 20 46 73 64 69 72 4c 65 76 65 6c 20 2a 70 4c    FsdirLevel *pL
4530: 76 6c 20 3d 20 26 70 43 75 72 2d 3e 61 4c 76 6c  vl = &pCur->aLvl
4540: 5b 69 5d 3b 0a 20 20 20 20 69 66 28 20 70 4c 76  [i];.    if( pLv
4550: 6c 2d 3e 70 44 69 72 20 29 20 63 6c 6f 73 65 64  l->pDir ) closed
4560: 69 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a  ir(pLvl->pDir);.
4570: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
4580: 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20  (pLvl->zDir);.  
4590: 7d 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  }.  sqlite3_free
45a0: 28 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20  (pCur->zPath);. 
45b0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43   sqlite3_free(pC
45c0: 75 72 2d 3e 61 4c 76 6c 29 3b 0a 20 20 70 43 75  ur->aLvl);.  pCu
45d0: 72 2d 3e 61 4c 76 6c 20 3d 20 30 3b 0a 20 20 70  r->aLvl = 0;.  p
45e0: 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 30 3b 0a  Cur->zPath = 0;.
45f0: 20 20 70 43 75 72 2d 3e 7a 42 61 73 65 20 3d 20    pCur->zBase = 
4600: 30 3b 0a 20 20 70 43 75 72 2d 3e 6e 42 61 73 65  0;.  pCur->nBase
4610: 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 6e 4c   = 0;.  pCur->nL
4620: 76 6c 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e  vl = 0;.  pCur->
4630: 69 4c 76 6c 20 3d 20 2d 31 3b 0a 20 20 70 43 75  iLvl = -1;.  pCu
4640: 72 2d 3e 69 52 6f 77 69 64 20 3d 20 31 3b 0a 7d  r->iRowid = 1;.}
4650: 0a 0a 2f 2a 0a 2a 2a 20 44 65 73 74 72 75 63 74  ../*.** Destruct
4660: 6f 72 20 66 6f 72 20 61 6e 20 66 73 64 69 72 5f  or for an fsdir_
4670: 63 75 72 73 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69  cursor..*/.stati
4680: 63 20 69 6e 74 20 66 73 64 69 72 43 6c 6f 73 65  c int fsdirClose
4690: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
46a0: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 73  rsor *cur){.  fs
46b0: 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  dir_cursor *pCur
46c0: 20 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72   = (fsdir_cursor
46d0: 2a 29 63 75 72 3b 0a 0a 20 20 66 73 64 69 72 52  *)cur;..  fsdirR
46e0: 65 73 65 74 43 75 72 73 6f 72 28 70 43 75 72 29  esetCursor(pCur)
46f0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
4700: 28 70 43 75 72 29 3b 0a 20 20 72 65 74 75 72 6e  (pCur);.  return
4710: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
4720: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 65 72 72  *.** Set the err
4730: 6f 72 20 6d 65 73 73 61 67 65 20 66 6f 72 20 74  or message for t
4740: 68 65 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65  he virtual table
4750: 20 61 73 73 6f 63 69 61 74 65 64 20 77 69 74 68   associated with
4760: 20 63 75 72 73 6f 72 0a 2a 2a 20 70 43 75 72 20   cursor.** pCur 
4770: 74 6f 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f  to the results o
4780: 66 20 76 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20  f vprintf(zFmt, 
4790: 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  ...)..*/.static 
47a0: 76 6f 69 64 20 66 73 64 69 72 53 65 74 45 72 72  void fsdirSetErr
47b0: 6d 73 67 28 66 73 64 69 72 5f 63 75 72 73 6f 72  msg(fsdir_cursor
47c0: 20 2a 70 43 75 72 2c 20 63 6f 6e 73 74 20 63 68   *pCur, const ch
47d0: 61 72 20 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a  ar *zFmt, ...){.
47e0: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
47f0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6d  va_start(ap, zFm
4800: 74 29 3b 0a 20 20 70 43 75 72 2d 3e 62 61 73 65  t);.  pCur->base
4810: 2e 70 56 74 61 62 2d 3e 7a 45 72 72 4d 73 67 20  .pVtab->zErrMsg 
4820: 3d 20 73 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e  = sqlite3_vmprin
4830: 74 66 28 7a 46 6d 74 2c 20 61 70 29 3b 0a 20 20  tf(zFmt, ap);.  
4840: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 0a  va_end(ap);.}...
4850: 2f 2a 0a 2a 2a 20 41 64 76 61 6e 63 65 20 61 6e  /*.** Advance an
4860: 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 74 6f   fsdir_cursor to
4870: 20 69 74 73 20 6e 65 78 74 20 72 6f 77 20 6f 66   its next row of
4880: 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74   output..*/.stat
4890: 69 63 20 69 6e 74 20 66 73 64 69 72 4e 65 78 74  ic int fsdirNext
48a0: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
48b0: 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66 73  rsor *cur){.  fs
48c0: 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72  dir_cursor *pCur
48d0: 20 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72   = (fsdir_cursor
48e0: 2a 29 63 75 72 3b 0a 20 20 6d 6f 64 65 5f 74 20  *)cur;.  mode_t 
48f0: 6d 20 3d 20 70 43 75 72 2d 3e 73 53 74 61 74 2e  m = pCur->sStat.
4900: 73 74 5f 6d 6f 64 65 3b 0a 0a 20 20 70 43 75 72  st_mode;..  pCur
4910: 2d 3e 69 52 6f 77 69 64 2b 2b 3b 0a 20 20 69 66  ->iRowid++;.  if
4920: 28 20 53 5f 49 53 44 49 52 28 6d 29 20 29 7b 0a  ( S_ISDIR(m) ){.
4930: 20 20 20 20 2f 2a 20 44 65 73 63 65 6e 64 20 69      /* Descend i
4940: 6e 74 6f 20 74 68 69 73 20 64 69 72 65 63 74 6f  nto this directo
4950: 72 79 20 2a 2f 0a 20 20 20 20 69 6e 74 20 69 4e  ry */.    int iN
4960: 65 77 20 3d 20 70 43 75 72 2d 3e 69 4c 76 6c 20  ew = pCur->iLvl 
4970: 2b 20 31 3b 0a 20 20 20 20 46 73 64 69 72 4c 65  + 1;.    FsdirLe
4980: 76 65 6c 20 2a 70 4c 76 6c 3b 0a 20 20 20 20 69  vel *pLvl;.    i
4990: 66 28 20 69 4e 65 77 3e 3d 70 43 75 72 2d 3e 6e  f( iNew>=pCur->n
49a0: 4c 76 6c 20 29 7b 0a 20 20 20 20 20 20 69 6e 74  Lvl ){.      int
49b0: 20 6e 4e 65 77 20 3d 20 69 4e 65 77 2b 31 3b 0a   nNew = iNew+1;.
49c0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69 6e        sqlite3_in
49d0: 74 36 34 20 6e 42 79 74 65 20 3d 20 6e 4e 65 77  t64 nByte = nNew
49e0: 2a 73 69 7a 65 6f 66 28 46 73 64 69 72 4c 65 76  *sizeof(FsdirLev
49f0: 65 6c 29 3b 0a 20 20 20 20 20 20 46 73 64 69 72  el);.      Fsdir
4a00: 4c 65 76 65 6c 20 2a 61 4e 65 77 20 3d 20 28 46  Level *aNew = (F
4a10: 73 64 69 72 4c 65 76 65 6c 2a 29 73 71 6c 69 74  sdirLevel*)sqlit
4a20: 65 33 5f 72 65 61 6c 6c 6f 63 36 34 28 70 43 75  e3_realloc64(pCu
4a30: 72 2d 3e 61 4c 76 6c 2c 20 6e 42 79 74 65 29 3b  r->aLvl, nByte);
4a40: 0a 20 20 20 20 20 20 69 66 28 20 61 4e 65 77 3d  .      if( aNew=
4a50: 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49  =0 ) return SQLI
4a60: 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20 20  TE_NOMEM;.      
4a70: 6d 65 6d 73 65 74 28 26 61 4e 65 77 5b 70 43 75  memset(&aNew[pCu
4a80: 72 2d 3e 6e 4c 76 6c 5d 2c 20 30 2c 20 73 69 7a  r->nLvl], 0, siz
4a90: 65 6f 66 28 46 73 64 69 72 4c 65 76 65 6c 29 2a  eof(FsdirLevel)*
4aa0: 28 6e 4e 65 77 2d 70 43 75 72 2d 3e 6e 4c 76 6c  (nNew-pCur->nLvl
4ab0: 29 29 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e  ));.      pCur->
4ac0: 61 4c 76 6c 20 3d 20 61 4e 65 77 3b 0a 20 20 20  aLvl = aNew;.   
4ad0: 20 20 20 70 43 75 72 2d 3e 6e 4c 76 6c 20 3d 20     pCur->nLvl = 
4ae0: 6e 4e 65 77 3b 0a 20 20 20 20 7d 0a 20 20 20 20  nNew;.    }.    
4af0: 70 43 75 72 2d 3e 69 4c 76 6c 20 3d 20 69 4e 65  pCur->iLvl = iNe
4b00: 77 3b 0a 20 20 20 20 70 4c 76 6c 20 3d 20 26 70  w;.    pLvl = &p
4b10: 43 75 72 2d 3e 61 4c 76 6c 5b 69 4e 65 77 5d 3b  Cur->aLvl[iNew];
4b20: 0a 20 20 20 20 0a 20 20 20 20 70 4c 76 6c 2d 3e  .    .    pLvl->
4b30: 7a 44 69 72 20 3d 20 70 43 75 72 2d 3e 7a 50 61  zDir = pCur->zPa
4b40: 74 68 3b 0a 20 20 20 20 70 43 75 72 2d 3e 7a 50  th;.    pCur->zP
4b50: 61 74 68 20 3d 20 30 3b 0a 20 20 20 20 70 4c 76  ath = 0;.    pLv
4b60: 6c 2d 3e 70 44 69 72 20 3d 20 6f 70 65 6e 64 69  l->pDir = opendi
4b70: 72 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20  r(pLvl->zDir);. 
4b80: 20 20 20 69 66 28 20 70 4c 76 6c 2d 3e 70 44 69     if( pLvl->pDi
4b90: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 66 73  r==0 ){.      fs
4ba0: 64 69 72 53 65 74 45 72 72 6d 73 67 28 70 43 75  dirSetErrmsg(pCu
4bb0: 72 2c 20 22 63 61 6e 6e 6f 74 20 72 65 61 64 20  r, "cannot read 
4bc0: 64 69 72 65 63 74 6f 72 79 3a 20 25 73 22 2c 20  directory: %s", 
4bd0: 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20  pCur->zPath);.  
4be0: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
4bf0: 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20 7d 0a 20  E_ERROR;.    }. 
4c00: 20 7d 0a 0a 20 20 77 68 69 6c 65 28 20 70 43 75   }..  while( pCu
4c10: 72 2d 3e 69 4c 76 6c 3e 3d 30 20 29 7b 0a 20 20  r->iLvl>=0 ){.  
4c20: 20 20 46 73 64 69 72 4c 65 76 65 6c 20 2a 70 4c    FsdirLevel *pL
4c30: 76 6c 20 3d 20 26 70 43 75 72 2d 3e 61 4c 76 6c  vl = &pCur->aLvl
4c40: 5b 70 43 75 72 2d 3e 69 4c 76 6c 5d 3b 0a 20 20  [pCur->iLvl];.  
4c50: 20 20 73 74 72 75 63 74 20 64 69 72 65 6e 74 20    struct dirent 
4c60: 2a 70 45 6e 74 72 79 20 3d 20 72 65 61 64 64 69  *pEntry = readdi
4c70: 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a 20  r(pLvl->pDir);. 
4c80: 20 20 20 69 66 28 20 70 45 6e 74 72 79 20 29 7b     if( pEntry ){
4c90: 0a 20 20 20 20 20 20 69 66 28 20 70 45 6e 74 72  .      if( pEntr
4ca0: 79 2d 3e 64 5f 6e 61 6d 65 5b 30 5d 3d 3d 27 2e  y->d_name[0]=='.
4cb0: 27 20 29 7b 0a 20 20 20 20 20 20 20 69 66 28 20  ' ){.       if( 
4cc0: 70 45 6e 74 72 79 2d 3e 64 5f 6e 61 6d 65 5b 31  pEntry->d_name[1
4cd0: 5d 3d 3d 27 2e 27 20 26 26 20 70 45 6e 74 72 79  ]=='.' && pEntry
4ce0: 2d 3e 64 5f 6e 61 6d 65 5b 32 5d 3d 3d 27 5c 30  ->d_name[2]=='\0
4cf0: 27 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20  ' ) continue;.  
4d00: 20 20 20 20 20 69 66 28 20 70 45 6e 74 72 79 2d       if( pEntry-
4d10: 3e 64 5f 6e 61 6d 65 5b 31 5d 3d 3d 27 5c 30 27  >d_name[1]=='\0'
4d20: 20 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20   ) continue;.   
4d30: 20 20 20 7d 0a 20 20 20 20 20 20 73 71 6c 69 74     }.      sqlit
4d40: 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a 50  e3_free(pCur->zP
4d50: 61 74 68 29 3b 0a 20 20 20 20 20 20 70 43 75 72  ath);.      pCur
4d60: 2d 3e 7a 50 61 74 68 20 3d 20 73 71 6c 69 74 65  ->zPath = sqlite
4d70: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 2f 25 73  3_mprintf("%s/%s
4d80: 22 2c 20 70 4c 76 6c 2d 3e 7a 44 69 72 2c 20 70  ", pLvl->zDir, p
4d90: 45 6e 74 72 79 2d 3e 64 5f 6e 61 6d 65 29 3b 0a  Entry->d_name);.
4da0: 20 20 20 20 20 20 69 66 28 20 70 43 75 72 2d 3e        if( pCur->
4db0: 7a 50 61 74 68 3d 3d 30 20 29 20 72 65 74 75 72  zPath==0 ) retur
4dc0: 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a  n SQLITE_NOMEM;.
4dd0: 20 20 20 20 20 20 69 66 28 20 66 69 6c 65 4c 69        if( fileLi
4de0: 6e 6b 53 74 61 74 28 70 43 75 72 2d 3e 7a 50 61  nkStat(pCur->zPa
4df0: 74 68 2c 20 26 70 43 75 72 2d 3e 73 53 74 61 74  th, &pCur->sStat
4e00: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 66 73 64  ) ){.        fsd
4e10: 69 72 53 65 74 45 72 72 6d 73 67 28 70 43 75 72  irSetErrmsg(pCur
4e20: 2c 20 22 63 61 6e 6e 6f 74 20 73 74 61 74 20 66  , "cannot stat f
4e30: 69 6c 65 3a 20 25 73 22 2c 20 70 43 75 72 2d 3e  ile: %s", pCur->
4e40: 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20 20 20  zPath);.        
4e50: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
4e60: 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ROR;.      }.   
4e70: 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45     return SQLITE
4e80: 5f 4f 4b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63  _OK;.    }.    c
4e90: 6c 6f 73 65 64 69 72 28 70 4c 76 6c 2d 3e 70 44  losedir(pLvl->pD
4ea0: 69 72 29 3b 0a 20 20 20 20 73 71 6c 69 74 65 33  ir);.    sqlite3
4eb0: 5f 66 72 65 65 28 70 4c 76 6c 2d 3e 7a 44 69 72  _free(pLvl->zDir
4ec0: 29 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 70 44 69  );.    pLvl->pDi
4ed0: 72 20 3d 20 30 3b 0a 20 20 20 20 70 4c 76 6c 2d  r = 0;.    pLvl-
4ee0: 3e 7a 44 69 72 20 3d 20 30 3b 0a 20 20 20 20 70  >zDir = 0;.    p
4ef0: 43 75 72 2d 3e 69 4c 76 6c 2d 2d 3b 0a 20 20 7d  Cur->iLvl--;.  }
4f00: 0a 0a 20 20 2f 2a 20 45 4f 46 20 2a 2f 0a 20 20  ..  /* EOF */.  
4f10: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75  sqlite3_free(pCu
4f20: 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 70 43 75  r->zPath);.  pCu
4f30: 72 2d 3e 7a 50 61 74 68 20 3d 20 30 3b 0a 20 20  r->zPath = 0;.  
4f40: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
4f50: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
4f60: 6e 20 76 61 6c 75 65 73 20 6f 66 20 63 6f 6c 75  n values of colu
4f70: 6d 6e 73 20 66 6f 72 20 74 68 65 20 72 6f 77 20  mns for the row 
4f80: 61 74 20 77 68 69 63 68 20 74 68 65 20 73 65 72  at which the ser
4f90: 69 65 73 5f 63 75 72 73 6f 72 0a 2a 2a 20 69 73  ies_cursor.** is
4fa0: 20 63 75 72 72 65 6e 74 6c 79 20 70 6f 69 6e 74   currently point
4fb0: 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ing..*/.static i
4fc0: 6e 74 20 66 73 64 69 72 43 6f 6c 75 6d 6e 28 0a  nt fsdirColumn(.
4fd0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63    sqlite3_vtab_c
4fe0: 75 72 73 6f 72 20 2a 63 75 72 2c 20 20 20 2f 2a  ursor *cur,   /*
4ff0: 20 54 68 65 20 63 75 72 73 6f 72 20 2a 2f 0a 20   The cursor */. 
5000: 20 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74   sqlite3_context
5010: 20 2a 63 74 78 2c 20 20 20 20 20 20 20 2f 2a 20   *ctx,       /* 
5020: 46 69 72 73 74 20 61 72 67 75 6d 65 6e 74 20 74  First argument t
5030: 6f 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74  o sqlite3_result
5040: 5f 2e 2e 2e 28 29 20 2a 2f 0a 20 20 69 6e 74 20  _...() */.  int 
5050: 69 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  i               
5060: 20 20 20 20 20 20 20 20 2f 2a 20 57 68 69 63 68          /* Which
5070: 20 63 6f 6c 75 6d 6e 20 74 6f 20 72 65 74 75 72   column to retur
5080: 6e 20 2a 2f 0a 29 7b 0a 20 20 66 73 64 69 72 5f  n */.){.  fsdir_
5090: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
50a0: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
50b0: 72 3b 0a 20 20 73 77 69 74 63 68 28 20 69 20 29  r;.  switch( i )
50c0: 7b 0a 20 20 20 20 63 61 73 65 20 46 53 44 49 52  {.    case FSDIR
50d0: 5f 43 4f 4c 55 4d 4e 5f 4e 41 4d 45 3a 20 7b 0a  _COLUMN_NAME: {.
50e0: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65        sqlite3_re
50f0: 73 75 6c 74 5f 74 65 78 74 28 63 74 78 2c 20 26  sult_text(ctx, &
5100: 70 43 75 72 2d 3e 7a 50 61 74 68 5b 70 43 75 72  pCur->zPath[pCur
5110: 2d 3e 6e 42 61 73 65 5d 2c 20 2d 31 2c 20 53 51  ->nBase], -1, SQ
5120: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
5130: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
5140: 20 20 7d 0a 0a 20 20 20 20 63 61 73 65 20 46 53    }..    case FS
5150: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 4f 44 45 3a  DIR_COLUMN_MODE:
5160: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
5170: 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c  esult_int64(ctx,
5180: 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f   pCur->sStat.st_
5190: 6d 6f 64 65 29 3b 0a 20 20 20 20 20 20 62 72 65  mode);.      bre
51a0: 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 53  ak;..    case FS
51b0: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 4d 54 49 4d 45  DIR_COLUMN_MTIME
51c0: 3a 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  :.      sqlite3_
51d0: 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 74 78  result_int64(ctx
51e0: 2c 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74  , pCur->sStat.st
51f0: 5f 6d 74 69 6d 65 29 3b 0a 20 20 20 20 20 20 62  _mtime);.      b
5200: 72 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20  reak;..    case 
5210: 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 41 54  FSDIR_COLUMN_DAT
5220: 41 3a 20 7b 0a 20 20 20 20 20 20 6d 6f 64 65 5f  A: {.      mode_
5230: 74 20 6d 20 3d 20 70 43 75 72 2d 3e 73 53 74 61  t m = pCur->sSta
5240: 74 2e 73 74 5f 6d 6f 64 65 3b 0a 20 20 20 20 20  t.st_mode;.     
5250: 20 69 66 28 20 53 5f 49 53 44 49 52 28 6d 29 20   if( S_ISDIR(m) 
5260: 29 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  ){.        sqlit
5270: 65 33 5f 72 65 73 75 6c 74 5f 6e 75 6c 6c 28 63  e3_result_null(c
5280: 74 78 29 3b 0a 23 69 66 20 21 64 65 66 69 6e 65  tx);.#if !define
5290: 64 28 5f 57 49 4e 33 32 29 20 26 26 20 21 64 65  d(_WIN32) && !de
52a0: 66 69 6e 65 64 28 57 49 4e 33 32 29 0a 20 20 20  fined(WIN32).   
52b0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53 5f 49     }else if( S_I
52c0: 53 4c 4e 4b 28 6d 29 20 29 7b 0a 20 20 20 20 20  SLNK(m) ){.     
52d0: 20 20 20 63 68 61 72 20 61 53 74 61 74 69 63 5b     char aStatic[
52e0: 36 34 5d 3b 0a 20 20 20 20 20 20 20 20 63 68 61  64];.        cha
52f0: 72 20 2a 61 42 75 66 20 3d 20 61 53 74 61 74 69  r *aBuf = aStati
5300: 63 3b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74  c;.        sqlit
5310: 65 33 5f 69 6e 74 36 34 20 6e 42 75 66 20 3d 20  e3_int64 nBuf = 
5320: 36 34 3b 0a 20 20 20 20 20 20 20 20 69 6e 74 20  64;.        int 
5330: 6e 3b 0a 0a 20 20 20 20 20 20 20 20 77 68 69 6c  n;..        whil
5340: 65 28 20 31 20 29 7b 0a 20 20 20 20 20 20 20 20  e( 1 ){.        
5350: 20 20 6e 20 3d 20 72 65 61 64 6c 69 6e 6b 28 70    n = readlink(p
5360: 43 75 72 2d 3e 7a 50 61 74 68 2c 20 61 42 75 66  Cur->zPath, aBuf
5370: 2c 20 6e 42 75 66 29 3b 0a 20 20 20 20 20 20 20  , nBuf);.       
5380: 20 20 20 69 66 28 20 6e 3c 6e 42 75 66 20 29 20     if( n<nBuf ) 
5390: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 20 20 20  break;.         
53a0: 20 69 66 28 20 61 42 75 66 21 3d 61 53 74 61 74   if( aBuf!=aStat
53b0: 69 63 20 29 20 73 71 6c 69 74 65 33 5f 66 72 65  ic ) sqlite3_fre
53c0: 65 28 61 42 75 66 29 3b 0a 20 20 20 20 20 20 20  e(aBuf);.       
53d0: 20 20 20 6e 42 75 66 20 3d 20 6e 42 75 66 2a 32     nBuf = nBuf*2
53e0: 3b 0a 20 20 20 20 20 20 20 20 20 20 61 42 75 66  ;.          aBuf
53f0: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f   = sqlite3_mallo
5400: 63 36 34 28 6e 42 75 66 29 3b 0a 20 20 20 20 20  c64(nBuf);.     
5410: 20 20 20 20 20 69 66 28 20 61 42 75 66 3d 3d 30       if( aBuf==0
5420: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20   ){.            
5430: 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 65  sqlite3_result_e
5440: 72 72 6f 72 5f 6e 6f 6d 65 6d 28 63 74 78 29 3b  rror_nomem(ctx);
5450: 0a 20 20 20 20 20 20 20 20 20 20 20 20 72 65 74  .            ret
5460: 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  urn SQLITE_NOMEM
5470: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
5480: 20 20 20 20 20 20 7d 0a 0a 20 20 20 20 20 20 20        }..       
5490: 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f   sqlite3_result_
54a0: 74 65 78 74 28 63 74 78 2c 20 61 42 75 66 2c 20  text(ctx, aBuf, 
54b0: 6e 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  n, SQLITE_TRANSI
54c0: 45 4e 54 29 3b 0a 20 20 20 20 20 20 20 20 69 66  ENT);.        if
54d0: 28 20 61 42 75 66 21 3d 61 53 74 61 74 69 63 20  ( aBuf!=aStatic 
54e0: 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61  ) sqlite3_free(a
54f0: 42 75 66 29 3b 0a 23 65 6e 64 69 66 0a 20 20 20  Buf);.#endif.   
5500: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5510: 20 20 72 65 61 64 46 69 6c 65 43 6f 6e 74 65 6e    readFileConten
5520: 74 73 28 63 74 78 2c 20 70 43 75 72 2d 3e 7a 50  ts(ctx, pCur->zP
5530: 61 74 68 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20  ath);.      }.  
5540: 20 20 7d 0a 20 20 20 20 63 61 73 65 20 46 53 44    }.    case FSD
5550: 49 52 5f 43 4f 4c 55 4d 4e 5f 50 41 54 48 3a 0a  IR_COLUMN_PATH:.
5560: 20 20 20 20 64 65 66 61 75 6c 74 3a 20 7b 0a 20      default: {. 
5570: 20 20 20 20 20 2f 2a 20 54 68 65 20 46 53 44 49       /* The FSDI
5580: 52 5f 43 4f 4c 55 4d 4e 5f 50 41 54 48 20 61 6e  R_COLUMN_PATH an
5590: 64 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44  d FSDIR_COLUMN_D
55a0: 49 52 20 61 72 65 20 69 6e 70 75 74 20 70 61 72  IR are input par
55b0: 61 6d 65 74 65 72 73 2e 0a 20 20 20 20 20 20 2a  ameters..      *
55c0: 2a 20 61 6c 77 61 79 73 20 72 65 74 75 72 6e 20  * always return 
55d0: 74 68 65 69 72 20 76 61 6c 75 65 73 20 61 73 20  their values as 
55e0: 4e 55 4c 4c 20 2a 2f 0a 20 20 20 20 20 20 62 72  NULL */.      br
55f0: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  eak;.    }.  }. 
5600: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
5610: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  K;.}../*.** Retu
5620: 72 6e 20 74 68 65 20 72 6f 77 69 64 20 66 6f 72  rn the rowid for
5630: 20 74 68 65 20 63 75 72 72 65 6e 74 20 72 6f 77   the current row
5640: 2e 20 49 6e 20 74 68 69 73 20 69 6d 70 6c 65 6d  . In this implem
5650: 65 6e 74 61 74 69 6f 6e 2c 20 74 68 65 0a 2a 2a  entation, the.**
5660: 20 66 69 72 73 74 20 72 6f 77 20 72 65 74 75 72   first row retur
5670: 6e 65 64 20 69 73 20 61 73 73 69 67 6e 65 64 20  ned is assigned 
5680: 72 6f 77 69 64 20 76 61 6c 75 65 20 31 2c 20 61  rowid value 1, a
5690: 6e 64 20 65 61 63 68 20 73 75 62 73 65 71 75 65  nd each subseque
56a0: 6e 74 0a 2a 2a 20 72 6f 77 20 61 20 76 61 6c 75  nt.** row a valu
56b0: 65 20 31 20 6d 6f 72 65 20 74 68 61 6e 20 74 68  e 1 more than th
56c0: 61 74 20 6f 66 20 74 68 65 20 70 72 65 76 69 6f  at of the previo
56d0: 75 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  us..*/.static in
56e0: 74 20 66 73 64 69 72 52 6f 77 69 64 28 73 71 6c  t fsdirRowid(sql
56f0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
5700: 20 2a 63 75 72 2c 20 73 71 6c 69 74 65 5f 69 6e   *cur, sqlite_in
5710: 74 36 34 20 2a 70 52 6f 77 69 64 29 7b 0a 20 20  t64 *pRowid){.  
5720: 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43  fsdir_cursor *pC
5730: 75 72 20 3d 20 28 66 73 64 69 72 5f 63 75 72 73  ur = (fsdir_curs
5740: 6f 72 2a 29 63 75 72 3b 0a 20 20 2a 70 52 6f 77  or*)cur;.  *pRow
5750: 69 64 20 3d 20 70 43 75 72 2d 3e 69 52 6f 77 69  id = pCur->iRowi
5760: 64 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  d;.  return SQLI
5770: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
5780: 52 65 74 75 72 6e 20 54 52 55 45 20 69 66 20 74  Return TRUE if t
5790: 68 65 20 63 75 72 73 6f 72 20 68 61 73 20 62 65  he cursor has be
57a0: 65 6e 20 6d 6f 76 65 64 20 6f 66 66 20 6f 66 20  en moved off of 
57b0: 74 68 65 20 6c 61 73 74 0a 2a 2a 20 72 6f 77 20  the last.** row 
57c0: 6f 66 20 6f 75 74 70 75 74 2e 0a 2a 2f 0a 73 74  of output..*/.st
57d0: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 45 6f  atic int fsdirEo
57e0: 66 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63  f(sqlite3_vtab_c
57f0: 75 72 73 6f 72 20 2a 63 75 72 29 7b 0a 20 20 66  ursor *cur){.  f
5800: 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75  sdir_cursor *pCu
5810: 72 20 3d 20 28 66 73 64 69 72 5f 63 75 72 73 6f  r = (fsdir_curso
5820: 72 2a 29 63 75 72 3b 0a 20 20 72 65 74 75 72 6e  r*)cur;.  return
5830: 20 28 70 43 75 72 2d 3e 7a 50 61 74 68 3d 3d 30   (pCur->zPath==0
5840: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 78 46 69 6c  );.}../*.** xFil
5850: 74 65 72 20 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a  ter callback..**
5860: 0a 2a 2a 20 69 64 78 4e 75 6d 3d 3d 31 20 20 20  .** idxNum==1   
5870: 50 41 54 48 20 70 61 72 61 6d 65 74 65 72 20 6f  PATH parameter o
5880: 6e 6c 79 0a 2a 2a 20 69 64 78 4e 75 6d 3d 3d 32  nly.** idxNum==2
5890: 20 20 20 42 6f 74 68 20 50 41 54 48 20 61 6e 64     Both PATH and
58a0: 20 44 49 52 20 73 75 70 70 6c 69 65 64 0a 2a 2f   DIR supplied.*/
58b0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64 69  .static int fsdi
58c0: 72 46 69 6c 74 65 72 28 0a 20 20 73 71 6c 69 74  rFilter(.  sqlit
58d0: 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a  e3_vtab_cursor *
58e0: 63 75 72 2c 20 0a 20 20 69 6e 74 20 69 64 78 4e  cur, .  int idxN
58f0: 75 6d 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  um, const char *
5900: 69 64 78 53 74 72 2c 0a 20 20 69 6e 74 20 61 72  idxStr,.  int ar
5910: 67 63 2c 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  gc, sqlite3_valu
5920: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 63 6f  e **argv.){.  co
5930: 6e 73 74 20 63 68 61 72 20 2a 7a 44 69 72 20 3d  nst char *zDir =
5940: 20 30 3b 0a 20 20 66 73 64 69 72 5f 63 75 72 73   0;.  fsdir_curs
5950: 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69  or *pCur = (fsdi
5960: 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20  r_cursor*)cur;. 
5970: 20 28 76 6f 69 64 29 69 64 78 53 74 72 3b 0a 20   (void)idxStr;. 
5980: 20 66 73 64 69 72 52 65 73 65 74 43 75 72 73 6f   fsdirResetCurso
5990: 72 28 70 43 75 72 29 3b 0a 0a 20 20 69 66 28 20  r(pCur);..  if( 
59a0: 69 64 78 4e 75 6d 3d 3d 30 20 29 7b 0a 20 20 20  idxNum==0 ){.   
59b0: 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28   fsdirSetErrmsg(
59c0: 70 43 75 72 2c 20 22 74 61 62 6c 65 20 66 75 6e  pCur, "table fun
59d0: 63 74 69 6f 6e 20 66 73 64 69 72 20 72 65 71 75  ction fsdir requ
59e0: 69 72 65 73 20 61 6e 20 61 72 67 75 6d 65 6e 74  ires an argument
59f0: 22 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53  ");.    return S
5a00: 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d  QLITE_ERROR;.  }
5a10: 0a 0a 20 20 61 73 73 65 72 74 28 20 61 72 67 63  ..  assert( argc
5a20: 3d 3d 69 64 78 4e 75 6d 20 26 26 20 28 61 72 67  ==idxNum && (arg
5a30: 63 3d 3d 31 20 7c 7c 20 61 72 67 63 3d 3d 32 29  c==1 || argc==2)
5a40: 20 29 3b 0a 20 20 7a 44 69 72 20 3d 20 28 63 6f   );.  zDir = (co
5a50: 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65  nst char*)sqlite
5a60: 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67  3_value_text(arg
5a70: 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20 7a 44 69  v[0]);.  if( zDi
5a80: 72 3d 3d 30 20 29 7b 0a 20 20 20 20 66 73 64 69  r==0 ){.    fsdi
5a90: 72 53 65 74 45 72 72 6d 73 67 28 70 43 75 72 2c  rSetErrmsg(pCur,
5aa0: 20 22 74 61 62 6c 65 20 66 75 6e 63 74 69 6f 6e   "table function
5ab0: 20 66 73 64 69 72 20 72 65 71 75 69 72 65 73 20   fsdir requires 
5ac0: 61 20 6e 6f 6e 2d 4e 55 4c 4c 20 61 72 67 75 6d  a non-NULL argum
5ad0: 65 6e 74 22 29 3b 0a 20 20 20 20 72 65 74 75 72  ent");.    retur
5ae0: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
5af0: 20 20 7d 0a 20 20 69 66 28 20 61 72 67 63 3d 3d    }.  if( argc==
5b00: 32 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e 7a  2 ){.    pCur->z
5b10: 42 61 73 65 20 3d 20 28 63 6f 6e 73 74 20 63 68  Base = (const ch
5b20: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
5b30: 65 5f 74 65 78 74 28 61 72 67 76 5b 31 5d 29 3b  e_text(argv[1]);
5b40: 0a 20 20 7d 0a 20 20 69 66 28 20 70 43 75 72 2d  .  }.  if( pCur-
5b50: 3e 7a 42 61 73 65 20 29 7b 0a 20 20 20 20 70 43  >zBase ){.    pC
5b60: 75 72 2d 3e 6e 42 61 73 65 20 3d 20 28 69 6e 74  ur->nBase = (int
5b70: 29 73 74 72 6c 65 6e 28 70 43 75 72 2d 3e 7a 42  )strlen(pCur->zB
5b80: 61 73 65 29 2b 31 3b 0a 20 20 20 20 70 43 75 72  ase)+1;.    pCur
5b90: 2d 3e 7a 50 61 74 68 20 3d 20 73 71 6c 69 74 65  ->zPath = sqlite
5ba0: 33 5f 6d 70 72 69 6e 74 66 28 22 25 73 2f 25 73  3_mprintf("%s/%s
5bb0: 22 2c 20 70 43 75 72 2d 3e 7a 42 61 73 65 2c 20  ", pCur->zBase, 
5bc0: 7a 44 69 72 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  zDir);.  }else{.
5bd0: 20 20 20 20 70 43 75 72 2d 3e 7a 50 61 74 68 20      pCur->zPath 
5be0: 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74  = sqlite3_mprint
5bf0: 66 28 22 25 73 22 2c 20 7a 44 69 72 29 3b 0a 20  f("%s", zDir);. 
5c00: 20 7d 0a 0a 20 20 69 66 28 20 70 43 75 72 2d 3e   }..  if( pCur->
5c10: 7a 50 61 74 68 3d 3d 30 20 29 7b 0a 20 20 20 20  zPath==0 ){.    
5c20: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
5c30: 4d 45 4d 3b 0a 20 20 7d 0a 20 20 69 66 28 20 66  MEM;.  }.  if( f
5c40: 69 6c 65 4c 69 6e 6b 53 74 61 74 28 70 43 75 72  ileLinkStat(pCur
5c50: 2d 3e 7a 50 61 74 68 2c 20 26 70 43 75 72 2d 3e  ->zPath, &pCur->
5c60: 73 53 74 61 74 29 20 29 7b 0a 20 20 20 20 66 73  sStat) ){.    fs
5c70: 64 69 72 53 65 74 45 72 72 6d 73 67 28 70 43 75  dirSetErrmsg(pCu
5c80: 72 2c 20 22 63 61 6e 6e 6f 74 20 73 74 61 74 20  r, "cannot stat 
5c90: 66 69 6c 65 3a 20 25 73 22 2c 20 70 43 75 72 2d  file: %s", pCur-
5ca0: 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 72 65 74  >zPath);.    ret
5cb0: 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  urn SQLITE_ERROR
5cc0: 3b 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20  ;.  }..  return 
5cd0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
5ce0: 0a 2a 2a 20 53 51 4c 69 74 65 20 77 69 6c 6c 20  .** SQLite will 
5cf0: 69 6e 76 6f 6b 65 20 74 68 69 73 20 6d 65 74 68  invoke this meth
5d00: 6f 64 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 74  od one or more t
5d10: 69 6d 65 73 20 77 68 69 6c 65 20 70 6c 61 6e 6e  imes while plann
5d20: 69 6e 67 20 61 20 71 75 65 72 79 0a 2a 2a 20 74  ing a query.** t
5d30: 68 61 74 20 75 73 65 73 20 74 68 65 20 67 65 6e  hat uses the gen
5d40: 65 72 61 74 65 5f 73 65 72 69 65 73 20 76 69 72  erate_series vir
5d50: 74 75 61 6c 20 74 61 62 6c 65 2e 20 20 54 68 69  tual table.  Thi
5d60: 73 20 72 6f 75 74 69 6e 65 20 6e 65 65 64 73 20  s routine needs 
5d70: 74 6f 20 63 72 65 61 74 65 0a 2a 2a 20 61 20 71  to create.** a q
5d80: 75 65 72 79 20 70 6c 61 6e 20 66 6f 72 20 65 61  uery plan for ea
5d90: 63 68 20 69 6e 76 6f 63 61 74 69 6f 6e 20 61 6e  ch invocation an
5da0: 64 20 63 6f 6d 70 75 74 65 20 61 6e 20 65 73 74  d compute an est
5db0: 69 6d 61 74 65 64 20 63 6f 73 74 20 66 6f 72 20  imated cost for 
5dc0: 74 68 61 74 0a 2a 2a 20 70 6c 61 6e 2e 0a 2a 2a  that.** plan..**
5dd0: 0a 2a 2a 20 49 6e 20 74 68 69 73 20 69 6d 70 6c  .** In this impl
5de0: 65 6d 65 6e 74 61 74 69 6f 6e 20 69 64 78 4e 75  ementation idxNu
5df0: 6d 20 69 73 20 75 73 65 64 20 74 6f 20 72 65 70  m is used to rep
5e00: 72 65 73 65 6e 74 20 74 68 65 0a 2a 2a 20 71 75  resent the.** qu
5e10: 65 72 79 20 70 6c 61 6e 2e 20 20 69 64 78 53 74  ery plan.  idxSt
5e20: 72 20 69 73 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a  r is unused..**.
5e30: 2a 2a 20 54 68 65 20 71 75 65 72 79 20 70 6c 61  ** The query pla
5e40: 6e 20 69 73 20 72 65 70 72 65 73 65 6e 74 65 64  n is represented
5e50: 20 62 79 20 76 61 6c 75 65 73 20 6f 66 20 69 64   by values of id
5e60: 78 4e 75 6d 3a 0a 2a 2a 0a 2a 2a 20 20 28 31 29  xNum:.**.**  (1)
5e70: 20 20 54 68 65 20 70 61 74 68 20 76 61 6c 75 65    The path value
5e80: 20 69 73 20 73 75 70 70 6c 69 65 64 20 62 79 20   is supplied by 
5e90: 61 72 67 76 5b 30 5d 0a 2a 2a 20 20 28 32 29 20  argv[0].**  (2) 
5ea0: 20 50 61 74 68 20 69 73 20 69 6e 20 61 72 67 76   Path is in argv
5eb0: 5b 30 5d 20 61 6e 64 20 64 69 72 20 69 73 20 69  [0] and dir is i
5ec0: 6e 20 61 72 67 76 5b 31 5d 0a 2a 2f 0a 73 74 61  n argv[1].*/.sta
5ed0: 74 69 63 20 69 6e 74 20 66 73 64 69 72 42 65 73  tic int fsdirBes
5ee0: 74 49 6e 64 65 78 28 0a 20 20 73 71 6c 69 74 65  tIndex(.  sqlite
5ef0: 33 5f 76 74 61 62 20 2a 74 61 62 2c 0a 20 20 73  3_vtab *tab,.  s
5f00: 71 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66  qlite3_index_inf
5f10: 6f 20 2a 70 49 64 78 49 6e 66 6f 0a 29 7b 0a 20  o *pIdxInfo.){. 
5f20: 20 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20   int i;         
5f30: 20 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20          /* Loop 
5f40: 6f 76 65 72 20 63 6f 6e 73 74 72 61 69 6e 74 73  over constraints
5f50: 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78 50 61 74   */.  int idxPat
5f60: 68 20 3d 20 2d 31 3b 20 20 20 20 20 20 2f 2a 20  h = -1;      /* 
5f70: 49 6e 64 65 78 20 69 6e 20 70 49 64 78 49 6e 66  Index in pIdxInf
5f80: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 20 6f  o->aConstraint o
5f90: 66 20 50 41 54 48 3d 20 2a 2f 0a 20 20 69 6e 74  f PATH= */.  int
5fa0: 20 69 64 78 44 69 72 20 3d 20 2d 31 3b 20 20 20   idxDir = -1;   
5fb0: 20 20 20 20 2f 2a 20 49 6e 64 65 78 20 69 6e 20      /* Index in 
5fc0: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
5fd0: 72 61 69 6e 74 20 6f 66 20 44 49 52 3d 20 2a 2f  raint of DIR= */
5fe0: 0a 20 20 69 6e 74 20 73 65 65 6e 50 61 74 68 20  .  int seenPath 
5ff0: 3d 20 30 3b 20 20 20 20 20 20 2f 2a 20 54 72 75  = 0;      /* Tru
6000: 65 20 69 66 20 61 6e 20 75 6e 75 73 61 62 6c 65  e if an unusable
6010: 20 50 41 54 48 3d 20 63 6f 6e 73 74 72 61 69 6e   PATH= constrain
6020: 74 20 69 73 20 73 65 65 6e 20 2a 2f 0a 20 20 69  t is seen */.  i
6030: 6e 74 20 73 65 65 6e 44 69 72 20 3d 20 30 3b 20  nt seenDir = 0; 
6040: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
6050: 20 61 6e 20 75 6e 75 73 61 62 6c 65 20 44 49 52   an unusable DIR
6060: 3d 20 63 6f 6e 73 74 72 61 69 6e 74 20 69 73 20  = constraint is 
6070: 73 65 65 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  seen */.  const 
6080: 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f 69  struct sqlite3_i
6090: 6e 64 65 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20  ndex_constraint 
60a0: 2a 70 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 0a 20  *pConstraint;.. 
60b0: 20 28 76 6f 69 64 29 74 61 62 3b 0a 20 20 70 43   (void)tab;.  pC
60c0: 6f 6e 73 74 72 61 69 6e 74 20 3d 20 70 49 64 78  onstraint = pIdx
60d0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
60e0: 74 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c  t;.  for(i=0; i<
60f0: 70 49 64 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74  pIdxInfo->nConst
6100: 72 61 69 6e 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e  raint; i++, pCon
6110: 73 74 72 61 69 6e 74 2b 2b 29 7b 0a 20 20 20 20  straint++){.    
6120: 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  if( pConstraint-
6130: 3e 6f 70 21 3d 53 51 4c 49 54 45 5f 49 4e 44 45  >op!=SQLITE_INDE
6140: 58 5f 43 4f 4e 53 54 52 41 49 4e 54 5f 45 51 20  X_CONSTRAINT_EQ 
6150: 29 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20  ) continue;.    
6160: 73 77 69 74 63 68 28 20 70 43 6f 6e 73 74 72 61  switch( pConstra
6170: 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 20 29 7b 0a  int->iColumn ){.
6180: 20 20 20 20 20 20 63 61 73 65 20 46 53 44 49 52        case FSDIR
6190: 5f 43 4f 4c 55 4d 4e 5f 50 41 54 48 3a 20 7b 0a  _COLUMN_PATH: {.
61a0: 20 20 20 20 20 20 20 20 69 66 28 20 70 43 6f 6e          if( pCon
61b0: 73 74 72 61 69 6e 74 2d 3e 75 73 61 62 6c 65 20  straint->usable 
61c0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 64 78  ){.          idx
61d0: 50 61 74 68 20 3d 20 69 3b 0a 20 20 20 20 20 20  Path = i;.      
61e0: 20 20 20 20 73 65 65 6e 50 61 74 68 20 3d 20 30      seenPath = 0
61f0: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20  ;.        }else 
6200: 69 66 28 20 69 64 78 50 61 74 68 3c 30 20 29 7b  if( idxPath<0 ){
6210: 0a 20 20 20 20 20 20 20 20 20 20 73 65 65 6e 50  .          seenP
6220: 61 74 68 20 3d 20 31 3b 0a 20 20 20 20 20 20 20  ath = 1;.       
6230: 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b   }.        break
6240: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
6250: 63 61 73 65 20 46 53 44 49 52 5f 43 4f 4c 55 4d  case FSDIR_COLUM
6260: 4e 5f 44 49 52 3a 20 7b 0a 20 20 20 20 20 20 20  N_DIR: {.       
6270: 20 69 66 28 20 70 43 6f 6e 73 74 72 61 69 6e 74   if( pConstraint
6280: 2d 3e 75 73 61 62 6c 65 20 29 7b 0a 20 20 20 20  ->usable ){.    
6290: 20 20 20 20 20 20 69 64 78 44 69 72 20 3d 20 69        idxDir = i
62a0: 3b 0a 20 20 20 20 20 20 20 20 20 20 73 65 65 6e  ;.          seen
62b0: 44 69 72 20 3d 20 30 3b 0a 20 20 20 20 20 20 20  Dir = 0;.       
62c0: 20 7d 65 6c 73 65 20 69 66 28 20 69 64 78 44 69   }else if( idxDi
62d0: 72 3c 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  r<0 ){.         
62e0: 20 73 65 65 6e 44 69 72 20 3d 20 31 3b 0a 20 20   seenDir = 1;.  
62f0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20        }.        
6300: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7d 0a 20  break;.      }. 
6310: 20 20 20 7d 20 0a 20 20 7d 0a 20 20 69 66 28 20     } .  }.  if( 
6320: 73 65 65 6e 50 61 74 68 20 7c 7c 20 73 65 65 6e  seenPath || seen
6330: 44 69 72 20 29 7b 0a 20 20 20 20 2f 2a 20 49 66  Dir ){.    /* If
6340: 20 69 6e 70 75 74 20 70 61 72 61 6d 65 74 65 72   input parameter
6350: 73 20 61 72 65 20 75 6e 75 73 61 62 6c 65 2c 20  s are unusable, 
6360: 64 69 73 61 6c 6c 6f 77 20 74 68 69 73 20 70 6c  disallow this pl
6370: 61 6e 20 2a 2f 0a 20 20 20 20 72 65 74 75 72 6e  an */.    return
6380: 20 53 51 4c 49 54 45 5f 43 4f 4e 53 54 52 41 49   SQLITE_CONSTRAI
6390: 4e 54 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69  NT;.  }..  if( i
63a0: 64 78 50 61 74 68 3c 30 20 29 7b 0a 20 20 20 20  dxPath<0 ){.    
63b0: 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d  pIdxInfo->idxNum
63c0: 20 3d 20 30 3b 0a 20 20 20 20 2f 2a 20 54 68 65   = 0;.    /* The
63d0: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
63e0: 61 74 65 64 43 6f 73 74 20 73 68 6f 75 6c 64 20  atedCost should 
63f0: 68 61 76 65 20 62 65 65 6e 20 69 6e 69 74 69 61  have been initia
6400: 6c 69 7a 65 64 20 74 6f 20 61 20 68 75 67 65 0a  lized to a huge.
6410: 20 20 20 20 2a 2a 20 6e 75 6d 62 65 72 2e 20 20      ** number.  
6420: 4c 65 61 76 65 20 69 74 20 75 6e 63 68 61 6e 67  Leave it unchang
6430: 65 64 2e 20 2a 2f 0a 20 20 20 20 70 49 64 78 49  ed. */.    pIdxI
6440: 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64 52 6f  nfo->estimatedRo
6450: 77 73 20 3d 20 30 78 37 66 66 66 66 66 66 66 3b  ws = 0x7fffffff;
6460: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 49  .  }else{.    pI
6470: 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61  dxInfo->aConstra
6480: 69 6e 74 55 73 61 67 65 5b 69 64 78 50 61 74 68  intUsage[idxPath
6490: 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20  ].omit = 1;.    
64a0: 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74  pIdxInfo->aConst
64b0: 72 61 69 6e 74 55 73 61 67 65 5b 69 64 78 50 61  raintUsage[idxPa
64c0: 74 68 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20  th].argvIndex = 
64d0: 31 3b 0a 20 20 20 20 69 66 28 20 69 64 78 44 69  1;.    if( idxDi
64e0: 72 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 70 49  r>=0 ){.      pI
64f0: 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61  dxInfo->aConstra
6500: 69 6e 74 55 73 61 67 65 5b 69 64 78 44 69 72 5d  intUsage[idxDir]
6510: 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20 20 20  .omit = 1;.     
6520: 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73   pIdxInfo->aCons
6530: 74 72 61 69 6e 74 55 73 61 67 65 5b 69 64 78 44  traintUsage[idxD
6540: 69 72 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20  ir].argvIndex = 
6550: 32 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66  2;.      pIdxInf
6560: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 32 3b 0a 20  o->idxNum = 2;. 
6570: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65       pIdxInfo->e
6580: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31  stimatedCost = 1
6590: 30 2e 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  0.0;.    }else{.
65a0: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
65b0: 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20 20 20 20  idxNum = 1;.    
65c0: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
65d0: 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30 30 2e  matedCost = 100.
65e0: 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  0;.    }.  }..  
65f0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
6600: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73  ;.}../*.** Regis
6610: 74 65 72 20 74 68 65 20 22 66 73 64 69 72 22 20  ter the "fsdir" 
6620: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a  virtual table..*
6630: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64  /.static int fsd
6640: 69 72 52 65 67 69 73 74 65 72 28 73 71 6c 69 74  irRegister(sqlit
6650: 65 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69  e3 *db){.  stati
6660: 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65  c sqlite3_module
6670: 20 66 73 64 69 72 4d 6f 64 75 6c 65 20 3d 20 7b   fsdirModule = {
6680: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
6690: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
66a0: 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20  /* iVersion */. 
66b0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
66c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
66d0: 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20   xCreate */.    
66e0: 66 73 64 69 72 43 6f 6e 6e 65 63 74 2c 20 20 20  fsdirConnect,   
66f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
6700: 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20 66 73  onnect */.    fs
6710: 64 69 72 42 65 73 74 49 6e 64 65 78 2c 20 20 20  dirBestIndex,   
6720: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73           /* xBes
6730: 74 49 6e 64 65 78 20 2a 2f 0a 20 20 20 20 66 73  tIndex */.    fs
6740: 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20  dirDisconnect,  
6750: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 69 73           /* xDis
6760: 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20 30  connect */.    0
6770: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6780: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
6790: 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20 66 73 64  stroy */.    fsd
67a0: 69 72 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  irOpen,         
67b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
67c0: 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72   - open a cursor
67d0: 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 43 6c 6f   */.    fsdirClo
67e0: 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
67f0: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63     /* xClose - c
6800: 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  lose a cursor */
6810: 0a 20 20 20 20 66 73 64 69 72 46 69 6c 74 65 72  .    fsdirFilter
6820: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
6830: 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e  /* xFilter - con
6840: 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e 73  figure scan cons
6850: 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 20 20 66  traints */.    f
6860: 73 64 69 72 4e 65 78 74 2c 20 20 20 20 20 20 20  sdirNext,       
6870: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e 65            /* xNe
6880: 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20 63  xt - advance a c
6890: 75 72 73 6f 72 20 2a 2f 0a 20 20 20 20 66 73 64  ursor */.    fsd
68a0: 69 72 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20  irEof,          
68b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20          /* xEof 
68c0: 2d 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64 20  - check for end 
68d0: 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20 20 20 66  of scan */.    f
68e0: 73 64 69 72 43 6f 6c 75 6d 6e 2c 20 20 20 20 20  sdirColumn,     
68f0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
6900: 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61  lumn - read data
6910: 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 52 6f 77   */.    fsdirRow
6920: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  id,             
6930: 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72     /* xRowid - r
6940: 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 20 20  ead data */.    
6950: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
6960: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
6970: 70 64 61 74 65 20 2a 2f 0a 20 20 20 20 30 2c 20  pdate */.    0, 
6980: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6990: 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69          /* xBegi
69a0: 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  n */.    0,     
69b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69c0: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a      /* xSync */.
69d0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
69e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
69f0: 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20 20  * xCommit */.   
6a00: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6a20: 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 20 20  Rollback */.    
6a30: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
6a40: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
6a50: 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 20  indMethod */.   
6a60: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
6a70: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6a80: 52 65 6e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c  Rename */.    0,
6a90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6aa0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 61 76           /* xSav
6ab0: 65 70 6f 69 6e 74 20 2a 2f 0a 20 20 20 20 30 2c  epoint */.    0,
6ac0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ad0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6c           /* xRel
6ae0: 65 61 73 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20  ease */.    0,  
6af0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b00: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
6b10: 61 63 6b 54 6f 20 2a 2f 0a 20 20 20 20 30 2c 20  ackTo */.    0, 
6b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b30: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 61 64          /* xShad
6b40: 6f 77 4e 61 6d 65 20 2a 2f 0a 20 20 7d 3b 0a 0a  owName */.  };..
6b50: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
6b60: 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65  e3_create_module
6b70: 28 64 62 2c 20 22 66 73 64 69 72 22 2c 20 26 66  (db, "fsdir", &f
6b80: 73 64 69 72 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a  sdirModule, 0);.
6b90: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
6ba0: 65 6c 73 65 20 20 20 20 20 20 20 20 20 2f 2a 20  else         /* 
6bb0: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54  SQLITE_OMIT_VIRT
6bc0: 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 23 20 64 65  UALTABLE */.# de
6bd0: 66 69 6e 65 20 66 73 64 69 72 52 65 67 69 73 74  fine fsdirRegist
6be0: 65 72 28 78 29 20 53 51 4c 49 54 45 5f 4f 4b 0a  er(x) SQLITE_OK.
6bf0: 23 65 6e 64 69 66 0a 0a 23 69 66 64 65 66 20 5f  #endif..#ifdef _
6c00: 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65 63  WIN32.__declspec
6c10: 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e 64  (dllexport).#end
6c20: 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 66  if.int sqlite3_f
6c30: 69 6c 65 69 6f 5f 69 6e 69 74 28 0a 20 20 73 71  ileio_init(.  sq
6c40: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 68  lite3 *db, .  ch
6c50: 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c 20 0a  ar **pzErrMsg, .
6c60: 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
6c70: 61 70 69 5f 72 6f 75 74 69 6e 65 73 20 2a 70 41  api_routines *pA
6c80: 70 69 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  pi.){.  int rc =
6c90: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 51   SQLITE_OK;.  SQ
6ca0: 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49  LITE_EXTENSION_I
6cb0: 4e 49 54 32 28 70 41 70 69 29 3b 0a 20 20 28 76  NIT2(pApi);.  (v
6cc0: 6f 69 64 29 70 7a 45 72 72 4d 73 67 3b 20 20 2f  oid)pzErrMsg;  /
6cd0: 2a 20 55 6e 75 73 65 64 20 70 61 72 61 6d 65 74  * Unused paramet
6ce0: 65 72 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  er */.  rc = sql
6cf0: 69 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63  ite3_create_func
6d00: 74 69 6f 6e 28 64 62 2c 20 22 72 65 61 64 66 69  tion(db, "readfi
6d10: 6c 65 22 2c 20 31 2c 20 53 51 4c 49 54 45 5f 55  le", 1, SQLITE_U
6d20: 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20 20  TF8, 0,.        
6d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d40: 20 20 20 20 20 20 20 72 65 61 64 66 69 6c 65 46         readfileF
6d50: 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 69 66  unc, 0, 0);.  if
6d60: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6d70: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
6d80: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
6d90: 69 6f 6e 28 64 62 2c 20 22 77 72 69 74 65 66 69  ion(db, "writefi
6da0: 6c 65 22 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f  le", -1, SQLITE_
6db0: 55 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20  UTF8, 0,.       
6dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6dd0: 20 20 20 20 20 20 20 20 20 20 77 72 69 74 65 66            writef
6de0: 69 6c 65 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a  ileFunc, 0, 0);.
6df0: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
6e00: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
6e10: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
6e20: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  te_function(db, 
6e30: 22 6c 73 6d 6f 64 65 22 2c 20 31 2c 20 53 51 4c  "lsmode", 1, SQL
6e40: 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a 20 20 20  ITE_UTF8, 0,.   
6e50: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 73                ls
6e70: 4d 6f 64 65 46 75 6e 63 2c 20 30 2c 20 30 29 3b  ModeFunc, 0, 0);
6e80: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
6e90: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
6ea0: 72 63 20 3d 20 66 73 64 69 72 52 65 67 69 73 74  rc = fsdirRegist
6eb0: 65 72 28 64 62 29 3b 0a 20 20 7d 0a 20 20 72 65  er(db);.  }.  re
6ec0: 74 75 72 6e 20 72 63 3b 0a 7d 0a                 turn rc;.}.