/ Hex Artifact Content
Login

Artifact 288e7230e0fe464d71b0694e2d8bdd3a353118ac2e31da3964b95f460f09915f:


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 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29  =(sqlite3_int64)
1500: 66 72 65 61 64 28 70 42 75 66 2c 20 31 2c 20 28  fread(pBuf, 1, (
1510: 73 69 7a 65 5f 74 29 6e 49 6e 2c 20 69 6e 29 20  size_t)nIn, in) 
1520: 29 7b 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72  ){.    sqlite3_r
1530: 65 73 75 6c 74 5f 62 6c 6f 62 36 34 28 63 74 78  esult_blob64(ctx
1540: 2c 20 70 42 75 66 2c 20 6e 49 6e 2c 20 73 71 6c  , pBuf, nIn, sql
1550: 69 74 65 33 5f 66 72 65 65 29 3b 0a 20 20 7d 65  ite3_free);.  }e
1560: 6c 73 65 7b 0a 20 20 20 20 73 71 6c 69 74 65 33  lse{.    sqlite3
1570: 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f 63 6f  _result_error_co
1580: 64 65 28 63 74 78 2c 20 53 51 4c 49 54 45 5f 49  de(ctx, SQLITE_I
1590: 4f 45 52 52 29 3b 0a 20 20 20 20 73 71 6c 69 74  OERR);.    sqlit
15a0: 65 33 5f 66 72 65 65 28 70 42 75 66 29 3b 0a 20  e3_free(pBuf);. 
15b0: 20 7d 0a 20 20 66 63 6c 6f 73 65 28 69 6e 29 3b   }.  fclose(in);
15c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d  .}../*.** Implem
15d0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  entation of the 
15e0: 22 72 65 61 64 66 69 6c 65 28 58 29 22 20 53 51  "readfile(X)" SQ
15f0: 4c 20 66 75 6e 63 74 69 6f 6e 2e 20 20 54 68 65  L function.  The
1600: 20 65 6e 74 69 72 65 20 63 6f 6e 74 65 6e 74 0a   entire content.
1610: 2a 2a 20 6f 66 20 74 68 65 20 66 69 6c 65 20 6e  ** of the file n
1620: 61 6d 65 64 20 58 20 69 73 20 72 65 61 64 20 61  amed X is read a
1630: 6e 64 20 72 65 74 75 72 6e 65 64 20 61 73 20 61  nd returned as a
1640: 20 42 4c 4f 42 2e 20 20 4e 55 4c 4c 20 69 73 20   BLOB.  NULL is 
1650: 72 65 74 75 72 6e 65 64 0a 2a 2a 20 69 66 20 74  returned.** if t
1660: 68 65 20 66 69 6c 65 20 64 6f 65 73 20 6e 6f 74  he file does not
1670: 20 65 78 69 73 74 20 6f 72 20 69 73 20 75 6e 72   exist or is unr
1680: 65 61 64 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  eadable..*/.stat
1690: 69 63 20 76 6f 69 64 20 72 65 61 64 66 69 6c 65  ic void readfile
16a0: 46 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f  Func(.  sqlite3_
16b0: 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74  context *context
16c0: 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20  ,.  int argc,.  
16d0: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
16e0: 61 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20  argv.){.  const 
16f0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 28  char *zName;.  (
1700: 76 6f 69 64 29 28 61 72 67 63 29 3b 20 20 2f 2a  void)(argc);  /*
1710: 20 55 6e 75 73 65 64 20 70 61 72 61 6d 65 74 65   Unused paramete
1720: 72 20 2a 2f 0a 20 20 7a 4e 61 6d 65 20 3d 20 28  r */.  zName = (
1730: 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c 69  const char*)sqli
1740: 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74 28 61  te3_value_text(a
1750: 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28 20 7a  rgv[0]);.  if( z
1760: 4e 61 6d 65 3d 3d 30 20 29 20 72 65 74 75 72 6e  Name==0 ) return
1770: 3b 0a 20 20 72 65 61 64 46 69 6c 65 43 6f 6e 74  ;.  readFileCont
1780: 65 6e 74 73 28 63 6f 6e 74 65 78 74 2c 20 7a 4e  ents(context, zN
1790: 61 6d 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ame);.}../*.** S
17a0: 65 74 20 74 68 65 20 65 72 72 6f 72 20 6d 65 73  et the error mes
17b0: 73 61 67 65 20 63 6f 6e 74 61 69 6e 65 64 20 69  sage contained i
17c0: 6e 20 63 6f 6e 74 65 78 74 20 63 74 78 20 74 6f  n context ctx to
17d0: 20 74 68 65 20 72 65 73 75 6c 74 73 20 6f 66 0a   the results of.
17e0: 2a 2a 20 76 70 72 69 6e 74 66 28 7a 46 6d 74 2c  ** vprintf(zFmt,
17f0: 20 2e 2e 2e 29 2e 0a 2a 2f 0a 73 74 61 74 69 63   ...)..*/.static
1800: 20 76 6f 69 64 20 63 74 78 45 72 72 6f 72 4d 73   void ctxErrorMs
1810: 67 28 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78  g(sqlite3_contex
1820: 74 20 2a 63 74 78 2c 20 63 6f 6e 73 74 20 63 68  t *ctx, const ch
1830: 61 72 20 2a 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a  ar *zFmt, ...){.
1840: 20 20 63 68 61 72 20 2a 7a 4d 73 67 20 3d 20 30    char *zMsg = 0
1850: 3b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  ;.  va_list ap;.
1860: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
1870: 46 6d 74 29 3b 0a 20 20 7a 4d 73 67 20 3d 20 73  Fmt);.  zMsg = s
1880: 71 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28  qlite3_vmprintf(
1890: 7a 46 6d 74 2c 20 61 70 29 3b 0a 20 20 73 71 6c  zFmt, ap);.  sql
18a0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f  ite3_result_erro
18b0: 72 28 63 74 78 2c 20 7a 4d 73 67 2c 20 2d 31 29  r(ctx, zMsg, -1)
18c0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65  ;.  sqlite3_free
18d0: 28 7a 4d 73 67 29 3b 0a 20 20 76 61 5f 65 6e 64  (zMsg);.  va_end
18e0: 28 61 70 29 3b 0a 7d 0a 0a 23 69 66 20 64 65 66  (ap);.}..#if def
18f0: 69 6e 65 64 28 5f 57 49 4e 33 32 29 0a 2f 2a 0a  ined(_WIN32)./*.
1900: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
1910: 20 69 73 20 64 65 73 69 67 6e 65 64 20 74 6f 20   is designed to 
1920: 63 6f 6e 76 65 72 74 20 61 20 57 69 6e 33 32 20  convert a Win32 
1930: 46 49 4c 45 54 49 4d 45 20 73 74 72 75 63 74 75  FILETIME structu
1940: 72 65 20 69 6e 74 6f 20 74 68 65 0a 2a 2a 20 6e  re into the.** n
1950: 75 6d 62 65 72 20 6f 66 20 73 65 63 6f 6e 64 73  umber of seconds
1960: 20 73 69 6e 63 65 20 74 68 65 20 55 6e 69 78 20   since the Unix 
1970: 45 70 6f 63 68 20 28 31 39 37 30 2d 30 31 2d 30  Epoch (1970-01-0
1980: 31 20 30 30 3a 30 30 3a 30 30 20 55 54 43 29 2e  1 00:00:00 UTC).
1990: 0a 2a 2f 0a 73 74 61 74 69 63 20 73 71 6c 69 74  .*/.static sqlit
19a0: 65 33 5f 75 69 6e 74 36 34 20 66 69 6c 65 54 69  e3_uint64 fileTi
19b0: 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 0a 20 20  meToUnixTime(.  
19c0: 4c 50 46 49 4c 45 54 49 4d 45 20 70 46 69 6c 65  LPFILETIME pFile
19d0: 54 69 6d 65 0a 29 7b 0a 20 20 53 59 53 54 45 4d  Time.){.  SYSTEM
19e0: 54 49 4d 45 20 65 70 6f 63 68 53 79 73 74 65 6d  TIME epochSystem
19f0: 54 69 6d 65 3b 0a 20 20 55 4c 41 52 47 45 5f 49  Time;.  ULARGE_I
1a00: 4e 54 45 47 45 52 20 65 70 6f 63 68 49 6e 74 65  NTEGER epochInte
1a10: 72 76 61 6c 73 3b 0a 20 20 46 49 4c 45 54 49 4d  rvals;.  FILETIM
1a20: 45 20 65 70 6f 63 68 46 69 6c 65 54 69 6d 65 3b  E epochFileTime;
1a30: 0a 20 20 55 4c 41 52 47 45 5f 49 4e 54 45 47 45  .  ULARGE_INTEGE
1a40: 52 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 3b  R fileIntervals;
1a50: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 65 70 6f 63  ..  memset(&epoc
1a60: 68 53 79 73 74 65 6d 54 69 6d 65 2c 20 30 2c 20  hSystemTime, 0, 
1a70: 73 69 7a 65 6f 66 28 53 59 53 54 45 4d 54 49 4d  sizeof(SYSTEMTIM
1a80: 45 29 29 3b 0a 20 20 65 70 6f 63 68 53 79 73 74  E));.  epochSyst
1a90: 65 6d 54 69 6d 65 2e 77 59 65 61 72 20 3d 20 31  emTime.wYear = 1
1aa0: 39 37 30 3b 0a 20 20 65 70 6f 63 68 53 79 73 74  970;.  epochSyst
1ab0: 65 6d 54 69 6d 65 2e 77 4d 6f 6e 74 68 20 3d 20  emTime.wMonth = 
1ac0: 31 3b 0a 20 20 65 70 6f 63 68 53 79 73 74 65 6d  1;.  epochSystem
1ad0: 54 69 6d 65 2e 77 44 61 79 20 3d 20 31 3b 0a 20  Time.wDay = 1;. 
1ae0: 20 53 79 73 74 65 6d 54 69 6d 65 54 6f 46 69 6c   SystemTimeToFil
1af0: 65 54 69 6d 65 28 26 65 70 6f 63 68 53 79 73 74  eTime(&epochSyst
1b00: 65 6d 54 69 6d 65 2c 20 26 65 70 6f 63 68 46 69  emTime, &epochFi
1b10: 6c 65 54 69 6d 65 29 3b 0a 20 20 65 70 6f 63 68  leTime);.  epoch
1b20: 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50 61 72  Intervals.LowPar
1b30: 74 20 3d 20 65 70 6f 63 68 46 69 6c 65 54 69 6d  t = epochFileTim
1b40: 65 2e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b  e.dwLowDateTime;
1b50: 0a 20 20 65 70 6f 63 68 49 6e 74 65 72 76 61 6c  .  epochInterval
1b60: 73 2e 48 69 67 68 50 61 72 74 20 3d 20 65 70 6f  s.HighPart = epo
1b70: 63 68 46 69 6c 65 54 69 6d 65 2e 64 77 48 69 67  chFileTime.dwHig
1b80: 68 44 61 74 65 54 69 6d 65 3b 0a 0a 20 20 66 69  hDateTime;..  fi
1b90: 6c 65 49 6e 74 65 72 76 61 6c 73 2e 4c 6f 77 50  leIntervals.LowP
1ba0: 61 72 74 20 3d 20 70 46 69 6c 65 54 69 6d 65 2d  art = pFileTime-
1bb0: 3e 64 77 4c 6f 77 44 61 74 65 54 69 6d 65 3b 0a  >dwLowDateTime;.
1bc0: 20 20 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e    fileIntervals.
1bd0: 48 69 67 68 50 61 72 74 20 3d 20 70 46 69 6c 65  HighPart = pFile
1be0: 54 69 6d 65 2d 3e 64 77 48 69 67 68 44 61 74 65  Time->dwHighDate
1bf0: 54 69 6d 65 3b 0a 0a 20 20 72 65 74 75 72 6e 20  Time;..  return 
1c00: 28 66 69 6c 65 49 6e 74 65 72 76 61 6c 73 2e 51  (fileIntervals.Q
1c10: 75 61 64 50 61 72 74 20 2d 20 65 70 6f 63 68 49  uadPart - epochI
1c20: 6e 74 65 72 76 61 6c 73 2e 51 75 61 64 50 61 72  ntervals.QuadPar
1c30: 74 29 20 2f 20 31 30 30 30 30 30 30 30 3b 0a 7d  t) / 10000000;.}
1c40: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e  ../*.** This fun
1c50: 63 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20 74  ction attempts t
1c60: 6f 20 6e 6f 72 6d 61 6c 69 7a 65 20 74 68 65 20  o normalize the 
1c70: 74 69 6d 65 20 76 61 6c 75 65 73 20 66 6f 75 6e  time values foun
1c80: 64 20 69 6e 20 74 68 65 20 73 74 61 74 28 29 0a  d in the stat().
1c90: 2a 2a 20 62 75 66 66 65 72 20 74 6f 20 55 54 43  ** buffer to UTC
1ca0: 2e 20 20 54 68 69 73 20 69 73 20 6e 65 63 65 73  .  This is neces
1cb0: 73 61 72 79 20 6f 6e 20 57 69 6e 33 32 2c 20 77  sary on Win32, w
1cc0: 68 65 72 65 20 74 68 65 20 72 75 6e 74 69 6d 65  here the runtime
1cd0: 20 6c 69 62 72 61 72 79 0a 2a 2a 20 61 70 70 65   library.** appe
1ce0: 61 72 73 20 74 6f 20 72 65 74 75 72 6e 20 74 68  ars to return th
1cf0: 65 73 65 20 76 61 6c 75 65 73 20 61 73 20 6c 6f  ese values as lo
1d00: 63 61 6c 20 74 69 6d 65 73 2e 0a 2a 2f 0a 73 74  cal times..*/.st
1d10: 61 74 69 63 20 76 6f 69 64 20 73 74 61 74 54 69  atic void statTi
1d20: 6d 65 73 54 6f 55 74 63 28 0a 20 20 63 6f 6e 73  mesToUtc(.  cons
1d30: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 0a 20  t char *zPath,. 
1d40: 20 73 74 72 75 63 74 20 73 74 61 74 20 2a 70 53   struct stat *pS
1d50: 74 61 74 42 75 66 0a 29 7b 0a 20 20 48 41 4e 44  tatBuf.){.  HAND
1d60: 4c 45 20 68 46 69 6e 64 46 69 6c 65 3b 0a 20 20  LE hFindFile;.  
1d70: 57 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41 57  WIN32_FIND_DATAW
1d80: 20 66 64 3b 0a 20 20 4c 50 57 53 54 52 20 7a 55   fd;.  LPWSTR zU
1d90: 6e 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20 65 78  nicodeName;.  ex
1da0: 74 65 72 6e 20 4c 50 57 53 54 52 20 73 71 6c 69  tern LPWSTR sqli
1db0: 74 65 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74  te3_win32_utf8_t
1dc0: 6f 5f 75 6e 69 63 6f 64 65 28 63 6f 6e 73 74 20  o_unicode(const 
1dd0: 63 68 61 72 2a 29 3b 0a 20 20 7a 55 6e 69 63 6f  char*);.  zUnico
1de0: 64 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65 33  deName = sqlite3
1df0: 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f 75  _win32_utf8_to_u
1e00: 6e 69 63 6f 64 65 28 7a 50 61 74 68 29 3b 0a 20  nicode(zPath);. 
1e10: 20 69 66 28 20 7a 55 6e 69 63 6f 64 65 4e 61 6d   if( zUnicodeNam
1e20: 65 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28  e ){.    memset(
1e30: 26 66 64 2c 20 30 2c 20 73 69 7a 65 6f 66 28 57  &fd, 0, sizeof(W
1e40: 49 4e 33 32 5f 46 49 4e 44 5f 44 41 54 41 57 29  IN32_FIND_DATAW)
1e50: 29 3b 0a 20 20 20 20 68 46 69 6e 64 46 69 6c 65  );.    hFindFile
1e60: 20 3d 20 46 69 6e 64 46 69 72 73 74 46 69 6c 65   = FindFirstFile
1e70: 57 28 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 2c 20  W(zUnicodeName, 
1e80: 26 66 64 29 3b 0a 20 20 20 20 69 66 28 20 68 46  &fd);.    if( hF
1e90: 69 6e 64 46 69 6c 65 21 3d 4e 55 4c 4c 20 29 7b  indFile!=NULL ){
1ea0: 0a 20 20 20 20 20 20 70 53 74 61 74 42 75 66 2d  .      pStatBuf-
1eb0: 3e 73 74 5f 63 74 69 6d 65 20 3d 20 28 74 69 6d  >st_ctime = (tim
1ec0: 65 5f 74 29 66 69 6c 65 54 69 6d 65 54 6f 55 6e  e_t)fileTimeToUn
1ed0: 69 78 54 69 6d 65 28 26 66 64 2e 66 74 43 72 65  ixTime(&fd.ftCre
1ee0: 61 74 69 6f 6e 54 69 6d 65 29 3b 0a 20 20 20 20  ationTime);.    
1ef0: 20 20 70 53 74 61 74 42 75 66 2d 3e 73 74 5f 61    pStatBuf->st_a
1f00: 74 69 6d 65 20 3d 20 28 74 69 6d 65 5f 74 29 66  time = (time_t)f
1f10: 69 6c 65 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d  ileTimeToUnixTim
1f20: 65 28 26 66 64 2e 66 74 4c 61 73 74 41 63 63 65  e(&fd.ftLastAcce
1f30: 73 73 54 69 6d 65 29 3b 0a 20 20 20 20 20 20 70  ssTime);.      p
1f40: 53 74 61 74 42 75 66 2d 3e 73 74 5f 6d 74 69 6d  StatBuf->st_mtim
1f50: 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 69 6c 65  e = (time_t)file
1f60: 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 26  TimeToUnixTime(&
1f70: 66 64 2e 66 74 4c 61 73 74 57 72 69 74 65 54 69  fd.ftLastWriteTi
1f80: 6d 65 29 3b 0a 20 20 20 20 20 20 46 69 6e 64 43  me);.      FindC
1f90: 6c 6f 73 65 28 68 46 69 6e 64 46 69 6c 65 29 3b  lose(hFindFile);
1fa0: 0a 20 20 20 20 7d 0a 20 20 20 20 73 71 6c 69 74  .    }.    sqlit
1fb0: 65 33 5f 66 72 65 65 28 7a 55 6e 69 63 6f 64 65  e3_free(zUnicode
1fc0: 4e 61 6d 65 29 3b 0a 20 20 7d 0a 7d 0a 23 65 6e  Name);.  }.}.#en
1fd0: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  dif../*.** This 
1fe0: 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73 65 64  function is used
1ff0: 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 73 74 61   in place of sta
2000: 74 28 29 2e 20 20 4f 6e 20 57 69 6e 64 6f 77 73  t().  On Windows
2010: 2c 20 73 70 65 63 69 61 6c 20 68 61 6e 64 6c 69  , special handli
2020: 6e 67 0a 2a 2a 20 69 73 20 72 65 71 75 69 72 65  ng.** is require
2030: 64 20 69 6e 20 6f 72 64 65 72 20 66 6f 72 20 74  d in order for t
2040: 68 65 20 69 6e 63 6c 75 64 65 64 20 74 69 6d 65  he included time
2050: 20 74 6f 20 62 65 20 72 65 74 75 72 6e 65 64 20   to be returned 
2060: 61 73 20 55 54 43 2e 20 20 4f 6e 20 61 6c 6c 0a  as UTC.  On all.
2070: 2a 2a 20 6f 74 68 65 72 20 73 79 73 74 65 6d 73  ** other systems
2080: 2c 20 74 68 69 73 20 66 75 6e 63 74 69 6f 6e 20  , this function 
2090: 73 69 6d 70 6c 79 20 63 61 6c 6c 73 20 73 74 61  simply calls sta
20a0: 74 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  t()..*/.static i
20b0: 6e 74 20 66 69 6c 65 53 74 61 74 28 0a 20 20 63  nt fileStat(.  c
20c0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68  onst char *zPath
20d0: 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20  ,.  struct stat 
20e0: 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69 66  *pStatBuf.){.#if
20f0: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29   defined(_WIN32)
2100: 0a 20 20 69 6e 74 20 72 63 20 3d 20 73 74 61 74  .  int rc = stat
2110: 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66  (zPath, pStatBuf
2120: 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30 20 29  );.  if( rc==0 )
2130: 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63 28   statTimesToUtc(
2140: 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66 29  zPath, pStatBuf)
2150: 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 23  ;.  return rc;.#
2160: 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20 73 74  else.  return st
2170: 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42  at(zPath, pStatB
2180: 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a 2f  uf);.#endif.}../
2190: 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69  *.** This functi
21a0: 6f 6e 20 69 73 20 75 73 65 64 20 69 6e 20 70 6c  on is used in pl
21b0: 61 63 65 20 6f 66 20 6c 73 74 61 74 28 29 2e 20  ace of lstat(). 
21c0: 20 4f 6e 20 57 69 6e 64 6f 77 73 2c 20 73 70 65   On Windows, spe
21d0: 63 69 61 6c 20 68 61 6e 64 6c 69 6e 67 0a 2a 2a  cial handling.**
21e0: 20 69 73 20 72 65 71 75 69 72 65 64 20 69 6e 20   is required in 
21f0: 6f 72 64 65 72 20 66 6f 72 20 74 68 65 20 69 6e  order for the in
2200: 63 6c 75 64 65 64 20 74 69 6d 65 20 74 6f 20 62  cluded time to b
2210: 65 20 72 65 74 75 72 6e 65 64 20 61 73 20 55 54  e returned as UT
2220: 43 2e 20 20 4f 6e 20 61 6c 6c 0a 2a 2a 20 6f 74  C.  On all.** ot
2230: 68 65 72 20 73 79 73 74 65 6d 73 2c 20 74 68 69  her systems, thi
2240: 73 20 66 75 6e 63 74 69 6f 6e 20 73 69 6d 70 6c  s function simpl
2250: 79 20 63 61 6c 6c 73 20 6c 73 74 61 74 28 29 2e  y calls lstat().
2260: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
2270: 69 6c 65 4c 69 6e 6b 53 74 61 74 28 0a 20 20 63  ileLinkStat(.  c
2280: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 61 74 68  onst char *zPath
2290: 2c 0a 20 20 73 74 72 75 63 74 20 73 74 61 74 20  ,.  struct stat 
22a0: 2a 70 53 74 61 74 42 75 66 0a 29 7b 0a 23 69 66  *pStatBuf.){.#if
22b0: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29   defined(_WIN32)
22c0: 0a 20 20 69 6e 74 20 72 63 20 3d 20 6c 73 74 61  .  int rc = lsta
22d0: 74 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75  t(zPath, pStatBu
22e0: 66 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30 20  f);.  if( rc==0 
22f0: 29 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63  ) statTimesToUtc
2300: 28 7a 50 61 74 68 2c 20 70 53 74 61 74 42 75 66  (zPath, pStatBuf
2310: 29 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a  );.  return rc;.
2320: 23 65 6c 73 65 0a 20 20 72 65 74 75 72 6e 20 6c  #else.  return l
2330: 73 74 61 74 28 7a 50 61 74 68 2c 20 70 53 74 61  stat(zPath, pSta
2340: 74 42 75 66 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a  tBuf);.#endif.}.
2350: 0a 2f 2a 0a 2a 2a 20 41 72 67 75 6d 65 6e 74 20  ./*.** Argument 
2360: 7a 46 69 6c 65 20 69 73 20 74 68 65 20 6e 61 6d  zFile is the nam
2370: 65 20 6f 66 20 61 20 66 69 6c 65 20 74 68 61 74  e of a file that
2380: 20 77 69 6c 6c 20 62 65 20 63 72 65 61 74 65 64   will be created
2390: 20 61 6e 64 2f 6f 72 20 77 72 69 74 74 65 6e 0a   and/or written.
23a0: 2a 2a 20 62 79 20 53 51 4c 20 66 75 6e 63 74 69  ** by SQL functi
23b0: 6f 6e 20 77 72 69 74 65 66 69 6c 65 28 29 2e 20  on writefile(). 
23c0: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 65 6e  This function en
23d0: 73 75 72 65 73 20 74 68 61 74 20 74 68 65 20 64  sures that the d
23e0: 69 72 65 63 74 6f 72 79 0a 2a 2a 20 7a 46 69 6c  irectory.** zFil
23f0: 65 20 77 69 6c 6c 20 62 65 20 77 72 69 74 74 65  e will be writte
2400: 6e 20 74 6f 20 65 78 69 73 74 73 2c 20 63 72 65  n to exists, cre
2410: 61 74 69 6e 67 20 69 74 20 69 66 20 72 65 71 75  ating it if requ
2420: 69 72 65 64 2e 20 54 68 65 20 70 65 72 6d 69 73  ired. The permis
2430: 73 69 6f 6e 73 0a 2a 2a 20 66 6f 72 20 61 6e 79  sions.** for any
2440: 20 70 61 74 68 20 63 6f 6d 70 6f 6e 65 6e 74 73   path components
2450: 20 63 72 65 61 74 65 64 20 62 79 20 74 68 69 73   created by this
2460: 20 66 75 6e 63 74 69 6f 6e 20 61 72 65 20 73 65   function are se
2470: 74 20 69 6e 20 61 63 63 6f 72 64 61 6e 63 65 0a  t in accordance.
2480: 2a 2a 20 77 69 74 68 20 74 68 65 20 63 75 72 72  ** with the curr
2490: 65 6e 74 20 75 6d 61 73 6b 2e 0a 2a 2a 0a 2a 2a  ent umask..**.**
24a0: 20 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69   If an OOM condi
24b0: 74 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65  tion is encounte
24c0: 72 65 64 2c 20 53 51 4c 49 54 45 5f 4e 4f 4d 45  red, SQLITE_NOME
24d0: 4d 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f  M is returned. O
24e0: 74 68 65 72 77 69 73 65 2c 0a 2a 2a 20 53 51 4c  therwise,.** SQL
24f0: 49 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e  ITE_OK is return
2500: 65 64 20 69 66 20 74 68 65 20 64 69 72 65 63 74  ed if the direct
2510: 6f 72 79 20 69 73 20 73 75 63 63 65 73 73 66 75  ory is successfu
2520: 6c 6c 79 20 63 72 65 61 74 65 64 2c 20 6f 72 0a  lly created, or.
2530: 2a 2a 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 20  ** SQLITE_ERROR 
2540: 6f 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74  otherwise..*/.st
2550: 61 74 69 63 20 69 6e 74 20 6d 61 6b 65 44 69 72  atic int makeDir
2560: 65 63 74 6f 72 79 28 0a 20 20 63 6f 6e 73 74 20  ectory(.  const 
2570: 63 68 61 72 20 2a 7a 46 69 6c 65 0a 29 7b 0a 20  char *zFile.){. 
2580: 20 63 68 61 72 20 2a 7a 43 6f 70 79 20 3d 20 73   char *zCopy = s
2590: 71 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22  qlite3_mprintf("
25a0: 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20 69  %s", zFile);.  i
25b0: 6e 74 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f  nt rc = SQLITE_O
25c0: 4b 3b 0a 0a 20 20 69 66 28 20 7a 43 6f 70 79 3d  K;..  if( zCopy=
25d0: 3d 30 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53  =0 ){.    rc = S
25e0: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d  QLITE_NOMEM;.  }
25f0: 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74 20 6e 43  else{.    int nC
2600: 6f 70 79 20 3d 20 28 69 6e 74 29 73 74 72 6c 65  opy = (int)strle
2610: 6e 28 7a 43 6f 70 79 29 3b 0a 20 20 20 20 69 6e  n(zCopy);.    in
2620: 74 20 69 20 3d 20 31 3b 0a 0a 20 20 20 20 77 68  t i = 1;..    wh
2630: 69 6c 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f  ile( rc==SQLITE_
2640: 4f 4b 20 29 7b 0a 20 20 20 20 20 20 73 74 72 75  OK ){.      stru
2650: 63 74 20 73 74 61 74 20 73 53 74 61 74 3b 0a 20  ct stat sStat;. 
2660: 20 20 20 20 20 69 6e 74 20 72 63 32 3b 0a 0a 20       int rc2;.. 
2670: 20 20 20 20 20 66 6f 72 28 3b 20 7a 43 6f 70 79       for(; zCopy
2680: 5b 69 5d 21 3d 27 2f 27 20 26 26 20 69 3c 6e 43  [i]!='/' && i<nC
2690: 6f 70 79 3b 20 69 2b 2b 29 3b 0a 20 20 20 20 20  opy; i++);.     
26a0: 20 69 66 28 20 69 3d 3d 6e 43 6f 70 79 20 29 20   if( i==nCopy ) 
26b0: 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 7a 43 6f  break;.      zCo
26c0: 70 79 5b 69 5d 20 3d 20 27 5c 30 27 3b 0a 0a 20  py[i] = '\0';.. 
26d0: 20 20 20 20 20 72 63 32 20 3d 20 66 69 6c 65 53       rc2 = fileS
26e0: 74 61 74 28 7a 43 6f 70 79 2c 20 26 73 53 74 61  tat(zCopy, &sSta
26f0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63  t);.      if( rc
2700: 32 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  2!=0 ){.        
2710: 69 66 28 20 6d 6b 64 69 72 28 7a 43 6f 70 79 2c  if( mkdir(zCopy,
2720: 20 30 37 37 37 29 20 29 20 72 63 20 3d 20 53 51   0777) ) rc = SQ
2730: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 20 20  LITE_ERROR;.    
2740: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20    }else{.       
2750: 20 69 66 28 20 21 53 5f 49 53 44 49 52 28 73 53   if( !S_ISDIR(sS
2760: 74 61 74 2e 73 74 5f 6d 6f 64 65 29 20 29 20 72  tat.st_mode) ) r
2770: 63 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52  c = SQLITE_ERROR
2780: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
2790: 7a 43 6f 70 79 5b 69 5d 20 3d 20 27 2f 27 3b 0a  zCopy[i] = '/';.
27a0: 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 7d        i++;.    }
27b0: 0a 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72  ..    sqlite3_fr
27c0: 65 65 28 7a 43 6f 70 79 29 3b 0a 20 20 7d 0a 0a  ee(zCopy);.  }..
27d0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a    return rc;.}..
27e0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  /*.** This funct
27f0: 69 6f 6e 20 64 6f 65 73 20 74 68 65 20 77 6f 72  ion does the wor
2800: 6b 20 66 6f 72 20 74 68 65 20 77 72 69 74 65 66  k for the writef
2810: 69 6c 65 28 29 20 55 44 46 2e 20 52 65 66 65 72  ile() UDF. Refer
2820: 20 74 6f 20 0a 2a 2a 20 68 65 61 64 65 72 20 63   to .** header c
2830: 6f 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74  omments at the t
2840: 6f 70 20 6f 66 20 74 68 69 73 20 66 69 6c 65 20  op of this file 
2850: 66 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a  for details..*/.
2860: 73 74 61 74 69 63 20 69 6e 74 20 77 72 69 74 65  static int write
2870: 46 69 6c 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  File(.  sqlite3_
2880: 63 6f 6e 74 65 78 74 20 2a 70 43 74 78 2c 20 20  context *pCtx,  
2890: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65          /* Conte
28a0: 78 74 20 74 6f 20 72 65 74 75 72 6e 20 62 79 74  xt to return byt
28b0: 65 73 20 77 72 69 74 74 65 6e 20 69 6e 20 2a 2f  es written in */
28c0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
28d0: 46 69 6c 65 2c 20 20 20 20 20 20 20 20 20 20 20  File,           
28e0: 20 20 20 2f 2a 20 46 69 6c 65 20 74 6f 20 77 72     /* File to wr
28f0: 69 74 65 20 2a 2f 0a 20 20 73 71 6c 69 74 65 33  ite */.  sqlite3
2900: 5f 76 61 6c 75 65 20 2a 70 44 61 74 61 2c 20 20  _value *pData,  
2910: 20 20 20 20 20 20 20 20 20 2f 2a 20 44 61 74 61           /* Data
2920: 20 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 6d   to write */.  m
2930: 6f 64 65 5f 74 20 6d 6f 64 65 2c 20 20 20 20 20  ode_t mode,     
2940: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2950: 2a 20 4d 4f 44 45 20 70 61 72 61 6d 65 74 65 72  * MODE parameter
2960: 20 70 61 73 73 65 64 20 74 6f 20 77 72 69 74 65   passed to write
2970: 66 69 6c 65 28 29 20 2a 2f 0a 20 20 73 71 6c 69  file() */.  sqli
2980: 74 65 33 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20  te3_int64 mtime 
2990: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4d              /* M
29a0: 54 49 4d 45 20 70 61 72 61 6d 65 74 65 72 20 28  TIME parameter (
29b0: 6f 72 20 2d 31 20 74 6f 20 6e 6f 74 20 73 65 74  or -1 to not set
29c0: 20 74 69 6d 65 29 20 2a 2f 0a 29 7b 0a 23 69 66   time) */.){.#if
29d0: 20 21 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32   !defined(_WIN32
29e0: 29 20 26 26 20 21 64 65 66 69 6e 65 64 28 57 49  ) && !defined(WI
29f0: 4e 33 32 29 0a 20 20 69 66 28 20 53 5f 49 53 4c  N32).  if( S_ISL
2a00: 4e 4b 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20  NK(mode) ){.    
2a10: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 6f 20  const char *zTo 
2a20: 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73  = (const char*)s
2a30: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78  qlite3_value_tex
2a40: 74 28 70 44 61 74 61 29 3b 0a 20 20 20 20 69 66  t(pData);.    if
2a50: 28 20 73 79 6d 6c 69 6e 6b 28 7a 54 6f 2c 20 7a  ( symlink(zTo, z
2a60: 46 69 6c 65 29 3c 30 20 29 20 72 65 74 75 72 6e  File)<0 ) return
2a70: 20 31 3b 0a 20 20 7d 65 6c 73 65 0a 23 65 6e 64   1;.  }else.#end
2a80: 69 66 0a 20 20 7b 0a 20 20 20 20 69 66 28 20 53  if.  {.    if( S
2a90: 5f 49 53 44 49 52 28 6d 6f 64 65 29 20 29 7b 0a  _ISDIR(mode) ){.
2aa0: 20 20 20 20 20 20 69 66 28 20 6d 6b 64 69 72 28        if( mkdir(
2ab0: 7a 46 69 6c 65 2c 20 6d 6f 64 65 29 20 29 7b 0a  zFile, mode) ){.
2ac0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 6d          /* The m
2ad0: 6b 64 69 72 28 29 20 63 61 6c 6c 20 74 6f 20 63  kdir() call to c
2ae0: 72 65 61 74 65 20 74 68 65 20 64 69 72 65 63 74  reate the direct
2af0: 6f 72 79 20 66 61 69 6c 65 64 2e 20 54 68 69 73  ory failed. This
2b00: 20 6d 69 67 68 74 20 6e 6f 74 0a 20 20 20 20 20   might not.     
2b10: 20 20 20 2a 2a 20 62 65 20 61 6e 20 65 72 72 6f     ** be an erro
2b20: 72 20 74 68 6f 75 67 68 20 2d 20 69 66 20 74 68  r though - if th
2b30: 65 72 65 20 69 73 20 61 6c 72 65 61 64 79 20 61  ere is already a
2b40: 20 64 69 72 65 63 74 6f 72 79 20 61 74 20 74 68   directory at th
2b50: 65 20 73 61 6d 65 0a 20 20 20 20 20 20 20 20 2a  e same.        *
2b60: 2a 20 70 61 74 68 20 61 6e 64 20 65 69 74 68 65  * path and eithe
2b70: 72 20 74 68 65 20 70 65 72 6d 69 73 73 69 6f 6e  r the permission
2b80: 73 20 61 6c 72 65 61 64 79 20 6d 61 74 63 68 20  s already match 
2b90: 6f 72 20 63 61 6e 20 62 65 20 63 68 61 6e 67 65  or can be change
2ba0: 64 0a 20 20 20 20 20 20 20 20 2a 2a 20 74 6f 20  d.        ** to 
2bb0: 64 6f 20 73 6f 20 75 73 69 6e 67 20 63 68 6d 6f  do so using chmo
2bc0: 64 28 29 2c 20 69 74 20 69 73 20 6e 6f 74 20 61  d(), it is not a
2bd0: 6e 20 65 72 72 6f 72 2e 20 20 2a 2f 0a 20 20 20  n error.  */.   
2be0: 20 20 20 20 20 73 74 72 75 63 74 20 73 74 61 74       struct stat
2bf0: 20 73 53 74 61 74 3b 0a 20 20 20 20 20 20 20 20   sStat;.        
2c00: 69 66 28 20 65 72 72 6e 6f 21 3d 45 45 58 49 53  if( errno!=EEXIS
2c10: 54 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 30 21  T.         || 0!
2c20: 3d 66 69 6c 65 53 74 61 74 28 7a 46 69 6c 65 2c  =fileStat(zFile,
2c30: 20 26 73 53 74 61 74 29 0a 20 20 20 20 20 20 20   &sStat).       
2c40: 20 20 7c 7c 20 21 53 5f 49 53 44 49 52 28 73 53    || !S_ISDIR(sS
2c50: 74 61 74 2e 73 74 5f 6d 6f 64 65 29 0a 20 20 20  tat.st_mode).   
2c60: 20 20 20 20 20 20 7c 7c 20 28 28 73 53 74 61 74        || ((sStat
2c70: 2e 73 74 5f 6d 6f 64 65 26 30 37 37 37 29 21 3d  .st_mode&0777)!=
2c80: 28 6d 6f 64 65 26 30 37 37 37 29 20 26 26 20 30  (mode&0777) && 0
2c90: 21 3d 63 68 6d 6f 64 28 7a 46 69 6c 65 2c 20 6d  !=chmod(zFile, m
2ca0: 6f 64 65 26 30 37 37 37 29 29 0a 20 20 20 20 20  ode&0777)).     
2cb0: 20 20 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20     ){.          
2cc0: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 20 20  return 1;.      
2cd0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
2ce0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 73 71 6c  }else{.      sql
2cf0: 69 74 65 33 5f 69 6e 74 36 34 20 6e 57 72 69 74  ite3_int64 nWrit
2d00: 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 6f 6e  e = 0;.      con
2d10: 73 74 20 63 68 61 72 20 2a 7a 3b 0a 20 20 20 20  st char *z;.    
2d20: 20 20 69 6e 74 20 72 63 20 3d 20 30 3b 0a 20 20    int rc = 0;.  
2d30: 20 20 20 20 46 49 4c 45 20 2a 6f 75 74 20 3d 20      FILE *out = 
2d40: 66 6f 70 65 6e 28 7a 46 69 6c 65 2c 20 22 77 62  fopen(zFile, "wb
2d50: 22 29 3b 0a 20 20 20 20 20 20 69 66 28 20 6f 75  ");.      if( ou
2d60: 74 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b  t==0 ) return 1;
2d70: 0a 20 20 20 20 20 20 7a 20 3d 20 28 63 6f 6e 73  .      z = (cons
2d80: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
2d90: 76 61 6c 75 65 5f 62 6c 6f 62 28 70 44 61 74 61  value_blob(pData
2da0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 20 29  );.      if( z )
2db0: 7b 0a 20 20 20 20 20 20 20 20 73 71 6c 69 74 65  {.        sqlite
2dc0: 33 5f 69 6e 74 36 34 20 6e 20 3d 20 66 77 72 69  3_int64 n = fwri
2dd0: 74 65 28 7a 2c 20 31 2c 20 73 71 6c 69 74 65 33  te(z, 1, sqlite3
2de0: 5f 76 61 6c 75 65 5f 62 79 74 65 73 28 70 44 61  _value_bytes(pDa
2df0: 74 61 29 2c 20 6f 75 74 29 3b 0a 20 20 20 20 20  ta), out);.     
2e00: 20 20 20 6e 57 72 69 74 65 20 3d 20 73 71 6c 69     nWrite = sqli
2e10: 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65 73 28  te3_value_bytes(
2e20: 70 44 61 74 61 29 3b 0a 20 20 20 20 20 20 20 20  pData);.        
2e30: 69 66 28 20 6e 57 72 69 74 65 21 3d 6e 20 29 7b  if( nWrite!=n ){
2e40: 0a 20 20 20 20 20 20 20 20 20 20 72 63 20 3d 20  .          rc = 
2e50: 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  1;.        }.   
2e60: 20 20 20 7d 0a 20 20 20 20 20 20 66 63 6c 6f 73     }.      fclos
2e70: 65 28 6f 75 74 29 3b 0a 20 20 20 20 20 20 69 66  e(out);.      if
2e80: 28 20 72 63 3d 3d 30 20 26 26 20 6d 6f 64 65 20  ( rc==0 && mode 
2e90: 26 26 20 63 68 6d 6f 64 28 7a 46 69 6c 65 2c 20  && chmod(zFile, 
2ea0: 6d 6f 64 65 20 26 20 30 37 37 37 29 20 29 7b 0a  mode & 0777) ){.
2eb0: 20 20 20 20 20 20 20 20 72 63 20 3d 20 31 3b 0a          rc = 1;.
2ec0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
2ed0: 28 20 72 63 20 29 20 72 65 74 75 72 6e 20 32 3b  ( rc ) return 2;
2ee0: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72  .      sqlite3_r
2ef0: 65 73 75 6c 74 5f 69 6e 74 36 34 28 70 43 74 78  esult_int64(pCtx
2f00: 2c 20 6e 57 72 69 74 65 29 3b 0a 20 20 20 20 7d  , nWrite);.    }
2f10: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 6d 74 69 6d  .  }..  if( mtim
2f20: 65 3e 3d 30 20 29 7b 0a 23 69 66 20 64 65 66 69  e>=0 ){.#if defi
2f30: 6e 65 64 28 5f 57 49 4e 33 32 29 0a 20 20 20 20  ned(_WIN32).    
2f40: 2f 2a 20 57 69 6e 64 6f 77 73 20 2a 2f 0a 20 20  /* Windows */.  
2f50: 20 20 46 49 4c 45 54 49 4d 45 20 6c 61 73 74 41    FILETIME lastA
2f60: 63 63 65 73 73 3b 0a 20 20 20 20 46 49 4c 45 54  ccess;.    FILET
2f70: 49 4d 45 20 6c 61 73 74 57 72 69 74 65 3b 0a 20  IME lastWrite;. 
2f80: 20 20 20 53 59 53 54 45 4d 54 49 4d 45 20 63 75     SYSTEMTIME cu
2f90: 72 72 65 6e 74 54 69 6d 65 3b 0a 20 20 20 20 4c  rrentTime;.    L
2fa0: 4f 4e 47 4c 4f 4e 47 20 69 6e 74 65 72 76 61 6c  ONGLONG interval
2fb0: 73 3b 0a 20 20 20 20 48 41 4e 44 4c 45 20 68 46  s;.    HANDLE hF
2fc0: 69 6c 65 3b 0a 20 20 20 20 4c 50 57 53 54 52 20  ile;.    LPWSTR 
2fd0: 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 3b 0a 20 20  zUnicodeName;.  
2fe0: 20 20 65 78 74 65 72 6e 20 4c 50 57 53 54 52 20    extern LPWSTR 
2ff0: 73 71 6c 69 74 65 33 5f 77 69 6e 33 32 5f 75 74  sqlite3_win32_ut
3000: 66 38 5f 74 6f 5f 75 6e 69 63 6f 64 65 28 63 6f  f8_to_unicode(co
3010: 6e 73 74 20 63 68 61 72 2a 29 3b 0a 0a 20 20 20  nst char*);..   
3020: 20 47 65 74 53 79 73 74 65 6d 54 69 6d 65 28 26   GetSystemTime(&
3030: 63 75 72 72 65 6e 74 54 69 6d 65 29 3b 0a 20 20  currentTime);.  
3040: 20 20 53 79 73 74 65 6d 54 69 6d 65 54 6f 46 69    SystemTimeToFi
3050: 6c 65 54 69 6d 65 28 26 63 75 72 72 65 6e 74 54  leTime(&currentT
3060: 69 6d 65 2c 20 26 6c 61 73 74 41 63 63 65 73 73  ime, &lastAccess
3070: 29 3b 0a 20 20 20 20 69 6e 74 65 72 76 61 6c 73  );.    intervals
3080: 20 3d 20 49 6e 74 33 32 78 33 32 54 6f 36 34 28   = Int32x32To64(
3090: 6d 74 69 6d 65 2c 20 31 30 30 30 30 30 30 30 29  mtime, 10000000)
30a0: 20 2b 20 31 31 36 34 34 34 37 33 36 30 30 30 30   + 1164447360000
30b0: 30 30 30 30 30 3b 0a 20 20 20 20 6c 61 73 74 57  00000;.    lastW
30c0: 72 69 74 65 2e 64 77 4c 6f 77 44 61 74 65 54 69  rite.dwLowDateTi
30d0: 6d 65 20 3d 20 28 44 57 4f 52 44 29 69 6e 74 65  me = (DWORD)inte
30e0: 72 76 61 6c 73 3b 0a 20 20 20 20 6c 61 73 74 57  rvals;.    lastW
30f0: 72 69 74 65 2e 64 77 48 69 67 68 44 61 74 65 54  rite.dwHighDateT
3100: 69 6d 65 20 3d 20 69 6e 74 65 72 76 61 6c 73 20  ime = intervals 
3110: 3e 3e 20 33 32 3b 0a 20 20 20 20 7a 55 6e 69 63  >> 32;.    zUnic
3120: 6f 64 65 4e 61 6d 65 20 3d 20 73 71 6c 69 74 65  odeName = sqlite
3130: 33 5f 77 69 6e 33 32 5f 75 74 66 38 5f 74 6f 5f  3_win32_utf8_to_
3140: 75 6e 69 63 6f 64 65 28 7a 46 69 6c 65 29 3b 0a  unicode(zFile);.
3150: 20 20 20 20 69 66 28 20 7a 55 6e 69 63 6f 64 65      if( zUnicode
3160: 4e 61 6d 65 3d 3d 30 20 29 7b 0a 20 20 20 20 20  Name==0 ){.     
3170: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d   return 1;.    }
3180: 0a 20 20 20 20 68 46 69 6c 65 20 3d 20 43 72 65  .    hFile = Cre
3190: 61 74 65 46 69 6c 65 57 28 0a 20 20 20 20 20 20  ateFileW(.      
31a0: 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 2c 20 46 49  zUnicodeName, FI
31b0: 4c 45 5f 57 52 49 54 45 5f 41 54 54 52 49 42 55  LE_WRITE_ATTRIBU
31c0: 54 45 53 2c 20 30 2c 20 4e 55 4c 4c 2c 20 4f 50  TES, 0, NULL, OP
31d0: 45 4e 5f 45 58 49 53 54 49 4e 47 2c 0a 20 20 20  EN_EXISTING,.   
31e0: 20 20 20 46 49 4c 45 5f 46 4c 41 47 5f 42 41 43     FILE_FLAG_BAC
31f0: 4b 55 50 5f 53 45 4d 41 4e 54 49 43 53 2c 20 4e  KUP_SEMANTICS, N
3200: 55 4c 4c 0a 20 20 20 20 29 3b 0a 20 20 20 20 73  ULL.    );.    s
3210: 71 6c 69 74 65 33 5f 66 72 65 65 28 7a 55 6e 69  qlite3_free(zUni
3220: 63 6f 64 65 4e 61 6d 65 29 3b 0a 20 20 20 20 69  codeName);.    i
3230: 66 28 20 68 46 69 6c 65 21 3d 49 4e 56 41 4c 49  f( hFile!=INVALI
3240: 44 5f 48 41 4e 44 4c 45 5f 56 41 4c 55 45 20 29  D_HANDLE_VALUE )
3250: 7b 0a 20 20 20 20 20 20 42 4f 4f 4c 20 62 52 65  {.      BOOL bRe
3260: 73 75 6c 74 20 3d 20 53 65 74 46 69 6c 65 54 69  sult = SetFileTi
3270: 6d 65 28 68 46 69 6c 65 2c 20 4e 55 4c 4c 2c 20  me(hFile, NULL, 
3280: 26 6c 61 73 74 41 63 63 65 73 73 2c 20 26 6c 61  &lastAccess, &la
3290: 73 74 57 72 69 74 65 29 3b 0a 20 20 20 20 20 20  stWrite);.      
32a0: 43 6c 6f 73 65 48 61 6e 64 6c 65 28 68 46 69 6c  CloseHandle(hFil
32b0: 65 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e  e);.      return
32c0: 20 21 62 52 65 73 75 6c 74 3b 0a 20 20 20 20 7d   !bResult;.    }
32d0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 72 65 74 75  else{.      retu
32e0: 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6c 69  rn 1;.    }.#eli
32f0: 66 20 64 65 66 69 6e 65 64 28 41 54 5f 46 44 43  f defined(AT_FDC
3300: 57 44 29 20 26 26 20 30 20 2f 2a 20 75 74 69 6d  WD) && 0 /* utim
3310: 65 6e 73 61 74 28 29 20 69 73 20 6e 6f 74 20 75  ensat() is not u
3320: 6e 69 76 65 72 73 61 6c 6c 79 20 61 76 61 69 6c  niversally avail
3330: 61 62 6c 65 20 2a 2f 0a 20 20 20 20 2f 2a 20 52  able */.    /* R
3340: 65 63 65 6e 74 20 75 6e 69 78 20 2a 2f 0a 20 20  ecent unix */.  
3350: 20 20 73 74 72 75 63 74 20 74 69 6d 65 73 70 65    struct timespe
3360: 63 20 74 69 6d 65 73 5b 32 5d 3b 0a 20 20 20 20  c times[2];.    
3370: 74 69 6d 65 73 5b 30 5d 2e 74 76 5f 6e 73 65 63  times[0].tv_nsec
3380: 20 3d 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 6e   = times[1].tv_n
3390: 73 65 63 20 3d 20 30 3b 0a 20 20 20 20 74 69 6d  sec = 0;.    tim
33a0: 65 73 5b 30 5d 2e 74 76 5f 73 65 63 20 3d 20 74  es[0].tv_sec = t
33b0: 69 6d 65 28 30 29 3b 0a 20 20 20 20 74 69 6d 65  ime(0);.    time
33c0: 73 5b 31 5d 2e 74 76 5f 73 65 63 20 3d 20 6d 74  s[1].tv_sec = mt
33d0: 69 6d 65 3b 0a 20 20 20 20 69 66 28 20 75 74 69  ime;.    if( uti
33e0: 6d 65 6e 73 61 74 28 41 54 5f 46 44 43 57 44 2c  mensat(AT_FDCWD,
33f0: 20 7a 46 69 6c 65 2c 20 74 69 6d 65 73 2c 20 41   zFile, times, A
3400: 54 5f 53 59 4d 4c 49 4e 4b 5f 4e 4f 46 4f 4c 4c  T_SYMLINK_NOFOLL
3410: 4f 57 29 20 29 7b 0a 20 20 20 20 20 20 72 65 74  OW) ){.      ret
3420: 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6c  urn 1;.    }.#el
3430: 73 65 0a 20 20 20 20 2f 2a 20 4c 65 67 61 63 79  se.    /* Legacy
3440: 20 75 6e 69 78 20 2a 2f 0a 20 20 20 20 73 74 72   unix */.    str
3450: 75 63 74 20 74 69 6d 65 76 61 6c 20 74 69 6d 65  uct timeval time
3460: 73 5b 32 5d 3b 0a 20 20 20 20 74 69 6d 65 73 5b  s[2];.    times[
3470: 30 5d 2e 74 76 5f 75 73 65 63 20 3d 20 74 69 6d  0].tv_usec = tim
3480: 65 73 5b 31 5d 2e 74 76 5f 75 73 65 63 20 3d 20  es[1].tv_usec = 
3490: 30 3b 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e  0;.    times[0].
34a0: 74 76 5f 73 65 63 20 3d 20 74 69 6d 65 28 30 29  tv_sec = time(0)
34b0: 3b 0a 20 20 20 20 74 69 6d 65 73 5b 31 5d 2e 74  ;.    times[1].t
34c0: 76 5f 73 65 63 20 3d 20 6d 74 69 6d 65 3b 0a 20  v_sec = mtime;. 
34d0: 20 20 20 69 66 28 20 75 74 69 6d 65 73 28 7a 46     if( utimes(zF
34e0: 69 6c 65 2c 20 74 69 6d 65 73 29 20 29 7b 0a 20  ile, times) ){. 
34f0: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
3500: 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20 7d 0a     }.#endif.  }.
3510: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a  .  return 0;.}..
3520: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 61  /*.** Implementa
3530: 74 69 6f 6e 20 6f 66 20 74 68 65 20 22 77 72 69  tion of the "wri
3540: 74 65 66 69 6c 65 28 57 2c 58 5b 2c 59 5b 2c 5a  tefile(W,X[,Y[,Z
3550: 5d 5d 5d 29 22 20 53 51 4c 20 66 75 6e 63 74 69  ]]])" SQL functi
3560: 6f 6e 2e 20 20 0a 2a 2a 20 52 65 66 65 72 20 74  on.  .** Refer t
3570: 6f 20 68 65 61 64 65 72 20 63 6f 6d 6d 65 6e 74  o header comment
3580: 73 20 61 74 20 74 68 65 20 74 6f 70 20 6f 66 20  s at the top of 
3590: 74 68 69 73 20 66 69 6c 65 20 66 6f 72 20 64 65  this file for de
35a0: 74 61 69 6c 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  tails..*/.static
35b0: 20 76 6f 69 64 20 77 72 69 74 65 66 69 6c 65 46   void writefileF
35c0: 75 6e 63 28 0a 20 20 73 71 6c 69 74 65 33 5f 63  unc(.  sqlite3_c
35d0: 6f 6e 74 65 78 74 20 2a 63 6f 6e 74 65 78 74 2c  ontext *context,
35e0: 0a 20 20 69 6e 74 20 61 72 67 63 2c 0a 20 20 73  .  int argc,.  s
35f0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a 61  qlite3_value **a
3600: 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63  rgv.){.  const c
3610: 68 61 72 20 2a 7a 46 69 6c 65 3b 0a 20 20 6d 6f  har *zFile;.  mo
3620: 64 65 5f 74 20 6d 6f 64 65 20 3d 20 30 3b 0a 20  de_t mode = 0;. 
3630: 20 69 6e 74 20 72 65 73 3b 0a 20 20 73 71 6c 69   int res;.  sqli
3640: 74 65 33 5f 69 6e 74 36 34 20 6d 74 69 6d 65 20  te3_int64 mtime 
3650: 3d 20 2d 31 3b 0a 0a 20 20 69 66 28 20 61 72 67  = -1;..  if( arg
3660: 63 3c 32 20 7c 7c 20 61 72 67 63 3e 34 20 29 7b  c<2 || argc>4 ){
3670: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73  .    sqlite3_res
3680: 75 6c 74 5f 65 72 72 6f 72 28 63 6f 6e 74 65 78  ult_error(contex
3690: 74 2c 20 0a 20 20 20 20 20 20 20 20 22 77 72 6f  t, .        "wro
36a0: 6e 67 20 6e 75 6d 62 65 72 20 6f 66 20 61 72 67  ng number of arg
36b0: 75 6d 65 6e 74 73 20 74 6f 20 66 75 6e 63 74 69  uments to functi
36c0: 6f 6e 20 77 72 69 74 65 66 69 6c 65 28 29 22 2c  on writefile()",
36d0: 20 2d 31 0a 20 20 20 20 29 3b 0a 20 20 20 20 72   -1.    );.    r
36e0: 65 74 75 72 6e 3b 0a 20 20 7d 0a 0a 20 20 7a 46  eturn;.  }..  zF
36f0: 69 6c 65 20 3d 20 28 63 6f 6e 73 74 20 63 68 61  ile = (const cha
3700: 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  r*)sqlite3_value
3710: 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b 0a  _text(argv[0]);.
3720: 20 20 69 66 28 20 7a 46 69 6c 65 3d 3d 30 20 29    if( zFile==0 )
3730: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 61   return;.  if( a
3740: 72 67 63 3e 3d 33 20 29 7b 0a 20 20 20 20 6d 6f  rgc>=3 ){.    mo
3750: 64 65 20 3d 20 28 6d 6f 64 65 5f 74 29 73 71 6c  de = (mode_t)sql
3760: 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74 28 61  ite3_value_int(a
3770: 72 67 76 5b 32 5d 29 3b 0a 20 20 7d 0a 20 20 69  rgv[2]);.  }.  i
3780: 66 28 20 61 72 67 63 3d 3d 34 20 29 7b 0a 20 20  f( argc==4 ){.  
3790: 20 20 6d 74 69 6d 65 20 3d 20 73 71 6c 69 74 65    mtime = sqlite
37a0: 33 5f 76 61 6c 75 65 5f 69 6e 74 36 34 28 61 72  3_value_int64(ar
37b0: 67 76 5b 33 5d 29 3b 0a 20 20 7d 0a 0a 20 20 72  gv[3]);.  }..  r
37c0: 65 73 20 3d 20 77 72 69 74 65 46 69 6c 65 28 63  es = writeFile(c
37d0: 6f 6e 74 65 78 74 2c 20 7a 46 69 6c 65 2c 20 61  ontext, zFile, a
37e0: 72 67 76 5b 31 5d 2c 20 6d 6f 64 65 2c 20 6d 74  rgv[1], mode, mt
37f0: 69 6d 65 29 3b 0a 20 20 69 66 28 20 72 65 73 3d  ime);.  if( res=
3800: 3d 31 20 26 26 20 65 72 72 6e 6f 3d 3d 45 4e 4f  =1 && errno==ENO
3810: 45 4e 54 20 29 7b 0a 20 20 20 20 69 66 28 20 6d  ENT ){.    if( m
3820: 61 6b 65 44 69 72 65 63 74 6f 72 79 28 7a 46 69  akeDirectory(zFi
3830: 6c 65 29 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29  le)==SQLITE_OK )
3840: 7b 0a 20 20 20 20 20 20 72 65 73 20 3d 20 77 72  {.      res = wr
3850: 69 74 65 46 69 6c 65 28 63 6f 6e 74 65 78 74 2c  iteFile(context,
3860: 20 7a 46 69 6c 65 2c 20 61 72 67 76 5b 31 5d 2c   zFile, argv[1],
3870: 20 6d 6f 64 65 2c 20 6d 74 69 6d 65 29 3b 0a 20   mode, mtime);. 
3880: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28 20     }.  }..  if( 
3890: 61 72 67 63 3e 32 20 26 26 20 72 65 73 21 3d 30  argc>2 && res!=0
38a0: 20 29 7b 0a 20 20 20 20 69 66 28 20 53 5f 49 53   ){.    if( S_IS
38b0: 4c 4e 4b 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20  LNK(mode) ){.   
38c0: 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67 28 63     ctxErrorMsg(c
38d0: 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65 64 20  ontext, "failed 
38e0: 74 6f 20 63 72 65 61 74 65 20 73 79 6d 6c 69 6e  to create symlin
38f0: 6b 3a 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a  k: %s", zFile);.
3900: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 53 5f      }else if( S_
3910: 49 53 44 49 52 28 6d 6f 64 65 29 20 29 7b 0a 20  ISDIR(mode) ){. 
3920: 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67       ctxErrorMsg
3930: 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65  (context, "faile
3940: 64 20 74 6f 20 63 72 65 61 74 65 20 64 69 72 65  d to create dire
3950: 63 74 6f 72 79 3a 20 25 73 22 2c 20 7a 46 69 6c  ctory: %s", zFil
3960: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  e);.    }else{. 
3970: 20 20 20 20 20 63 74 78 45 72 72 6f 72 4d 73 67       ctxErrorMsg
3980: 28 63 6f 6e 74 65 78 74 2c 20 22 66 61 69 6c 65  (context, "faile
3990: 64 20 74 6f 20 77 72 69 74 65 20 66 69 6c 65 3a  d to write file:
39a0: 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20   %s", zFile);.  
39b0: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
39c0: 20 53 51 4c 20 66 75 6e 63 74 69 6f 6e 3a 20 20   SQL function:  
39d0: 20 6c 73 6d 6f 64 65 28 4d 4f 44 45 29 0a 2a 2a   lsmode(MODE).**
39e0: 0a 2a 2a 20 47 69 76 65 6e 20 61 20 6e 75 6d 62  .** Given a numb
39f0: 65 72 69 63 20 73 74 5f 6d 6f 64 65 20 66 72 6f  eric st_mode fro
3a00: 6d 20 73 74 61 74 28 29 2c 20 63 6f 6e 76 65 72  m stat(), conver
3a10: 74 20 69 74 20 69 6e 74 6f 20 61 20 68 75 6d 61  t it into a huma
3a20: 6e 2d 72 65 61 64 61 62 6c 65 0a 2a 2a 20 74 65  n-readable.** te
3a30: 78 74 20 73 74 72 69 6e 67 20 69 6e 20 74 68 65  xt string in the
3a40: 20 73 74 79 6c 65 20 6f 66 20 22 6c 73 20 2d 6c   style of "ls -l
3a50: 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  "..*/.static voi
3a60: 64 20 6c 73 4d 6f 64 65 46 75 6e 63 28 0a 20 20  d lsModeFunc(.  
3a70: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
3a80: 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  *context,.  int 
3a90: 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
3aa0: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
3ab0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 69    int i;.  int i
3ac0: 4d 6f 64 65 20 3d 20 73 71 6c 69 74 65 33 5f 76  Mode = sqlite3_v
3ad0: 61 6c 75 65 5f 69 6e 74 28 61 72 67 76 5b 30 5d  alue_int(argv[0]
3ae0: 29 3b 0a 20 20 63 68 61 72 20 7a 5b 31 36 5d 3b  );.  char z[16];
3af0: 0a 20 20 28 76 6f 69 64 29 61 72 67 63 3b 0a 20  .  (void)argc;. 
3b00: 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 69 4d 6f   if( S_ISLNK(iMo
3b10: 64 65 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20  de) ){.    z[0] 
3b20: 3d 20 27 6c 27 3b 0a 20 20 7d 65 6c 73 65 20 69  = 'l';.  }else i
3b30: 66 28 20 53 5f 49 53 52 45 47 28 69 4d 6f 64 65  f( S_ISREG(iMode
3b40: 29 20 29 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d 20  ) ){.    z[0] = 
3b50: 27 2d 27 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  '-';.  }else if(
3b60: 20 53 5f 49 53 44 49 52 28 69 4d 6f 64 65 29 20   S_ISDIR(iMode) 
3b70: 29 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d 20 27 64  ){.    z[0] = 'd
3b80: 27 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  ';.  }else{.    
3b90: 7a 5b 30 5d 20 3d 20 27 3f 27 3b 0a 20 20 7d 0a  z[0] = '?';.  }.
3ba0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 33 3b 20    for(i=0; i<3; 
3bb0: 69 2b 2b 29 7b 0a 20 20 20 20 69 6e 74 20 6d 20  i++){.    int m 
3bc0: 3d 20 28 69 4d 6f 64 65 20 3e 3e 20 28 28 32 2d  = (iMode >> ((2-
3bd0: 69 29 2a 33 29 29 3b 0a 20 20 20 20 63 68 61 72  i)*3));.    char
3be0: 20 2a 61 20 3d 20 26 7a 5b 31 20 2b 20 69 2a 33   *a = &z[1 + i*3
3bf0: 5d 3b 0a 20 20 20 20 61 5b 30 5d 20 3d 20 28 6d  ];.    a[0] = (m
3c00: 20 26 20 30 78 34 29 20 3f 20 27 72 27 20 3a 20   & 0x4) ? 'r' : 
3c10: 27 2d 27 3b 0a 20 20 20 20 61 5b 31 5d 20 3d 20  '-';.    a[1] = 
3c20: 28 6d 20 26 20 30 78 32 29 20 3f 20 27 77 27 20  (m & 0x2) ? 'w' 
3c30: 3a 20 27 2d 27 3b 0a 20 20 20 20 61 5b 32 5d 20  : '-';.    a[2] 
3c40: 3d 20 28 6d 20 26 20 30 78 31 29 20 3f 20 27 78  = (m & 0x1) ? 'x
3c50: 27 20 3a 20 27 2d 27 3b 0a 20 20 7d 0a 20 20 7a  ' : '-';.  }.  z
3c60: 5b 31 30 5d 20 3d 20 27 5c 30 27 3b 0a 20 20 73  [10] = '\0';.  s
3c70: 71 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65  qlite3_result_te
3c80: 78 74 28 63 6f 6e 74 65 78 74 2c 20 7a 2c 20 2d  xt(context, z, -
3c90: 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53 49  1, SQLITE_TRANSI
3ca0: 45 4e 54 29 3b 0a 7d 0a 0a 23 69 66 6e 64 65 66  ENT);.}..#ifndef
3cb0: 20 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52   SQLITE_OMIT_VIR
3cc0: 54 55 41 4c 54 41 42 4c 45 0a 0a 2f 2a 20 0a 2a  TUALTABLE../* .*
3cd0: 2a 20 43 75 72 73 6f 72 20 74 79 70 65 20 66 6f  * Cursor type fo
3ce0: 72 20 72 65 63 75 72 73 69 76 65 6c 79 20 69 74  r recursively it
3cf0: 65 72 61 74 69 6e 67 20 74 68 72 6f 75 67 68 20  erating through 
3d00: 61 20 64 69 72 65 63 74 6f 72 79 20 73 74 72 75  a directory stru
3d10: 63 74 75 72 65 2e 0a 2a 2f 0a 74 79 70 65 64 65  cture..*/.typede
3d20: 66 20 73 74 72 75 63 74 20 66 73 64 69 72 5f 63  f struct fsdir_c
3d30: 75 72 73 6f 72 20 66 73 64 69 72 5f 63 75 72 73  ursor fsdir_curs
3d40: 6f 72 3b 0a 74 79 70 65 64 65 66 20 73 74 72 75  or;.typedef stru
3d50: 63 74 20 46 73 64 69 72 4c 65 76 65 6c 20 46 73  ct FsdirLevel Fs
3d60: 64 69 72 4c 65 76 65 6c 3b 0a 0a 73 74 72 75 63  dirLevel;..struc
3d70: 74 20 46 73 64 69 72 4c 65 76 65 6c 20 7b 0a 20  t FsdirLevel {. 
3d80: 20 44 49 52 20 2a 70 44 69 72 3b 20 20 20 20 20   DIR *pDir;     
3d90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 46              /* F
3da0: 72 6f 6d 20 6f 70 65 6e 64 69 72 28 29 20 2a 2f  rom opendir() */
3db0: 0a 20 20 63 68 61 72 20 2a 7a 44 69 72 3b 20 20  .  char *zDir;  
3dc0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
3dd0: 20 4e 61 6d 65 20 6f 66 20 64 69 72 65 63 74 6f   Name of directo
3de0: 72 79 20 28 6e 75 6c 2d 74 65 72 6d 69 6e 61 74  ry (nul-terminat
3df0: 65 64 29 20 2a 2f 0a 7d 3b 0a 0a 73 74 72 75 63  ed) */.};..struc
3e00: 74 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 7b  t fsdir_cursor {
3e10: 0a 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 5f  .  sqlite3_vtab_
3e20: 63 75 72 73 6f 72 20 62 61 73 65 3b 20 20 2f 2a  cursor base;  /*
3e30: 20 42 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75   Base class - mu
3e40: 73 74 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 0a  st be first */..
3e50: 20 20 69 6e 74 20 6e 4c 76 6c 3b 20 20 20 20 20    int nLvl;     
3e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
3e70: 4e 75 6d 62 65 72 20 6f 66 20 65 6e 74 72 69 65  Number of entrie
3e80: 73 20 69 6e 20 61 4c 76 6c 5b 5d 20 61 72 72 61  s in aLvl[] arra
3e90: 79 20 2a 2f 0a 20 20 69 6e 74 20 69 4c 76 6c 3b  y */.  int iLvl;
3ea0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
3eb0: 20 20 2f 2a 20 49 6e 64 65 78 20 6f 66 20 63 75    /* Index of cu
3ec0: 72 72 65 6e 74 20 65 6e 74 72 79 20 2a 2f 0a 20  rrent entry */. 
3ed0: 20 46 73 64 69 72 4c 65 76 65 6c 20 2a 61 4c 76   FsdirLevel *aLv
3ee0: 6c 3b 20 20 20 20 20 20 20 20 20 20 2f 2a 20 48  l;          /* H
3ef0: 69 65 72 61 72 63 68 79 20 6f 66 20 64 69 72 65  ierarchy of dire
3f00: 63 74 6f 72 69 65 73 20 62 65 69 6e 67 20 74 72  ctories being tr
3f10: 61 76 65 72 73 65 64 20 2a 2f 0a 0a 20 20 63 6f  aversed */..  co
3f20: 6e 73 74 20 63 68 61 72 20 2a 7a 42 61 73 65 3b  nst char *zBase;
3f30: 0a 20 20 69 6e 74 20 6e 42 61 73 65 3b 0a 0a 20  .  int nBase;.. 
3f40: 20 73 74 72 75 63 74 20 73 74 61 74 20 73 53 74   struct stat sSt
3f50: 61 74 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 43  at;         /* C
3f60: 75 72 72 65 6e 74 20 6c 73 74 61 74 28 29 20 72  urrent lstat() r
3f70: 65 73 75 6c 74 73 20 2a 2f 0a 20 20 63 68 61 72  esults */.  char
3f80: 20 2a 7a 50 61 74 68 3b 20 20 20 20 20 20 20 20   *zPath;        
3f90: 20 20 20 20 20 20 20 2f 2a 20 50 61 74 68 20 74         /* Path t
3fa0: 6f 20 63 75 72 72 65 6e 74 20 65 6e 74 72 79 20  o current entry 
3fb0: 2a 2f 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74  */.  sqlite3_int
3fc0: 36 34 20 69 52 6f 77 69 64 3b 20 20 20 20 20 20  64 iRowid;      
3fd0: 2f 2a 20 43 75 72 72 65 6e 74 20 72 6f 77 69 64  /* Current rowid
3fe0: 20 2a 2f 0a 7d 3b 0a 0a 74 79 70 65 64 65 66 20   */.};..typedef 
3ff0: 73 74 72 75 63 74 20 66 73 64 69 72 5f 74 61 62  struct fsdir_tab
4000: 20 66 73 64 69 72 5f 74 61 62 3b 0a 73 74 72 75   fsdir_tab;.stru
4010: 63 74 20 66 73 64 69 72 5f 74 61 62 20 7b 0a 20  ct fsdir_tab {. 
4020: 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 62 61   sqlite3_vtab ba
4030: 73 65 3b 20 20 20 20 20 20 20 20 20 2f 2a 20 42  se;         /* B
4040: 61 73 65 20 63 6c 61 73 73 20 2d 20 6d 75 73 74  ase class - must
4050: 20 62 65 20 66 69 72 73 74 20 2a 2f 0a 7d 3b 0a   be first */.};.
4060: 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63 74  ./*.** Construct
4070: 20 61 20 6e 65 77 20 66 73 64 69 72 20 76 69 72   a new fsdir vir
4080: 74 75 61 6c 20 74 61 62 6c 65 20 6f 62 6a 65 63  tual table objec
4090: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
40a0: 20 66 73 64 69 72 43 6f 6e 6e 65 63 74 28 0a 20   fsdirConnect(. 
40b0: 20 73 71 6c 69 74 65 33 20 2a 64 62 2c 0a 20 20   sqlite3 *db,.  
40c0: 76 6f 69 64 20 2a 70 41 75 78 2c 0a 20 20 69 6e  void *pAux,.  in
40d0: 74 20 61 72 67 63 2c 20 63 6f 6e 73 74 20 63 68  t argc, const ch
40e0: 61 72 20 2a 63 6f 6e 73 74 2a 61 72 67 76 2c 0a  ar *const*argv,.
40f0: 20 20 73 71 6c 69 74 65 33 5f 76 74 61 62 20 2a    sqlite3_vtab *
4100: 2a 70 70 56 74 61 62 2c 0a 20 20 63 68 61 72 20  *ppVtab,.  char 
4110: 2a 2a 70 7a 45 72 72 0a 29 7b 0a 20 20 66 73 64  **pzErr.){.  fsd
4120: 69 72 5f 74 61 62 20 2a 70 4e 65 77 20 3d 20 30  ir_tab *pNew = 0
4130: 3b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20 28 76  ;.  int rc;.  (v
4140: 6f 69 64 29 70 41 75 78 3b 0a 20 20 28 76 6f 69  oid)pAux;.  (voi
4150: 64 29 61 72 67 63 3b 0a 20 20 28 76 6f 69 64 29  d)argc;.  (void)
4160: 61 72 67 76 3b 0a 20 20 28 76 6f 69 64 29 70 7a  argv;.  (void)pz
4170: 45 72 72 3b 0a 20 20 72 63 20 3d 20 73 71 6c 69  Err;.  rc = sqli
4180: 74 65 33 5f 64 65 63 6c 61 72 65 5f 76 74 61 62  te3_declare_vtab
4190: 28 64 62 2c 20 22 43 52 45 41 54 45 20 54 41 42  (db, "CREATE TAB
41a0: 4c 45 20 78 22 20 46 53 44 49 52 5f 53 43 48 45  LE x" FSDIR_SCHE
41b0: 4d 41 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 53  MA);.  if( rc==S
41c0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
41d0: 70 4e 65 77 20 3d 20 28 66 73 64 69 72 5f 74 61  pNew = (fsdir_ta
41e0: 62 2a 29 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f  b*)sqlite3_mallo
41f0: 63 28 20 73 69 7a 65 6f 66 28 2a 70 4e 65 77 29  c( sizeof(*pNew)
4200: 20 29 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77   );.    if( pNew
4210: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
4220: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 6d  ITE_NOMEM;.    m
4230: 65 6d 73 65 74 28 70 4e 65 77 2c 20 30 2c 20 73  emset(pNew, 0, s
4240: 69 7a 65 6f 66 28 2a 70 4e 65 77 29 29 3b 0a 20  izeof(*pNew));. 
4250: 20 7d 0a 20 20 2a 70 70 56 74 61 62 20 3d 20 28   }.  *ppVtab = (
4260: 73 71 6c 69 74 65 33 5f 76 74 61 62 2a 29 70 4e  sqlite3_vtab*)pN
4270: 65 77 3b 0a 20 20 72 65 74 75 72 6e 20 72 63 3b  ew;.  return rc;
4280: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 6d  .}../*.** This m
4290: 65 74 68 6f 64 20 69 73 20 74 68 65 20 64 65 73  ethod is the des
42a0: 74 72 75 63 74 6f 72 20 66 6f 72 20 66 73 64 69  tructor for fsdi
42b0: 72 20 76 74 61 62 20 6f 62 6a 65 63 74 73 2e 0a  r vtab objects..
42c0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
42d0: 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 28 73 71  dirDisconnect(sq
42e0: 6c 69 74 65 33 5f 76 74 61 62 20 2a 70 56 74 61  lite3_vtab *pVta
42f0: 62 29 7b 0a 20 20 73 71 6c 69 74 65 33 5f 66 72  b){.  sqlite3_fr
4300: 65 65 28 70 56 74 61 62 29 3b 0a 20 20 72 65 74  ee(pVtab);.  ret
4310: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
4320: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 73 74 72 75 63  ../*.** Construc
4330: 74 6f 72 20 66 6f 72 20 61 20 6e 65 77 20 66 73  tor for a new fs
4340: 64 69 72 5f 63 75 72 73 6f 72 20 6f 62 6a 65 63  dir_cursor objec
4350: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  t..*/.static int
4360: 20 66 73 64 69 72 4f 70 65 6e 28 73 71 6c 69 74   fsdirOpen(sqlit
4370: 65 33 5f 76 74 61 62 20 2a 70 2c 20 73 71 6c 69  e3_vtab *p, sqli
4380: 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72 20  te3_vtab_cursor 
4390: 2a 2a 70 70 43 75 72 73 6f 72 29 7b 0a 20 20 66  **ppCursor){.  f
43a0: 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43 75  sdir_cursor *pCu
43b0: 72 3b 0a 20 20 28 76 6f 69 64 29 70 3b 0a 20 20  r;.  (void)p;.  
43c0: 70 43 75 72 20 3d 20 73 71 6c 69 74 65 33 5f 6d  pCur = sqlite3_m
43d0: 61 6c 6c 6f 63 28 20 73 69 7a 65 6f 66 28 2a 70  alloc( sizeof(*p
43e0: 43 75 72 29 20 29 3b 0a 20 20 69 66 28 20 70 43  Cur) );.  if( pC
43f0: 75 72 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53  ur==0 ) return S
4400: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d  QLITE_NOMEM;.  m
4410: 65 6d 73 65 74 28 70 43 75 72 2c 20 30 2c 20 73  emset(pCur, 0, s
4420: 69 7a 65 6f 66 28 2a 70 43 75 72 29 29 3b 0a 20  izeof(*pCur));. 
4430: 20 70 43 75 72 2d 3e 69 4c 76 6c 20 3d 20 2d 31   pCur->iLvl = -1
4440: 3b 0a 20 20 2a 70 70 43 75 72 73 6f 72 20 3d 20  ;.  *ppCursor = 
4450: 26 70 43 75 72 2d 3e 62 61 73 65 3b 0a 20 20 72  &pCur->base;.  r
4460: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4470: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65 74 20  .}../*.** Reset 
4480: 61 20 63 75 72 73 6f 72 20 62 61 63 6b 20 74 6f  a cursor back to
4490: 20 74 68 65 20 73 74 61 74 65 20 69 74 20 77 61   the state it wa
44a0: 73 20 69 6e 20 77 68 65 6e 20 66 69 72 73 74 20  s in when first 
44b0: 72 65 74 75 72 6e 65 64 0a 2a 2a 20 62 79 20 66  returned.** by f
44c0: 73 64 69 72 4f 70 65 6e 28 29 2e 0a 2a 2f 0a 73  sdirOpen()..*/.s
44d0: 74 61 74 69 63 20 76 6f 69 64 20 66 73 64 69 72  tatic void fsdir
44e0: 52 65 73 65 74 43 75 72 73 6f 72 28 66 73 64 69  ResetCursor(fsdi
44f0: 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 29 7b  r_cursor *pCur){
4500: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28  .  int i;.  for(
4510: 69 3d 30 3b 20 69 3c 3d 70 43 75 72 2d 3e 69 4c  i=0; i<=pCur->iL
4520: 76 6c 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 46 73  vl; i++){.    Fs
4530: 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d  dirLevel *pLvl =
4540: 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 69 5d 3b   &pCur->aLvl[i];
4550: 0a 20 20 20 20 69 66 28 20 70 4c 76 6c 2d 3e 70  .    if( pLvl->p
4560: 44 69 72 20 29 20 63 6c 6f 73 65 64 69 72 28 70  Dir ) closedir(p
4570: 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20  Lvl->pDir);.    
4580: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 4c 76  sqlite3_free(pLv
4590: 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 7d 0a 20 20  l->zDir);.  }.  
45a0: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75  sqlite3_free(pCu
45b0: 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 73 71 6c  r->zPath);.  sql
45c0: 69 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e  ite3_free(pCur->
45d0: 61 4c 76 6c 29 3b 0a 20 20 70 43 75 72 2d 3e 61  aLvl);.  pCur->a
45e0: 4c 76 6c 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d  Lvl = 0;.  pCur-
45f0: 3e 7a 50 61 74 68 20 3d 20 30 3b 0a 20 20 70 43  >zPath = 0;.  pC
4600: 75 72 2d 3e 7a 42 61 73 65 20 3d 20 30 3b 0a 20  ur->zBase = 0;. 
4610: 20 70 43 75 72 2d 3e 6e 42 61 73 65 20 3d 20 30   pCur->nBase = 0
4620: 3b 0a 20 20 70 43 75 72 2d 3e 6e 4c 76 6c 20 3d  ;.  pCur->nLvl =
4630: 20 30 3b 0a 20 20 70 43 75 72 2d 3e 69 4c 76 6c   0;.  pCur->iLvl
4640: 20 3d 20 2d 31 3b 0a 20 20 70 43 75 72 2d 3e 69   = -1;.  pCur->i
4650: 52 6f 77 69 64 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a  Rowid = 1;.}../*
4660: 0a 2a 2a 20 44 65 73 74 72 75 63 74 6f 72 20 66  .** Destructor f
4670: 6f 72 20 61 6e 20 66 73 64 69 72 5f 63 75 72 73  or an fsdir_curs
4680: 6f 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  or..*/.static in
4690: 74 20 66 73 64 69 72 43 6c 6f 73 65 28 73 71 6c  t fsdirClose(sql
46a0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
46b0: 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72 5f   *cur){.  fsdir_
46c0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
46d0: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
46e0: 72 3b 0a 0a 20 20 66 73 64 69 72 52 65 73 65 74  r;..  fsdirReset
46f0: 43 75 72 73 6f 72 28 70 43 75 72 29 3b 0a 20 20  Cursor(pCur);.  
4700: 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 43 75  sqlite3_free(pCu
4710: 72 29 3b 0a 20 20 72 65 74 75 72 6e 20 53 51 4c  r);.  return SQL
4720: 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ITE_OK;.}../*.**
4730: 20 53 65 74 20 74 68 65 20 65 72 72 6f 72 20 6d   Set the error m
4740: 65 73 73 61 67 65 20 66 6f 72 20 74 68 65 20 76  essage for the v
4750: 69 72 74 75 61 6c 20 74 61 62 6c 65 20 61 73 73  irtual table ass
4760: 6f 63 69 61 74 65 64 20 77 69 74 68 20 63 75 72  ociated with cur
4770: 73 6f 72 0a 2a 2a 20 70 43 75 72 20 74 6f 20 74  sor.** pCur to t
4780: 68 65 20 72 65 73 75 6c 74 73 20 6f 66 20 76 70  he results of vp
4790: 72 69 6e 74 66 28 7a 46 6d 74 2c 20 2e 2e 2e 29  rintf(zFmt, ...)
47a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
47b0: 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28   fsdirSetErrmsg(
47c0: 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a 70 43  fsdir_cursor *pC
47d0: 75 72 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ur, const char *
47e0: 7a 46 6d 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61  zFmt, ...){.  va
47f0: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73  _list ap;.  va_s
4800: 74 61 72 74 28 61 70 2c 20 7a 46 6d 74 29 3b 0a  tart(ap, zFmt);.
4810: 20 20 70 43 75 72 2d 3e 62 61 73 65 2e 70 56 74    pCur->base.pVt
4820: 61 62 2d 3e 7a 45 72 72 4d 73 67 20 3d 20 73 71  ab->zErrMsg = sq
4830: 6c 69 74 65 33 5f 76 6d 70 72 69 6e 74 66 28 7a  lite3_vmprintf(z
4840: 46 6d 74 2c 20 61 70 29 3b 0a 20 20 76 61 5f 65  Fmt, ap);.  va_e
4850: 6e 64 28 61 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a  nd(ap);.}.../*.*
4860: 2a 20 41 64 76 61 6e 63 65 20 61 6e 20 66 73 64  * Advance an fsd
4870: 69 72 5f 63 75 72 73 6f 72 20 74 6f 20 69 74 73  ir_cursor to its
4880: 20 6e 65 78 74 20 72 6f 77 20 6f 66 20 6f 75 74   next row of out
4890: 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  put..*/.static i
48a0: 6e 74 20 66 73 64 69 72 4e 65 78 74 28 73 71 6c  nt fsdirNext(sql
48b0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
48c0: 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72 5f   *cur){.  fsdir_
48d0: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
48e0: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
48f0: 72 3b 0a 20 20 6d 6f 64 65 5f 74 20 6d 20 3d 20  r;.  mode_t m = 
4900: 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d  pCur->sStat.st_m
4910: 6f 64 65 3b 0a 0a 20 20 70 43 75 72 2d 3e 69 52  ode;..  pCur->iR
4920: 6f 77 69 64 2b 2b 3b 0a 20 20 69 66 28 20 53 5f  owid++;.  if( S_
4930: 49 53 44 49 52 28 6d 29 20 29 7b 0a 20 20 20 20  ISDIR(m) ){.    
4940: 2f 2a 20 44 65 73 63 65 6e 64 20 69 6e 74 6f 20  /* Descend into 
4950: 74 68 69 73 20 64 69 72 65 63 74 6f 72 79 20 2a  this directory *
4960: 2f 0a 20 20 20 20 69 6e 74 20 69 4e 65 77 20 3d  /.    int iNew =
4970: 20 70 43 75 72 2d 3e 69 4c 76 6c 20 2b 20 31 3b   pCur->iLvl + 1;
4980: 0a 20 20 20 20 46 73 64 69 72 4c 65 76 65 6c 20  .    FsdirLevel 
4990: 2a 70 4c 76 6c 3b 0a 20 20 20 20 69 66 28 20 69  *pLvl;.    if( i
49a0: 4e 65 77 3e 3d 70 43 75 72 2d 3e 6e 4c 76 6c 20  New>=pCur->nLvl 
49b0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 4e 65  ){.      int nNe
49c0: 77 20 3d 20 69 4e 65 77 2b 31 3b 0a 20 20 20 20  w = iNew+1;.    
49d0: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
49e0: 6e 42 79 74 65 20 3d 20 6e 4e 65 77 2a 73 69 7a  nByte = nNew*siz
49f0: 65 6f 66 28 46 73 64 69 72 4c 65 76 65 6c 29 3b  eof(FsdirLevel);
4a00: 0a 20 20 20 20 20 20 46 73 64 69 72 4c 65 76 65  .      FsdirLeve
4a10: 6c 20 2a 61 4e 65 77 20 3d 20 28 46 73 64 69 72  l *aNew = (Fsdir
4a20: 4c 65 76 65 6c 2a 29 73 71 6c 69 74 65 33 5f 72  Level*)sqlite3_r
4a30: 65 61 6c 6c 6f 63 36 34 28 70 43 75 72 2d 3e 61  ealloc64(pCur->a
4a40: 4c 76 6c 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20  Lvl, nByte);.   
4a50: 20 20 20 69 66 28 20 61 4e 65 77 3d 3d 30 20 29     if( aNew==0 )
4a60: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
4a70: 4f 4d 45 4d 3b 0a 20 20 20 20 20 20 6d 65 6d 73  OMEM;.      mems
4a80: 65 74 28 26 61 4e 65 77 5b 70 43 75 72 2d 3e 6e  et(&aNew[pCur->n
4a90: 4c 76 6c 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28  Lvl], 0, sizeof(
4aa0: 46 73 64 69 72 4c 65 76 65 6c 29 2a 28 6e 4e 65  FsdirLevel)*(nNe
4ab0: 77 2d 70 43 75 72 2d 3e 6e 4c 76 6c 29 29 3b 0a  w-pCur->nLvl));.
4ac0: 20 20 20 20 20 20 70 43 75 72 2d 3e 61 4c 76 6c        pCur->aLvl
4ad0: 20 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70   = aNew;.      p
4ae0: 43 75 72 2d 3e 6e 4c 76 6c 20 3d 20 6e 4e 65 77  Cur->nLvl = nNew
4af0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 75 72  ;.    }.    pCur
4b00: 2d 3e 69 4c 76 6c 20 3d 20 69 4e 65 77 3b 0a 20  ->iLvl = iNew;. 
4b10: 20 20 20 70 4c 76 6c 20 3d 20 26 70 43 75 72 2d     pLvl = &pCur-
4b20: 3e 61 4c 76 6c 5b 69 4e 65 77 5d 3b 0a 20 20 20  >aLvl[iNew];.   
4b30: 20 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69 72   .    pLvl->zDir
4b40: 20 3d 20 70 43 75 72 2d 3e 7a 50 61 74 68 3b 0a   = pCur->zPath;.
4b50: 20 20 20 20 70 43 75 72 2d 3e 7a 50 61 74 68 20      pCur->zPath 
4b60: 3d 20 30 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 70  = 0;.    pLvl->p
4b70: 44 69 72 20 3d 20 6f 70 65 6e 64 69 72 28 70 4c  Dir = opendir(pL
4b80: 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 20 20 69  vl->zDir);.    i
4b90: 66 28 20 70 4c 76 6c 2d 3e 70 44 69 72 3d 3d 30  f( pLvl->pDir==0
4ba0: 20 29 7b 0a 20 20 20 20 20 20 66 73 64 69 72 53   ){.      fsdirS
4bb0: 65 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22  etErrmsg(pCur, "
4bc0: 63 61 6e 6e 6f 74 20 72 65 61 64 20 64 69 72 65  cannot read dire
4bd0: 63 74 6f 72 79 3a 20 25 73 22 2c 20 70 43 75 72  ctory: %s", pCur
4be0: 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20  ->zPath);.      
4bf0: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52  return SQLITE_ER
4c00: 52 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a  ROR;.    }.  }..
4c10: 20 20 77 68 69 6c 65 28 20 70 43 75 72 2d 3e 69    while( pCur->i
4c20: 4c 76 6c 3e 3d 30 20 29 7b 0a 20 20 20 20 46 73  Lvl>=0 ){.    Fs
4c30: 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d  dirLevel *pLvl =
4c40: 20 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 70 43 75   &pCur->aLvl[pCu
4c50: 72 2d 3e 69 4c 76 6c 5d 3b 0a 20 20 20 20 73 74  r->iLvl];.    st
4c60: 72 75 63 74 20 64 69 72 65 6e 74 20 2a 70 45 6e  ruct dirent *pEn
4c70: 74 72 79 20 3d 20 72 65 61 64 64 69 72 28 70 4c  try = readdir(pL
4c80: 76 6c 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20 69  vl->pDir);.    i
4c90: 66 28 20 70 45 6e 74 72 79 20 29 7b 0a 20 20 20  f( pEntry ){.   
4ca0: 20 20 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 64     if( pEntry->d
4cb0: 5f 6e 61 6d 65 5b 30 5d 3d 3d 27 2e 27 20 29 7b  _name[0]=='.' ){
4cc0: 0a 20 20 20 20 20 20 20 69 66 28 20 70 45 6e 74  .       if( pEnt
4cd0: 72 79 2d 3e 64 5f 6e 61 6d 65 5b 31 5d 3d 3d 27  ry->d_name[1]=='
4ce0: 2e 27 20 26 26 20 70 45 6e 74 72 79 2d 3e 64 5f  .' && pEntry->d_
4cf0: 6e 61 6d 65 5b 32 5d 3d 3d 27 5c 30 27 20 29 20  name[2]=='\0' ) 
4d00: 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20  continue;.      
4d10: 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 64 5f 6e   if( pEntry->d_n
4d20: 61 6d 65 5b 31 5d 3d 3d 27 5c 30 27 20 29 20 63  ame[1]=='\0' ) c
4d30: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d  ontinue;.      }
4d40: 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66  .      sqlite3_f
4d50: 72 65 65 28 70 43 75 72 2d 3e 7a 50 61 74 68 29  ree(pCur->zPath)
4d60: 3b 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 7a 50  ;.      pCur->zP
4d70: 61 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ath = sqlite3_mp
4d80: 72 69 6e 74 66 28 22 25 73 2f 25 73 22 2c 20 70  rintf("%s/%s", p
4d90: 4c 76 6c 2d 3e 7a 44 69 72 2c 20 70 45 6e 74 72  Lvl->zDir, pEntr
4da0: 79 2d 3e 64 5f 6e 61 6d 65 29 3b 0a 20 20 20 20  y->d_name);.    
4db0: 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 50 61 74    if( pCur->zPat
4dc0: 68 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51  h==0 ) return SQ
4dd0: 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20  LITE_NOMEM;.    
4de0: 20 20 69 66 28 20 66 69 6c 65 4c 69 6e 6b 53 74    if( fileLinkSt
4df0: 61 74 28 70 43 75 72 2d 3e 7a 50 61 74 68 2c 20  at(pCur->zPath, 
4e00: 26 70 43 75 72 2d 3e 73 53 74 61 74 29 20 29 7b  &pCur->sStat) ){
4e10: 0a 20 20 20 20 20 20 20 20 66 73 64 69 72 53 65  .        fsdirSe
4e20: 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 63  tErrmsg(pCur, "c
4e30: 61 6e 6e 6f 74 20 73 74 61 74 20 66 69 6c 65 3a  annot stat file:
4e40: 20 25 73 22 2c 20 70 43 75 72 2d 3e 7a 50 61 74   %s", pCur->zPat
4e50: 68 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75  h);.        retu
4e60: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
4e70: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72  .      }.      r
4e80: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b  eturn SQLITE_OK;
4e90: 0a 20 20 20 20 7d 0a 20 20 20 20 63 6c 6f 73 65  .    }.    close
4ea0: 64 69 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b  dir(pLvl->pDir);
4eb0: 0a 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65  .    sqlite3_fre
4ec0: 65 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20  e(pLvl->zDir);. 
4ed0: 20 20 20 70 4c 76 6c 2d 3e 70 44 69 72 20 3d 20     pLvl->pDir = 
4ee0: 30 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69  0;.    pLvl->zDi
4ef0: 72 20 3d 20 30 3b 0a 20 20 20 20 70 43 75 72 2d  r = 0;.    pCur-
4f00: 3e 69 4c 76 6c 2d 2d 3b 0a 20 20 7d 0a 0a 20 20  >iLvl--;.  }..  
4f10: 2f 2a 20 45 4f 46 20 2a 2f 0a 20 20 73 71 6c 69  /* EOF */.  sqli
4f20: 74 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a  te3_free(pCur->z
4f30: 50 61 74 68 29 3b 0a 20 20 70 43 75 72 2d 3e 7a  Path);.  pCur->z
4f40: 50 61 74 68 20 3d 20 30 3b 0a 20 20 72 65 74 75  Path = 0;.  retu
4f50: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
4f60: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 76 61  ./*.** Return va
4f70: 6c 75 65 73 20 6f 66 20 63 6f 6c 75 6d 6e 73 20  lues of columns 
4f80: 66 6f 72 20 74 68 65 20 72 6f 77 20 61 74 20 77  for the row at w
4f90: 68 69 63 68 20 74 68 65 20 73 65 72 69 65 73 5f  hich the series_
4fa0: 63 75 72 73 6f 72 0a 2a 2a 20 69 73 20 63 75 72  cursor.** is cur
4fb0: 72 65 6e 74 6c 79 20 70 6f 69 6e 74 69 6e 67 2e  rently pointing.
4fc0: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66  .*/.static int f
4fd0: 73 64 69 72 43 6f 6c 75 6d 6e 28 0a 20 20 73 71  sdirColumn(.  sq
4fe0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
4ff0: 72 20 2a 63 75 72 2c 20 20 20 2f 2a 20 54 68 65  r *cur,   /* The
5000: 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 73 71 6c   cursor */.  sql
5010: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74  ite3_context *ct
5020: 78 2c 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73  x,       /* Firs
5030: 74 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 71  t argument to sq
5040: 6c 69 74 65 33 5f 72 65 73 75 6c 74 5f 2e 2e 2e  lite3_result_...
5050: 28 29 20 2a 2f 0a 20 20 69 6e 74 20 69 20 20 20  () */.  int i   
5060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5070: 20 20 20 20 2f 2a 20 57 68 69 63 68 20 63 6f 6c      /* Which col
5080: 75 6d 6e 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f  umn to return */
5090: 0a 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73  .){.  fsdir_curs
50a0: 6f 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69  or *pCur = (fsdi
50b0: 72 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20  r_cursor*)cur;. 
50c0: 20 73 77 69 74 63 68 28 20 69 20 29 7b 0a 20 20   switch( i ){.  
50d0: 20 20 63 61 73 65 20 46 53 44 49 52 5f 43 4f 4c    case FSDIR_COL
50e0: 55 4d 4e 5f 4e 41 4d 45 3a 20 7b 0a 20 20 20 20  UMN_NAME: {.    
50f0: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
5100: 5f 74 65 78 74 28 63 74 78 2c 20 26 70 43 75 72  _text(ctx, &pCur
5110: 2d 3e 7a 50 61 74 68 5b 70 43 75 72 2d 3e 6e 42  ->zPath[pCur->nB
5120: 61 73 65 5d 2c 20 2d 31 2c 20 53 51 4c 49 54 45  ase], -1, SQLITE
5130: 5f 54 52 41 4e 53 49 45 4e 54 29 3b 0a 20 20 20  _TRANSIENT);.   
5140: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
5150: 0a 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f  .    case FSDIR_
5160: 43 4f 4c 55 4d 4e 5f 4d 4f 44 45 3a 0a 20 20 20  COLUMN_MODE:.   
5170: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
5180: 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43 75  t_int64(ctx, pCu
5190: 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65  r->sStat.st_mode
51a0: 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a  );.      break;.
51b0: 0a 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f  .    case FSDIR_
51c0: 43 4f 4c 55 4d 4e 5f 4d 54 49 4d 45 3a 0a 20 20  COLUMN_MTIME:.  
51d0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
51e0: 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43  lt_int64(ctx, pC
51f0: 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 74 69  ur->sStat.st_mti
5200: 6d 65 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  me);.      break
5210: 3b 0a 0a 20 20 20 20 63 61 73 65 20 46 53 44 49  ;..    case FSDI
5220: 52 5f 43 4f 4c 55 4d 4e 5f 44 41 54 41 3a 20 7b  R_COLUMN_DATA: {
5230: 0a 20 20 20 20 20 20 6d 6f 64 65 5f 74 20 6d 20  .      mode_t m 
5240: 3d 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74  = pCur->sStat.st
5250: 5f 6d 6f 64 65 3b 0a 20 20 20 20 20 20 69 66 28  _mode;.      if(
5260: 20 53 5f 49 53 44 49 52 28 6d 29 20 29 7b 0a 20   S_ISDIR(m) ){. 
5270: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 72         sqlite3_r
5280: 65 73 75 6c 74 5f 6e 75 6c 6c 28 63 74 78 29 3b  esult_null(ctx);
5290: 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f 57  .#if !defined(_W
52a0: 49 4e 33 32 29 20 26 26 20 21 64 65 66 69 6e 65  IN32) && !define
52b0: 64 28 57 49 4e 33 32 29 0a 20 20 20 20 20 20 7d  d(WIN32).      }
52c0: 65 6c 73 65 20 69 66 28 20 53 5f 49 53 4c 4e 4b  else if( S_ISLNK
52d0: 28 6d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63  (m) ){.        c
52e0: 68 61 72 20 61 53 74 61 74 69 63 5b 36 34 5d 3b  har aStatic[64];
52f0: 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 61  .        char *a
5300: 42 75 66 20 3d 20 61 53 74 61 74 69 63 3b 0a 20  Buf = aStatic;. 
5310: 20 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 69         sqlite3_i
5320: 6e 74 36 34 20 6e 42 75 66 20 3d 20 36 34 3b 0a  nt64 nBuf = 64;.
5330: 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a 0a          int n;..
5340: 20 20 20 20 20 20 20 20 77 68 69 6c 65 28 20 31          while( 1
5350: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e 20   ){.          n 
5360: 3d 20 72 65 61 64 6c 69 6e 6b 28 70 43 75 72 2d  = readlink(pCur-
5370: 3e 7a 50 61 74 68 2c 20 61 42 75 66 2c 20 6e 42  >zPath, aBuf, nB
5380: 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69  uf);.          i
5390: 66 28 20 6e 3c 6e 42 75 66 20 29 20 62 72 65 61  f( n<nBuf ) brea
53a0: 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  k;.          if(
53b0: 20 61 42 75 66 21 3d 61 53 74 61 74 69 63 20 29   aBuf!=aStatic )
53c0: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61 42   sqlite3_free(aB
53d0: 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20 6e  uf);.          n
53e0: 42 75 66 20 3d 20 6e 42 75 66 2a 32 3b 0a 20 20  Buf = nBuf*2;.  
53f0: 20 20 20 20 20 20 20 20 61 42 75 66 20 3d 20 73          aBuf = s
5400: 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 36 34 28  qlite3_malloc64(
5410: 6e 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20  nBuf);.         
5420: 20 69 66 28 20 61 42 75 66 3d 3d 30 20 29 7b 0a   if( aBuf==0 ){.
5430: 20 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69              sqli
5440: 74 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72  te3_result_error
5450: 5f 6e 6f 6d 65 6d 28 63 74 78 29 3b 0a 20 20 20  _nomem(ctx);.   
5460: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20           return 
5470: 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20  SQLITE_NOMEM;.  
5480: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
5490: 20 20 7d 0a 0a 20 20 20 20 20 20 20 20 73 71 6c    }..        sql
54a0: 69 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74  ite3_result_text
54b0: 28 63 74 78 2c 20 61 42 75 66 2c 20 6e 2c 20 53  (ctx, aBuf, n, S
54c0: 51 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29  QLITE_TRANSIENT)
54d0: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 42  ;.        if( aB
54e0: 75 66 21 3d 61 53 74 61 74 69 63 20 29 20 73 71  uf!=aStatic ) sq
54f0: 6c 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29  lite3_free(aBuf)
5500: 3b 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 7d  ;.#endif.      }
5510: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65  else{.        re
5520: 61 64 46 69 6c 65 43 6f 6e 74 65 6e 74 73 28 63  adFileContents(c
5530: 74 78 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68 29  tx, pCur->zPath)
5540: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a  ;.      }.    }.
5550: 20 20 20 20 63 61 73 65 20 46 53 44 49 52 5f 43      case FSDIR_C
5560: 4f 4c 55 4d 4e 5f 50 41 54 48 3a 0a 20 20 20 20  OLUMN_PATH:.    
5570: 64 65 66 61 75 6c 74 3a 20 7b 0a 20 20 20 20 20  default: {.     
5580: 20 2f 2a 20 54 68 65 20 46 53 44 49 52 5f 43 4f   /* The FSDIR_CO
5590: 4c 55 4d 4e 5f 50 41 54 48 20 61 6e 64 20 46 53  LUMN_PATH and FS
55a0: 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 49 52 20 61  DIR_COLUMN_DIR a
55b0: 72 65 20 69 6e 70 75 74 20 70 61 72 61 6d 65 74  re input paramet
55c0: 65 72 73 2e 0a 20 20 20 20 20 20 2a 2a 20 61 6c  ers..      ** al
55d0: 77 61 79 73 20 72 65 74 75 72 6e 20 74 68 65 69  ways return thei
55e0: 72 20 76 61 6c 75 65 73 20 61 73 20 4e 55 4c 4c  r values as NULL
55f0: 20 2a 2f 0a 20 20 20 20 20 20 62 72 65 61 6b 3b   */.      break;
5600: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 72 65 74  .    }.  }.  ret
5610: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
5620: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
5630: 68 65 20 72 6f 77 69 64 20 66 6f 72 20 74 68 65  he rowid for the
5640: 20 63 75 72 72 65 6e 74 20 72 6f 77 2e 20 49 6e   current row. In
5650: 20 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e 74 61   this implementa
5660: 74 69 6f 6e 2c 20 74 68 65 0a 2a 2a 20 66 69 72  tion, the.** fir
5670: 73 74 20 72 6f 77 20 72 65 74 75 72 6e 65 64 20  st row returned 
5680: 69 73 20 61 73 73 69 67 6e 65 64 20 72 6f 77 69  is assigned rowi
5690: 64 20 76 61 6c 75 65 20 31 2c 20 61 6e 64 20 65  d value 1, and e
56a0: 61 63 68 20 73 75 62 73 65 71 75 65 6e 74 0a 2a  ach subsequent.*
56b0: 2a 20 72 6f 77 20 61 20 76 61 6c 75 65 20 31 20  * row a value 1 
56c0: 6d 6f 72 65 20 74 68 61 6e 20 74 68 61 74 20 6f  more than that o
56d0: 66 20 74 68 65 20 70 72 65 76 69 6f 75 73 2e 0a  f the previous..
56e0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
56f0: 64 69 72 52 6f 77 69 64 28 73 71 6c 69 74 65 33  dirRowid(sqlite3
5700: 5f 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75  _vtab_cursor *cu
5710: 72 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  r, sqlite_int64 
5720: 2a 70 52 6f 77 69 64 29 7b 0a 20 20 66 73 64 69  *pRowid){.  fsdi
5730: 72 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d  r_cursor *pCur =
5740: 20 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29   (fsdir_cursor*)
5750: 63 75 72 3b 0a 20 20 2a 70 52 6f 77 69 64 20 3d  cur;.  *pRowid =
5760: 20 70 43 75 72 2d 3e 69 52 6f 77 69 64 3b 0a 20   pCur->iRowid;. 
5770: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
5780: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  K;.}../*.** Retu
5790: 72 6e 20 54 52 55 45 20 69 66 20 74 68 65 20 63  rn TRUE if the c
57a0: 75 72 73 6f 72 20 68 61 73 20 62 65 65 6e 20 6d  ursor has been m
57b0: 6f 76 65 64 20 6f 66 66 20 6f 66 20 74 68 65 20  oved off of the 
57c0: 6c 61 73 74 0a 2a 2a 20 72 6f 77 20 6f 66 20 6f  last.** row of o
57d0: 75 74 70 75 74 2e 0a 2a 2f 0a 73 74 61 74 69 63  utput..*/.static
57e0: 20 69 6e 74 20 66 73 64 69 72 45 6f 66 28 73 71   int fsdirEof(sq
57f0: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
5800: 72 20 2a 63 75 72 29 7b 0a 20 20 66 73 64 69 72  r *cur){.  fsdir
5810: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20  _cursor *pCur = 
5820: 28 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63  (fsdir_cursor*)c
5830: 75 72 3b 0a 20 20 72 65 74 75 72 6e 20 28 70 43  ur;.  return (pC
5840: 75 72 2d 3e 7a 50 61 74 68 3d 3d 30 29 3b 0a 7d  ur->zPath==0);.}
5850: 0a 0a 2f 2a 0a 2a 2a 20 78 46 69 6c 74 65 72 20  ../*.** xFilter 
5860: 63 61 6c 6c 62 61 63 6b 2e 0a 2a 2a 0a 2a 2a 20  callback..**.** 
5870: 69 64 78 4e 75 6d 3d 3d 31 20 20 20 50 41 54 48  idxNum==1   PATH
5880: 20 70 61 72 61 6d 65 74 65 72 20 6f 6e 6c 79 0a   parameter only.
5890: 2a 2a 20 69 64 78 4e 75 6d 3d 3d 32 20 20 20 42  ** idxNum==2   B
58a0: 6f 74 68 20 50 41 54 48 20 61 6e 64 20 44 49 52  oth PATH and DIR
58b0: 20 73 75 70 70 6c 69 65 64 0a 2a 2f 0a 73 74 61   supplied.*/.sta
58c0: 74 69 63 20 69 6e 74 20 66 73 64 69 72 46 69 6c  tic int fsdirFil
58d0: 74 65 72 28 0a 20 20 73 71 6c 69 74 65 33 5f 76  ter(.  sqlite3_v
58e0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 2c  tab_cursor *cur,
58f0: 20 0a 20 20 69 6e 74 20 69 64 78 4e 75 6d 2c 20   .  int idxNum, 
5900: 63 6f 6e 73 74 20 63 68 61 72 20 2a 69 64 78 53  const char *idxS
5910: 74 72 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c 20  tr,.  int argc, 
5920: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 2a  sqlite3_value **
5930: 61 72 67 76 0a 29 7b 0a 20 20 63 6f 6e 73 74 20  argv.){.  const 
5940: 63 68 61 72 20 2a 7a 44 69 72 20 3d 20 30 3b 0a  char *zDir = 0;.
5950: 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20 2a    fsdir_cursor *
5960: 70 43 75 72 20 3d 20 28 66 73 64 69 72 5f 63 75  pCur = (fsdir_cu
5970: 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 28 76 6f  rsor*)cur;.  (vo
5980: 69 64 29 69 64 78 53 74 72 3b 0a 20 20 66 73 64  id)idxStr;.  fsd
5990: 69 72 52 65 73 65 74 43 75 72 73 6f 72 28 70 43  irResetCursor(pC
59a0: 75 72 29 3b 0a 0a 20 20 69 66 28 20 69 64 78 4e  ur);..  if( idxN
59b0: 75 6d 3d 3d 30 20 29 7b 0a 20 20 20 20 66 73 64  um==0 ){.    fsd
59c0: 69 72 53 65 74 45 72 72 6d 73 67 28 70 43 75 72  irSetErrmsg(pCur
59d0: 2c 20 22 74 61 62 6c 65 20 66 75 6e 63 74 69 6f  , "table functio
59e0: 6e 20 66 73 64 69 72 20 72 65 71 75 69 72 65 73  n fsdir requires
59f0: 20 61 6e 20 61 72 67 75 6d 65 6e 74 22 29 3b 0a   an argument");.
5a00: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5a10: 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20  E_ERROR;.  }..  
5a20: 61 73 73 65 72 74 28 20 61 72 67 63 3d 3d 69 64  assert( argc==id
5a30: 78 4e 75 6d 20 26 26 20 28 61 72 67 63 3d 3d 31  xNum && (argc==1
5a40: 20 7c 7c 20 61 72 67 63 3d 3d 32 29 20 29 3b 0a   || argc==2) );.
5a50: 20 20 7a 44 69 72 20 3d 20 28 63 6f 6e 73 74 20    zDir = (const 
5a60: 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61  char*)sqlite3_va
5a70: 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d  lue_text(argv[0]
5a80: 29 3b 0a 20 20 69 66 28 20 7a 44 69 72 3d 3d 30  );.  if( zDir==0
5a90: 20 29 7b 0a 20 20 20 20 66 73 64 69 72 53 65 74   ){.    fsdirSet
5aa0: 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 74 61  Errmsg(pCur, "ta
5ab0: 62 6c 65 20 66 75 6e 63 74 69 6f 6e 20 66 73 64  ble function fsd
5ac0: 69 72 20 72 65 71 75 69 72 65 73 20 61 20 6e 6f  ir requires a no
5ad0: 6e 2d 4e 55 4c 4c 20 61 72 67 75 6d 65 6e 74 22  n-NULL argument"
5ae0: 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51  );.    return SQ
5af0: 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20 7d 0a  LITE_ERROR;.  }.
5b00: 20 20 69 66 28 20 61 72 67 63 3d 3d 32 20 29 7b    if( argc==2 ){
5b10: 0a 20 20 20 20 70 43 75 72 2d 3e 7a 42 61 73 65  .    pCur->zBase
5b20: 20 3d 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29   = (const char*)
5b30: 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65  sqlite3_value_te
5b40: 78 74 28 61 72 67 76 5b 31 5d 29 3b 0a 20 20 7d  xt(argv[1]);.  }
5b50: 0a 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 42 61  .  if( pCur->zBa
5b60: 73 65 20 29 7b 0a 20 20 20 20 70 43 75 72 2d 3e  se ){.    pCur->
5b70: 6e 42 61 73 65 20 3d 20 28 69 6e 74 29 73 74 72  nBase = (int)str
5b80: 6c 65 6e 28 70 43 75 72 2d 3e 7a 42 61 73 65 29  len(pCur->zBase)
5b90: 2b 31 3b 0a 20 20 20 20 70 43 75 72 2d 3e 7a 50  +1;.    pCur->zP
5ba0: 61 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ath = sqlite3_mp
5bb0: 72 69 6e 74 66 28 22 25 73 2f 25 73 22 2c 20 70  rintf("%s/%s", p
5bc0: 43 75 72 2d 3e 7a 42 61 73 65 2c 20 7a 44 69 72  Cur->zBase, zDir
5bd0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
5be0: 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 73 71  pCur->zPath = sq
5bf0: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
5c00: 73 22 2c 20 7a 44 69 72 29 3b 0a 20 20 7d 0a 0a  s", zDir);.  }..
5c10: 20 20 69 66 28 20 70 43 75 72 2d 3e 7a 50 61 74    if( pCur->zPat
5c20: 68 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74 75  h==0 ){.    retu
5c30: 72 6e 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b  rn SQLITE_NOMEM;
5c40: 0a 20 20 7d 0a 20 20 69 66 28 20 66 69 6c 65 4c  .  }.  if( fileL
5c50: 69 6e 6b 53 74 61 74 28 70 43 75 72 2d 3e 7a 50  inkStat(pCur->zP
5c60: 61 74 68 2c 20 26 70 43 75 72 2d 3e 73 53 74 61  ath, &pCur->sSta
5c70: 74 29 20 29 7b 0a 20 20 20 20 66 73 64 69 72 53  t) ){.    fsdirS
5c80: 65 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22  etErrmsg(pCur, "
5c90: 63 61 6e 6e 6f 74 20 73 74 61 74 20 66 69 6c 65  cannot stat file
5ca0: 3a 20 25 73 22 2c 20 70 43 75 72 2d 3e 7a 50 61  : %s", pCur->zPa
5cb0: 74 68 29 3b 0a 20 20 20 20 72 65 74 75 72 6e 20  th);.    return 
5cc0: 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a 20 20  SQLITE_ERROR;.  
5cd0: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49  }..  return SQLI
5ce0: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
5cf0: 53 51 4c 69 74 65 20 77 69 6c 6c 20 69 6e 76 6f  SQLite will invo
5d00: 6b 65 20 74 68 69 73 20 6d 65 74 68 6f 64 20 6f  ke this method o
5d10: 6e 65 20 6f 72 20 6d 6f 72 65 20 74 69 6d 65 73  ne or more times
5d20: 20 77 68 69 6c 65 20 70 6c 61 6e 6e 69 6e 67 20   while planning 
5d30: 61 20 71 75 65 72 79 0a 2a 2a 20 74 68 61 74 20  a query.** that 
5d40: 75 73 65 73 20 74 68 65 20 67 65 6e 65 72 61 74  uses the generat
5d50: 65 5f 73 65 72 69 65 73 20 76 69 72 74 75 61 6c  e_series virtual
5d60: 20 74 61 62 6c 65 2e 20 20 54 68 69 73 20 72 6f   table.  This ro
5d70: 75 74 69 6e 65 20 6e 65 65 64 73 20 74 6f 20 63  utine needs to c
5d80: 72 65 61 74 65 0a 2a 2a 20 61 20 71 75 65 72 79  reate.** a query
5d90: 20 70 6c 61 6e 20 66 6f 72 20 65 61 63 68 20 69   plan for each i
5da0: 6e 76 6f 63 61 74 69 6f 6e 20 61 6e 64 20 63 6f  nvocation and co
5db0: 6d 70 75 74 65 20 61 6e 20 65 73 74 69 6d 61 74  mpute an estimat
5dc0: 65 64 20 63 6f 73 74 20 66 6f 72 20 74 68 61 74  ed cost for that
5dd0: 0a 2a 2a 20 70 6c 61 6e 2e 0a 2a 2a 0a 2a 2a 20  .** plan..**.** 
5de0: 49 6e 20 74 68 69 73 20 69 6d 70 6c 65 6d 65 6e  In this implemen
5df0: 74 61 74 69 6f 6e 20 69 64 78 4e 75 6d 20 69 73  tation idxNum is
5e00: 20 75 73 65 64 20 74 6f 20 72 65 70 72 65 73 65   used to represe
5e10: 6e 74 20 74 68 65 0a 2a 2a 20 71 75 65 72 79 20  nt the.** query 
5e20: 70 6c 61 6e 2e 20 20 69 64 78 53 74 72 20 69 73  plan.  idxStr is
5e30: 20 75 6e 75 73 65 64 2e 0a 2a 2a 0a 2a 2a 20 54   unused..**.** T
5e40: 68 65 20 71 75 65 72 79 20 70 6c 61 6e 20 69 73  he query plan is
5e50: 20 72 65 70 72 65 73 65 6e 74 65 64 20 62 79 20   represented by 
5e60: 76 61 6c 75 65 73 20 6f 66 20 69 64 78 4e 75 6d  values of idxNum
5e70: 3a 0a 2a 2a 0a 2a 2a 20 20 28 31 29 20 20 54 68  :.**.**  (1)  Th
5e80: 65 20 70 61 74 68 20 76 61 6c 75 65 20 69 73 20  e path value is 
5e90: 73 75 70 70 6c 69 65 64 20 62 79 20 61 72 67 76  supplied by argv
5ea0: 5b 30 5d 0a 2a 2a 20 20 28 32 29 20 20 50 61 74  [0].**  (2)  Pat
5eb0: 68 20 69 73 20 69 6e 20 61 72 67 76 5b 30 5d 20  h is in argv[0] 
5ec0: 61 6e 64 20 64 69 72 20 69 73 20 69 6e 20 61 72  and dir is in ar
5ed0: 67 76 5b 31 5d 0a 2a 2f 0a 73 74 61 74 69 63 20  gv[1].*/.static 
5ee0: 69 6e 74 20 66 73 64 69 72 42 65 73 74 49 6e 64  int fsdirBestInd
5ef0: 65 78 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 74  ex(.  sqlite3_vt
5f00: 61 62 20 2a 74 61 62 2c 0a 20 20 73 71 6c 69 74  ab *tab,.  sqlit
5f10: 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f 20 2a 70  e3_index_info *p
5f20: 49 64 78 49 6e 66 6f 0a 29 7b 0a 20 20 69 6e 74  IdxInfo.){.  int
5f30: 20 69 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   i;             
5f40: 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 6f 76 65 72      /* Loop over
5f50: 20 63 6f 6e 73 74 72 61 69 6e 74 73 20 2a 2f 0a   constraints */.
5f60: 20 20 69 6e 74 20 69 64 78 50 61 74 68 20 3d 20    int idxPath = 
5f70: 2d 31 3b 20 20 20 20 20 20 2f 2a 20 49 6e 64 65  -1;      /* Inde
5f80: 78 20 69 6e 20 70 49 64 78 49 6e 66 6f 2d 3e 61  x in pIdxInfo->a
5f90: 43 6f 6e 73 74 72 61 69 6e 74 20 6f 66 20 50 41  Constraint of PA
5fa0: 54 48 3d 20 2a 2f 0a 20 20 69 6e 74 20 69 64 78  TH= */.  int idx
5fb0: 44 69 72 20 3d 20 2d 31 3b 20 20 20 20 20 20 20  Dir = -1;       
5fc0: 2f 2a 20 49 6e 64 65 78 20 69 6e 20 70 49 64 78  /* Index in pIdx
5fd0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
5fe0: 74 20 6f 66 20 44 49 52 3d 20 2a 2f 0a 20 20 69  t of DIR= */.  i
5ff0: 6e 74 20 73 65 65 6e 50 61 74 68 20 3d 20 30 3b  nt seenPath = 0;
6000: 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20 69 66        /* True if
6010: 20 61 6e 20 75 6e 75 73 61 62 6c 65 20 50 41 54   an unusable PAT
6020: 48 3d 20 63 6f 6e 73 74 72 61 69 6e 74 20 69 73  H= constraint is
6030: 20 73 65 65 6e 20 2a 2f 0a 20 20 69 6e 74 20 73   seen */.  int s
6040: 65 65 6e 44 69 72 20 3d 20 30 3b 20 20 20 20 20  eenDir = 0;     
6050: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 6e 20    /* True if an 
6060: 75 6e 75 73 61 62 6c 65 20 44 49 52 3d 20 63 6f  unusable DIR= co
6070: 6e 73 74 72 61 69 6e 74 20 69 73 20 73 65 65 6e  nstraint is seen
6080: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 73 74 72 75   */.  const stru
6090: 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65 78  ct sqlite3_index
60a0: 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43 6f  _constraint *pCo
60b0: 6e 73 74 72 61 69 6e 74 3b 0a 0a 20 20 28 76 6f  nstraint;..  (vo
60c0: 69 64 29 74 61 62 3b 0a 20 20 70 43 6f 6e 73 74  id)tab;.  pConst
60d0: 72 61 69 6e 74 20 3d 20 70 49 64 78 49 6e 66 6f  raint = pIdxInfo
60e0: 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 3b 0a 20  ->aConstraint;. 
60f0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 64 78   for(i=0; i<pIdx
6100: 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69 6e  Info->nConstrain
6110: 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e 73 74 72 61  t; i++, pConstra
6120: 69 6e 74 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20  int++){.    if( 
6130: 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 6f 70 21  pConstraint->op!
6140: 3d 53 51 4c 49 54 45 5f 49 4e 44 45 58 5f 43 4f  =SQLITE_INDEX_CO
6150: 4e 53 54 52 41 49 4e 54 5f 45 51 20 29 20 63 6f  NSTRAINT_EQ ) co
6160: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 73 77 69 74  ntinue;.    swit
6170: 63 68 28 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d  ch( pConstraint-
6180: 3e 69 43 6f 6c 75 6d 6e 20 29 7b 0a 20 20 20 20  >iColumn ){.    
6190: 20 20 63 61 73 65 20 46 53 44 49 52 5f 43 4f 4c    case FSDIR_COL
61a0: 55 4d 4e 5f 50 41 54 48 3a 20 7b 0a 20 20 20 20  UMN_PATH: {.    
61b0: 20 20 20 20 69 66 28 20 70 43 6f 6e 73 74 72 61      if( pConstra
61c0: 69 6e 74 2d 3e 75 73 61 62 6c 65 20 29 7b 0a 20  int->usable ){. 
61d0: 20 20 20 20 20 20 20 20 20 69 64 78 50 61 74 68           idxPath
61e0: 20 3d 20 69 3b 0a 20 20 20 20 20 20 20 20 20 20   = i;.          
61f0: 73 65 65 6e 50 61 74 68 20 3d 20 30 3b 0a 20 20  seenPath = 0;.  
6200: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
6210: 69 64 78 50 61 74 68 3c 30 20 29 7b 0a 20 20 20  idxPath<0 ){.   
6220: 20 20 20 20 20 20 20 73 65 65 6e 50 61 74 68 20         seenPath 
6230: 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20  = 1;.        }. 
6240: 20 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20         break;.  
6250: 20 20 20 20 7d 0a 20 20 20 20 20 20 63 61 73 65      }.      case
6260: 20 46 53 44 49 52 5f 43 4f 4c 55 4d 4e 5f 44 49   FSDIR_COLUMN_DI
6270: 52 3a 20 7b 0a 20 20 20 20 20 20 20 20 69 66 28  R: {.        if(
6280: 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75 73   pConstraint->us
6290: 61 62 6c 65 20 29 7b 0a 20 20 20 20 20 20 20 20  able ){.        
62a0: 20 20 69 64 78 44 69 72 20 3d 20 69 3b 0a 20 20    idxDir = i;.  
62b0: 20 20 20 20 20 20 20 20 73 65 65 6e 44 69 72 20          seenDir 
62c0: 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  = 0;.        }el
62d0: 73 65 20 69 66 28 20 69 64 78 44 69 72 3c 30 20  se if( idxDir<0 
62e0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 73 65 65  ){.          see
62f0: 6e 44 69 72 20 3d 20 31 3b 0a 20 20 20 20 20 20  nDir = 1;.      
6300: 20 20 7d 0a 20 20 20 20 20 20 20 20 62 72 65 61    }.        brea
6310: 6b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  k;.      }.    }
6320: 20 0a 20 20 7d 0a 20 20 69 66 28 20 73 65 65 6e   .  }.  if( seen
6330: 50 61 74 68 20 7c 7c 20 73 65 65 6e 44 69 72 20  Path || seenDir 
6340: 29 7b 0a 20 20 20 20 2f 2a 20 49 66 20 69 6e 70  ){.    /* If inp
6350: 75 74 20 70 61 72 61 6d 65 74 65 72 73 20 61 72  ut parameters ar
6360: 65 20 75 6e 75 73 61 62 6c 65 2c 20 64 69 73 61  e unusable, disa
6370: 6c 6c 6f 77 20 74 68 69 73 20 70 6c 61 6e 20 2a  llow this plan *
6380: 2f 0a 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c  /.    return SQL
6390: 49 54 45 5f 43 4f 4e 53 54 52 41 49 4e 54 3b 0a  ITE_CONSTRAINT;.
63a0: 20 20 7d 0a 0a 20 20 69 66 28 20 69 64 78 50 61    }..  if( idxPa
63b0: 74 68 3c 30 20 29 7b 0a 20 20 20 20 70 49 64 78  th<0 ){.    pIdx
63c0: 49 6e 66 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 30  Info->idxNum = 0
63d0: 3b 0a 20 20 20 20 2f 2a 20 54 68 65 20 70 49 64  ;.    /* The pId
63e0: 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65 64  xInfo->estimated
63f0: 43 6f 73 74 20 73 68 6f 75 6c 64 20 68 61 76 65  Cost should have
6400: 20 62 65 65 6e 20 69 6e 69 74 69 61 6c 69 7a 65   been initialize
6410: 64 20 74 6f 20 61 20 68 75 67 65 0a 20 20 20 20  d to a huge.    
6420: 2a 2a 20 6e 75 6d 62 65 72 2e 20 20 4c 65 61 76  ** number.  Leav
6430: 65 20 69 74 20 75 6e 63 68 61 6e 67 65 64 2e 20  e it unchanged. 
6440: 2a 2f 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d  */.    pIdxInfo-
6450: 3e 65 73 74 69 6d 61 74 65 64 52 6f 77 73 20 3d  >estimatedRows =
6460: 20 30 78 37 66 66 66 66 66 66 66 3b 0a 20 20 7d   0x7fffffff;.  }
6470: 65 6c 73 65 7b 0a 20 20 20 20 70 49 64 78 49 6e  else{.    pIdxIn
6480: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
6490: 73 61 67 65 5b 69 64 78 50 61 74 68 5d 2e 6f 6d  sage[idxPath].om
64a0: 69 74 20 3d 20 31 3b 0a 20 20 20 20 70 49 64 78  it = 1;.    pIdx
64b0: 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e  Info->aConstrain
64c0: 74 55 73 61 67 65 5b 69 64 78 50 61 74 68 5d 2e  tUsage[idxPath].
64d0: 61 72 67 76 49 6e 64 65 78 20 3d 20 31 3b 0a 20  argvIndex = 1;. 
64e0: 20 20 20 69 66 28 20 69 64 78 44 69 72 3e 3d 30     if( idxDir>=0
64f0: 20 29 7b 0a 20 20 20 20 20 20 70 49 64 78 49 6e   ){.      pIdxIn
6500: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
6510: 73 61 67 65 5b 69 64 78 44 69 72 5d 2e 6f 6d 69  sage[idxDir].omi
6520: 74 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49 64  t = 1;.      pId
6530: 78 49 6e 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69  xInfo->aConstrai
6540: 6e 74 55 73 61 67 65 5b 69 64 78 44 69 72 5d 2e  ntUsage[idxDir].
6550: 61 72 67 76 49 6e 64 65 78 20 3d 20 32 3b 0a 20  argvIndex = 2;. 
6560: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69       pIdxInfo->i
6570: 64 78 4e 75 6d 20 3d 20 32 3b 0a 20 20 20 20 20  dxNum = 2;.     
6580: 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d   pIdxInfo->estim
6590: 61 74 65 64 43 6f 73 74 20 3d 20 31 30 2e 30 3b  atedCost = 10.0;
65a0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
65b0: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69 64 78 4e    pIdxInfo->idxN
65c0: 75 6d 20 3d 20 31 3b 0a 20 20 20 20 20 20 70 49  um = 1;.      pI
65d0: 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74 65  dxInfo->estimate
65e0: 64 43 6f 73 74 20 3d 20 31 30 30 2e 30 3b 0a 20  dCost = 100.0;. 
65f0: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
6600: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a  rn SQLITE_OK;.}.
6610: 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73 74 65 72 20  ./*.** Register 
6620: 74 68 65 20 22 66 73 64 69 72 22 20 76 69 72 74  the "fsdir" virt
6630: 75 61 6c 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74  ual table..*/.st
6640: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 52 65  atic int fsdirRe
6650: 67 69 73 74 65 72 28 73 71 6c 69 74 65 33 20 2a  gister(sqlite3 *
6660: 64 62 29 7b 0a 20 20 73 74 61 74 69 63 20 73 71  db){.  static sq
6670: 6c 69 74 65 33 5f 6d 6f 64 75 6c 65 20 66 73 64  lite3_module fsd
6680: 69 72 4d 6f 64 75 6c 65 20 3d 20 7b 0a 20 20 20  irModule = {.   
6690: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
66a0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 69              /* i
66b0: 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 20 20 30  Version */.    0
66c0: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
66d0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 72            /* xCr
66e0: 65 61 74 65 20 2a 2f 0a 20 20 20 20 66 73 64 69  eate */.    fsdi
66f0: 72 43 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20 20  rConnect,       
6700: 20 20 20 20 20 20 20 2f 2a 20 78 43 6f 6e 6e 65         /* xConne
6710: 63 74 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 42  ct */.    fsdirB
6720: 65 73 74 49 6e 64 65 78 2c 20 20 20 20 20 20 20  estIndex,       
6730: 20 20 20 20 20 2f 2a 20 78 42 65 73 74 49 6e 64       /* xBestInd
6740: 65 78 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 44  ex */.    fsdirD
6750: 69 73 63 6f 6e 6e 65 63 74 2c 20 20 20 20 20 20  isconnect,      
6760: 20 20 20 20 20 2f 2a 20 78 44 69 73 63 6f 6e 6e       /* xDisconn
6770: 65 63 74 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20  ect */.    0,   
6780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6790: 20 20 20 20 20 20 2f 2a 20 78 44 65 73 74 72 6f        /* xDestro
67a0: 79 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 4f 70  y */.    fsdirOp
67b0: 65 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  en,             
67c0: 20 20 20 20 2f 2a 20 78 4f 70 65 6e 20 2d 20 6f      /* xOpen - o
67d0: 70 65 6e 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a  pen a cursor */.
67e0: 20 20 20 20 66 73 64 69 72 43 6c 6f 73 65 2c 20      fsdirClose, 
67f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6800: 2a 20 78 43 6c 6f 73 65 20 2d 20 63 6c 6f 73 65  * xClose - close
6810: 20 61 20 63 75 72 73 6f 72 20 2a 2f 0a 20 20 20   a cursor */.   
6820: 20 66 73 64 69 72 46 69 6c 74 65 72 2c 20 20 20   fsdirFilter,   
6830: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6840: 46 69 6c 74 65 72 20 2d 20 63 6f 6e 66 69 67 75  Filter - configu
6850: 72 65 20 73 63 61 6e 20 63 6f 6e 73 74 72 61 69  re scan constrai
6860: 6e 74 73 20 2a 2f 0a 20 20 20 20 66 73 64 69 72  nts */.    fsdir
6870: 4e 65 78 74 2c 20 20 20 20 20 20 20 20 20 20 20  Next,           
6880: 20 20 20 20 20 20 2f 2a 20 78 4e 65 78 74 20 2d        /* xNext -
6890: 20 61 64 76 61 6e 63 65 20 61 20 63 75 72 73 6f   advance a curso
68a0: 72 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 45 6f  r */.    fsdirEo
68b0: 66 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  f,              
68c0: 20 20 20 20 2f 2a 20 78 45 6f 66 20 2d 20 63 68      /* xEof - ch
68d0: 65 63 6b 20 66 6f 72 20 65 6e 64 20 6f 66 20 73  eck for end of s
68e0: 63 61 6e 20 2a 2f 0a 20 20 20 20 66 73 64 69 72  can */.    fsdir
68f0: 43 6f 6c 75 6d 6e 2c 20 20 20 20 20 20 20 20 20  Column,         
6900: 20 20 20 20 20 20 2f 2a 20 78 43 6f 6c 75 6d 6e        /* xColumn
6910: 20 2d 20 72 65 61 64 20 64 61 74 61 20 2a 2f 0a   - read data */.
6920: 20 20 20 20 66 73 64 69 72 52 6f 77 69 64 2c 20      fsdirRowid, 
6930: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6940: 2a 20 78 52 6f 77 69 64 20 2d 20 72 65 61 64 20  * xRowid - read 
6950: 64 61 74 61 20 2a 2f 0a 20 20 20 20 30 2c 20 20  data */.    0,  
6960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6970: 20 20 20 20 20 20 20 2f 2a 20 78 55 70 64 61 74         /* xUpdat
6980: 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  e */.    0,     
6990: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69a0: 20 20 20 20 2f 2a 20 78 42 65 67 69 6e 20 2a 2f      /* xBegin */
69b0: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
69c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
69d0: 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a 20 20 20 20  /* xSync */.    
69e0: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
69f0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
6a00: 6f 6d 6d 69 74 20 2a 2f 0a 20 20 20 20 30 2c 20  ommit */.    0, 
6a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a20: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c          /* xRoll
6a30: 62 61 63 6b 20 2a 2f 0a 20 20 20 20 30 2c 20 20  back */.    0,  
6a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a50: 20 20 20 20 20 20 20 2f 2a 20 78 46 69 6e 64 4d         /* xFindM
6a60: 65 74 68 6f 64 20 2a 2f 0a 20 20 20 20 30 2c 20  ethod */.    0, 
6a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6a80: 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6e 61          /* xRena
6a90: 6d 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  me */.    0,    
6aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ab0: 20 20 20 20 20 2f 2a 20 78 53 61 76 65 70 6f 69       /* xSavepoi
6ac0: 6e 74 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20  nt */.    0,    
6ad0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6ae0: 20 20 20 20 20 2f 2a 20 78 52 65 6c 65 61 73 65       /* xRelease
6af0: 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20 20   */.    0,      
6b00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b10: 20 20 20 2f 2a 20 78 52 6f 6c 6c 62 61 63 6b 54     /* xRollbackT
6b20: 6f 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  o */.    0,     
6b30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6b40: 20 20 20 20 2f 2a 20 78 53 68 61 64 6f 77 4e 61      /* xShadowNa
6b50: 6d 65 20 2a 2f 0a 20 20 7d 3b 0a 0a 20 20 69 6e  me */.  };..  in
6b60: 74 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 63  t rc = sqlite3_c
6b70: 72 65 61 74 65 5f 6d 6f 64 75 6c 65 28 64 62 2c  reate_module(db,
6b80: 20 22 66 73 64 69 72 22 2c 20 26 66 73 64 69 72   "fsdir", &fsdir
6b90: 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a 20 20 72 65  Module, 0);.  re
6ba0: 74 75 72 6e 20 72 63 3b 0a 7d 0a 23 65 6c 73 65  turn rc;.}.#else
6bb0: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 51 4c 49           /* SQLI
6bc0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
6bd0: 41 42 4c 45 20 2a 2f 0a 23 20 64 65 66 69 6e 65  ABLE */.# define
6be0: 20 66 73 64 69 72 52 65 67 69 73 74 65 72 28 78   fsdirRegister(x
6bf0: 29 20 53 51 4c 49 54 45 5f 4f 4b 0a 23 65 6e 64  ) SQLITE_OK.#end
6c00: 69 66 0a 0a 23 69 66 64 65 66 20 5f 57 49 4e 33  if..#ifdef _WIN3
6c10: 32 0a 5f 5f 64 65 63 6c 73 70 65 63 28 64 6c 6c  2.__declspec(dll
6c20: 65 78 70 6f 72 74 29 0a 23 65 6e 64 69 66 0a 69  export).#endif.i
6c30: 6e 74 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 69  nt sqlite3_filei
6c40: 6f 5f 69 6e 69 74 28 0a 20 20 73 71 6c 69 74 65  o_init(.  sqlite
6c50: 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20 2a  3 *db, .  char *
6c60: 2a 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20 63 6f  *pzErrMsg, .  co
6c70: 6e 73 74 20 73 71 6c 69 74 65 33 5f 61 70 69 5f  nst sqlite3_api_
6c80: 72 6f 75 74 69 6e 65 73 20 2a 70 41 70 69 0a 29  routines *pApi.)
6c90: 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51 4c  {.  int rc = SQL
6ca0: 49 54 45 5f 4f 4b 3b 0a 20 20 53 51 4c 49 54 45  ITE_OK;.  SQLITE
6cb0: 5f 45 58 54 45 4e 53 49 4f 4e 5f 49 4e 49 54 32  _EXTENSION_INIT2
6cc0: 28 70 41 70 69 29 3b 0a 20 20 28 76 6f 69 64 29  (pApi);.  (void)
6cd0: 70 7a 45 72 72 4d 73 67 3b 20 20 2f 2a 20 55 6e  pzErrMsg;  /* Un
6ce0: 75 73 65 64 20 70 61 72 61 6d 65 74 65 72 20 2a  used parameter *
6cf0: 2f 0a 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33  /.  rc = sqlite3
6d00: 5f 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e  _create_function
6d10: 28 64 62 2c 20 22 72 65 61 64 66 69 6c 65 22 2c  (db, "readfile",
6d20: 20 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38 2c   1, SQLITE_UTF8,
6d30: 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20   0,.            
6d40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6d50: 20 20 20 72 65 61 64 66 69 6c 65 46 75 6e 63 2c     readfileFunc,
6d60: 20 30 2c 20 30 29 3b 0a 20 20 69 66 28 20 72 63   0, 0);.  if( rc
6d70: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
6d80: 20 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f     rc = sqlite3_
6d90: 63 72 65 61 74 65 5f 66 75 6e 63 74 69 6f 6e 28  create_function(
6da0: 64 62 2c 20 22 77 72 69 74 65 66 69 6c 65 22 2c  db, "writefile",
6db0: 20 2d 31 2c 20 53 51 4c 49 54 45 5f 55 54 46 38   -1, SQLITE_UTF8
6dc0: 2c 20 30 2c 0a 20 20 20 20 20 20 20 20 20 20 20  , 0,.           
6dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6de0: 20 20 20 20 20 20 77 72 69 74 65 66 69 6c 65 46        writefileF
6df0: 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d 0a  unc, 0, 0);.  }.
6e00: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
6e10: 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d 20  _OK ){.    rc = 
6e20: 73 71 6c 69 74 65 33 5f 63 72 65 61 74 65 5f 66  sqlite3_create_f
6e30: 75 6e 63 74 69 6f 6e 28 64 62 2c 20 22 6c 73 6d  unction(db, "lsm
6e40: 6f 64 65 22 2c 20 31 2c 20 53 51 4c 49 54 45 5f  ode", 1, SQLITE_
6e50: 55 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20  UTF8, 0,.       
6e60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6e70: 20 20 20 20 20 20 20 20 20 20 6c 73 4d 6f 64 65            lsMode
6e80: 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 7d  Func, 0, 0);.  }
6e90: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
6ea0: 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72 63 20 3d  E_OK ){.    rc =
6eb0: 20 66 73 64 69 72 52 65 67 69 73 74 65 72 28 64   fsdirRegister(d
6ec0: 62 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  b);.  }.  return
6ed0: 20 72 63 3b 0a 7d 0a                              rc;.}.