/ Hex Artifact Content
Login

Artifact 70f933c2e530bdceb35fbf4fe529fc1bdcdd26454c77cf8c4bc456c4123e612b:


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: 23 64 65 66 69 6e 65 20 46 53 44 49 52 5f 53 43  #define FSDIR_SC
0eb0: 48 45 4d 41 20 22 28 6e 61 6d 65 2c 6d 6f 64 65  HEMA "(name,mode
0ec0: 2c 6d 74 69 6d 65 2c 64 61 74 61 2c 70 61 74 68  ,mtime,data,path
0ed0: 20 48 49 44 44 45 4e 2c 64 69 72 20 48 49 44 44   HIDDEN,dir HIDD
0ee0: 45 4e 29 22 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  EN)"../*.** Set 
0ef0: 74 68 65 20 72 65 73 75 6c 74 20 73 74 6f 72 65  the result store
0f00: 64 20 62 79 20 63 6f 6e 74 65 78 74 20 63 74 78  d by context ctx
0f10: 20 74 6f 20 61 20 62 6c 6f 62 20 63 6f 6e 74 61   to a blob conta
0f20: 69 6e 69 6e 67 20 74 68 65 20 0a 2a 2a 20 63 6f  ining the .** co
0f30: 6e 74 65 6e 74 73 20 6f 66 20 66 69 6c 65 20 7a  ntents of file z
0f40: 4e 61 6d 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  Name..*/.static 
0f50: 76 6f 69 64 20 72 65 61 64 46 69 6c 65 43 6f 6e  void readFileCon
0f60: 74 65 6e 74 73 28 73 71 6c 69 74 65 33 5f 63 6f  tents(sqlite3_co
0f70: 6e 74 65 78 74 20 2a 63 74 78 2c 20 63 6f 6e 73  ntext *ctx, cons
0f80: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 29 7b 0a  t char *zName){.
0f90: 20 20 46 49 4c 45 20 2a 69 6e 3b 0a 20 20 6c 6f    FILE *in;.  lo
0fa0: 6e 67 20 6e 49 6e 3b 0a 20 20 76 6f 69 64 20 2a  ng nIn;.  void *
0fb0: 70 42 75 66 3b 0a 0a 20 20 69 6e 20 3d 20 66 6f  pBuf;..  in = fo
0fc0: 70 65 6e 28 7a 4e 61 6d 65 2c 20 22 72 62 22 29  pen(zName, "rb")
0fd0: 3b 0a 20 20 69 66 28 20 69 6e 3d 3d 30 20 29 20  ;.  if( in==0 ) 
0fe0: 72 65 74 75 72 6e 3b 0a 20 20 66 73 65 65 6b 28  return;.  fseek(
0ff0: 69 6e 2c 20 30 2c 20 53 45 45 4b 5f 45 4e 44 29  in, 0, SEEK_END)
1000: 3b 0a 20 20 6e 49 6e 20 3d 20 66 74 65 6c 6c 28  ;.  nIn = ftell(
1010: 69 6e 29 3b 0a 20 20 72 65 77 69 6e 64 28 69 6e  in);.  rewind(in
1020: 29 3b 0a 20 20 70 42 75 66 20 3d 20 73 71 6c 69  );.  pBuf = sqli
1030: 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 6e 49 6e 20  te3_malloc( nIn 
1040: 29 3b 0a 20 20 69 66 28 20 70 42 75 66 20 26 26  );.  if( pBuf &&
1050: 20 31 3d 3d 66 72 65 61 64 28 70 42 75 66 2c 20   1==fread(pBuf, 
1060: 6e 49 6e 2c 20 31 2c 20 69 6e 29 20 29 7b 0a 20  nIn, 1, in) ){. 
1070: 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c     sqlite3_resul
1080: 74 5f 62 6c 6f 62 28 63 74 78 2c 20 70 42 75 66  t_blob(ctx, pBuf
1090: 2c 20 6e 49 6e 2c 20 73 71 6c 69 74 65 33 5f 66  , nIn, sqlite3_f
10a0: 72 65 65 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  ree);.  }else{. 
10b0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
10c0: 70 42 75 66 29 3b 0a 20 20 7d 0a 20 20 66 63 6c  pBuf);.  }.  fcl
10d0: 6f 73 65 28 69 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  ose(in);.}../*.*
10e0: 2a 20 49 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e  * Implementation
10f0: 20 6f 66 20 74 68 65 20 22 72 65 61 64 66 69 6c   of the "readfil
1100: 65 28 58 29 22 20 53 51 4c 20 66 75 6e 63 74 69  e(X)" SQL functi
1110: 6f 6e 2e 20 20 54 68 65 20 65 6e 74 69 72 65 20  on.  The entire 
1120: 63 6f 6e 74 65 6e 74 0a 2a 2a 20 6f 66 20 74 68  content.** of th
1130: 65 20 66 69 6c 65 20 6e 61 6d 65 64 20 58 20 69  e file named X i
1140: 73 20 72 65 61 64 20 61 6e 64 20 72 65 74 75 72  s read and retur
1150: 6e 65 64 20 61 73 20 61 20 42 4c 4f 42 2e 20 20  ned as a BLOB.  
1160: 4e 55 4c 4c 20 69 73 20 72 65 74 75 72 6e 65 64  NULL is returned
1170: 0a 2a 2a 20 69 66 20 74 68 65 20 66 69 6c 65 20  .** if the file 
1180: 64 6f 65 73 20 6e 6f 74 20 65 78 69 73 74 20 6f  does not exist o
1190: 72 20 69 73 20 75 6e 72 65 61 64 61 62 6c 65 2e  r is unreadable.
11a0: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
11b0: 72 65 61 64 66 69 6c 65 46 75 6e 63 28 0a 20 20  readfileFunc(.  
11c0: 73 71 6c 69 74 65 33 5f 63 6f 6e 74 65 78 74 20  sqlite3_context 
11d0: 2a 63 6f 6e 74 65 78 74 2c 0a 20 20 69 6e 74 20  *context,.  int 
11e0: 61 72 67 63 2c 0a 20 20 73 71 6c 69 74 65 33 5f  argc,.  sqlite3_
11f0: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
1200: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e    const char *zN
1210: 61 6d 65 3b 0a 20 20 28 76 6f 69 64 29 28 61 72  ame;.  (void)(ar
1220: 67 63 29 3b 20 20 2f 2a 20 55 6e 75 73 65 64 20  gc);  /* Unused 
1230: 70 61 72 61 6d 65 74 65 72 20 2a 2f 0a 20 20 7a  parameter */.  z
1240: 4e 61 6d 65 20 3d 20 28 63 6f 6e 73 74 20 63 68  Name = (const ch
1250: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
1260: 65 5f 74 65 78 74 28 61 72 67 76 5b 30 5d 29 3b  e_text(argv[0]);
1270: 0a 20 20 69 66 28 20 7a 4e 61 6d 65 3d 3d 30 20  .  if( zName==0 
1280: 29 20 72 65 74 75 72 6e 3b 0a 20 20 72 65 61 64  ) return;.  read
1290: 46 69 6c 65 43 6f 6e 74 65 6e 74 73 28 63 6f 6e  FileContents(con
12a0: 74 65 78 74 2c 20 7a 4e 61 6d 65 29 3b 0a 7d 0a  text, zName);.}.
12b0: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 65  ./*.** Set the e
12c0: 72 72 6f 72 20 6d 65 73 73 61 67 65 20 63 6f 6e  rror message con
12d0: 74 61 69 6e 65 64 20 69 6e 20 63 6f 6e 74 65 78  tained in contex
12e0: 74 20 63 74 78 20 74 6f 20 74 68 65 20 72 65 73  t ctx to the res
12f0: 75 6c 74 73 20 6f 66 0a 2a 2a 20 76 70 72 69 6e  ults of.** vprin
1300: 74 66 28 7a 46 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a  tf(zFmt, ...)..*
1310: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 63 74  /.static void ct
1320: 78 45 72 72 6f 72 4d 73 67 28 73 71 6c 69 74 65  xErrorMsg(sqlite
1330: 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78 2c 20  3_context *ctx, 
1340: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6d 74  const char *zFmt
1350: 2c 20 2e 2e 2e 29 7b 0a 20 20 63 68 61 72 20 2a  , ...){.  char *
1360: 7a 4d 73 67 20 3d 20 30 3b 0a 20 20 76 61 5f 6c  zMsg = 0;.  va_l
1370: 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61  ist ap;.  va_sta
1380: 72 74 28 61 70 2c 20 7a 46 6d 74 29 3b 0a 20 20  rt(ap, zFmt);.  
1390: 7a 4d 73 67 20 3d 20 73 71 6c 69 74 65 33 5f 76  zMsg = sqlite3_v
13a0: 6d 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20 61 70  mprintf(zFmt, ap
13b0: 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f 72 65 73  );.  sqlite3_res
13c0: 75 6c 74 5f 65 72 72 6f 72 28 63 74 78 2c 20 7a  ult_error(ctx, z
13d0: 4d 73 67 2c 20 2d 31 29 3b 0a 20 20 73 71 6c 69  Msg, -1);.  sqli
13e0: 74 65 33 5f 66 72 65 65 28 7a 4d 73 67 29 3b 0a  te3_free(zMsg);.
13f0: 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a    va_end(ap);.}.
1400: 0a 23 69 66 20 64 65 66 69 6e 65 64 28 5f 57 49  .#if defined(_WI
1410: 4e 33 32 29 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  N32)./*.** This 
1420: 66 75 6e 63 74 69 6f 6e 20 69 73 20 64 65 73 69  function is desi
1430: 67 6e 65 64 20 74 6f 20 63 6f 6e 76 65 72 74 20  gned to convert 
1440: 61 20 57 69 6e 33 32 20 46 49 4c 45 54 49 4d 45  a Win32 FILETIME
1450: 20 73 74 72 75 63 74 75 72 65 20 69 6e 74 6f 20   structure into 
1460: 74 68 65 0a 2a 2a 20 6e 75 6d 62 65 72 20 6f 66  the.** number of
1470: 20 73 65 63 6f 6e 64 73 20 73 69 6e 63 65 20 74   seconds since t
1480: 68 65 20 55 6e 69 78 20 45 70 6f 63 68 20 28 31  he Unix Epoch (1
1490: 39 37 30 2d 30 31 2d 30 31 20 30 30 3a 30 30 3a  970-01-01 00:00:
14a0: 30 30 20 55 54 43 29 2e 0a 2a 2f 0a 73 74 61 74  00 UTC)..*/.stat
14b0: 69 63 20 73 71 6c 69 74 65 33 5f 75 69 6e 74 36  ic sqlite3_uint6
14c0: 34 20 66 69 6c 65 54 69 6d 65 54 6f 55 6e 69 78  4 fileTimeToUnix
14d0: 54 69 6d 65 28 0a 20 20 4c 50 46 49 4c 45 54 49  Time(.  LPFILETI
14e0: 4d 45 20 70 46 69 6c 65 54 69 6d 65 0a 29 7b 0a  ME pFileTime.){.
14f0: 20 20 53 59 53 54 45 4d 54 49 4d 45 20 65 70 6f    SYSTEMTIME epo
1500: 63 68 53 79 73 74 65 6d 54 69 6d 65 3b 0a 20 20  chSystemTime;.  
1510: 55 4c 41 52 47 45 5f 49 4e 54 45 47 45 52 20 65  ULARGE_INTEGER e
1520: 70 6f 63 68 49 6e 74 65 72 76 61 6c 73 3b 0a 20  pochIntervals;. 
1530: 20 46 49 4c 45 54 49 4d 45 20 65 70 6f 63 68 46   FILETIME epochF
1540: 69 6c 65 54 69 6d 65 3b 0a 20 20 55 4c 41 52 47  ileTime;.  ULARG
1550: 45 5f 49 4e 54 45 47 45 52 20 66 69 6c 65 49 6e  E_INTEGER fileIn
1560: 74 65 72 76 61 6c 73 3b 0a 0a 20 20 6d 65 6d 73  tervals;..  mems
1570: 65 74 28 26 65 70 6f 63 68 53 79 73 74 65 6d 54  et(&epochSystemT
1580: 69 6d 65 2c 20 30 2c 20 73 69 7a 65 6f 66 28 53  ime, 0, sizeof(S
1590: 59 53 54 45 4d 54 49 4d 45 29 29 3b 0a 20 20 65  YSTEMTIME));.  e
15a0: 70 6f 63 68 53 79 73 74 65 6d 54 69 6d 65 2e 77  pochSystemTime.w
15b0: 59 65 61 72 20 3d 20 31 39 37 30 3b 0a 20 20 65  Year = 1970;.  e
15c0: 70 6f 63 68 53 79 73 74 65 6d 54 69 6d 65 2e 77  pochSystemTime.w
15d0: 4d 6f 6e 74 68 20 3d 20 31 3b 0a 20 20 65 70 6f  Month = 1;.  epo
15e0: 63 68 53 79 73 74 65 6d 54 69 6d 65 2e 77 44 61  chSystemTime.wDa
15f0: 79 20 3d 20 31 3b 0a 20 20 53 79 73 74 65 6d 54  y = 1;.  SystemT
1600: 69 6d 65 54 6f 46 69 6c 65 54 69 6d 65 28 26 65  imeToFileTime(&e
1610: 70 6f 63 68 53 79 73 74 65 6d 54 69 6d 65 2c 20  pochSystemTime, 
1620: 26 65 70 6f 63 68 46 69 6c 65 54 69 6d 65 29 3b  &epochFileTime);
1630: 0a 20 20 65 70 6f 63 68 49 6e 74 65 72 76 61 6c  .  epochInterval
1640: 73 2e 4c 6f 77 50 61 72 74 20 3d 20 65 70 6f 63  s.LowPart = epoc
1650: 68 46 69 6c 65 54 69 6d 65 2e 64 77 4c 6f 77 44  hFileTime.dwLowD
1660: 61 74 65 54 69 6d 65 3b 0a 20 20 65 70 6f 63 68  ateTime;.  epoch
1670: 49 6e 74 65 72 76 61 6c 73 2e 48 69 67 68 50 61  Intervals.HighPa
1680: 72 74 20 3d 20 65 70 6f 63 68 46 69 6c 65 54 69  rt = epochFileTi
1690: 6d 65 2e 64 77 48 69 67 68 44 61 74 65 54 69 6d  me.dwHighDateTim
16a0: 65 3b 0a 0a 20 20 66 69 6c 65 49 6e 74 65 72 76  e;..  fileInterv
16b0: 61 6c 73 2e 4c 6f 77 50 61 72 74 20 3d 20 70 46  als.LowPart = pF
16c0: 69 6c 65 54 69 6d 65 2d 3e 64 77 4c 6f 77 44 61  ileTime->dwLowDa
16d0: 74 65 54 69 6d 65 3b 0a 20 20 66 69 6c 65 49 6e  teTime;.  fileIn
16e0: 74 65 72 76 61 6c 73 2e 48 69 67 68 50 61 72 74  tervals.HighPart
16f0: 20 3d 20 70 46 69 6c 65 54 69 6d 65 2d 3e 64 77   = pFileTime->dw
1700: 48 69 67 68 44 61 74 65 54 69 6d 65 3b 0a 0a 20  HighDateTime;.. 
1710: 20 72 65 74 75 72 6e 20 28 66 69 6c 65 49 6e 74   return (fileInt
1720: 65 72 76 61 6c 73 2e 51 75 61 64 50 61 72 74 20  ervals.QuadPart 
1730: 2d 20 65 70 6f 63 68 49 6e 74 65 72 76 61 6c 73  - epochIntervals
1740: 2e 51 75 61 64 50 61 72 74 29 20 2f 20 31 30 30  .QuadPart) / 100
1750: 30 30 30 30 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  00000;.}../*.** 
1760: 54 68 69 73 20 66 75 6e 63 74 69 6f 6e 20 61 74  This function at
1770: 74 65 6d 70 74 73 20 74 6f 20 6e 6f 72 6d 61 6c  tempts to normal
1780: 69 7a 65 20 74 68 65 20 74 69 6d 65 20 76 61 6c  ize the time val
1790: 75 65 73 20 66 6f 75 6e 64 20 69 6e 20 74 68 65  ues found in the
17a0: 20 73 74 61 74 28 29 0a 2a 2a 20 62 75 66 66 65   stat().** buffe
17b0: 72 20 74 6f 20 55 54 43 2e 20 20 54 68 69 73 20  r to UTC.  This 
17c0: 69 73 20 6e 65 63 65 73 73 61 72 79 20 6f 6e 20  is necessary on 
17d0: 57 69 6e 33 32 2c 20 77 68 65 72 65 20 74 68 65  Win32, where the
17e0: 20 72 75 6e 74 69 6d 65 20 6c 69 62 72 61 72 79   runtime library
17f0: 0a 2a 2a 20 61 70 70 65 61 72 73 20 74 6f 20 72  .** appears to r
1800: 65 74 75 72 6e 20 74 68 65 73 65 20 76 61 6c 75  eturn these valu
1810: 65 73 20 61 73 20 6c 6f 63 61 6c 20 74 69 6d 65  es as local time
1820: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  s..*/.static voi
1830: 64 20 73 74 61 74 54 69 6d 65 73 54 6f 55 74 63  d statTimesToUtc
1840: 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  (.  const char *
1850: 7a 50 61 74 68 2c 0a 20 20 73 74 72 75 63 74 20  zPath,.  struct 
1860: 73 74 61 74 20 2a 70 53 74 61 74 42 75 66 0a 29  stat *pStatBuf.)
1870: 7b 0a 20 20 48 41 4e 44 4c 45 20 68 46 69 6e 64  {.  HANDLE hFind
1880: 46 69 6c 65 3b 0a 20 20 57 49 4e 33 32 5f 46 49  File;.  WIN32_FI
1890: 4e 44 5f 44 41 54 41 57 20 66 64 3b 0a 20 20 4c  ND_DATAW fd;.  L
18a0: 50 57 53 54 52 20 7a 55 6e 69 63 6f 64 65 4e 61  PWSTR zUnicodeNa
18b0: 6d 65 3b 0a 20 20 65 78 74 65 72 6e 20 4c 50 57  me;.  extern LPW
18c0: 53 54 52 20 73 71 6c 69 74 65 33 5f 77 69 6e 33  STR sqlite3_win3
18d0: 32 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 63 6f 64  2_utf8_to_unicod
18e0: 65 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 3b 0a  e(const char*);.
18f0: 20 20 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 20 3d    zUnicodeName =
1900: 20 73 71 6c 69 74 65 33 5f 77 69 6e 33 32 5f 75   sqlite3_win32_u
1910: 74 66 38 5f 74 6f 5f 75 6e 69 63 6f 64 65 28 7a  tf8_to_unicode(z
1920: 50 61 74 68 29 3b 0a 20 20 69 66 28 20 7a 55 6e  Path);.  if( zUn
1930: 69 63 6f 64 65 4e 61 6d 65 20 29 7b 0a 20 20 20  icodeName ){.   
1940: 20 6d 65 6d 73 65 74 28 26 66 64 2c 20 30 2c 20   memset(&fd, 0, 
1950: 73 69 7a 65 6f 66 28 57 49 4e 33 32 5f 46 49 4e  sizeof(WIN32_FIN
1960: 44 5f 44 41 54 41 57 29 29 3b 0a 20 20 20 20 68  D_DATAW));.    h
1970: 46 69 6e 64 46 69 6c 65 20 3d 20 46 69 6e 64 46  FindFile = FindF
1980: 69 72 73 74 46 69 6c 65 57 28 7a 55 6e 69 63 6f  irstFileW(zUnico
1990: 64 65 4e 61 6d 65 2c 20 26 66 64 29 3b 0a 20 20  deName, &fd);.  
19a0: 20 20 69 66 28 20 68 46 69 6e 64 46 69 6c 65 21    if( hFindFile!
19b0: 3d 4e 55 4c 4c 20 29 7b 0a 20 20 20 20 20 20 70  =NULL ){.      p
19c0: 53 74 61 74 42 75 66 2d 3e 73 74 5f 63 74 69 6d  StatBuf->st_ctim
19d0: 65 20 3d 20 28 74 69 6d 65 5f 74 29 66 69 6c 65  e = (time_t)file
19e0: 54 69 6d 65 54 6f 55 6e 69 78 54 69 6d 65 28 26  TimeToUnixTime(&
19f0: 66 64 2e 66 74 43 72 65 61 74 69 6f 6e 54 69 6d  fd.ftCreationTim
1a00: 65 29 3b 0a 20 20 20 20 20 20 70 53 74 61 74 42  e);.      pStatB
1a10: 75 66 2d 3e 73 74 5f 61 74 69 6d 65 20 3d 20 28  uf->st_atime = (
1a20: 74 69 6d 65 5f 74 29 66 69 6c 65 54 69 6d 65 54  time_t)fileTimeT
1a30: 6f 55 6e 69 78 54 69 6d 65 28 26 66 64 2e 66 74  oUnixTime(&fd.ft
1a40: 4c 61 73 74 41 63 63 65 73 73 54 69 6d 65 29 3b  LastAccessTime);
1a50: 0a 20 20 20 20 20 20 70 53 74 61 74 42 75 66 2d  .      pStatBuf-
1a60: 3e 73 74 5f 6d 74 69 6d 65 20 3d 20 28 74 69 6d  >st_mtime = (tim
1a70: 65 5f 74 29 66 69 6c 65 54 69 6d 65 54 6f 55 6e  e_t)fileTimeToUn
1a80: 69 78 54 69 6d 65 28 26 66 64 2e 66 74 4c 61 73  ixTime(&fd.ftLas
1a90: 74 57 72 69 74 65 54 69 6d 65 29 3b 0a 20 20 20  tWriteTime);.   
1aa0: 20 20 20 46 69 6e 64 43 6c 6f 73 65 28 68 46 69     FindClose(hFi
1ab0: 6e 64 46 69 6c 65 29 3b 0a 20 20 20 20 7d 0a 20  ndFile);.    }. 
1ac0: 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28     sqlite3_free(
1ad0: 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 29 3b 0a 20  zUnicodeName);. 
1ae0: 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a   }.}.#endif../*.
1af0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
1b00: 20 69 73 20 75 73 65 64 20 69 6e 20 70 6c 61 63   is used in plac
1b10: 65 20 6f 66 20 73 74 61 74 28 29 2e 20 20 4f 6e  e of stat().  On
1b20: 20 57 69 6e 64 6f 77 73 2c 20 73 70 65 63 69 61   Windows, specia
1b30: 6c 20 68 61 6e 64 6c 69 6e 67 0a 2a 2a 20 69 73  l handling.** is
1b40: 20 72 65 71 75 69 72 65 64 20 69 6e 20 6f 72 64   required in ord
1b50: 65 72 20 66 6f 72 20 74 68 65 20 69 6e 63 6c 75  er for the inclu
1b60: 64 65 64 20 74 69 6d 65 20 74 6f 20 62 65 20 72  ded time to be r
1b70: 65 74 75 72 6e 65 64 20 61 73 20 55 54 43 2e 20  eturned as UTC. 
1b80: 20 4f 6e 20 61 6c 6c 0a 2a 2a 20 6f 74 68 65 72   On all.** other
1b90: 20 73 79 73 74 65 6d 73 2c 20 74 68 69 73 20 66   systems, this f
1ba0: 75 6e 63 74 69 6f 6e 20 73 69 6d 70 6c 79 20 63  unction simply c
1bb0: 61 6c 6c 73 20 73 74 61 74 28 29 2e 0a 2a 2f 0a  alls stat()..*/.
1bc0: 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65 53  static int fileS
1bd0: 74 61 74 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  tat(.  const cha
1be0: 72 20 2a 7a 50 61 74 68 2c 0a 20 20 73 74 72 75  r *zPath,.  stru
1bf0: 63 74 20 73 74 61 74 20 2a 70 53 74 61 74 42 75  ct stat *pStatBu
1c00: 66 0a 29 7b 0a 23 69 66 20 64 65 66 69 6e 65 64  f.){.#if defined
1c10: 28 5f 57 49 4e 33 32 29 0a 20 20 69 6e 74 20 72  (_WIN32).  int r
1c20: 63 20 3d 20 73 74 61 74 28 7a 50 61 74 68 2c 20  c = stat(zPath, 
1c30: 70 53 74 61 74 42 75 66 29 3b 0a 20 20 69 66 28  pStatBuf);.  if(
1c40: 20 72 63 3d 3d 30 20 29 20 73 74 61 74 54 69 6d   rc==0 ) statTim
1c50: 65 73 54 6f 55 74 63 28 7a 50 61 74 68 2c 20 70  esToUtc(zPath, p
1c60: 53 74 61 74 42 75 66 29 3b 0a 20 20 72 65 74 75  StatBuf);.  retu
1c70: 72 6e 20 72 63 3b 0a 23 65 6c 73 65 0a 20 20 72  rn rc;.#else.  r
1c80: 65 74 75 72 6e 20 73 74 61 74 28 7a 50 61 74 68  eturn stat(zPath
1c90: 2c 20 70 53 74 61 74 42 75 66 29 3b 0a 23 65 6e  , pStatBuf);.#en
1ca0: 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  dif.}../*.** Thi
1cb0: 73 20 66 75 6e 63 74 69 6f 6e 20 69 73 20 75 73  s function is us
1cc0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 6c  ed in place of l
1cd0: 73 74 61 74 28 29 2e 20 20 4f 6e 20 57 69 6e 64  stat().  On Wind
1ce0: 6f 77 73 2c 20 73 70 65 63 69 61 6c 20 68 61 6e  ows, special han
1cf0: 64 6c 69 6e 67 0a 2a 2a 20 69 73 20 72 65 71 75  dling.** is requ
1d00: 69 72 65 64 20 69 6e 20 6f 72 64 65 72 20 66 6f  ired in order fo
1d10: 72 20 74 68 65 20 69 6e 63 6c 75 64 65 64 20 74  r the included t
1d20: 69 6d 65 20 74 6f 20 62 65 20 72 65 74 75 72 6e  ime to be return
1d30: 65 64 20 61 73 20 55 54 43 2e 20 20 4f 6e 20 61  ed as UTC.  On a
1d40: 6c 6c 0a 2a 2a 20 6f 74 68 65 72 20 73 79 73 74  ll.** other syst
1d50: 65 6d 73 2c 20 74 68 69 73 20 66 75 6e 63 74 69  ems, this functi
1d60: 6f 6e 20 73 69 6d 70 6c 79 20 63 61 6c 6c 73 20  on simply calls 
1d70: 6c 73 74 61 74 28 29 2e 0a 2a 2f 0a 73 74 61 74  lstat()..*/.stat
1d80: 69 63 20 69 6e 74 20 66 69 6c 65 4c 69 6e 6b 53  ic int fileLinkS
1d90: 74 61 74 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  tat(.  const cha
1da0: 72 20 2a 7a 50 61 74 68 2c 0a 20 20 73 74 72 75  r *zPath,.  stru
1db0: 63 74 20 73 74 61 74 20 2a 70 53 74 61 74 42 75  ct stat *pStatBu
1dc0: 66 0a 29 7b 0a 23 69 66 20 64 65 66 69 6e 65 64  f.){.#if defined
1dd0: 28 5f 57 49 4e 33 32 29 0a 20 20 69 6e 74 20 72  (_WIN32).  int r
1de0: 63 20 3d 20 6c 73 74 61 74 28 7a 50 61 74 68 2c  c = lstat(zPath,
1df0: 20 70 53 74 61 74 42 75 66 29 3b 0a 20 20 69 66   pStatBuf);.  if
1e00: 28 20 72 63 3d 3d 30 20 29 20 73 74 61 74 54 69  ( rc==0 ) statTi
1e10: 6d 65 73 54 6f 55 74 63 28 7a 50 61 74 68 2c 20  mesToUtc(zPath, 
1e20: 70 53 74 61 74 42 75 66 29 3b 0a 20 20 72 65 74  pStatBuf);.  ret
1e30: 75 72 6e 20 72 63 3b 0a 23 65 6c 73 65 0a 20 20  urn rc;.#else.  
1e40: 72 65 74 75 72 6e 20 6c 73 74 61 74 28 7a 50 61  return lstat(zPa
1e50: 74 68 2c 20 70 53 74 61 74 42 75 66 29 3b 0a 23  th, pStatBuf);.#
1e60: 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  endif.}../*.** A
1e70: 72 67 75 6d 65 6e 74 20 7a 46 69 6c 65 20 69 73  rgument zFile is
1e80: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 61 20 66   the name of a f
1e90: 69 6c 65 20 74 68 61 74 20 77 69 6c 6c 20 62 65  ile that will be
1ea0: 20 63 72 65 61 74 65 64 20 61 6e 64 2f 6f 72 20   created and/or 
1eb0: 77 72 69 74 74 65 6e 0a 2a 2a 20 62 79 20 53 51  written.** by SQ
1ec0: 4c 20 66 75 6e 63 74 69 6f 6e 20 77 72 69 74 65  L function write
1ed0: 66 69 6c 65 28 29 2e 20 54 68 69 73 20 66 75 6e  file(). This fun
1ee0: 63 74 69 6f 6e 20 65 6e 73 75 72 65 73 20 74 68  ction ensures th
1ef0: 61 74 20 74 68 65 20 64 69 72 65 63 74 6f 72 79  at the directory
1f00: 0a 2a 2a 20 7a 46 69 6c 65 20 77 69 6c 6c 20 62  .** zFile will b
1f10: 65 20 77 72 69 74 74 65 6e 20 74 6f 20 65 78 69  e written to exi
1f20: 73 74 73 2c 20 63 72 65 61 74 69 6e 67 20 69 74  sts, creating it
1f30: 20 69 66 20 72 65 71 75 69 72 65 64 2e 20 54 68   if required. Th
1f40: 65 20 70 65 72 6d 69 73 73 69 6f 6e 73 0a 2a 2a  e permissions.**
1f50: 20 66 6f 72 20 61 6e 79 20 70 61 74 68 20 63 6f   for any path co
1f60: 6d 70 6f 6e 65 6e 74 73 20 63 72 65 61 74 65 64  mponents created
1f70: 20 62 79 20 74 68 69 73 20 66 75 6e 63 74 69 6f   by this functio
1f80: 6e 20 61 72 65 20 73 65 74 20 74 6f 20 28 6d 6f  n are set to (mo
1f90: 64 65 26 30 37 37 37 29 2e 0a 2a 2a 0a 2a 2a 20  de&0777)..**.** 
1fa0: 49 66 20 61 6e 20 4f 4f 4d 20 63 6f 6e 64 69 74  If an OOM condit
1fb0: 69 6f 6e 20 69 73 20 65 6e 63 6f 75 6e 74 65 72  ion is encounter
1fc0: 65 64 2c 20 53 51 4c 49 54 45 5f 4e 4f 4d 45 4d  ed, SQLITE_NOMEM
1fd0: 20 69 73 20 72 65 74 75 72 6e 65 64 2e 20 4f 74   is returned. Ot
1fe0: 68 65 72 77 69 73 65 2c 0a 2a 2a 20 53 51 4c 49  herwise,.** SQLI
1ff0: 54 45 5f 4f 4b 20 69 73 20 72 65 74 75 72 6e 65  TE_OK is returne
2000: 64 20 69 66 20 74 68 65 20 64 69 72 65 63 74 6f  d if the directo
2010: 72 79 20 69 73 20 73 75 63 63 65 73 73 66 75 6c  ry is successful
2020: 6c 79 20 63 72 65 61 74 65 64 2c 20 6f 72 0a 2a  ly created, or.*
2030: 2a 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 20 6f  * SQLITE_ERROR o
2040: 74 68 65 72 77 69 73 65 2e 0a 2a 2f 0a 73 74 61  therwise..*/.sta
2050: 74 69 63 20 69 6e 74 20 6d 61 6b 65 44 69 72 65  tic int makeDire
2060: 63 74 6f 72 79 28 0a 20 20 63 6f 6e 73 74 20 63  ctory(.  const c
2070: 68 61 72 20 2a 7a 46 69 6c 65 2c 0a 20 20 6d 6f  har *zFile,.  mo
2080: 64 65 5f 74 20 6d 6f 64 65 0a 29 7b 0a 20 20 63  de_t mode.){.  c
2090: 68 61 72 20 2a 7a 43 6f 70 79 20 3d 20 73 71 6c  har *zCopy = sql
20a0: 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25 73  ite3_mprintf("%s
20b0: 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20 69 6e 74  ", zFile);.  int
20c0: 20 72 63 20 3d 20 53 51 4c 49 54 45 5f 4f 4b 3b   rc = SQLITE_OK;
20d0: 0a 0a 20 20 69 66 28 20 7a 43 6f 70 79 3d 3d 30  ..  if( zCopy==0
20e0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 53 51 4c   ){.    rc = SQL
20f0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 65 6c  ITE_NOMEM;.  }el
2100: 73 65 7b 0a 20 20 20 20 69 6e 74 20 6e 43 6f 70  se{.    int nCop
2110: 79 20 3d 20 28 69 6e 74 29 73 74 72 6c 65 6e 28  y = (int)strlen(
2120: 7a 43 6f 70 79 29 3b 0a 20 20 20 20 69 6e 74 20  zCopy);.    int 
2130: 69 20 3d 20 31 3b 0a 0a 20 20 20 20 77 68 69 6c  i = 1;..    whil
2140: 65 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b  e( rc==SQLITE_OK
2150: 20 29 7b 0a 20 20 20 20 20 20 73 74 72 75 63 74   ){.      struct
2160: 20 73 74 61 74 20 73 53 74 61 74 3b 0a 20 20 20   stat sStat;.   
2170: 20 20 20 69 6e 74 20 72 63 32 3b 0a 0a 20 20 20     int rc2;..   
2180: 20 20 20 66 6f 72 28 3b 20 7a 43 6f 70 79 5b 69     for(; zCopy[i
2190: 5d 21 3d 27 2f 27 20 26 26 20 69 3c 6e 43 6f 70  ]!='/' && i<nCop
21a0: 79 3b 20 69 2b 2b 29 3b 0a 20 20 20 20 20 20 69  y; i++);.      i
21b0: 66 28 20 69 3d 3d 6e 43 6f 70 79 20 29 20 62 72  f( i==nCopy ) br
21c0: 65 61 6b 3b 0a 20 20 20 20 20 20 7a 43 6f 70 79  eak;.      zCopy
21d0: 5b 69 5d 20 3d 20 27 5c 30 27 3b 0a 0a 20 20 20  [i] = '\0';..   
21e0: 20 20 20 72 63 32 20 3d 20 66 69 6c 65 53 74 61     rc2 = fileSta
21f0: 74 28 7a 43 6f 70 79 2c 20 26 73 53 74 61 74 29  t(zCopy, &sStat)
2200: 3b 0a 20 20 20 20 20 20 69 66 28 20 72 63 32 21  ;.      if( rc2!
2210: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 69 66  =0 ){.        if
2220: 28 20 6d 6b 64 69 72 28 7a 43 6f 70 79 2c 20 6d  ( mkdir(zCopy, m
2230: 6f 64 65 20 26 20 30 37 37 37 29 20 29 20 72 63  ode & 0777) ) rc
2240: 20 3d 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b   = SQLITE_ERROR;
2250: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
2260: 20 20 20 20 20 20 69 66 28 20 21 53 5f 49 53 44        if( !S_ISD
2270: 49 52 28 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65  IR(sStat.st_mode
2280: 29 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  ) ) rc = SQLITE_
2290: 45 52 52 4f 52 3b 0a 20 20 20 20 20 20 7d 0a 20  ERROR;.      }. 
22a0: 20 20 20 20 20 7a 43 6f 70 79 5b 69 5d 20 3d 20       zCopy[i] = 
22b0: 27 2f 27 3b 0a 20 20 20 20 20 20 69 2b 2b 3b 0a  '/';.      i++;.
22c0: 20 20 20 20 7d 0a 0a 20 20 20 20 73 71 6c 69 74      }..    sqlit
22d0: 65 33 5f 66 72 65 65 28 7a 43 6f 70 79 29 3b 0a  e3_free(zCopy);.
22e0: 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 72 63    }..  return rc
22f0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
2300: 66 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 74 68  function does th
2310: 65 20 77 6f 72 6b 20 66 6f 72 20 74 68 65 20 77  e work for the w
2320: 72 69 74 65 66 69 6c 65 28 29 20 55 44 46 2e 20  ritefile() UDF. 
2330: 52 65 66 65 72 20 74 6f 20 0a 2a 2a 20 68 65 61  Refer to .** hea
2340: 64 65 72 20 63 6f 6d 6d 65 6e 74 73 20 61 74 20  der comments at 
2350: 74 68 65 20 74 6f 70 20 6f 66 20 74 68 69 73 20  the top of this 
2360: 66 69 6c 65 20 66 6f 72 20 64 65 74 61 69 6c 73  file for details
2370: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2380: 77 72 69 74 65 46 69 6c 65 28 0a 20 20 73 71 6c  writeFile(.  sql
2390: 69 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 70 43  ite3_context *pC
23a0: 74 78 2c 20 20 20 20 20 20 20 20 20 20 2f 2a 20  tx,          /* 
23b0: 43 6f 6e 74 65 78 74 20 74 6f 20 72 65 74 75 72  Context to retur
23c0: 6e 20 62 79 74 65 73 20 77 72 69 74 74 65 6e 20  n bytes written 
23d0: 69 6e 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  in */.  const ch
23e0: 61 72 20 2a 7a 46 69 6c 65 2c 20 20 20 20 20 20  ar *zFile,      
23f0: 20 20 20 20 20 20 20 20 2f 2a 20 46 69 6c 65 20          /* File 
2400: 74 6f 20 77 72 69 74 65 20 2a 2f 0a 20 20 73 71  to write */.  sq
2410: 6c 69 74 65 33 5f 76 61 6c 75 65 20 2a 70 44 61  lite3_value *pDa
2420: 74 61 2c 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ta,           /*
2430: 20 44 61 74 61 20 74 6f 20 77 72 69 74 65 20 2a   Data to write *
2440: 2f 0a 20 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 2c  /.  mode_t mode,
2450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
2460: 20 20 20 20 2f 2a 20 4d 4f 44 45 20 70 61 72 61      /* MODE para
2470: 6d 65 74 65 72 20 70 61 73 73 65 64 20 74 6f 20  meter passed to 
2480: 77 72 69 74 65 66 69 6c 65 28 29 20 2a 2f 0a 20  writefile() */. 
2490: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6d   sqlite3_int64 m
24a0: 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 20 20  time            
24b0: 20 2f 2a 20 4d 54 49 4d 45 20 70 61 72 61 6d 65   /* MTIME parame
24c0: 74 65 72 20 28 6f 72 20 2d 31 20 74 6f 20 6e 6f  ter (or -1 to no
24d0: 74 20 73 65 74 20 74 69 6d 65 29 20 2a 2f 0a 29  t set time) */.)
24e0: 7b 0a 23 69 66 20 21 64 65 66 69 6e 65 64 28 5f  {.#if !defined(_
24f0: 57 49 4e 33 32 29 20 26 26 20 21 64 65 66 69 6e  WIN32) && !defin
2500: 65 64 28 57 49 4e 33 32 29 0a 20 20 69 66 28 20  ed(WIN32).  if( 
2510: 53 5f 49 53 4c 4e 4b 28 6d 6f 64 65 29 20 29 7b  S_ISLNK(mode) ){
2520: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
2530: 2a 7a 54 6f 20 3d 20 28 63 6f 6e 73 74 20 63 68  *zTo = (const ch
2540: 61 72 2a 29 73 71 6c 69 74 65 33 5f 76 61 6c 75  ar*)sqlite3_valu
2550: 65 5f 74 65 78 74 28 70 44 61 74 61 29 3b 0a 20  e_text(pData);. 
2560: 20 20 20 69 66 28 20 73 79 6d 6c 69 6e 6b 28 7a     if( symlink(z
2570: 54 6f 2c 20 7a 46 69 6c 65 29 3c 30 20 29 20 72  To, zFile)<0 ) r
2580: 65 74 75 72 6e 20 31 3b 0a 20 20 7d 65 6c 73 65  eturn 1;.  }else
2590: 0a 23 65 6e 64 69 66 0a 20 20 7b 0a 20 20 20 20  .#endif.  {.    
25a0: 69 66 28 20 53 5f 49 53 44 49 52 28 6d 6f 64 65  if( S_ISDIR(mode
25b0: 29 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 6d  ) ){.      if( m
25c0: 6b 64 69 72 28 7a 46 69 6c 65 2c 20 6d 6f 64 65  kdir(zFile, mode
25d0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 2f 2a 20  ) ){.        /* 
25e0: 54 68 65 20 6d 6b 64 69 72 28 29 20 63 61 6c 6c  The mkdir() call
25f0: 20 74 6f 20 63 72 65 61 74 65 20 74 68 65 20 64   to create the d
2600: 69 72 65 63 74 6f 72 79 20 66 61 69 6c 65 64 2e  irectory failed.
2610: 20 54 68 69 73 20 6d 69 67 68 74 20 6e 6f 74 0a   This might not.
2620: 20 20 20 20 20 20 20 20 2a 2a 20 62 65 20 61 6e          ** be an
2630: 20 65 72 72 6f 72 20 74 68 6f 75 67 68 20 2d 20   error though - 
2640: 69 66 20 74 68 65 72 65 20 69 73 20 61 6c 72 65  if there is alre
2650: 61 64 79 20 61 20 64 69 72 65 63 74 6f 72 79 20  ady a directory 
2660: 61 74 20 74 68 65 20 73 61 6d 65 0a 20 20 20 20  at the same.    
2670: 20 20 20 20 2a 2a 20 70 61 74 68 20 61 6e 64 20      ** path and 
2680: 65 69 74 68 65 72 20 74 68 65 20 70 65 72 6d 69  either the permi
2690: 73 73 69 6f 6e 73 20 61 6c 72 65 61 64 79 20 6d  ssions already m
26a0: 61 74 63 68 20 6f 72 20 63 61 6e 20 62 65 20 63  atch or can be c
26b0: 68 61 6e 67 65 64 0a 20 20 20 20 20 20 20 20 2a  hanged.        *
26c0: 2a 20 74 6f 20 64 6f 20 73 6f 20 75 73 69 6e 67  * to do so using
26d0: 20 63 68 6d 6f 64 28 29 2c 20 69 74 20 69 73 20   chmod(), it is 
26e0: 6e 6f 74 20 61 6e 20 65 72 72 6f 72 2e 20 20 2a  not an error.  *
26f0: 2f 0a 20 20 20 20 20 20 20 20 73 74 72 75 63 74  /.        struct
2700: 20 73 74 61 74 20 73 53 74 61 74 3b 0a 20 20 20   stat sStat;.   
2710: 20 20 20 20 20 69 66 28 20 65 72 72 6e 6f 21 3d       if( errno!=
2720: 45 45 58 49 53 54 0a 20 20 20 20 20 20 20 20 20  EEXIST.         
2730: 7c 7c 20 30 21 3d 66 69 6c 65 53 74 61 74 28 7a  || 0!=fileStat(z
2740: 46 69 6c 65 2c 20 26 73 53 74 61 74 29 0a 20 20  File, &sStat).  
2750: 20 20 20 20 20 20 20 7c 7c 20 21 53 5f 49 53 44         || !S_ISD
2760: 49 52 28 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65  IR(sStat.st_mode
2770: 29 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 28 28  ).         || ((
2780: 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65 26 30 37  sStat.st_mode&07
2790: 37 37 29 21 3d 28 6d 6f 64 65 26 30 37 37 37 29  77)!=(mode&0777)
27a0: 20 26 26 20 30 21 3d 63 68 6d 6f 64 28 7a 46 69   && 0!=chmod(zFi
27b0: 6c 65 2c 20 6d 6f 64 65 26 30 37 37 37 29 29 0a  le, mode&0777)).
27c0: 20 20 20 20 20 20 20 20 29 7b 0a 20 20 20 20 20          ){.     
27d0: 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20       return 1;. 
27e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
27f0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
2800: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
2810: 6e 57 72 69 74 65 20 3d 20 30 3b 0a 20 20 20 20  nWrite = 0;.    
2820: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 3b    const char *z;
2830: 0a 20 20 20 20 20 20 69 6e 74 20 72 63 20 3d 20  .      int rc = 
2840: 30 3b 0a 20 20 20 20 20 20 46 49 4c 45 20 2a 6f  0;.      FILE *o
2850: 75 74 20 3d 20 66 6f 70 65 6e 28 7a 46 69 6c 65  ut = fopen(zFile
2860: 2c 20 22 77 62 22 29 3b 0a 20 20 20 20 20 20 69  , "wb");.      i
2870: 66 28 20 6f 75 74 3d 3d 30 20 29 20 72 65 74 75  f( out==0 ) retu
2880: 72 6e 20 31 3b 0a 20 20 20 20 20 20 7a 20 3d 20  rn 1;.      z = 
2890: 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71 6c  (const char*)sql
28a0: 69 74 65 33 5f 76 61 6c 75 65 5f 62 6c 6f 62 28  ite3_value_blob(
28b0: 70 44 61 74 61 29 3b 0a 20 20 20 20 20 20 69 66  pData);.      if
28c0: 28 20 7a 20 29 7b 0a 20 20 20 20 20 20 20 20 73  ( z ){.        s
28d0: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6e 20 3d  qlite3_int64 n =
28e0: 20 66 77 72 69 74 65 28 7a 2c 20 31 2c 20 73 71   fwrite(z, 1, sq
28f0: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62 79 74 65  lite3_value_byte
2900: 73 28 70 44 61 74 61 29 2c 20 6f 75 74 29 3b 0a  s(pData), out);.
2910: 20 20 20 20 20 20 20 20 6e 57 72 69 74 65 20 3d          nWrite =
2920: 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 62   sqlite3_value_b
2930: 79 74 65 73 28 70 44 61 74 61 29 3b 0a 20 20 20  ytes(pData);.   
2940: 20 20 20 20 20 69 66 28 20 6e 57 72 69 74 65 21       if( nWrite!
2950: 3d 6e 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =n ){.          
2960: 72 63 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20  rc = 1;.        
2970: 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  }.      }.      
2980: 66 63 6c 6f 73 65 28 6f 75 74 29 3b 0a 20 20 20  fclose(out);.   
2990: 20 20 20 69 66 28 20 72 63 3d 3d 30 20 26 26 20     if( rc==0 && 
29a0: 6d 6f 64 65 20 26 26 20 63 68 6d 6f 64 28 7a 46  mode && chmod(zF
29b0: 69 6c 65 2c 20 6d 6f 64 65 20 26 20 30 37 37 37  ile, mode & 0777
29c0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 72 63 20  ) ){.        rc 
29d0: 3d 20 31 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  = 1;.      }.   
29e0: 20 20 20 69 66 28 20 72 63 20 29 20 72 65 74 75     if( rc ) retu
29f0: 72 6e 20 32 3b 0a 20 20 20 20 20 20 73 71 6c 69  rn 2;.      sqli
2a00: 74 65 33 5f 72 65 73 75 6c 74 5f 69 6e 74 36 34  te3_result_int64
2a10: 28 70 43 74 78 2c 20 6e 57 72 69 74 65 29 3b 0a  (pCtx, nWrite);.
2a20: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 69 66 28      }.  }..  if(
2a30: 20 6d 74 69 6d 65 3e 3d 30 20 29 7b 0a 23 69 66   mtime>=0 ){.#if
2a40: 20 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29   defined(_WIN32)
2a50: 0a 20 20 20 20 2f 2a 20 57 69 6e 64 6f 77 73 20  .    /* Windows 
2a60: 2a 2f 0a 20 20 20 20 46 49 4c 45 54 49 4d 45 20  */.    FILETIME 
2a70: 6c 61 73 74 41 63 63 65 73 73 3b 0a 20 20 20 20  lastAccess;.    
2a80: 46 49 4c 45 54 49 4d 45 20 6c 61 73 74 57 72 69  FILETIME lastWri
2a90: 74 65 3b 0a 20 20 20 20 53 59 53 54 45 4d 54 49  te;.    SYSTEMTI
2aa0: 4d 45 20 63 75 72 72 65 6e 74 54 69 6d 65 3b 0a  ME currentTime;.
2ab0: 20 20 20 20 4c 4f 4e 47 4c 4f 4e 47 20 69 6e 74      LONGLONG int
2ac0: 65 72 76 61 6c 73 3b 0a 20 20 20 20 48 41 4e 44  ervals;.    HAND
2ad0: 4c 45 20 68 46 69 6c 65 3b 0a 20 20 20 20 4c 50  LE hFile;.    LP
2ae0: 57 53 54 52 20 7a 55 6e 69 63 6f 64 65 4e 61 6d  WSTR zUnicodeNam
2af0: 65 3b 0a 20 20 20 20 65 78 74 65 72 6e 20 4c 50  e;.    extern LP
2b00: 57 53 54 52 20 73 71 6c 69 74 65 33 5f 77 69 6e  WSTR sqlite3_win
2b10: 33 32 5f 75 74 66 38 5f 74 6f 5f 75 6e 69 63 6f  32_utf8_to_unico
2b20: 64 65 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 3b  de(const char*);
2b30: 0a 0a 20 20 20 20 47 65 74 53 79 73 74 65 6d 54  ..    GetSystemT
2b40: 69 6d 65 28 26 63 75 72 72 65 6e 74 54 69 6d 65  ime(&currentTime
2b50: 29 3b 0a 20 20 20 20 53 79 73 74 65 6d 54 69 6d  );.    SystemTim
2b60: 65 54 6f 46 69 6c 65 54 69 6d 65 28 26 63 75 72  eToFileTime(&cur
2b70: 72 65 6e 74 54 69 6d 65 2c 20 26 6c 61 73 74 41  rentTime, &lastA
2b80: 63 63 65 73 73 29 3b 0a 20 20 20 20 69 6e 74 65  ccess);.    inte
2b90: 72 76 61 6c 73 20 3d 20 49 6e 74 33 32 78 33 32  rvals = Int32x32
2ba0: 54 6f 36 34 28 6d 74 69 6d 65 2c 20 31 30 30 30  To64(mtime, 1000
2bb0: 30 30 30 30 29 20 2b 20 31 31 36 34 34 34 37 33  0000) + 11644473
2bc0: 36 30 30 30 30 30 30 30 30 30 3b 0a 20 20 20 20  6000000000;.    
2bd0: 6c 61 73 74 57 72 69 74 65 2e 64 77 4c 6f 77 44  lastWrite.dwLowD
2be0: 61 74 65 54 69 6d 65 20 3d 20 28 44 57 4f 52 44  ateTime = (DWORD
2bf0: 29 69 6e 74 65 72 76 61 6c 73 3b 0a 20 20 20 20  )intervals;.    
2c00: 6c 61 73 74 57 72 69 74 65 2e 64 77 48 69 67 68  lastWrite.dwHigh
2c10: 44 61 74 65 54 69 6d 65 20 3d 20 69 6e 74 65 72  DateTime = inter
2c20: 76 61 6c 73 20 3e 3e 20 33 32 3b 0a 20 20 20 20  vals >> 32;.    
2c30: 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 20 3d 20 73  zUnicodeName = s
2c40: 71 6c 69 74 65 33 5f 77 69 6e 33 32 5f 75 74 66  qlite3_win32_utf
2c50: 38 5f 74 6f 5f 75 6e 69 63 6f 64 65 28 7a 46 69  8_to_unicode(zFi
2c60: 6c 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 55 6e  le);.    if( zUn
2c70: 69 63 6f 64 65 4e 61 6d 65 3d 3d 30 20 29 7b 0a  icodeName==0 ){.
2c80: 20 20 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a        return 1;.
2c90: 20 20 20 20 7d 0a 20 20 20 20 68 46 69 6c 65 20      }.    hFile 
2ca0: 3d 20 43 72 65 61 74 65 46 69 6c 65 57 28 0a 20  = CreateFileW(. 
2cb0: 20 20 20 20 20 7a 55 6e 69 63 6f 64 65 4e 61 6d       zUnicodeNam
2cc0: 65 2c 20 46 49 4c 45 5f 57 52 49 54 45 5f 41 54  e, FILE_WRITE_AT
2cd0: 54 52 49 42 55 54 45 53 2c 20 30 2c 20 4e 55 4c  TRIBUTES, 0, NUL
2ce0: 4c 2c 20 4f 50 45 4e 5f 45 58 49 53 54 49 4e 47  L, OPEN_EXISTING
2cf0: 2c 0a 20 20 20 20 20 20 46 49 4c 45 5f 46 4c 41  ,.      FILE_FLA
2d00: 47 5f 42 41 43 4b 55 50 5f 53 45 4d 41 4e 54 49  G_BACKUP_SEMANTI
2d10: 43 53 2c 20 4e 55 4c 4c 0a 20 20 20 20 29 3b 0a  CS, NULL.    );.
2d20: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
2d30: 28 7a 55 6e 69 63 6f 64 65 4e 61 6d 65 29 3b 0a  (zUnicodeName);.
2d40: 20 20 20 20 69 66 28 20 68 46 69 6c 65 21 3d 49      if( hFile!=I
2d50: 4e 56 41 4c 49 44 5f 48 41 4e 44 4c 45 5f 56 41  NVALID_HANDLE_VA
2d60: 4c 55 45 20 29 7b 0a 20 20 20 20 20 20 42 4f 4f  LUE ){.      BOO
2d70: 4c 20 62 52 65 73 75 6c 74 20 3d 20 53 65 74 46  L bResult = SetF
2d80: 69 6c 65 54 69 6d 65 28 68 46 69 6c 65 2c 20 4e  ileTime(hFile, N
2d90: 55 4c 4c 2c 20 26 6c 61 73 74 41 63 63 65 73 73  ULL, &lastAccess
2da0: 2c 20 26 6c 61 73 74 57 72 69 74 65 29 3b 0a 20  , &lastWrite);. 
2db0: 20 20 20 20 20 43 6c 6f 73 65 48 61 6e 64 6c 65       CloseHandle
2dc0: 28 68 46 69 6c 65 29 3b 0a 20 20 20 20 20 20 72  (hFile);.      r
2dd0: 65 74 75 72 6e 20 21 62 52 65 73 75 6c 74 3b 0a  eturn !bResult;.
2de0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
2df0: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d   return 1;.    }
2e00: 0a 23 65 6c 69 66 20 64 65 66 69 6e 65 64 28 41  .#elif defined(A
2e10: 54 5f 46 44 43 57 44 29 20 26 26 20 30 20 2f 2a  T_FDCWD) && 0 /*
2e20: 20 75 74 69 6d 65 6e 73 61 74 28 29 20 69 73 20   utimensat() is 
2e30: 6e 6f 74 20 75 6e 69 76 65 72 73 61 6c 6c 79 20  not universally 
2e40: 61 76 61 69 6c 61 62 6c 65 20 2a 2f 0a 20 20 20  available */.   
2e50: 20 2f 2a 20 52 65 63 65 6e 74 20 75 6e 69 78 20   /* Recent unix 
2e60: 2a 2f 0a 20 20 20 20 73 74 72 75 63 74 20 74 69  */.    struct ti
2e70: 6d 65 73 70 65 63 20 74 69 6d 65 73 5b 32 5d 3b  mespec times[2];
2e80: 0a 20 20 20 20 74 69 6d 65 73 5b 30 5d 2e 74 76  .    times[0].tv
2e90: 5f 6e 73 65 63 20 3d 20 74 69 6d 65 73 5b 31 5d  _nsec = times[1]
2ea0: 2e 74 76 5f 6e 73 65 63 20 3d 20 30 3b 0a 20 20  .tv_nsec = 0;.  
2eb0: 20 20 74 69 6d 65 73 5b 30 5d 2e 74 76 5f 73 65    times[0].tv_se
2ec0: 63 20 3d 20 74 69 6d 65 28 30 29 3b 0a 20 20 20  c = time(0);.   
2ed0: 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 73 65 63   times[1].tv_sec
2ee0: 20 3d 20 6d 74 69 6d 65 3b 0a 20 20 20 20 69 66   = mtime;.    if
2ef0: 28 20 75 74 69 6d 65 6e 73 61 74 28 41 54 5f 46  ( utimensat(AT_F
2f00: 44 43 57 44 2c 20 7a 46 69 6c 65 2c 20 74 69 6d  DCWD, zFile, tim
2f10: 65 73 2c 20 41 54 5f 53 59 4d 4c 49 4e 4b 5f 4e  es, AT_SYMLINK_N
2f20: 4f 46 4f 4c 4c 4f 57 29 20 29 7b 0a 20 20 20 20  OFOLLOW) ){.    
2f30: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20    return 1;.    
2f40: 7d 0a 23 65 6c 73 65 0a 20 20 20 20 2f 2a 20 4c  }.#else.    /* L
2f50: 65 67 61 63 79 20 75 6e 69 78 20 2a 2f 0a 20 20  egacy unix */.  
2f60: 20 20 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c    struct timeval
2f70: 20 74 69 6d 65 73 5b 32 5d 3b 0a 20 20 20 20 74   times[2];.    t
2f80: 69 6d 65 73 5b 30 5d 2e 74 76 5f 75 73 65 63 20  imes[0].tv_usec 
2f90: 3d 20 74 69 6d 65 73 5b 31 5d 2e 74 76 5f 75 73  = times[1].tv_us
2fa0: 65 63 20 3d 20 30 3b 0a 20 20 20 20 74 69 6d 65  ec = 0;.    time
2fb0: 73 5b 30 5d 2e 74 76 5f 73 65 63 20 3d 20 74 69  s[0].tv_sec = ti
2fc0: 6d 65 28 30 29 3b 0a 20 20 20 20 74 69 6d 65 73  me(0);.    times
2fd0: 5b 31 5d 2e 74 76 5f 73 65 63 20 3d 20 6d 74 69  [1].tv_sec = mti
2fe0: 6d 65 3b 0a 20 20 20 20 69 66 28 20 75 74 69 6d  me;.    if( utim
2ff0: 65 73 28 7a 46 69 6c 65 2c 20 74 69 6d 65 73 29  es(zFile, times)
3000: 20 29 7b 0a 20 20 20 20 20 20 72 65 74 75 72 6e   ){.      return
3010: 20 31 3b 0a 20 20 20 20 7d 0a 23 65 6e 64 69 66   1;.    }.#endif
3020: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 30  .  }..  return 0
3030: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65  ;.}../*.** Imple
3040: 6d 65 6e 74 61 74 69 6f 6e 20 6f 66 20 74 68 65  mentation of the
3050: 20 22 77 72 69 74 65 66 69 6c 65 28 57 2c 58 5b   "writefile(W,X[
3060: 2c 59 5b 2c 5a 5d 5d 5d 29 22 20 53 51 4c 20 66  ,Y[,Z]]])" SQL f
3070: 75 6e 63 74 69 6f 6e 2e 20 20 0a 2a 2a 20 52 65  unction.  .** Re
3080: 66 65 72 20 74 6f 20 68 65 61 64 65 72 20 63 6f  fer to header co
3090: 6d 6d 65 6e 74 73 20 61 74 20 74 68 65 20 74 6f  mments at the to
30a0: 70 20 6f 66 20 74 68 69 73 20 66 69 6c 65 20 66  p of this file f
30b0: 6f 72 20 64 65 74 61 69 6c 73 2e 0a 2a 2f 0a 73  or details..*/.s
30c0: 74 61 74 69 63 20 76 6f 69 64 20 77 72 69 74 65  tatic void write
30d0: 66 69 6c 65 46 75 6e 63 28 0a 20 20 73 71 6c 69  fileFunc(.  sqli
30e0: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e  te3_context *con
30f0: 74 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63  text,.  int argc
3100: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75  ,.  sqlite3_valu
3110: 65 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 63 6f  e **argv.){.  co
3120: 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 3b  nst char *zFile;
3130: 0a 20 20 6d 6f 64 65 5f 74 20 6d 6f 64 65 20 3d  .  mode_t mode =
3140: 20 30 3b 0a 20 20 69 6e 74 20 72 65 73 3b 0a 20   0;.  int res;. 
3150: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 6d   sqlite3_int64 m
3160: 74 69 6d 65 20 3d 20 2d 31 3b 0a 0a 20 20 69 66  time = -1;..  if
3170: 28 20 61 72 67 63 3c 32 20 7c 7c 20 61 72 67 63  ( argc<2 || argc
3180: 3e 34 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  >4 ){.    sqlite
3190: 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 28 63  3_result_error(c
31a0: 6f 6e 74 65 78 74 2c 20 0a 20 20 20 20 20 20 20  ontext, .       
31b0: 20 22 77 72 6f 6e 67 20 6e 75 6d 62 65 72 20 6f   "wrong number o
31c0: 66 20 61 72 67 75 6d 65 6e 74 73 20 74 6f 20 66  f arguments to f
31d0: 75 6e 63 74 69 6f 6e 20 77 72 69 74 65 66 69 6c  unction writefil
31e0: 65 28 29 22 2c 20 2d 31 0a 20 20 20 20 29 3b 0a  e()", -1.    );.
31f0: 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 7d 0a      return;.  }.
3200: 0a 20 20 7a 46 69 6c 65 20 3d 20 28 63 6f 6e 73  .  zFile = (cons
3210: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
3220: 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b  value_text(argv[
3230: 30 5d 29 3b 0a 20 20 69 66 28 20 7a 46 69 6c 65  0]);.  if( zFile
3240: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
3250: 69 66 28 20 61 72 67 63 3e 3d 33 20 29 7b 0a 20  if( argc>=3 ){. 
3260: 20 20 20 6d 6f 64 65 20 3d 20 28 6d 6f 64 65 5f     mode = (mode_
3270: 74 29 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  t)sqlite3_value_
3280: 69 6e 74 28 61 72 67 76 5b 32 5d 29 3b 0a 20 20  int(argv[2]);.  
3290: 7d 0a 20 20 69 66 28 20 61 72 67 63 3d 3d 34 20  }.  if( argc==4 
32a0: 29 7b 0a 20 20 20 20 6d 74 69 6d 65 20 3d 20 73  ){.    mtime = s
32b0: 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f 69 6e 74  qlite3_value_int
32c0: 36 34 28 61 72 67 76 5b 33 5d 29 3b 0a 20 20 7d  64(argv[3]);.  }
32d0: 0a 0a 20 20 72 65 73 20 3d 20 77 72 69 74 65 46  ..  res = writeF
32e0: 69 6c 65 28 63 6f 6e 74 65 78 74 2c 20 7a 46 69  ile(context, zFi
32f0: 6c 65 2c 20 61 72 67 76 5b 31 5d 2c 20 6d 6f 64  le, argv[1], mod
3300: 65 2c 20 6d 74 69 6d 65 29 3b 0a 20 20 69 66 28  e, mtime);.  if(
3310: 20 72 65 73 3d 3d 31 20 26 26 20 65 72 72 6e 6f   res==1 && errno
3320: 3d 3d 45 4e 4f 45 4e 54 20 29 7b 0a 20 20 20 20  ==ENOENT ){.    
3330: 69 66 28 20 6d 61 6b 65 44 69 72 65 63 74 6f 72  if( makeDirector
3340: 79 28 7a 46 69 6c 65 2c 20 6d 6f 64 65 29 3d 3d  y(zFile, mode)==
3350: 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20  SQLITE_OK ){.   
3360: 20 20 20 72 65 73 20 3d 20 77 72 69 74 65 46 69     res = writeFi
3370: 6c 65 28 63 6f 6e 74 65 78 74 2c 20 7a 46 69 6c  le(context, zFil
3380: 65 2c 20 61 72 67 76 5b 31 5d 2c 20 6d 6f 64 65  e, argv[1], mode
3390: 2c 20 6d 74 69 6d 65 29 3b 0a 20 20 20 20 7d 0a  , mtime);.    }.
33a0: 20 20 7d 0a 0a 20 20 69 66 28 20 61 72 67 63 3e    }..  if( argc>
33b0: 32 20 26 26 20 72 65 73 21 3d 30 20 29 7b 0a 20  2 && res!=0 ){. 
33c0: 20 20 20 69 66 28 20 53 5f 49 53 4c 4e 4b 28 6d     if( S_ISLNK(m
33d0: 6f 64 65 29 20 29 7b 0a 20 20 20 20 20 20 63 74  ode) ){.      ct
33e0: 78 45 72 72 6f 72 4d 73 67 28 63 6f 6e 74 65 78  xErrorMsg(contex
33f0: 74 2c 20 22 66 61 69 6c 65 64 20 74 6f 20 63 72  t, "failed to cr
3400: 65 61 74 65 20 73 79 6d 6c 69 6e 6b 3a 20 25 73  eate symlink: %s
3410: 22 2c 20 7a 46 69 6c 65 29 3b 0a 20 20 20 20 7d  ", zFile);.    }
3420: 65 6c 73 65 20 69 66 28 20 53 5f 49 53 44 49 52  else if( S_ISDIR
3430: 28 6d 6f 64 65 29 20 29 7b 0a 20 20 20 20 20 20  (mode) ){.      
3440: 63 74 78 45 72 72 6f 72 4d 73 67 28 63 6f 6e 74  ctxErrorMsg(cont
3450: 65 78 74 2c 20 22 66 61 69 6c 65 64 20 74 6f 20  ext, "failed to 
3460: 63 72 65 61 74 65 20 64 69 72 65 63 74 6f 72 79  create directory
3470: 3a 20 25 73 22 2c 20 7a 46 69 6c 65 29 3b 0a 20  : %s", zFile);. 
3480: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3490: 63 74 78 45 72 72 6f 72 4d 73 67 28 63 6f 6e 74  ctxErrorMsg(cont
34a0: 65 78 74 2c 20 22 66 61 69 6c 65 64 20 74 6f 20  ext, "failed to 
34b0: 77 72 69 74 65 20 66 69 6c 65 3a 20 25 73 22 2c  write file: %s",
34c0: 20 7a 46 69 6c 65 29 3b 0a 20 20 20 20 7d 0a 20   zFile);.    }. 
34d0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 20   }.}../*.** SQL 
34e0: 66 75 6e 63 74 69 6f 6e 3a 20 20 20 6c 73 6d 6f  function:   lsmo
34f0: 64 65 28 4d 4f 44 45 29 0a 2a 2a 0a 2a 2a 20 47  de(MODE).**.** G
3500: 69 76 65 6e 20 61 20 6e 75 6d 62 65 72 69 63 20  iven a numberic 
3510: 73 74 5f 6d 6f 64 65 20 66 72 6f 6d 20 73 74 61  st_mode from sta
3520: 74 28 29 2c 20 63 6f 6e 76 65 72 74 20 69 74 20  t(), convert it 
3530: 69 6e 74 6f 20 61 20 68 75 6d 61 6e 2d 72 65 61  into a human-rea
3540: 64 61 62 6c 65 0a 2a 2a 20 74 65 78 74 20 73 74  dable.** text st
3550: 72 69 6e 67 20 69 6e 20 74 68 65 20 73 74 79 6c  ring in the styl
3560: 65 20 6f 66 20 22 6c 73 20 2d 6c 22 2e 0a 2a 2f  e of "ls -l"..*/
3570: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6c 73 4d  .static void lsM
3580: 6f 64 65 46 75 6e 63 28 0a 20 20 73 71 6c 69 74  odeFunc(.  sqlit
3590: 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 6f 6e 74  e3_context *cont
35a0: 65 78 74 2c 0a 20 20 69 6e 74 20 61 72 67 63 2c  ext,.  int argc,
35b0: 0a 20 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65  .  sqlite3_value
35c0: 20 2a 2a 61 72 67 76 0a 29 7b 0a 20 20 69 6e 74   **argv.){.  int
35d0: 20 69 3b 0a 20 20 69 6e 74 20 69 4d 6f 64 65 20   i;.  int iMode 
35e0: 3d 20 73 71 6c 69 74 65 33 5f 76 61 6c 75 65 5f  = sqlite3_value_
35f0: 69 6e 74 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20  int(argv[0]);.  
3600: 63 68 61 72 20 7a 5b 31 36 5d 3b 0a 20 20 28 76  char z[16];.  (v
3610: 6f 69 64 29 61 72 67 63 3b 0a 20 20 69 66 28 20  oid)argc;.  if( 
3620: 53 5f 49 53 4c 4e 4b 28 69 4d 6f 64 65 29 20 29  S_ISLNK(iMode) )
3630: 7b 0a 20 20 20 20 7a 5b 30 5d 20 3d 20 27 6c 27  {.    z[0] = 'l'
3640: 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 53 5f  ;.  }else if( S_
3650: 49 53 52 45 47 28 69 4d 6f 64 65 29 20 29 7b 0a  ISREG(iMode) ){.
3660: 20 20 20 20 7a 5b 30 5d 20 3d 20 27 2d 27 3b 0a      z[0] = '-';.
3670: 20 20 7d 65 6c 73 65 20 69 66 28 20 53 5f 49 53    }else if( S_IS
3680: 44 49 52 28 69 4d 6f 64 65 29 20 29 7b 0a 20 20  DIR(iMode) ){.  
3690: 20 20 7a 5b 30 5d 20 3d 20 27 64 27 3b 0a 20 20    z[0] = 'd';.  
36a0: 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 5b 30 5d 20  }else{.    z[0] 
36b0: 3d 20 27 3f 27 3b 0a 20 20 7d 0a 20 20 66 6f 72  = '?';.  }.  for
36c0: 28 69 3d 30 3b 20 69 3c 33 3b 20 69 2b 2b 29 7b  (i=0; i<3; i++){
36d0: 0a 20 20 20 20 69 6e 74 20 6d 20 3d 20 28 69 4d  .    int m = (iM
36e0: 6f 64 65 20 3e 3e 20 28 28 32 2d 69 29 2a 33 29  ode >> ((2-i)*3)
36f0: 29 3b 0a 20 20 20 20 63 68 61 72 20 2a 61 20 3d  );.    char *a =
3700: 20 26 7a 5b 31 20 2b 20 69 2a 33 5d 3b 0a 20 20   &z[1 + i*3];.  
3710: 20 20 61 5b 30 5d 20 3d 20 28 6d 20 26 20 30 78    a[0] = (m & 0x
3720: 34 29 20 3f 20 27 72 27 20 3a 20 27 2d 27 3b 0a  4) ? 'r' : '-';.
3730: 20 20 20 20 61 5b 31 5d 20 3d 20 28 6d 20 26 20      a[1] = (m & 
3740: 30 78 32 29 20 3f 20 27 77 27 20 3a 20 27 2d 27  0x2) ? 'w' : '-'
3750: 3b 0a 20 20 20 20 61 5b 32 5d 20 3d 20 28 6d 20  ;.    a[2] = (m 
3760: 26 20 30 78 31 29 20 3f 20 27 78 27 20 3a 20 27  & 0x1) ? 'x' : '
3770: 2d 27 3b 0a 20 20 7d 0a 20 20 7a 5b 31 30 5d 20  -';.  }.  z[10] 
3780: 3d 20 27 5c 30 27 3b 0a 20 20 73 71 6c 69 74 65  = '\0';.  sqlite
3790: 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28 63 6f  3_result_text(co
37a0: 6e 74 65 78 74 2c 20 7a 2c 20 2d 31 2c 20 53 51  ntext, z, -1, SQ
37b0: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
37c0: 0a 7d 0a 0a 23 69 66 6e 64 65 66 20 53 51 4c 49  .}..#ifndef SQLI
37d0: 54 45 5f 4f 4d 49 54 5f 56 49 52 54 55 41 4c 54  TE_OMIT_VIRTUALT
37e0: 41 42 4c 45 0a 0a 2f 2a 20 0a 2a 2a 20 43 75 72  ABLE../* .** Cur
37f0: 73 6f 72 20 74 79 70 65 20 66 6f 72 20 72 65 63  sor type for rec
3800: 75 72 73 69 76 65 6c 79 20 69 74 65 72 61 74 69  ursively iterati
3810: 6e 67 20 74 68 72 6f 75 67 68 20 61 20 64 69 72  ng through a dir
3820: 65 63 74 6f 72 79 20 73 74 72 75 63 74 75 72 65  ectory structure
3830: 2e 0a 2a 2f 0a 74 79 70 65 64 65 66 20 73 74 72  ..*/.typedef str
3840: 75 63 74 20 66 73 64 69 72 5f 63 75 72 73 6f 72  uct fsdir_cursor
3850: 20 66 73 64 69 72 5f 63 75 72 73 6f 72 3b 0a 74   fsdir_cursor;.t
3860: 79 70 65 64 65 66 20 73 74 72 75 63 74 20 46 73  ypedef struct Fs
3870: 64 69 72 4c 65 76 65 6c 20 46 73 64 69 72 4c 65  dirLevel FsdirLe
3880: 76 65 6c 3b 0a 0a 73 74 72 75 63 74 20 46 73 64  vel;..struct Fsd
3890: 69 72 4c 65 76 65 6c 20 7b 0a 20 20 44 49 52 20  irLevel {.  DIR 
38a0: 2a 70 44 69 72 3b 20 20 20 20 20 20 20 20 20 20  *pDir;          
38b0: 20 20 20 20 20 20 20 2f 2a 20 46 72 6f 6d 20 6f         /* From o
38c0: 70 65 6e 64 69 72 28 29 20 2a 2f 0a 20 20 63 68  pendir() */.  ch
38d0: 61 72 20 2a 7a 44 69 72 3b 20 20 20 20 20 20 20  ar *zDir;       
38e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 61 6d 65           /* Name
38f0: 20 6f 66 20 64 69 72 65 63 74 6f 72 79 20 28 6e   of directory (n
3900: 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 29 20 2a  ul-terminated) *
3910: 2f 0a 7d 3b 0a 0a 73 74 72 75 63 74 20 66 73 64  /.};..struct fsd
3920: 69 72 5f 63 75 72 73 6f 72 20 7b 0a 20 20 73 71  ir_cursor {.  sq
3930: 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f  lite3_vtab_curso
3940: 72 20 62 61 73 65 3b 20 20 2f 2a 20 42 61 73 65  r base;  /* Base
3950: 20 63 6c 61 73 73 20 2d 20 6d 75 73 74 20 62 65   class - must be
3960: 20 66 69 72 73 74 20 2a 2f 0a 0a 20 20 69 6e 74   first */..  int
3970: 20 6e 4c 76 6c 3b 20 20 20 20 20 20 20 20 20 20   nLvl;          
3980: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
3990: 72 20 6f 66 20 65 6e 74 72 69 65 73 20 69 6e 20  r of entries in 
39a0: 61 4c 76 6c 5b 5d 20 61 72 72 61 79 20 2a 2f 0a  aLvl[] array */.
39b0: 20 20 69 6e 74 20 69 4c 76 6c 3b 20 20 20 20 20    int iLvl;     
39c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
39d0: 49 6e 64 65 78 20 6f 66 20 63 75 72 72 65 6e 74  Index of current
39e0: 20 65 6e 74 72 79 20 2a 2f 0a 20 20 46 73 64 69   entry */.  Fsdi
39f0: 72 4c 65 76 65 6c 20 2a 61 4c 76 6c 3b 20 20 20  rLevel *aLvl;   
3a00: 20 20 20 20 20 20 20 2f 2a 20 48 69 65 72 61 72         /* Hierar
3a10: 63 68 79 20 6f 66 20 64 69 72 65 63 74 6f 72 69  chy of directori
3a20: 65 73 20 62 65 69 6e 67 20 74 72 61 76 65 72 73  es being travers
3a30: 65 64 20 2a 2f 0a 0a 20 20 63 6f 6e 73 74 20 63  ed */..  const c
3a40: 68 61 72 20 2a 7a 42 61 73 65 3b 0a 20 20 69 6e  har *zBase;.  in
3a50: 74 20 6e 42 61 73 65 3b 0a 0a 20 20 73 74 72 75  t nBase;..  stru
3a60: 63 74 20 73 74 61 74 20 73 53 74 61 74 3b 20 20  ct stat sStat;  
3a70: 20 20 20 20 20 20 20 2f 2a 20 43 75 72 72 65 6e         /* Curren
3a80: 74 20 6c 73 74 61 74 28 29 20 72 65 73 75 6c 74  t lstat() result
3a90: 73 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 50 61  s */.  char *zPa
3aa0: 74 68 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  th;             
3ab0: 20 20 2f 2a 20 50 61 74 68 20 74 6f 20 63 75 72    /* Path to cur
3ac0: 72 65 6e 74 20 65 6e 74 72 79 20 2a 2f 0a 20 20  rent entry */.  
3ad0: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 52  sqlite3_int64 iR
3ae0: 6f 77 69 64 3b 20 20 20 20 20 20 2f 2a 20 43 75  owid;      /* Cu
3af0: 72 72 65 6e 74 20 72 6f 77 69 64 20 2a 2f 0a 7d  rrent rowid */.}
3b00: 3b 0a 0a 74 79 70 65 64 65 66 20 73 74 72 75 63  ;..typedef struc
3b10: 74 20 66 73 64 69 72 5f 74 61 62 20 66 73 64 69  t fsdir_tab fsdi
3b20: 72 5f 74 61 62 3b 0a 73 74 72 75 63 74 20 66 73  r_tab;.struct fs
3b30: 64 69 72 5f 74 61 62 20 7b 0a 20 20 73 71 6c 69  dir_tab {.  sqli
3b40: 74 65 33 5f 76 74 61 62 20 62 61 73 65 3b 20 20  te3_vtab base;  
3b50: 20 20 20 20 20 20 20 2f 2a 20 42 61 73 65 20 63         /* Base c
3b60: 6c 61 73 73 20 2d 20 6d 75 73 74 20 62 65 20 66  lass - must be f
3b70: 69 72 73 74 20 2a 2f 0a 7d 3b 0a 0a 2f 2a 0a 2a  irst */.};../*.*
3b80: 2a 20 43 6f 6e 73 74 72 75 63 74 20 61 20 6e 65  * Construct a ne
3b90: 77 20 66 73 64 69 72 20 76 69 72 74 75 61 6c 20  w fsdir virtual 
3ba0: 74 61 62 6c 65 20 6f 62 6a 65 63 74 2e 0a 2a 2f  table object..*/
3bb0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64 69  .static int fsdi
3bc0: 72 43 6f 6e 6e 65 63 74 28 0a 20 20 73 71 6c 69  rConnect(.  sqli
3bd0: 74 65 33 20 2a 64 62 2c 0a 20 20 76 6f 69 64 20  te3 *db,.  void 
3be0: 2a 70 41 75 78 2c 0a 20 20 69 6e 74 20 61 72 67  *pAux,.  int arg
3bf0: 63 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 63  c, const char *c
3c00: 6f 6e 73 74 2a 61 72 67 76 2c 0a 20 20 73 71 6c  onst*argv,.  sql
3c10: 69 74 65 33 5f 76 74 61 62 20 2a 2a 70 70 56 74  ite3_vtab **ppVt
3c20: 61 62 2c 0a 20 20 63 68 61 72 20 2a 2a 70 7a 45  ab,.  char **pzE
3c30: 72 72 0a 29 7b 0a 20 20 66 73 64 69 72 5f 74 61  rr.){.  fsdir_ta
3c40: 62 20 2a 70 4e 65 77 20 3d 20 30 3b 0a 20 20 69  b *pNew = 0;.  i
3c50: 6e 74 20 72 63 3b 0a 20 20 28 76 6f 69 64 29 70  nt rc;.  (void)p
3c60: 41 75 78 3b 0a 20 20 28 76 6f 69 64 29 61 72 67  Aux;.  (void)arg
3c70: 63 3b 0a 20 20 28 76 6f 69 64 29 61 72 67 76 3b  c;.  (void)argv;
3c80: 0a 20 20 28 76 6f 69 64 29 70 7a 45 72 72 3b 0a  .  (void)pzErr;.
3c90: 20 20 72 63 20 3d 20 73 71 6c 69 74 65 33 5f 64    rc = sqlite3_d
3ca0: 65 63 6c 61 72 65 5f 76 74 61 62 28 64 62 2c 20  eclare_vtab(db, 
3cb0: 22 43 52 45 41 54 45 20 54 41 42 4c 45 20 78 22  "CREATE TABLE x"
3cc0: 20 46 53 44 49 52 5f 53 43 48 45 4d 41 29 3b 0a   FSDIR_SCHEMA);.
3cd0: 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45    if( rc==SQLITE
3ce0: 5f 4f 4b 20 29 7b 0a 20 20 20 20 70 4e 65 77 20  _OK ){.    pNew 
3cf0: 3d 20 28 66 73 64 69 72 5f 74 61 62 2a 29 73 71  = (fsdir_tab*)sq
3d00: 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 20 73 69  lite3_malloc( si
3d10: 7a 65 6f 66 28 2a 70 4e 65 77 29 20 29 3b 0a 20  zeof(*pNew) );. 
3d20: 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29     if( pNew==0 )
3d30: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e   return SQLITE_N
3d40: 4f 4d 45 4d 3b 0a 20 20 20 20 6d 65 6d 73 65 74  OMEM;.    memset
3d50: 28 70 4e 65 77 2c 20 30 2c 20 73 69 7a 65 6f 66  (pNew, 0, sizeof
3d60: 28 2a 70 4e 65 77 29 29 3b 0a 20 20 7d 0a 20 20  (*pNew));.  }.  
3d70: 2a 70 70 56 74 61 62 20 3d 20 28 73 71 6c 69 74  *ppVtab = (sqlit
3d80: 65 33 5f 76 74 61 62 2a 29 70 4e 65 77 3b 0a 20  e3_vtab*)pNew;. 
3d90: 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f   return rc;.}../
3da0: 2a 0a 2a 2a 20 54 68 69 73 20 6d 65 74 68 6f 64  *.** This method
3db0: 20 69 73 20 74 68 65 20 64 65 73 74 72 75 63 74   is the destruct
3dc0: 6f 72 20 66 6f 72 20 66 73 64 69 72 20 76 74 61  or for fsdir vta
3dd0: 62 20 6f 62 6a 65 63 74 73 2e 0a 2a 2f 0a 73 74  b objects..*/.st
3de0: 61 74 69 63 20 69 6e 74 20 66 73 64 69 72 44 69  atic int fsdirDi
3df0: 73 63 6f 6e 6e 65 63 74 28 73 71 6c 69 74 65 33  sconnect(sqlite3
3e00: 5f 76 74 61 62 20 2a 70 56 74 61 62 29 7b 0a 20  _vtab *pVtab){. 
3e10: 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 70 56   sqlite3_free(pV
3e20: 74 61 62 29 3b 0a 20 20 72 65 74 75 72 6e 20 53  tab);.  return S
3e30: 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a  QLITE_OK;.}../*.
3e40: 2a 2a 20 43 6f 6e 73 74 72 75 63 74 6f 72 20 66  ** Constructor f
3e50: 6f 72 20 61 20 6e 65 77 20 66 73 64 69 72 5f 63  or a new fsdir_c
3e60: 75 72 73 6f 72 20 6f 62 6a 65 63 74 2e 0a 2a 2f  ursor object..*/
3e70: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64 69  .static int fsdi
3e80: 72 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 74  rOpen(sqlite3_vt
3e90: 61 62 20 2a 70 2c 20 73 71 6c 69 74 65 33 5f 76  ab *p, sqlite3_v
3ea0: 74 61 62 5f 63 75 72 73 6f 72 20 2a 2a 70 70 43  tab_cursor **ppC
3eb0: 75 72 73 6f 72 29 7b 0a 20 20 66 73 64 69 72 5f  ursor){.  fsdir_
3ec0: 63 75 72 73 6f 72 20 2a 70 43 75 72 3b 0a 20 20  cursor *pCur;.  
3ed0: 28 76 6f 69 64 29 70 3b 0a 20 20 70 43 75 72 20  (void)p;.  pCur 
3ee0: 3d 20 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63  = sqlite3_malloc
3ef0: 28 20 73 69 7a 65 6f 66 28 2a 70 43 75 72 29 20  ( sizeof(*pCur) 
3f00: 29 3b 0a 20 20 69 66 28 20 70 43 75 72 3d 3d 30  );.  if( pCur==0
3f10: 20 29 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45   ) return SQLITE
3f20: 5f 4e 4f 4d 45 4d 3b 0a 20 20 6d 65 6d 73 65 74  _NOMEM;.  memset
3f30: 28 70 43 75 72 2c 20 30 2c 20 73 69 7a 65 6f 66  (pCur, 0, sizeof
3f40: 28 2a 70 43 75 72 29 29 3b 0a 20 20 70 43 75 72  (*pCur));.  pCur
3f50: 2d 3e 69 4c 76 6c 20 3d 20 2d 31 3b 0a 20 20 2a  ->iLvl = -1;.  *
3f60: 70 70 43 75 72 73 6f 72 20 3d 20 26 70 43 75 72  ppCursor = &pCur
3f70: 2d 3e 62 61 73 65 3b 0a 20 20 72 65 74 75 72 6e  ->base;.  return
3f80: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f   SQLITE_OK;.}../
3f90: 2a 0a 2a 2a 20 52 65 73 65 74 20 61 20 63 75 72  *.** Reset a cur
3fa0: 73 6f 72 20 62 61 63 6b 20 74 6f 20 74 68 65 20  sor back to the 
3fb0: 73 74 61 74 65 20 69 74 20 77 61 73 20 69 6e 20  state it was in 
3fc0: 77 68 65 6e 20 66 69 72 73 74 20 72 65 74 75 72  when first retur
3fd0: 6e 65 64 0a 2a 2a 20 62 79 20 66 73 64 69 72 4f  ned.** by fsdirO
3fe0: 70 65 6e 28 29 2e 0a 2a 2f 0a 73 74 61 74 69 63  pen()..*/.static
3ff0: 20 76 6f 69 64 20 66 73 64 69 72 52 65 73 65 74   void fsdirReset
4000: 43 75 72 73 6f 72 28 66 73 64 69 72 5f 63 75 72  Cursor(fsdir_cur
4010: 73 6f 72 20 2a 70 43 75 72 29 7b 0a 20 20 69 6e  sor *pCur){.  in
4020: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
4030: 69 3c 3d 70 43 75 72 2d 3e 69 4c 76 6c 3b 20 69  i<=pCur->iLvl; i
4040: 2b 2b 29 7b 0a 20 20 20 20 46 73 64 69 72 4c 65  ++){.    FsdirLe
4050: 76 65 6c 20 2a 70 4c 76 6c 20 3d 20 26 70 43 75  vel *pLvl = &pCu
4060: 72 2d 3e 61 4c 76 6c 5b 69 5d 3b 0a 20 20 20 20  r->aLvl[i];.    
4070: 69 66 28 20 70 4c 76 6c 2d 3e 70 44 69 72 20 29  if( pLvl->pDir )
4080: 20 63 6c 6f 73 65 64 69 72 28 70 4c 76 6c 2d 3e   closedir(pLvl->
4090: 70 44 69 72 29 3b 0a 20 20 20 20 73 71 6c 69 74  pDir);.    sqlit
40a0: 65 33 5f 66 72 65 65 28 70 4c 76 6c 2d 3e 7a 44  e3_free(pLvl->zD
40b0: 69 72 29 3b 0a 20 20 7d 0a 20 20 73 71 6c 69 74  ir);.  }.  sqlit
40c0: 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a 50  e3_free(pCur->zP
40d0: 61 74 68 29 3b 0a 20 20 73 71 6c 69 74 65 33 5f  ath);.  sqlite3_
40e0: 66 72 65 65 28 70 43 75 72 2d 3e 61 4c 76 6c 29  free(pCur->aLvl)
40f0: 3b 0a 20 20 70 43 75 72 2d 3e 61 4c 76 6c 20 3d  ;.  pCur->aLvl =
4100: 20 30 3b 0a 20 20 70 43 75 72 2d 3e 7a 50 61 74   0;.  pCur->zPat
4110: 68 20 3d 20 30 3b 0a 20 20 70 43 75 72 2d 3e 7a  h = 0;.  pCur->z
4120: 42 61 73 65 20 3d 20 30 3b 0a 20 20 70 43 75 72  Base = 0;.  pCur
4130: 2d 3e 6e 42 61 73 65 20 3d 20 30 3b 0a 20 20 70  ->nBase = 0;.  p
4140: 43 75 72 2d 3e 6e 4c 76 6c 20 3d 20 30 3b 0a 20  Cur->nLvl = 0;. 
4150: 20 70 43 75 72 2d 3e 69 4c 76 6c 20 3d 20 2d 31   pCur->iLvl = -1
4160: 3b 0a 20 20 70 43 75 72 2d 3e 69 52 6f 77 69 64  ;.  pCur->iRowid
4170: 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44   = 1;.}../*.** D
4180: 65 73 74 72 75 63 74 6f 72 20 66 6f 72 20 61 6e  estructor for an
4190: 20 66 73 64 69 72 5f 63 75 72 73 6f 72 2e 0a 2a   fsdir_cursor..*
41a0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64  /.static int fsd
41b0: 69 72 43 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f  irClose(sqlite3_
41c0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
41d0: 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f  ){.  fsdir_curso
41e0: 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69 72  r *pCur = (fsdir
41f0: 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 0a 20  _cursor*)cur;.. 
4200: 20 66 73 64 69 72 52 65 73 65 74 43 75 72 73 6f   fsdirResetCurso
4210: 72 28 70 43 75 72 29 3b 0a 20 20 73 71 6c 69 74  r(pCur);.  sqlit
4220: 65 33 5f 66 72 65 65 28 70 43 75 72 29 3b 0a 20  e3_free(pCur);. 
4230: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f   return SQLITE_O
4240: 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20  K;.}../*.** Set 
4250: 74 68 65 20 65 72 72 6f 72 20 6d 65 73 73 61 67  the error messag
4260: 65 20 66 6f 72 20 74 68 65 20 76 69 72 74 75 61  e for the virtua
4270: 6c 20 74 61 62 6c 65 20 61 73 73 6f 63 69 61 74  l table associat
4280: 65 64 20 77 69 74 68 20 63 75 72 73 6f 72 0a 2a  ed with cursor.*
4290: 2a 20 70 43 75 72 20 74 6f 20 74 68 65 20 72 65  * pCur to the re
42a0: 73 75 6c 74 73 20 6f 66 20 76 70 72 69 6e 74 66  sults of vprintf
42b0: 28 7a 46 6d 74 2c 20 2e 2e 2e 29 2e 0a 2a 2f 0a  (zFmt, ...)..*/.
42c0: 73 74 61 74 69 63 20 76 6f 69 64 20 66 73 64 69  static void fsdi
42d0: 72 53 65 74 45 72 72 6d 73 67 28 66 73 64 69 72  rSetErrmsg(fsdir
42e0: 5f 63 75 72 73 6f 72 20 2a 70 43 75 72 2c 20 63  _cursor *pCur, c
42f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6d 74 2c  onst char *zFmt,
4300: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74   ...){.  va_list
4310: 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74 28   ap;.  va_start(
4320: 61 70 2c 20 7a 46 6d 74 29 3b 0a 20 20 70 43 75  ap, zFmt);.  pCu
4330: 72 2d 3e 62 61 73 65 2e 70 56 74 61 62 2d 3e 7a  r->base.pVtab->z
4340: 45 72 72 4d 73 67 20 3d 20 73 71 6c 69 74 65 33  ErrMsg = sqlite3
4350: 5f 76 6d 70 72 69 6e 74 66 28 7a 46 6d 74 2c 20  _vmprintf(zFmt, 
4360: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  ap);.  va_end(ap
4370: 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 41 64 76  );.}.../*.** Adv
4380: 61 6e 63 65 20 61 6e 20 66 73 64 69 72 5f 63 75  ance an fsdir_cu
4390: 72 73 6f 72 20 74 6f 20 69 74 73 20 6e 65 78 74  rsor to its next
43a0: 20 72 6f 77 20 6f 66 20 6f 75 74 70 75 74 2e 0a   row of output..
43b0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
43c0: 64 69 72 4e 65 78 74 28 73 71 6c 69 74 65 33 5f  dirNext(sqlite3_
43d0: 76 74 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72  vtab_cursor *cur
43e0: 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f  ){.  fsdir_curso
43f0: 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69 72  r *pCur = (fsdir
4400: 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20  _cursor*)cur;.  
4410: 6d 6f 64 65 5f 74 20 6d 20 3d 20 70 43 75 72 2d  mode_t m = pCur-
4420: 3e 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65 3b 0a  >sStat.st_mode;.
4430: 0a 20 20 70 43 75 72 2d 3e 69 52 6f 77 69 64 2b  .  pCur->iRowid+
4440: 2b 3b 0a 20 20 69 66 28 20 53 5f 49 53 44 49 52  +;.  if( S_ISDIR
4450: 28 6d 29 20 29 7b 0a 20 20 20 20 2f 2a 20 44 65  (m) ){.    /* De
4460: 73 63 65 6e 64 20 69 6e 74 6f 20 74 68 69 73 20  scend into this 
4470: 64 69 72 65 63 74 6f 72 79 20 2a 2f 0a 20 20 20  directory */.   
4480: 20 69 6e 74 20 69 4e 65 77 20 3d 20 70 43 75 72   int iNew = pCur
4490: 2d 3e 69 4c 76 6c 20 2b 20 31 3b 0a 20 20 20 20  ->iLvl + 1;.    
44a0: 46 73 64 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c  FsdirLevel *pLvl
44b0: 3b 0a 20 20 20 20 69 66 28 20 69 4e 65 77 3e 3d  ;.    if( iNew>=
44c0: 70 43 75 72 2d 3e 6e 4c 76 6c 20 29 7b 0a 20 20  pCur->nLvl ){.  
44d0: 20 20 20 20 69 6e 74 20 6e 4e 65 77 20 3d 20 69      int nNew = i
44e0: 4e 65 77 2b 31 3b 0a 20 20 20 20 20 20 69 6e 74  New+1;.      int
44f0: 20 6e 42 79 74 65 20 3d 20 6e 4e 65 77 2a 73 69   nByte = nNew*si
4500: 7a 65 6f 66 28 46 73 64 69 72 4c 65 76 65 6c 29  zeof(FsdirLevel)
4510: 3b 0a 20 20 20 20 20 20 46 73 64 69 72 4c 65 76  ;.      FsdirLev
4520: 65 6c 20 2a 61 4e 65 77 20 3d 20 28 46 73 64 69  el *aNew = (Fsdi
4530: 72 4c 65 76 65 6c 2a 29 73 71 6c 69 74 65 33 5f  rLevel*)sqlite3_
4540: 72 65 61 6c 6c 6f 63 28 70 43 75 72 2d 3e 61 4c  realloc(pCur->aL
4550: 76 6c 2c 20 6e 42 79 74 65 29 3b 0a 20 20 20 20  vl, nByte);.    
4560: 20 20 69 66 28 20 61 4e 65 77 3d 3d 30 20 29 20    if( aNew==0 ) 
4570: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4e 4f  return SQLITE_NO
4580: 4d 45 4d 3b 0a 20 20 20 20 20 20 6d 65 6d 73 65  MEM;.      memse
4590: 74 28 26 61 4e 65 77 5b 70 43 75 72 2d 3e 6e 4c  t(&aNew[pCur->nL
45a0: 76 6c 5d 2c 20 30 2c 20 73 69 7a 65 6f 66 28 46  vl], 0, sizeof(F
45b0: 73 64 69 72 4c 65 76 65 6c 29 2a 28 6e 4e 65 77  sdirLevel)*(nNew
45c0: 2d 70 43 75 72 2d 3e 6e 4c 76 6c 29 29 3b 0a 20  -pCur->nLvl));. 
45d0: 20 20 20 20 20 70 43 75 72 2d 3e 61 4c 76 6c 20       pCur->aLvl 
45e0: 3d 20 61 4e 65 77 3b 0a 20 20 20 20 20 20 70 43  = aNew;.      pC
45f0: 75 72 2d 3e 6e 4c 76 6c 20 3d 20 6e 4e 65 77 3b  ur->nLvl = nNew;
4600: 0a 20 20 20 20 7d 0a 20 20 20 20 70 43 75 72 2d  .    }.    pCur-
4610: 3e 69 4c 76 6c 20 3d 20 69 4e 65 77 3b 0a 20 20  >iLvl = iNew;.  
4620: 20 20 70 4c 76 6c 20 3d 20 26 70 43 75 72 2d 3e    pLvl = &pCur->
4630: 61 4c 76 6c 5b 69 4e 65 77 5d 3b 0a 20 20 20 20  aLvl[iNew];.    
4640: 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69 72 20  .    pLvl->zDir 
4650: 3d 20 70 43 75 72 2d 3e 7a 50 61 74 68 3b 0a 20  = pCur->zPath;. 
4660: 20 20 20 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d     pCur->zPath =
4670: 20 30 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 70 44   0;.    pLvl->pD
4680: 69 72 20 3d 20 6f 70 65 6e 64 69 72 28 70 4c 76  ir = opendir(pLv
4690: 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20 20 20 69 66  l->zDir);.    if
46a0: 28 20 70 4c 76 6c 2d 3e 70 44 69 72 3d 3d 30 20  ( pLvl->pDir==0 
46b0: 29 7b 0a 20 20 20 20 20 20 66 73 64 69 72 53 65  ){.      fsdirSe
46c0: 74 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 63  tErrmsg(pCur, "c
46d0: 61 6e 6e 6f 74 20 72 65 61 64 20 64 69 72 65 63  annot read direc
46e0: 74 6f 72 79 3a 20 25 73 22 2c 20 70 43 75 72 2d  tory: %s", pCur-
46f0: 3e 7a 50 61 74 68 29 3b 0a 20 20 20 20 20 20 72  >zPath);.      r
4700: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
4710: 4f 52 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  OR;.    }.  }.. 
4720: 20 77 68 69 6c 65 28 20 70 43 75 72 2d 3e 69 4c   while( pCur->iL
4730: 76 6c 3e 3d 30 20 29 7b 0a 20 20 20 20 46 73 64  vl>=0 ){.    Fsd
4740: 69 72 4c 65 76 65 6c 20 2a 70 4c 76 6c 20 3d 20  irLevel *pLvl = 
4750: 26 70 43 75 72 2d 3e 61 4c 76 6c 5b 70 43 75 72  &pCur->aLvl[pCur
4760: 2d 3e 69 4c 76 6c 5d 3b 0a 20 20 20 20 73 74 72  ->iLvl];.    str
4770: 75 63 74 20 64 69 72 65 6e 74 20 2a 70 45 6e 74  uct dirent *pEnt
4780: 72 79 20 3d 20 72 65 61 64 64 69 72 28 70 4c 76  ry = readdir(pLv
4790: 6c 2d 3e 70 44 69 72 29 3b 0a 20 20 20 20 69 66  l->pDir);.    if
47a0: 28 20 70 45 6e 74 72 79 20 29 7b 0a 20 20 20 20  ( pEntry ){.    
47b0: 20 20 69 66 28 20 70 45 6e 74 72 79 2d 3e 64 5f    if( pEntry->d_
47c0: 6e 61 6d 65 5b 30 5d 3d 3d 27 2e 27 20 29 7b 0a  name[0]=='.' ){.
47d0: 20 20 20 20 20 20 20 69 66 28 20 70 45 6e 74 72         if( pEntr
47e0: 79 2d 3e 64 5f 6e 61 6d 65 5b 31 5d 3d 3d 27 2e  y->d_name[1]=='.
47f0: 27 20 26 26 20 70 45 6e 74 72 79 2d 3e 64 5f 6e  ' && pEntry->d_n
4800: 61 6d 65 5b 32 5d 3d 3d 27 5c 30 27 20 29 20 63  ame[2]=='\0' ) c
4810: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 20  ontinue;.       
4820: 69 66 28 20 70 45 6e 74 72 79 2d 3e 64 5f 6e 61  if( pEntry->d_na
4830: 6d 65 5b 31 5d 3d 3d 27 5c 30 27 20 29 20 63 6f  me[1]=='\0' ) co
4840: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d 0a  ntinue;.      }.
4850: 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72        sqlite3_fr
4860: 65 65 28 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b  ee(pCur->zPath);
4870: 0a 20 20 20 20 20 20 70 43 75 72 2d 3e 7a 50 61  .      pCur->zPa
4880: 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72  th = sqlite3_mpr
4890: 69 6e 74 66 28 22 25 73 2f 25 73 22 2c 20 70 4c  intf("%s/%s", pL
48a0: 76 6c 2d 3e 7a 44 69 72 2c 20 70 45 6e 74 72 79  vl->zDir, pEntry
48b0: 2d 3e 64 5f 6e 61 6d 65 29 3b 0a 20 20 20 20 20  ->d_name);.     
48c0: 20 69 66 28 20 70 43 75 72 2d 3e 7a 50 61 74 68   if( pCur->zPath
48d0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 53 51 4c  ==0 ) return SQL
48e0: 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20 20 20  ITE_NOMEM;.     
48f0: 20 69 66 28 20 66 69 6c 65 4c 69 6e 6b 53 74 61   if( fileLinkSta
4900: 74 28 70 43 75 72 2d 3e 7a 50 61 74 68 2c 20 26  t(pCur->zPath, &
4910: 70 43 75 72 2d 3e 73 53 74 61 74 29 20 29 7b 0a  pCur->sStat) ){.
4920: 20 20 20 20 20 20 20 20 66 73 64 69 72 53 65 74          fsdirSet
4930: 45 72 72 6d 73 67 28 70 43 75 72 2c 20 22 63 61  Errmsg(pCur, "ca
4940: 6e 6e 6f 74 20 73 74 61 74 20 66 69 6c 65 3a 20  nnot stat file: 
4950: 25 73 22 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68  %s", pCur->zPath
4960: 29 3b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  );.        retur
4970: 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b 0a  n SQLITE_ERROR;.
4980: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 72 65        }.      re
4990: 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a  turn SQLITE_OK;.
49a0: 20 20 20 20 7d 0a 20 20 20 20 63 6c 6f 73 65 64      }.    closed
49b0: 69 72 28 70 4c 76 6c 2d 3e 70 44 69 72 29 3b 0a  ir(pLvl->pDir);.
49c0: 20 20 20 20 73 71 6c 69 74 65 33 5f 66 72 65 65      sqlite3_free
49d0: 28 70 4c 76 6c 2d 3e 7a 44 69 72 29 3b 0a 20 20  (pLvl->zDir);.  
49e0: 20 20 70 4c 76 6c 2d 3e 70 44 69 72 20 3d 20 30    pLvl->pDir = 0
49f0: 3b 0a 20 20 20 20 70 4c 76 6c 2d 3e 7a 44 69 72  ;.    pLvl->zDir
4a00: 20 3d 20 30 3b 0a 20 20 20 20 70 43 75 72 2d 3e   = 0;.    pCur->
4a10: 69 4c 76 6c 2d 2d 3b 0a 20 20 7d 0a 0a 20 20 2f  iLvl--;.  }..  /
4a20: 2a 20 45 4f 46 20 2a 2f 0a 20 20 73 71 6c 69 74  * EOF */.  sqlit
4a30: 65 33 5f 66 72 65 65 28 70 43 75 72 2d 3e 7a 50  e3_free(pCur->zP
4a40: 61 74 68 29 3b 0a 20 20 70 43 75 72 2d 3e 7a 50  ath);.  pCur->zP
4a50: 61 74 68 20 3d 20 30 3b 0a 20 20 72 65 74 75 72  ath = 0;.  retur
4a60: 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a  n SQLITE_OK;.}..
4a70: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 76 61 6c  /*.** Return val
4a80: 75 65 73 20 6f 66 20 63 6f 6c 75 6d 6e 73 20 66  ues of columns f
4a90: 6f 72 20 74 68 65 20 72 6f 77 20 61 74 20 77 68  or the row at wh
4aa0: 69 63 68 20 74 68 65 20 73 65 72 69 65 73 5f 63  ich the series_c
4ab0: 75 72 73 6f 72 0a 2a 2a 20 69 73 20 63 75 72 72  ursor.** is curr
4ac0: 65 6e 74 6c 79 20 70 6f 69 6e 74 69 6e 67 2e 0a  ently pointing..
4ad0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73  */.static int fs
4ae0: 64 69 72 43 6f 6c 75 6d 6e 28 0a 20 20 73 71 6c  dirColumn(.  sql
4af0: 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73 6f 72  ite3_vtab_cursor
4b00: 20 2a 63 75 72 2c 20 20 20 2f 2a 20 54 68 65 20   *cur,   /* The 
4b10: 63 75 72 73 6f 72 20 2a 2f 0a 20 20 73 71 6c 69  cursor */.  sqli
4b20: 74 65 33 5f 63 6f 6e 74 65 78 74 20 2a 63 74 78  te3_context *ctx
4b30: 2c 20 20 20 20 20 20 20 2f 2a 20 46 69 72 73 74  ,       /* First
4b40: 20 61 72 67 75 6d 65 6e 74 20 74 6f 20 73 71 6c   argument to sql
4b50: 69 74 65 33 5f 72 65 73 75 6c 74 5f 2e 2e 2e 28  ite3_result_...(
4b60: 29 20 2a 2f 0a 20 20 69 6e 74 20 69 20 20 20 20  ) */.  int i    
4b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
4b80: 20 20 20 2f 2a 20 57 68 69 63 68 20 63 6f 6c 75     /* Which colu
4b90: 6d 6e 20 74 6f 20 72 65 74 75 72 6e 20 2a 2f 0a  mn to return */.
4ba0: 29 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f  ){.  fsdir_curso
4bb0: 72 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69 72  r *pCur = (fsdir
4bc0: 5f 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20  _cursor*)cur;.  
4bd0: 73 77 69 74 63 68 28 20 69 20 29 7b 0a 20 20 20  switch( i ){.   
4be0: 20 63 61 73 65 20 30 3a 20 7b 20 2f 2a 20 6e 61   case 0: { /* na
4bf0: 6d 65 20 2a 2f 0a 20 20 20 20 20 20 73 71 6c 69  me */.      sqli
4c00: 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28  te3_result_text(
4c10: 63 74 78 2c 20 26 70 43 75 72 2d 3e 7a 50 61 74  ctx, &pCur->zPat
4c20: 68 5b 70 43 75 72 2d 3e 6e 42 61 73 65 5d 2c 20  h[pCur->nBase], 
4c30: 2d 31 2c 20 53 51 4c 49 54 45 5f 54 52 41 4e 53  -1, SQLITE_TRANS
4c40: 49 45 4e 54 29 3b 0a 20 20 20 20 20 20 62 72 65  IENT);.      bre
4c50: 61 6b 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 63  ak;.    }..    c
4c60: 61 73 65 20 31 3a 20 2f 2a 20 6d 6f 64 65 20 2a  ase 1: /* mode *
4c70: 2f 0a 20 20 20 20 20 20 73 71 6c 69 74 65 33 5f  /.      sqlite3_
4c80: 72 65 73 75 6c 74 5f 69 6e 74 36 34 28 63 74 78  result_int64(ctx
4c90: 2c 20 70 43 75 72 2d 3e 73 53 74 61 74 2e 73 74  , pCur->sStat.st
4ca0: 5f 6d 6f 64 65 29 3b 0a 20 20 20 20 20 20 62 72  _mode);.      br
4cb0: 65 61 6b 3b 0a 0a 20 20 20 20 63 61 73 65 20 32  eak;..    case 2
4cc0: 3a 20 2f 2a 20 6d 74 69 6d 65 20 2a 2f 0a 20 20  : /* mtime */.  
4cd0: 20 20 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75      sqlite3_resu
4ce0: 6c 74 5f 69 6e 74 36 34 28 63 74 78 2c 20 70 43  lt_int64(ctx, pC
4cf0: 75 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 74 69  ur->sStat.st_mti
4d00: 6d 65 29 3b 0a 20 20 20 20 20 20 62 72 65 61 6b  me);.      break
4d10: 3b 0a 0a 20 20 20 20 63 61 73 65 20 33 3a 20 7b  ;..    case 3: {
4d20: 20 2f 2a 20 64 61 74 61 20 2a 2f 0a 20 20 20 20   /* data */.    
4d30: 20 20 6d 6f 64 65 5f 74 20 6d 20 3d 20 70 43 75    mode_t m = pCu
4d40: 72 2d 3e 73 53 74 61 74 2e 73 74 5f 6d 6f 64 65  r->sStat.st_mode
4d50: 3b 0a 20 20 20 20 20 20 69 66 28 20 53 5f 49 53  ;.      if( S_IS
4d60: 44 49 52 28 6d 29 20 29 7b 0a 20 20 20 20 20 20  DIR(m) ){.      
4d70: 20 20 73 71 6c 69 74 65 33 5f 72 65 73 75 6c 74    sqlite3_result
4d80: 5f 6e 75 6c 6c 28 63 74 78 29 3b 0a 23 69 66 20  _null(ctx);.#if 
4d90: 21 64 65 66 69 6e 65 64 28 5f 57 49 4e 33 32 29  !defined(_WIN32)
4da0: 20 26 26 20 21 64 65 66 69 6e 65 64 28 57 49 4e   && !defined(WIN
4db0: 33 32 29 0a 20 20 20 20 20 20 7d 65 6c 73 65 20  32).      }else 
4dc0: 69 66 28 20 53 5f 49 53 4c 4e 4b 28 6d 29 20 29  if( S_ISLNK(m) )
4dd0: 7b 0a 20 20 20 20 20 20 20 20 63 68 61 72 20 61  {.        char a
4de0: 53 74 61 74 69 63 5b 36 34 5d 3b 0a 20 20 20 20  Static[64];.    
4df0: 20 20 20 20 63 68 61 72 20 2a 61 42 75 66 20 3d      char *aBuf =
4e00: 20 61 53 74 61 74 69 63 3b 0a 20 20 20 20 20 20   aStatic;.      
4e10: 20 20 69 6e 74 20 6e 42 75 66 20 3d 20 36 34 3b    int nBuf = 64;
4e20: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 6e 3b 0a  .        int n;.
4e30: 0a 20 20 20 20 20 20 20 20 77 68 69 6c 65 28 20  .        while( 
4e40: 31 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 6e  1 ){.          n
4e50: 20 3d 20 72 65 61 64 6c 69 6e 6b 28 70 43 75 72   = readlink(pCur
4e60: 2d 3e 7a 50 61 74 68 2c 20 61 42 75 66 2c 20 6e  ->zPath, aBuf, n
4e70: 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Buf);.          
4e80: 69 66 28 20 6e 3c 6e 42 75 66 20 29 20 62 72 65  if( n<nBuf ) bre
4e90: 61 6b 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  ak;.          if
4ea0: 28 20 61 42 75 66 21 3d 61 53 74 61 74 69 63 20  ( aBuf!=aStatic 
4eb0: 29 20 73 71 6c 69 74 65 33 5f 66 72 65 65 28 61  ) sqlite3_free(a
4ec0: 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Buf);.          
4ed0: 6e 42 75 66 20 3d 20 6e 42 75 66 2a 32 3b 0a 20  nBuf = nBuf*2;. 
4ee0: 20 20 20 20 20 20 20 20 20 61 42 75 66 20 3d 20           aBuf = 
4ef0: 73 71 6c 69 74 65 33 5f 6d 61 6c 6c 6f 63 28 6e  sqlite3_malloc(n
4f00: 42 75 66 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Buf);.          
4f10: 69 66 28 20 61 42 75 66 3d 3d 30 20 29 7b 0a 20  if( aBuf==0 ){. 
4f20: 20 20 20 20 20 20 20 20 20 20 20 73 71 6c 69 74             sqlit
4f30: 65 33 5f 72 65 73 75 6c 74 5f 65 72 72 6f 72 5f  e3_result_error_
4f40: 6e 6f 6d 65 6d 28 63 74 78 29 3b 0a 20 20 20 20  nomem(ctx);.    
4f50: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 53          return S
4f60: 51 4c 49 54 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 20  QLITE_NOMEM;.   
4f70: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
4f80: 20 7d 0a 0a 20 20 20 20 20 20 20 20 73 71 6c 69   }..        sqli
4f90: 74 65 33 5f 72 65 73 75 6c 74 5f 74 65 78 74 28  te3_result_text(
4fa0: 63 74 78 2c 20 61 42 75 66 2c 20 6e 2c 20 53 51  ctx, aBuf, n, SQ
4fb0: 4c 49 54 45 5f 54 52 41 4e 53 49 45 4e 54 29 3b  LITE_TRANSIENT);
4fc0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 61 42 75  .        if( aBu
4fd0: 66 21 3d 61 53 74 61 74 69 63 20 29 20 73 71 6c  f!=aStatic ) sql
4fe0: 69 74 65 33 5f 66 72 65 65 28 61 42 75 66 29 3b  ite3_free(aBuf);
4ff0: 0a 23 65 6e 64 69 66 0a 20 20 20 20 20 20 7d 65  .#endif.      }e
5000: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 72 65 61  lse{.        rea
5010: 64 46 69 6c 65 43 6f 6e 74 65 6e 74 73 28 63 74  dFileContents(ct
5020: 78 2c 20 70 43 75 72 2d 3e 7a 50 61 74 68 29 3b  x, pCur->zPath);
5030: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
5040: 20 7d 0a 20 20 72 65 74 75 72 6e 20 53 51 4c 49   }.  return SQLI
5050: 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  TE_OK;.}../*.** 
5060: 52 65 74 75 72 6e 20 74 68 65 20 72 6f 77 69 64  Return the rowid
5070: 20 66 6f 72 20 74 68 65 20 63 75 72 72 65 6e 74   for the current
5080: 20 72 6f 77 2e 20 49 6e 20 74 68 69 73 20 69 6d   row. In this im
5090: 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 2c 20 74 68  plementation, th
50a0: 65 0a 2a 2a 20 66 69 72 73 74 20 72 6f 77 20 72  e.** first row r
50b0: 65 74 75 72 6e 65 64 20 69 73 20 61 73 73 69 67  eturned is assig
50c0: 6e 65 64 20 72 6f 77 69 64 20 76 61 6c 75 65 20  ned rowid value 
50d0: 31 2c 20 61 6e 64 20 65 61 63 68 20 73 75 62 73  1, and each subs
50e0: 65 71 75 65 6e 74 0a 2a 2a 20 72 6f 77 20 61 20  equent.** row a 
50f0: 76 61 6c 75 65 20 31 20 6d 6f 72 65 20 74 68 61  value 1 more tha
5100: 6e 20 74 68 61 74 20 6f 66 20 74 68 65 20 70 72  n that of the pr
5110: 65 76 69 6f 75 73 2e 0a 2a 2f 0a 73 74 61 74 69  evious..*/.stati
5120: 63 20 69 6e 74 20 66 73 64 69 72 52 6f 77 69 64  c int fsdirRowid
5130: 28 73 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75  (sqlite3_vtab_cu
5140: 72 73 6f 72 20 2a 63 75 72 2c 20 73 71 6c 69 74  rsor *cur, sqlit
5150: 65 5f 69 6e 74 36 34 20 2a 70 52 6f 77 69 64 29  e_int64 *pRowid)
5160: 7b 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72  {.  fsdir_cursor
5170: 20 2a 70 43 75 72 20 3d 20 28 66 73 64 69 72 5f   *pCur = (fsdir_
5180: 63 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 2a  cursor*)cur;.  *
5190: 70 52 6f 77 69 64 20 3d 20 70 43 75 72 2d 3e 69  pRowid = pCur->i
51a0: 52 6f 77 69 64 3b 0a 20 20 72 65 74 75 72 6e 20  Rowid;.  return 
51b0: 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d 0a 0a 2f 2a  SQLITE_OK;.}../*
51c0: 0a 2a 2a 20 52 65 74 75 72 6e 20 54 52 55 45 20  .** Return TRUE 
51d0: 69 66 20 74 68 65 20 63 75 72 73 6f 72 20 68 61  if the cursor ha
51e0: 73 20 62 65 65 6e 20 6d 6f 76 65 64 20 6f 66 66  s been moved off
51f0: 20 6f 66 20 74 68 65 20 6c 61 73 74 0a 2a 2a 20   of the last.** 
5200: 72 6f 77 20 6f 66 20 6f 75 74 70 75 74 2e 0a 2a  row of output..*
5210: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64  /.static int fsd
5220: 69 72 45 6f 66 28 73 71 6c 69 74 65 33 5f 76 74  irEof(sqlite3_vt
5230: 61 62 5f 63 75 72 73 6f 72 20 2a 63 75 72 29 7b  ab_cursor *cur){
5240: 0a 20 20 66 73 64 69 72 5f 63 75 72 73 6f 72 20  .  fsdir_cursor 
5250: 2a 70 43 75 72 20 3d 20 28 66 73 64 69 72 5f 63  *pCur = (fsdir_c
5260: 75 72 73 6f 72 2a 29 63 75 72 3b 0a 20 20 72 65  ursor*)cur;.  re
5270: 74 75 72 6e 20 28 70 43 75 72 2d 3e 7a 50 61 74  turn (pCur->zPat
5280: 68 3d 3d 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  h==0);.}../*.** 
5290: 78 46 69 6c 74 65 72 20 63 61 6c 6c 62 61 63 6b  xFilter callback
52a0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
52b0: 66 73 64 69 72 46 69 6c 74 65 72 28 0a 20 20 73  fsdirFilter(.  s
52c0: 71 6c 69 74 65 33 5f 76 74 61 62 5f 63 75 72 73  qlite3_vtab_curs
52d0: 6f 72 20 2a 63 75 72 2c 20 0a 20 20 69 6e 74 20  or *cur, .  int 
52e0: 69 64 78 4e 75 6d 2c 20 63 6f 6e 73 74 20 63 68  idxNum, const ch
52f0: 61 72 20 2a 69 64 78 53 74 72 2c 0a 20 20 69 6e  ar *idxStr,.  in
5300: 74 20 61 72 67 63 2c 20 73 71 6c 69 74 65 33 5f  t argc, sqlite3_
5310: 76 61 6c 75 65 20 2a 2a 61 72 67 76 0a 29 7b 0a  value **argv.){.
5320: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44    const char *zD
5330: 69 72 20 3d 20 30 3b 0a 20 20 66 73 64 69 72 5f  ir = 0;.  fsdir_
5340: 63 75 72 73 6f 72 20 2a 70 43 75 72 20 3d 20 28  cursor *pCur = (
5350: 66 73 64 69 72 5f 63 75 72 73 6f 72 2a 29 63 75  fsdir_cursor*)cu
5360: 72 3b 0a 20 20 28 76 6f 69 64 29 69 64 78 53 74  r;.  (void)idxSt
5370: 72 3b 0a 20 20 66 73 64 69 72 52 65 73 65 74 43  r;.  fsdirResetC
5380: 75 72 73 6f 72 28 70 43 75 72 29 3b 0a 0a 20 20  ursor(pCur);..  
5390: 69 66 28 20 69 64 78 4e 75 6d 3d 3d 30 20 29 7b  if( idxNum==0 ){
53a0: 0a 20 20 20 20 66 73 64 69 72 53 65 74 45 72 72  .    fsdirSetErr
53b0: 6d 73 67 28 70 43 75 72 2c 20 22 74 61 62 6c 65  msg(pCur, "table
53c0: 20 66 75 6e 63 74 69 6f 6e 20 66 73 64 69 72 20   function fsdir 
53d0: 72 65 71 75 69 72 65 73 20 61 6e 20 61 72 67 75  requires an argu
53e0: 6d 65 6e 74 22 29 3b 0a 20 20 20 20 72 65 74 75  ment");.    retu
53f0: 72 6e 20 53 51 4c 49 54 45 5f 45 52 52 4f 52 3b  rn SQLITE_ERROR;
5400: 0a 20 20 7d 0a 0a 20 20 61 73 73 65 72 74 28 20  .  }..  assert( 
5410: 61 72 67 63 3d 3d 69 64 78 4e 75 6d 20 26 26 20  argc==idxNum && 
5420: 28 61 72 67 63 3d 3d 31 20 7c 7c 20 61 72 67 63  (argc==1 || argc
5430: 3d 3d 32 29 20 29 3b 0a 20 20 7a 44 69 72 20 3d  ==2) );.  zDir =
5440: 20 28 63 6f 6e 73 74 20 63 68 61 72 2a 29 73 71   (const char*)sq
5450: 6c 69 74 65 33 5f 76 61 6c 75 65 5f 74 65 78 74  lite3_value_text
5460: 28 61 72 67 76 5b 30 5d 29 3b 0a 20 20 69 66 28  (argv[0]);.  if(
5470: 20 7a 44 69 72 3d 3d 30 20 29 7b 0a 20 20 20 20   zDir==0 ){.    
5480: 66 73 64 69 72 53 65 74 45 72 72 6d 73 67 28 70  fsdirSetErrmsg(p
5490: 43 75 72 2c 20 22 74 61 62 6c 65 20 66 75 6e 63  Cur, "table func
54a0: 74 69 6f 6e 20 66 73 64 69 72 20 72 65 71 75 69  tion fsdir requi
54b0: 72 65 73 20 61 20 6e 6f 6e 2d 4e 55 4c 4c 20 61  res a non-NULL a
54c0: 72 67 75 6d 65 6e 74 22 29 3b 0a 20 20 20 20 72  rgument");.    r
54d0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45 52 52  eturn SQLITE_ERR
54e0: 4f 52 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 72  OR;.  }.  if( ar
54f0: 67 63 3d 3d 32 20 29 7b 0a 20 20 20 20 70 43 75  gc==2 ){.    pCu
5500: 72 2d 3e 7a 42 61 73 65 20 3d 20 28 63 6f 6e 73  r->zBase = (cons
5510: 74 20 63 68 61 72 2a 29 73 71 6c 69 74 65 33 5f  t char*)sqlite3_
5520: 76 61 6c 75 65 5f 74 65 78 74 28 61 72 67 76 5b  value_text(argv[
5530: 31 5d 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70  1]);.  }.  if( p
5540: 43 75 72 2d 3e 7a 42 61 73 65 20 29 7b 0a 20 20  Cur->zBase ){.  
5550: 20 20 70 43 75 72 2d 3e 6e 42 61 73 65 20 3d 20    pCur->nBase = 
5560: 28 69 6e 74 29 73 74 72 6c 65 6e 28 70 43 75 72  (int)strlen(pCur
5570: 2d 3e 7a 42 61 73 65 29 2b 31 3b 0a 20 20 20 20  ->zBase)+1;.    
5580: 70 43 75 72 2d 3e 7a 50 61 74 68 20 3d 20 73 71  pCur->zPath = sq
5590: 6c 69 74 65 33 5f 6d 70 72 69 6e 74 66 28 22 25  lite3_mprintf("%
55a0: 73 2f 25 73 22 2c 20 70 43 75 72 2d 3e 7a 42 61  s/%s", pCur->zBa
55b0: 73 65 2c 20 7a 44 69 72 29 3b 0a 20 20 7d 65 6c  se, zDir);.  }el
55c0: 73 65 7b 0a 20 20 20 20 70 43 75 72 2d 3e 7a 50  se{.    pCur->zP
55d0: 61 74 68 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70  ath = sqlite3_mp
55e0: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 44 69 72  rintf("%s", zDir
55f0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 70 43  );.  }..  if( pC
5600: 75 72 2d 3e 7a 50 61 74 68 3d 3d 30 20 29 7b 0a  ur->zPath==0 ){.
5610: 20 20 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54      return SQLIT
5620: 45 5f 4e 4f 4d 45 4d 3b 0a 20 20 7d 0a 20 20 69  E_NOMEM;.  }.  i
5630: 66 28 20 66 69 6c 65 4c 69 6e 6b 53 74 61 74 28  f( fileLinkStat(
5640: 70 43 75 72 2d 3e 7a 50 61 74 68 2c 20 26 70 43  pCur->zPath, &pC
5650: 75 72 2d 3e 73 53 74 61 74 29 20 29 7b 0a 20 20  ur->sStat) ){.  
5660: 20 20 66 73 64 69 72 53 65 74 45 72 72 6d 73 67    fsdirSetErrmsg
5670: 28 70 43 75 72 2c 20 22 63 61 6e 6e 6f 74 20 73  (pCur, "cannot s
5680: 74 61 74 20 66 69 6c 65 3a 20 25 73 22 2c 20 70  tat file: %s", p
5690: 43 75 72 2d 3e 7a 50 61 74 68 29 3b 0a 20 20 20  Cur->zPath);.   
56a0: 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 45   return SQLITE_E
56b0: 52 52 4f 52 3b 0a 20 20 7d 0a 0a 20 20 72 65 74  RROR;.  }..  ret
56c0: 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 7d  urn SQLITE_OK;.}
56d0: 0a 0a 2f 2a 0a 2a 2a 20 53 51 4c 69 74 65 20 77  ../*.** SQLite w
56e0: 69 6c 6c 20 69 6e 76 6f 6b 65 20 74 68 69 73 20  ill invoke this 
56f0: 6d 65 74 68 6f 64 20 6f 6e 65 20 6f 72 20 6d 6f  method one or mo
5700: 72 65 20 74 69 6d 65 73 20 77 68 69 6c 65 20 70  re times while p
5710: 6c 61 6e 6e 69 6e 67 20 61 20 71 75 65 72 79 0a  lanning a query.
5720: 2a 2a 20 74 68 61 74 20 75 73 65 73 20 74 68 65  ** that uses the
5730: 20 67 65 6e 65 72 61 74 65 5f 73 65 72 69 65 73   generate_series
5740: 20 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 20   virtual table. 
5750: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 6e 65   This routine ne
5760: 65 64 73 20 74 6f 20 63 72 65 61 74 65 0a 2a 2a  eds to create.**
5770: 20 61 20 71 75 65 72 79 20 70 6c 61 6e 20 66 6f   a query plan fo
5780: 72 20 65 61 63 68 20 69 6e 76 6f 63 61 74 69 6f  r each invocatio
5790: 6e 20 61 6e 64 20 63 6f 6d 70 75 74 65 20 61 6e  n and compute an
57a0: 20 65 73 74 69 6d 61 74 65 64 20 63 6f 73 74 20   estimated cost 
57b0: 66 6f 72 20 74 68 61 74 0a 2a 2a 20 70 6c 61 6e  for that.** plan
57c0: 2e 0a 2a 2a 0a 2a 2a 20 49 6e 20 74 68 69 73 20  ..**.** In this 
57d0: 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 69  implementation i
57e0: 64 78 4e 75 6d 20 69 73 20 75 73 65 64 20 74 6f  dxNum is used to
57f0: 20 72 65 70 72 65 73 65 6e 74 20 74 68 65 0a 2a   represent the.*
5800: 2a 20 71 75 65 72 79 20 70 6c 61 6e 2e 20 20 69  * query plan.  i
5810: 64 78 53 74 72 20 69 73 20 75 6e 75 73 65 64 2e  dxStr is unused.
5820: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 71 75 65 72 79  .**.** The query
5830: 20 70 6c 61 6e 20 69 73 20 72 65 70 72 65 73 65   plan is represe
5840: 6e 74 65 64 20 62 79 20 62 69 74 73 20 69 6e 20  nted by bits in 
5850: 69 64 78 4e 75 6d 3a 0a 2a 2a 0a 2a 2a 20 20 28  idxNum:.**.**  (
5860: 31 29 20 20 73 74 61 72 74 20 3d 20 24 76 61 6c  1)  start = $val
5870: 75 65 20 20 2d 2d 20 63 6f 6e 73 74 72 61 69 6e  ue  -- constrain
5880: 74 20 65 78 69 73 74 73 0a 2a 2a 20 20 28 32 29  t exists.**  (2)
5890: 20 20 73 74 6f 70 20 3d 20 24 76 61 6c 75 65 20    stop = $value 
58a0: 20 20 2d 2d 20 63 6f 6e 73 74 72 61 69 6e 74 20    -- constraint 
58b0: 65 78 69 73 74 73 0a 2a 2a 20 20 28 34 29 20 20  exists.**  (4)  
58c0: 73 74 65 70 20 3d 20 24 76 61 6c 75 65 20 20 20  step = $value   
58d0: 2d 2d 20 63 6f 6e 73 74 72 61 69 6e 74 20 65 78  -- constraint ex
58e0: 69 73 74 73 0a 2a 2a 20 20 28 38 29 20 20 6f 75  ists.**  (8)  ou
58f0: 74 70 75 74 20 69 6e 20 64 65 73 63 65 6e 64 69  tput in descendi
5900: 6e 67 20 6f 72 64 65 72 0a 2a 2f 0a 73 74 61 74  ng order.*/.stat
5910: 69 63 20 69 6e 74 20 66 73 64 69 72 42 65 73 74  ic int fsdirBest
5920: 49 6e 64 65 78 28 0a 20 20 73 71 6c 69 74 65 33  Index(.  sqlite3
5930: 5f 76 74 61 62 20 2a 74 61 62 2c 0a 20 20 73 71  _vtab *tab,.  sq
5940: 6c 69 74 65 33 5f 69 6e 64 65 78 5f 69 6e 66 6f  lite3_index_info
5950: 20 2a 70 49 64 78 49 6e 66 6f 0a 29 7b 0a 20 20   *pIdxInfo.){.  
5960: 69 6e 74 20 69 3b 20 20 20 20 20 20 20 20 20 20  int i;          
5970: 20 20 20 20 20 20 20 2f 2a 20 4c 6f 6f 70 20 6f         /* Loop o
5980: 76 65 72 20 63 6f 6e 73 74 72 61 69 6e 74 73 20  ver constraints 
5990: 2a 2f 0a 20 20 69 6e 74 20 69 64 78 34 20 3d 20  */.  int idx4 = 
59a0: 2d 31 3b 0a 20 20 69 6e 74 20 69 64 78 35 20 3d  -1;.  int idx5 =
59b0: 20 2d 31 3b 0a 20 20 63 6f 6e 73 74 20 73 74 72   -1;.  const str
59c0: 75 63 74 20 73 71 6c 69 74 65 33 5f 69 6e 64 65  uct sqlite3_inde
59d0: 78 5f 63 6f 6e 73 74 72 61 69 6e 74 20 2a 70 43  x_constraint *pC
59e0: 6f 6e 73 74 72 61 69 6e 74 3b 0a 0a 20 20 28 76  onstraint;..  (v
59f0: 6f 69 64 29 74 61 62 3b 0a 20 20 70 43 6f 6e 73  oid)tab;.  pCons
5a00: 74 72 61 69 6e 74 20 3d 20 70 49 64 78 49 6e 66  traint = pIdxInf
5a10: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 3b 0a  o->aConstraint;.
5a20: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 70 49 64    for(i=0; i<pId
5a30: 78 49 6e 66 6f 2d 3e 6e 43 6f 6e 73 74 72 61 69  xInfo->nConstrai
5a40: 6e 74 3b 20 69 2b 2b 2c 20 70 43 6f 6e 73 74 72  nt; i++, pConstr
5a50: 61 69 6e 74 2b 2b 29 7b 0a 20 20 20 20 69 66 28  aint++){.    if(
5a60: 20 70 43 6f 6e 73 74 72 61 69 6e 74 2d 3e 75 73   pConstraint->us
5a70: 61 62 6c 65 3d 3d 30 20 29 20 63 6f 6e 74 69 6e  able==0 ) contin
5a80: 75 65 3b 0a 20 20 20 20 69 66 28 20 70 43 6f 6e  ue;.    if( pCon
5a90: 73 74 72 61 69 6e 74 2d 3e 6f 70 21 3d 53 51 4c  straint->op!=SQL
5aa0: 49 54 45 5f 49 4e 44 45 58 5f 43 4f 4e 53 54 52  ITE_INDEX_CONSTR
5ab0: 41 49 4e 54 5f 45 51 20 29 20 63 6f 6e 74 69 6e  AINT_EQ ) contin
5ac0: 75 65 3b 0a 20 20 20 20 69 66 28 20 70 43 6f 6e  ue;.    if( pCon
5ad0: 73 74 72 61 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e  straint->iColumn
5ae0: 3d 3d 34 20 29 20 69 64 78 34 20 3d 20 69 3b 0a  ==4 ) idx4 = i;.
5af0: 20 20 20 20 69 66 28 20 70 43 6f 6e 73 74 72 61      if( pConstra
5b00: 69 6e 74 2d 3e 69 43 6f 6c 75 6d 6e 3d 3d 35 20  int->iColumn==5 
5b10: 29 20 69 64 78 35 20 3d 20 69 3b 0a 20 20 7d 0a  ) idx5 = i;.  }.
5b20: 0a 20 20 69 66 28 20 69 64 78 34 3c 30 20 29 7b  .  if( idx4<0 ){
5b30: 0a 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 69  .    pIdxInfo->i
5b40: 64 78 4e 75 6d 20 3d 20 30 3b 0a 20 20 20 20 70  dxNum = 0;.    p
5b50: 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69 6d 61 74  IdxInfo->estimat
5b60: 65 64 43 6f 73 74 20 3d 20 28 64 6f 75 62 6c 65  edCost = (double
5b70: 29 28 28 28 73 71 6c 69 74 65 33 5f 69 6e 74 36  )(((sqlite3_int6
5b80: 34 29 31 29 20 3c 3c 20 35 30 29 3b 0a 20 20 7d  4)1) << 50);.  }
5b90: 65 6c 73 65 7b 0a 20 20 20 20 70 49 64 78 49 6e  else{.    pIdxIn
5ba0: 66 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55  fo->aConstraintU
5bb0: 73 61 67 65 5b 69 64 78 34 5d 2e 6f 6d 69 74 20  sage[idx4].omit 
5bc0: 3d 20 31 3b 0a 20 20 20 20 70 49 64 78 49 6e 66  = 1;.    pIdxInf
5bd0: 6f 2d 3e 61 43 6f 6e 73 74 72 61 69 6e 74 55 73  o->aConstraintUs
5be0: 61 67 65 5b 69 64 78 34 5d 2e 61 72 67 76 49 6e  age[idx4].argvIn
5bf0: 64 65 78 20 3d 20 31 3b 0a 20 20 20 20 69 66 28  dex = 1;.    if(
5c00: 20 69 64 78 35 3e 3d 30 20 29 7b 0a 20 20 20 20   idx5>=0 ){.    
5c10: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f 6e    pIdxInfo->aCon
5c20: 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 64 78  straintUsage[idx
5c30: 35 5d 2e 6f 6d 69 74 20 3d 20 31 3b 0a 20 20 20  5].omit = 1;.   
5c40: 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 61 43 6f     pIdxInfo->aCo
5c50: 6e 73 74 72 61 69 6e 74 55 73 61 67 65 5b 69 64  nstraintUsage[id
5c60: 78 35 5d 2e 61 72 67 76 49 6e 64 65 78 20 3d 20  x5].argvIndex = 
5c70: 32 3b 0a 20 20 20 20 20 20 70 49 64 78 49 6e 66  2;.      pIdxInf
5c80: 6f 2d 3e 69 64 78 4e 75 6d 20 3d 20 32 3b 0a 20  o->idxNum = 2;. 
5c90: 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65       pIdxInfo->e
5ca0: 73 74 69 6d 61 74 65 64 43 6f 73 74 20 3d 20 31  stimatedCost = 1
5cb0: 30 2e 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  0.0;.    }else{.
5cc0: 20 20 20 20 20 20 70 49 64 78 49 6e 66 6f 2d 3e        pIdxInfo->
5cd0: 69 64 78 4e 75 6d 20 3d 20 31 3b 0a 20 20 20 20  idxNum = 1;.    
5ce0: 20 20 70 49 64 78 49 6e 66 6f 2d 3e 65 73 74 69    pIdxInfo->esti
5cf0: 6d 61 74 65 64 43 6f 73 74 20 3d 20 31 30 30 2e  matedCost = 100.
5d00: 30 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  0;.    }.  }..  
5d10: 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 4f 4b  return SQLITE_OK
5d20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 67 69 73  ;.}../*.** Regis
5d30: 74 65 72 20 74 68 65 20 22 66 73 64 69 72 22 20  ter the "fsdir" 
5d40: 76 69 72 74 75 61 6c 20 74 61 62 6c 65 2e 0a 2a  virtual table..*
5d50: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 73 64  /.static int fsd
5d60: 69 72 52 65 67 69 73 74 65 72 28 73 71 6c 69 74  irRegister(sqlit
5d70: 65 33 20 2a 64 62 29 7b 0a 20 20 73 74 61 74 69  e3 *db){.  stati
5d80: 63 20 73 71 6c 69 74 65 33 5f 6d 6f 64 75 6c 65  c sqlite3_module
5d90: 20 66 73 64 69 72 4d 6f 64 75 6c 65 20 3d 20 7b   fsdirModule = {
5da0: 0a 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20  .    0,         
5db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5dc0: 2f 2a 20 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20  /* iVersion */. 
5dd0: 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20 20     0,           
5de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
5df0: 20 78 43 72 65 61 74 65 20 2a 2f 0a 20 20 20 20   xCreate */.    
5e00: 66 73 64 69 72 43 6f 6e 6e 65 63 74 2c 20 20 20  fsdirConnect,   
5e10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43             /* xC
5e20: 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20 66 73  onnect */.    fs
5e30: 64 69 72 42 65 73 74 49 6e 64 65 78 2c 20 20 20  dirBestIndex,   
5e40: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 73           /* xBes
5e50: 74 49 6e 64 65 78 20 2a 2f 0a 20 20 20 20 66 73  tIndex */.    fs
5e60: 64 69 72 44 69 73 63 6f 6e 6e 65 63 74 2c 20 20  dirDisconnect,  
5e70: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 69 73           /* xDis
5e80: 63 6f 6e 6e 65 63 74 20 2a 2f 0a 20 20 20 20 30  connect */.    0
5e90: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5ea0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 65            /* xDe
5eb0: 73 74 72 6f 79 20 2a 2f 0a 20 20 20 20 66 73 64  stroy */.    fsd
5ec0: 69 72 4f 70 65 6e 2c 20 20 20 20 20 20 20 20 20  irOpen,         
5ed0: 20 20 20 20 20 20 20 20 2f 2a 20 78 4f 70 65 6e          /* xOpen
5ee0: 20 2d 20 6f 70 65 6e 20 61 20 63 75 72 73 6f 72   - open a cursor
5ef0: 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 43 6c 6f   */.    fsdirClo
5f00: 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  se,             
5f10: 20 20 20 2f 2a 20 78 43 6c 6f 73 65 20 2d 20 63     /* xClose - c
5f20: 6c 6f 73 65 20 61 20 63 75 72 73 6f 72 20 2a 2f  lose a cursor */
5f30: 0a 20 20 20 20 66 73 64 69 72 46 69 6c 74 65 72  .    fsdirFilter
5f40: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ,               
5f50: 2f 2a 20 78 46 69 6c 74 65 72 20 2d 20 63 6f 6e  /* xFilter - con
5f60: 66 69 67 75 72 65 20 73 63 61 6e 20 63 6f 6e 73  figure scan cons
5f70: 74 72 61 69 6e 74 73 20 2a 2f 0a 20 20 20 20 66  traints */.    f
5f80: 73 64 69 72 4e 65 78 74 2c 20 20 20 20 20 20 20  sdirNext,       
5f90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 4e 65            /* xNe
5fa0: 78 74 20 2d 20 61 64 76 61 6e 63 65 20 61 20 63  xt - advance a c
5fb0: 75 72 73 6f 72 20 2a 2f 0a 20 20 20 20 66 73 64  ursor */.    fsd
5fc0: 69 72 45 6f 66 2c 20 20 20 20 20 20 20 20 20 20  irEof,          
5fd0: 20 20 20 20 20 20 20 20 2f 2a 20 78 45 6f 66 20          /* xEof 
5fe0: 2d 20 63 68 65 63 6b 20 66 6f 72 20 65 6e 64 20  - check for end 
5ff0: 6f 66 20 73 63 61 6e 20 2a 2f 0a 20 20 20 20 66  of scan */.    f
6000: 73 64 69 72 43 6f 6c 75 6d 6e 2c 20 20 20 20 20  sdirColumn,     
6010: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 6f            /* xCo
6020: 6c 75 6d 6e 20 2d 20 72 65 61 64 20 64 61 74 61  lumn - read data
6030: 20 2a 2f 0a 20 20 20 20 66 73 64 69 72 52 6f 77   */.    fsdirRow
6040: 69 64 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  id,             
6050: 20 20 20 2f 2a 20 78 52 6f 77 69 64 20 2d 20 72     /* xRowid - r
6060: 65 61 64 20 64 61 74 61 20 2a 2f 0a 20 20 20 20  ead data */.    
6070: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
6080: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55             /* xU
6090: 70 64 61 74 65 20 2a 2f 0a 20 20 20 20 30 2c 20  pdate */.    0, 
60a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60b0: 20 20 20 20 20 20 20 20 2f 2a 20 78 42 65 67 69          /* xBegi
60c0: 6e 20 2a 2f 0a 20 20 20 20 30 2c 20 20 20 20 20  n */.    0,     
60d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
60e0: 20 20 20 20 2f 2a 20 78 53 79 6e 63 20 2a 2f 0a      /* xSync */.
60f0: 20 20 20 20 30 2c 20 20 20 20 20 20 20 20 20 20      0,          
6100: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
6110: 2a 20 78 43 6f 6d 6d 69 74 20 2a 2f 0a 20 20 20  * xCommit */.   
6120: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
6130: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
6140: 52 6f 6c 6c 62 61 63 6b 20 2a 2f 0a 20 20 20 20  Rollback */.    
6150: 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  0,              
6160: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46             /* xF
6170: 69 6e 64 4d 65 74 68 6f 64 20 2a 2f 0a 20 20 20  indMethod */.   
6180: 20 30 2c 20 20 20 20 20 20 20 20 20 20 20 20 20   0,             
6190: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
61a0: 52 65 6e 61 6d 65 20 2a 2f 0a 20 20 20 20 30 2c  Rename */.    0,
61b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61c0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 61 76           /* xSav
61d0: 65 70 6f 69 6e 74 20 2a 2f 0a 20 20 20 20 30 2c  epoint */.    0,
61e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
61f0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 52 65 6c           /* xRel
6200: 65 61 73 65 20 2a 2f 0a 20 20 20 20 30 2c 20 20  ease */.    0,  
6210: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6220: 20 20 20 20 20 20 20 2f 2a 20 78 52 6f 6c 6c 62         /* xRollb
6230: 61 63 6b 54 6f 20 2a 2f 0a 20 20 20 20 30 2c 20  ackTo */.    0, 
6240: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6250: 20 20 20 20 20 20 20 20 2f 2a 20 78 53 68 61 64          /* xShad
6260: 6f 77 4e 61 6d 65 20 2a 2f 0a 20 20 7d 3b 0a 0a  owName */.  };..
6270: 20 20 69 6e 74 20 72 63 20 3d 20 73 71 6c 69 74    int rc = sqlit
6280: 65 33 5f 63 72 65 61 74 65 5f 6d 6f 64 75 6c 65  e3_create_module
6290: 28 64 62 2c 20 22 66 73 64 69 72 22 2c 20 26 66  (db, "fsdir", &f
62a0: 73 64 69 72 4d 6f 64 75 6c 65 2c 20 30 29 3b 0a  sdirModule, 0);.
62b0: 20 20 72 65 74 75 72 6e 20 72 63 3b 0a 7d 0a 23    return rc;.}.#
62c0: 65 6c 73 65 20 20 20 20 20 20 20 20 20 2f 2a 20  else         /* 
62d0: 53 51 4c 49 54 45 5f 4f 4d 49 54 5f 56 49 52 54  SQLITE_OMIT_VIRT
62e0: 55 41 4c 54 41 42 4c 45 20 2a 2f 0a 23 20 64 65  UALTABLE */.# de
62f0: 66 69 6e 65 20 66 73 64 69 72 52 65 67 69 73 74  fine fsdirRegist
6300: 65 72 28 78 29 20 53 51 4c 49 54 45 5f 4f 4b 0a  er(x) SQLITE_OK.
6310: 23 65 6e 64 69 66 0a 0a 23 69 66 64 65 66 20 5f  #endif..#ifdef _
6320: 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70 65 63  WIN32.__declspec
6330: 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65 6e 64  (dllexport).#end
6340: 69 66 0a 69 6e 74 20 73 71 6c 69 74 65 33 5f 66  if.int sqlite3_f
6350: 69 6c 65 69 6f 5f 69 6e 69 74 28 0a 20 20 73 71  ileio_init(.  sq
6360: 6c 69 74 65 33 20 2a 64 62 2c 20 0a 20 20 63 68  lite3 *db, .  ch
6370: 61 72 20 2a 2a 70 7a 45 72 72 4d 73 67 2c 20 0a  ar **pzErrMsg, .
6380: 20 20 63 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f    const sqlite3_
6390: 61 70 69 5f 72 6f 75 74 69 6e 65 73 20 2a 70 41  api_routines *pA
63a0: 70 69 0a 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d  pi.){.  int rc =
63b0: 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20 53 51   SQLITE_OK;.  SQ
63c0: 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f 4e 5f 49  LITE_EXTENSION_I
63d0: 4e 49 54 32 28 70 41 70 69 29 3b 0a 20 20 28 76  NIT2(pApi);.  (v
63e0: 6f 69 64 29 70 7a 45 72 72 4d 73 67 3b 20 20 2f  oid)pzErrMsg;  /
63f0: 2a 20 55 6e 75 73 65 64 20 70 61 72 61 6d 65 74  * Unused paramet
6400: 65 72 20 2a 2f 0a 20 20 72 63 20 3d 20 73 71 6c  er */.  rc = sql
6410: 69 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63  ite3_create_func
6420: 74 69 6f 6e 28 64 62 2c 20 22 72 65 61 64 66 69  tion(db, "readfi
6430: 6c 65 22 2c 20 31 2c 20 53 51 4c 49 54 45 5f 55  le", 1, SQLITE_U
6440: 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20 20  TF8, 0,.        
6450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6460: 20 20 20 20 20 20 20 72 65 61 64 66 69 6c 65 46         readfileF
6470: 75 6e 63 2c 20 30 2c 20 30 29 3b 0a 20 20 69 66  unc, 0, 0);.  if
6480: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
6490: 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69  ){.    rc = sqli
64a0: 74 65 33 5f 63 72 65 61 74 65 5f 66 75 6e 63 74  te3_create_funct
64b0: 69 6f 6e 28 64 62 2c 20 22 77 72 69 74 65 66 69  ion(db, "writefi
64c0: 6c 65 22 2c 20 2d 31 2c 20 53 51 4c 49 54 45 5f  le", -1, SQLITE_
64d0: 55 54 46 38 2c 20 30 2c 0a 20 20 20 20 20 20 20  UTF8, 0,.       
64e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
64f0: 20 20 20 20 20 20 20 20 20 20 77 72 69 74 65 66            writef
6500: 69 6c 65 46 75 6e 63 2c 20 30 2c 20 30 29 3b 0a  ileFunc, 0, 0);.
6510: 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53 51    }.  if( rc==SQ
6520: 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 72  LITE_OK ){.    r
6530: 63 20 3d 20 73 71 6c 69 74 65 33 5f 63 72 65 61  c = sqlite3_crea
6540: 74 65 5f 66 75 6e 63 74 69 6f 6e 28 64 62 2c 20  te_function(db, 
6550: 22 6c 73 6d 6f 64 65 22 2c 20 31 2c 20 53 51 4c  "lsmode", 1, SQL
6560: 49 54 45 5f 55 54 46 38 2c 20 30 2c 0a 20 20 20  ITE_UTF8, 0,.   
6570: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
6580: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c 73                ls
6590: 4d 6f 64 65 46 75 6e 63 2c 20 30 2c 20 30 29 3b  ModeFunc, 0, 0);
65a0: 0a 20 20 7d 0a 20 20 69 66 28 20 72 63 3d 3d 53  .  }.  if( rc==S
65b0: 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20  QLITE_OK ){.    
65c0: 72 63 20 3d 20 66 73 64 69 72 52 65 67 69 73 74  rc = fsdirRegist
65d0: 65 72 28 64 62 29 3b 0a 20 20 7d 0a 20 20 72 65  er(db);.  }.  re
65e0: 74 75 72 6e 20 72 63 3b 0a 7d 0a                 turn rc;.}.