xref: /sqlite-3.40.0/ext/misc/fileio.c (revision aeb4e6ee)
1 /*
2 ** 2014-06-13
3 **
4 ** The author disclaims copyright to this source code.  In place of
5 ** a legal notice, here is a blessing:
6 **
7 **    May you do good and not evil.
8 **    May you find forgiveness for yourself and forgive others.
9 **    May you share freely, never taking more than you give.
10 **
11 ******************************************************************************
12 **
13 ** This SQLite extension implements SQL functions readfile() and
14 ** writefile(), and eponymous virtual type "fsdir".
15 **
16 ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
17 **
18 **   If neither of the optional arguments is present, then this UDF
19 **   function writes blob DATA to file FILE. If successful, the number
20 **   of bytes written is returned. If an error occurs, NULL is returned.
21 **
22 **   If the first option argument - MODE - is present, then it must
23 **   be passed an integer value that corresponds to a POSIX mode
24 **   value (file type + permissions, as returned in the stat.st_mode
25 **   field by the stat() system call). Three types of files may
26 **   be written/created:
27 **
28 **     regular files:  (mode & 0170000)==0100000
29 **     symbolic links: (mode & 0170000)==0120000
30 **     directories:    (mode & 0170000)==0040000
31 **
32 **   For a directory, the DATA is ignored. For a symbolic link, it is
33 **   interpreted as text and used as the target of the link. For a
34 **   regular file, it is interpreted as a blob and written into the
35 **   named file. Regardless of the type of file, its permissions are
36 **   set to (mode & 0777) before returning.
37 **
38 **   If the optional MTIME argument is present, then it is interpreted
39 **   as an integer - the number of seconds since the unix epoch. The
40 **   modification-time of the target file is set to this value before
41 **   returning.
42 **
43 **   If three or more arguments are passed to this function and an
44 **   error is encountered, an exception is raised.
45 **
46 ** READFILE(FILE):
47 **
48 **   Read and return the contents of file FILE (type blob) from disk.
49 **
50 ** FSDIR:
51 **
52 **   Used as follows:
53 **
54 **     SELECT * FROM fsdir($path [, $dir]);
55 **
56 **   Parameter $path is an absolute or relative pathname. If the file that it
57 **   refers to does not exist, it is an error. If the path refers to a regular
58 **   file or symbolic link, it returns a single row. Or, if the path refers
59 **   to a directory, it returns one row for the directory, and one row for each
60 **   file within the hierarchy rooted at $path.
61 **
62 **   Each row has the following columns:
63 **
64 **     name:  Path to file or directory (text value).
65 **     mode:  Value of stat.st_mode for directory entry (an integer).
66 **     mtime: Value of stat.st_mtime for directory entry (an integer).
67 **     data:  For a regular file, a blob containing the file data. For a
68 **            symlink, a text value containing the text of the link. For a
69 **            directory, NULL.
70 **
71 **   If a non-NULL value is specified for the optional $dir parameter and
72 **   $path is a relative path, then $path is interpreted relative to $dir.
73 **   And the paths returned in the "name" column of the table are also
74 **   relative to directory $dir.
75 */
76 #include "sqlite3ext.h"
77 SQLITE_EXTENSION_INIT1
78 #include <stdio.h>
79 #include <string.h>
80 #include <assert.h>
81 
82 #include <sys/types.h>
83 #include <sys/stat.h>
84 #include <fcntl.h>
85 #if !defined(_WIN32) && !defined(WIN32)
86 #  include <unistd.h>
87 #  include <dirent.h>
88 #  include <utime.h>
89 #  include <sys/time.h>
90 #else
91 #  include "windows.h"
92 #  include <io.h>
93 #  include <direct.h>
94 #  include "test_windirent.h"
95 #  define dirent DIRENT
96 #  ifndef chmod
97 #    define chmod _chmod
98 #  endif
99 #  ifndef stat
100 #    define stat _stat
101 #  endif
102 #  define mkdir(path,mode) _mkdir(path)
103 #  define lstat(path,buf) stat(path,buf)
104 #endif
105 #include <time.h>
106 #include <errno.h>
107 
108 
109 /*
110 ** Structure of the fsdir() table-valued function
111 */
112                  /*    0    1    2     3    4           5             */
113 #define FSDIR_SCHEMA "(name,mode,mtime,data,path HIDDEN,dir HIDDEN)"
114 #define FSDIR_COLUMN_NAME     0     /* Name of the file */
115 #define FSDIR_COLUMN_MODE     1     /* Access mode */
116 #define FSDIR_COLUMN_MTIME    2     /* Last modification time */
117 #define FSDIR_COLUMN_DATA     3     /* File content */
118 #define FSDIR_COLUMN_PATH     4     /* Path to top of search */
119 #define FSDIR_COLUMN_DIR      5     /* Path is relative to this directory */
120 
121 
122 /*
123 ** Set the result stored by context ctx to a blob containing the
124 ** contents of file zName.  Or, leave the result unchanged (NULL)
125 ** if the file does not exist or is unreadable.
126 **
127 ** If the file exceeds the SQLite blob size limit, through an
128 ** SQLITE_TOOBIG error.
129 **
130 ** Throw an SQLITE_IOERR if there are difficulties pulling the file
131 ** off of disk.
132 */
133 static void readFileContents(sqlite3_context *ctx, const char *zName){
134   FILE *in;
135   sqlite3_int64 nIn;
136   void *pBuf;
137   sqlite3 *db;
138   int mxBlob;
139 
140   in = fopen(zName, "rb");
141   if( in==0 ){
142     /* File does not exist or is unreadable. Leave the result set to NULL. */
143     return;
144   }
145   fseek(in, 0, SEEK_END);
146   nIn = ftell(in);
147   rewind(in);
148   db = sqlite3_context_db_handle(ctx);
149   mxBlob = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1);
150   if( nIn>mxBlob ){
151     sqlite3_result_error_code(ctx, SQLITE_TOOBIG);
152     fclose(in);
153     return;
154   }
155   pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
156   if( pBuf==0 ){
157     sqlite3_result_error_nomem(ctx);
158     fclose(in);
159     return;
160   }
161   if( nIn==(sqlite3_int64)fread(pBuf, 1, (size_t)nIn, in) ){
162     sqlite3_result_blob64(ctx, pBuf, nIn, sqlite3_free);
163   }else{
164     sqlite3_result_error_code(ctx, SQLITE_IOERR);
165     sqlite3_free(pBuf);
166   }
167   fclose(in);
168 }
169 
170 /*
171 ** Implementation of the "readfile(X)" SQL function.  The entire content
172 ** of the file named X is read and returned as a BLOB.  NULL is returned
173 ** if the file does not exist or is unreadable.
174 */
175 static void readfileFunc(
176   sqlite3_context *context,
177   int argc,
178   sqlite3_value **argv
179 ){
180   const char *zName;
181   (void)(argc);  /* Unused parameter */
182   zName = (const char*)sqlite3_value_text(argv[0]);
183   if( zName==0 ) return;
184   readFileContents(context, zName);
185 }
186 
187 /*
188 ** Set the error message contained in context ctx to the results of
189 ** vprintf(zFmt, ...).
190 */
191 static void ctxErrorMsg(sqlite3_context *ctx, const char *zFmt, ...){
192   char *zMsg = 0;
193   va_list ap;
194   va_start(ap, zFmt);
195   zMsg = sqlite3_vmprintf(zFmt, ap);
196   sqlite3_result_error(ctx, zMsg, -1);
197   sqlite3_free(zMsg);
198   va_end(ap);
199 }
200 
201 #if defined(_WIN32)
202 /*
203 ** This function is designed to convert a Win32 FILETIME structure into the
204 ** number of seconds since the Unix Epoch (1970-01-01 00:00:00 UTC).
205 */
206 static sqlite3_uint64 fileTimeToUnixTime(
207   LPFILETIME pFileTime
208 ){
209   SYSTEMTIME epochSystemTime;
210   ULARGE_INTEGER epochIntervals;
211   FILETIME epochFileTime;
212   ULARGE_INTEGER fileIntervals;
213 
214   memset(&epochSystemTime, 0, sizeof(SYSTEMTIME));
215   epochSystemTime.wYear = 1970;
216   epochSystemTime.wMonth = 1;
217   epochSystemTime.wDay = 1;
218   SystemTimeToFileTime(&epochSystemTime, &epochFileTime);
219   epochIntervals.LowPart = epochFileTime.dwLowDateTime;
220   epochIntervals.HighPart = epochFileTime.dwHighDateTime;
221 
222   fileIntervals.LowPart = pFileTime->dwLowDateTime;
223   fileIntervals.HighPart = pFileTime->dwHighDateTime;
224 
225   return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
226 }
227 
228 /*
229 ** This function attempts to normalize the time values found in the stat()
230 ** buffer to UTC.  This is necessary on Win32, where the runtime library
231 ** appears to return these values as local times.
232 */
233 static void statTimesToUtc(
234   const char *zPath,
235   struct stat *pStatBuf
236 ){
237   HANDLE hFindFile;
238   WIN32_FIND_DATAW fd;
239   LPWSTR zUnicodeName;
240   extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
241   zUnicodeName = sqlite3_win32_utf8_to_unicode(zPath);
242   if( zUnicodeName ){
243     memset(&fd, 0, sizeof(WIN32_FIND_DATAW));
244     hFindFile = FindFirstFileW(zUnicodeName, &fd);
245     if( hFindFile!=NULL ){
246       pStatBuf->st_ctime = (time_t)fileTimeToUnixTime(&fd.ftCreationTime);
247       pStatBuf->st_atime = (time_t)fileTimeToUnixTime(&fd.ftLastAccessTime);
248       pStatBuf->st_mtime = (time_t)fileTimeToUnixTime(&fd.ftLastWriteTime);
249       FindClose(hFindFile);
250     }
251     sqlite3_free(zUnicodeName);
252   }
253 }
254 #endif
255 
256 /*
257 ** This function is used in place of stat().  On Windows, special handling
258 ** is required in order for the included time to be returned as UTC.  On all
259 ** other systems, this function simply calls stat().
260 */
261 static int fileStat(
262   const char *zPath,
263   struct stat *pStatBuf
264 ){
265 #if defined(_WIN32)
266   int rc = stat(zPath, pStatBuf);
267   if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
268   return rc;
269 #else
270   return stat(zPath, pStatBuf);
271 #endif
272 }
273 
274 /*
275 ** This function is used in place of lstat().  On Windows, special handling
276 ** is required in order for the included time to be returned as UTC.  On all
277 ** other systems, this function simply calls lstat().
278 */
279 static int fileLinkStat(
280   const char *zPath,
281   struct stat *pStatBuf
282 ){
283 #if defined(_WIN32)
284   int rc = lstat(zPath, pStatBuf);
285   if( rc==0 ) statTimesToUtc(zPath, pStatBuf);
286   return rc;
287 #else
288   return lstat(zPath, pStatBuf);
289 #endif
290 }
291 
292 /*
293 ** Argument zFile is the name of a file that will be created and/or written
294 ** by SQL function writefile(). This function ensures that the directory
295 ** zFile will be written to exists, creating it if required. The permissions
296 ** for any path components created by this function are set in accordance
297 ** with the current umask.
298 **
299 ** If an OOM condition is encountered, SQLITE_NOMEM is returned. Otherwise,
300 ** SQLITE_OK is returned if the directory is successfully created, or
301 ** SQLITE_ERROR otherwise.
302 */
303 static int makeDirectory(
304   const char *zFile
305 ){
306   char *zCopy = sqlite3_mprintf("%s", zFile);
307   int rc = SQLITE_OK;
308 
309   if( zCopy==0 ){
310     rc = SQLITE_NOMEM;
311   }else{
312     int nCopy = (int)strlen(zCopy);
313     int i = 1;
314 
315     while( rc==SQLITE_OK ){
316       struct stat sStat;
317       int rc2;
318 
319       for(; zCopy[i]!='/' && i<nCopy; i++);
320       if( i==nCopy ) break;
321       zCopy[i] = '\0';
322 
323       rc2 = fileStat(zCopy, &sStat);
324       if( rc2!=0 ){
325         if( mkdir(zCopy, 0777) ) rc = SQLITE_ERROR;
326       }else{
327         if( !S_ISDIR(sStat.st_mode) ) rc = SQLITE_ERROR;
328       }
329       zCopy[i] = '/';
330       i++;
331     }
332 
333     sqlite3_free(zCopy);
334   }
335 
336   return rc;
337 }
338 
339 /*
340 ** This function does the work for the writefile() UDF. Refer to
341 ** header comments at the top of this file for details.
342 */
343 static int writeFile(
344   sqlite3_context *pCtx,          /* Context to return bytes written in */
345   const char *zFile,              /* File to write */
346   sqlite3_value *pData,           /* Data to write */
347   mode_t mode,                    /* MODE parameter passed to writefile() */
348   sqlite3_int64 mtime             /* MTIME parameter (or -1 to not set time) */
349 ){
350 #if !defined(_WIN32) && !defined(WIN32)
351   if( S_ISLNK(mode) ){
352     const char *zTo = (const char*)sqlite3_value_text(pData);
353     if( symlink(zTo, zFile)<0 ) return 1;
354   }else
355 #endif
356   {
357     if( S_ISDIR(mode) ){
358       if( mkdir(zFile, mode) ){
359         /* The mkdir() call to create the directory failed. This might not
360         ** be an error though - if there is already a directory at the same
361         ** path and either the permissions already match or can be changed
362         ** to do so using chmod(), it is not an error.  */
363         struct stat sStat;
364         if( errno!=EEXIST
365          || 0!=fileStat(zFile, &sStat)
366          || !S_ISDIR(sStat.st_mode)
367          || ((sStat.st_mode&0777)!=(mode&0777) && 0!=chmod(zFile, mode&0777))
368         ){
369           return 1;
370         }
371       }
372     }else{
373       sqlite3_int64 nWrite = 0;
374       const char *z;
375       int rc = 0;
376       FILE *out = fopen(zFile, "wb");
377       if( out==0 ) return 1;
378       z = (const char*)sqlite3_value_blob(pData);
379       if( z ){
380         sqlite3_int64 n = fwrite(z, 1, sqlite3_value_bytes(pData), out);
381         nWrite = sqlite3_value_bytes(pData);
382         if( nWrite!=n ){
383           rc = 1;
384         }
385       }
386       fclose(out);
387       if( rc==0 && mode && chmod(zFile, mode & 0777) ){
388         rc = 1;
389       }
390       if( rc ) return 2;
391       sqlite3_result_int64(pCtx, nWrite);
392     }
393   }
394 
395   if( mtime>=0 ){
396 #if defined(_WIN32)
397 #if !SQLITE_OS_WINRT
398     /* Windows */
399     FILETIME lastAccess;
400     FILETIME lastWrite;
401     SYSTEMTIME currentTime;
402     LONGLONG intervals;
403     HANDLE hFile;
404     LPWSTR zUnicodeName;
405     extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
406 
407     GetSystemTime(&currentTime);
408     SystemTimeToFileTime(&currentTime, &lastAccess);
409     intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
410     lastWrite.dwLowDateTime = (DWORD)intervals;
411     lastWrite.dwHighDateTime = intervals >> 32;
412     zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
413     if( zUnicodeName==0 ){
414       return 1;
415     }
416     hFile = CreateFileW(
417       zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
418       FILE_FLAG_BACKUP_SEMANTICS, NULL
419     );
420     sqlite3_free(zUnicodeName);
421     if( hFile!=INVALID_HANDLE_VALUE ){
422       BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
423       CloseHandle(hFile);
424       return !bResult;
425     }else{
426       return 1;
427     }
428 #endif
429 #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
430     /* Recent unix */
431     struct timespec times[2];
432     times[0].tv_nsec = times[1].tv_nsec = 0;
433     times[0].tv_sec = time(0);
434     times[1].tv_sec = mtime;
435     if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
436       return 1;
437     }
438 #else
439     /* Legacy unix */
440     struct timeval times[2];
441     times[0].tv_usec = times[1].tv_usec = 0;
442     times[0].tv_sec = time(0);
443     times[1].tv_sec = mtime;
444     if( utimes(zFile, times) ){
445       return 1;
446     }
447 #endif
448   }
449 
450   return 0;
451 }
452 
453 /*
454 ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
455 ** Refer to header comments at the top of this file for details.
456 */
457 static void writefileFunc(
458   sqlite3_context *context,
459   int argc,
460   sqlite3_value **argv
461 ){
462   const char *zFile;
463   mode_t mode = 0;
464   int res;
465   sqlite3_int64 mtime = -1;
466 
467   if( argc<2 || argc>4 ){
468     sqlite3_result_error(context,
469         "wrong number of arguments to function writefile()", -1
470     );
471     return;
472   }
473 
474   zFile = (const char*)sqlite3_value_text(argv[0]);
475   if( zFile==0 ) return;
476   if( argc>=3 ){
477     mode = (mode_t)sqlite3_value_int(argv[2]);
478   }
479   if( argc==4 ){
480     mtime = sqlite3_value_int64(argv[3]);
481   }
482 
483   res = writeFile(context, zFile, argv[1], mode, mtime);
484   if( res==1 && errno==ENOENT ){
485     if( makeDirectory(zFile)==SQLITE_OK ){
486       res = writeFile(context, zFile, argv[1], mode, mtime);
487     }
488   }
489 
490   if( argc>2 && res!=0 ){
491     if( S_ISLNK(mode) ){
492       ctxErrorMsg(context, "failed to create symlink: %s", zFile);
493     }else if( S_ISDIR(mode) ){
494       ctxErrorMsg(context, "failed to create directory: %s", zFile);
495     }else{
496       ctxErrorMsg(context, "failed to write file: %s", zFile);
497     }
498   }
499 }
500 
501 /*
502 ** SQL function:   lsmode(MODE)
503 **
504 ** Given a numberic st_mode from stat(), convert it into a human-readable
505 ** text string in the style of "ls -l".
506 */
507 static void lsModeFunc(
508   sqlite3_context *context,
509   int argc,
510   sqlite3_value **argv
511 ){
512   int i;
513   int iMode = sqlite3_value_int(argv[0]);
514   char z[16];
515   (void)argc;
516   if( S_ISLNK(iMode) ){
517     z[0] = 'l';
518   }else if( S_ISREG(iMode) ){
519     z[0] = '-';
520   }else if( S_ISDIR(iMode) ){
521     z[0] = 'd';
522   }else{
523     z[0] = '?';
524   }
525   for(i=0; i<3; i++){
526     int m = (iMode >> ((2-i)*3));
527     char *a = &z[1 + i*3];
528     a[0] = (m & 0x4) ? 'r' : '-';
529     a[1] = (m & 0x2) ? 'w' : '-';
530     a[2] = (m & 0x1) ? 'x' : '-';
531   }
532   z[10] = '\0';
533   sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
534 }
535 
536 #ifndef SQLITE_OMIT_VIRTUALTABLE
537 
538 /*
539 ** Cursor type for recursively iterating through a directory structure.
540 */
541 typedef struct fsdir_cursor fsdir_cursor;
542 typedef struct FsdirLevel FsdirLevel;
543 
544 struct FsdirLevel {
545   DIR *pDir;                 /* From opendir() */
546   char *zDir;                /* Name of directory (nul-terminated) */
547 };
548 
549 struct fsdir_cursor {
550   sqlite3_vtab_cursor base;  /* Base class - must be first */
551 
552   int nLvl;                  /* Number of entries in aLvl[] array */
553   int iLvl;                  /* Index of current entry */
554   FsdirLevel *aLvl;          /* Hierarchy of directories being traversed */
555 
556   const char *zBase;
557   int nBase;
558 
559   struct stat sStat;         /* Current lstat() results */
560   char *zPath;               /* Path to current entry */
561   sqlite3_int64 iRowid;      /* Current rowid */
562 };
563 
564 typedef struct fsdir_tab fsdir_tab;
565 struct fsdir_tab {
566   sqlite3_vtab base;         /* Base class - must be first */
567 };
568 
569 /*
570 ** Construct a new fsdir virtual table object.
571 */
572 static int fsdirConnect(
573   sqlite3 *db,
574   void *pAux,
575   int argc, const char *const*argv,
576   sqlite3_vtab **ppVtab,
577   char **pzErr
578 ){
579   fsdir_tab *pNew = 0;
580   int rc;
581   (void)pAux;
582   (void)argc;
583   (void)argv;
584   (void)pzErr;
585   rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
586   if( rc==SQLITE_OK ){
587     pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
588     if( pNew==0 ) return SQLITE_NOMEM;
589     memset(pNew, 0, sizeof(*pNew));
590     sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
591   }
592   *ppVtab = (sqlite3_vtab*)pNew;
593   return rc;
594 }
595 
596 /*
597 ** This method is the destructor for fsdir vtab objects.
598 */
599 static int fsdirDisconnect(sqlite3_vtab *pVtab){
600   sqlite3_free(pVtab);
601   return SQLITE_OK;
602 }
603 
604 /*
605 ** Constructor for a new fsdir_cursor object.
606 */
607 static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
608   fsdir_cursor *pCur;
609   (void)p;
610   pCur = sqlite3_malloc( sizeof(*pCur) );
611   if( pCur==0 ) return SQLITE_NOMEM;
612   memset(pCur, 0, sizeof(*pCur));
613   pCur->iLvl = -1;
614   *ppCursor = &pCur->base;
615   return SQLITE_OK;
616 }
617 
618 /*
619 ** Reset a cursor back to the state it was in when first returned
620 ** by fsdirOpen().
621 */
622 static void fsdirResetCursor(fsdir_cursor *pCur){
623   int i;
624   for(i=0; i<=pCur->iLvl; i++){
625     FsdirLevel *pLvl = &pCur->aLvl[i];
626     if( pLvl->pDir ) closedir(pLvl->pDir);
627     sqlite3_free(pLvl->zDir);
628   }
629   sqlite3_free(pCur->zPath);
630   sqlite3_free(pCur->aLvl);
631   pCur->aLvl = 0;
632   pCur->zPath = 0;
633   pCur->zBase = 0;
634   pCur->nBase = 0;
635   pCur->nLvl = 0;
636   pCur->iLvl = -1;
637   pCur->iRowid = 1;
638 }
639 
640 /*
641 ** Destructor for an fsdir_cursor.
642 */
643 static int fsdirClose(sqlite3_vtab_cursor *cur){
644   fsdir_cursor *pCur = (fsdir_cursor*)cur;
645 
646   fsdirResetCursor(pCur);
647   sqlite3_free(pCur);
648   return SQLITE_OK;
649 }
650 
651 /*
652 ** Set the error message for the virtual table associated with cursor
653 ** pCur to the results of vprintf(zFmt, ...).
654 */
655 static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
656   va_list ap;
657   va_start(ap, zFmt);
658   pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
659   va_end(ap);
660 }
661 
662 
663 /*
664 ** Advance an fsdir_cursor to its next row of output.
665 */
666 static int fsdirNext(sqlite3_vtab_cursor *cur){
667   fsdir_cursor *pCur = (fsdir_cursor*)cur;
668   mode_t m = pCur->sStat.st_mode;
669 
670   pCur->iRowid++;
671   if( S_ISDIR(m) ){
672     /* Descend into this directory */
673     int iNew = pCur->iLvl + 1;
674     FsdirLevel *pLvl;
675     if( iNew>=pCur->nLvl ){
676       int nNew = iNew+1;
677       sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
678       FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
679       if( aNew==0 ) return SQLITE_NOMEM;
680       memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
681       pCur->aLvl = aNew;
682       pCur->nLvl = nNew;
683     }
684     pCur->iLvl = iNew;
685     pLvl = &pCur->aLvl[iNew];
686 
687     pLvl->zDir = pCur->zPath;
688     pCur->zPath = 0;
689     pLvl->pDir = opendir(pLvl->zDir);
690     if( pLvl->pDir==0 ){
691       fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
692       return SQLITE_ERROR;
693     }
694   }
695 
696   while( pCur->iLvl>=0 ){
697     FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
698     struct dirent *pEntry = readdir(pLvl->pDir);
699     if( pEntry ){
700       if( pEntry->d_name[0]=='.' ){
701        if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
702        if( pEntry->d_name[1]=='\0' ) continue;
703       }
704       sqlite3_free(pCur->zPath);
705       pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
706       if( pCur->zPath==0 ) return SQLITE_NOMEM;
707       if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
708         fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
709         return SQLITE_ERROR;
710       }
711       return SQLITE_OK;
712     }
713     closedir(pLvl->pDir);
714     sqlite3_free(pLvl->zDir);
715     pLvl->pDir = 0;
716     pLvl->zDir = 0;
717     pCur->iLvl--;
718   }
719 
720   /* EOF */
721   sqlite3_free(pCur->zPath);
722   pCur->zPath = 0;
723   return SQLITE_OK;
724 }
725 
726 /*
727 ** Return values of columns for the row at which the series_cursor
728 ** is currently pointing.
729 */
730 static int fsdirColumn(
731   sqlite3_vtab_cursor *cur,   /* The cursor */
732   sqlite3_context *ctx,       /* First argument to sqlite3_result_...() */
733   int i                       /* Which column to return */
734 ){
735   fsdir_cursor *pCur = (fsdir_cursor*)cur;
736   switch( i ){
737     case FSDIR_COLUMN_NAME: {
738       sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
739       break;
740     }
741 
742     case FSDIR_COLUMN_MODE:
743       sqlite3_result_int64(ctx, pCur->sStat.st_mode);
744       break;
745 
746     case FSDIR_COLUMN_MTIME:
747       sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
748       break;
749 
750     case FSDIR_COLUMN_DATA: {
751       mode_t m = pCur->sStat.st_mode;
752       if( S_ISDIR(m) ){
753         sqlite3_result_null(ctx);
754 #if !defined(_WIN32) && !defined(WIN32)
755       }else if( S_ISLNK(m) ){
756         char aStatic[64];
757         char *aBuf = aStatic;
758         sqlite3_int64 nBuf = 64;
759         int n;
760 
761         while( 1 ){
762           n = readlink(pCur->zPath, aBuf, nBuf);
763           if( n<nBuf ) break;
764           if( aBuf!=aStatic ) sqlite3_free(aBuf);
765           nBuf = nBuf*2;
766           aBuf = sqlite3_malloc64(nBuf);
767           if( aBuf==0 ){
768             sqlite3_result_error_nomem(ctx);
769             return SQLITE_NOMEM;
770           }
771         }
772 
773         sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
774         if( aBuf!=aStatic ) sqlite3_free(aBuf);
775 #endif
776       }else{
777         readFileContents(ctx, pCur->zPath);
778       }
779     }
780     case FSDIR_COLUMN_PATH:
781     default: {
782       /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
783       ** always return their values as NULL */
784       break;
785     }
786   }
787   return SQLITE_OK;
788 }
789 
790 /*
791 ** Return the rowid for the current row. In this implementation, the
792 ** first row returned is assigned rowid value 1, and each subsequent
793 ** row a value 1 more than that of the previous.
794 */
795 static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
796   fsdir_cursor *pCur = (fsdir_cursor*)cur;
797   *pRowid = pCur->iRowid;
798   return SQLITE_OK;
799 }
800 
801 /*
802 ** Return TRUE if the cursor has been moved off of the last
803 ** row of output.
804 */
805 static int fsdirEof(sqlite3_vtab_cursor *cur){
806   fsdir_cursor *pCur = (fsdir_cursor*)cur;
807   return (pCur->zPath==0);
808 }
809 
810 /*
811 ** xFilter callback.
812 **
813 ** idxNum==1   PATH parameter only
814 ** idxNum==2   Both PATH and DIR supplied
815 */
816 static int fsdirFilter(
817   sqlite3_vtab_cursor *cur,
818   int idxNum, const char *idxStr,
819   int argc, sqlite3_value **argv
820 ){
821   const char *zDir = 0;
822   fsdir_cursor *pCur = (fsdir_cursor*)cur;
823   (void)idxStr;
824   fsdirResetCursor(pCur);
825 
826   if( idxNum==0 ){
827     fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
828     return SQLITE_ERROR;
829   }
830 
831   assert( argc==idxNum && (argc==1 || argc==2) );
832   zDir = (const char*)sqlite3_value_text(argv[0]);
833   if( zDir==0 ){
834     fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
835     return SQLITE_ERROR;
836   }
837   if( argc==2 ){
838     pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
839   }
840   if( pCur->zBase ){
841     pCur->nBase = (int)strlen(pCur->zBase)+1;
842     pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
843   }else{
844     pCur->zPath = sqlite3_mprintf("%s", zDir);
845   }
846 
847   if( pCur->zPath==0 ){
848     return SQLITE_NOMEM;
849   }
850   if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
851     fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
852     return SQLITE_ERROR;
853   }
854 
855   return SQLITE_OK;
856 }
857 
858 /*
859 ** SQLite will invoke this method one or more times while planning a query
860 ** that uses the generate_series virtual table.  This routine needs to create
861 ** a query plan for each invocation and compute an estimated cost for that
862 ** plan.
863 **
864 ** In this implementation idxNum is used to represent the
865 ** query plan.  idxStr is unused.
866 **
867 ** The query plan is represented by values of idxNum:
868 **
869 **  (1)  The path value is supplied by argv[0]
870 **  (2)  Path is in argv[0] and dir is in argv[1]
871 */
872 static int fsdirBestIndex(
873   sqlite3_vtab *tab,
874   sqlite3_index_info *pIdxInfo
875 ){
876   int i;                 /* Loop over constraints */
877   int idxPath = -1;      /* Index in pIdxInfo->aConstraint of PATH= */
878   int idxDir = -1;       /* Index in pIdxInfo->aConstraint of DIR= */
879   int seenPath = 0;      /* True if an unusable PATH= constraint is seen */
880   int seenDir = 0;       /* True if an unusable DIR= constraint is seen */
881   const struct sqlite3_index_constraint *pConstraint;
882 
883   (void)tab;
884   pConstraint = pIdxInfo->aConstraint;
885   for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
886     if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
887     switch( pConstraint->iColumn ){
888       case FSDIR_COLUMN_PATH: {
889         if( pConstraint->usable ){
890           idxPath = i;
891           seenPath = 0;
892         }else if( idxPath<0 ){
893           seenPath = 1;
894         }
895         break;
896       }
897       case FSDIR_COLUMN_DIR: {
898         if( pConstraint->usable ){
899           idxDir = i;
900           seenDir = 0;
901         }else if( idxDir<0 ){
902           seenDir = 1;
903         }
904         break;
905       }
906     }
907   }
908   if( seenPath || seenDir ){
909     /* If input parameters are unusable, disallow this plan */
910     return SQLITE_CONSTRAINT;
911   }
912 
913   if( idxPath<0 ){
914     pIdxInfo->idxNum = 0;
915     /* The pIdxInfo->estimatedCost should have been initialized to a huge
916     ** number.  Leave it unchanged. */
917     pIdxInfo->estimatedRows = 0x7fffffff;
918   }else{
919     pIdxInfo->aConstraintUsage[idxPath].omit = 1;
920     pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
921     if( idxDir>=0 ){
922       pIdxInfo->aConstraintUsage[idxDir].omit = 1;
923       pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
924       pIdxInfo->idxNum = 2;
925       pIdxInfo->estimatedCost = 10.0;
926     }else{
927       pIdxInfo->idxNum = 1;
928       pIdxInfo->estimatedCost = 100.0;
929     }
930   }
931 
932   return SQLITE_OK;
933 }
934 
935 /*
936 ** Register the "fsdir" virtual table.
937 */
938 static int fsdirRegister(sqlite3 *db){
939   static sqlite3_module fsdirModule = {
940     0,                         /* iVersion */
941     0,                         /* xCreate */
942     fsdirConnect,              /* xConnect */
943     fsdirBestIndex,            /* xBestIndex */
944     fsdirDisconnect,           /* xDisconnect */
945     0,                         /* xDestroy */
946     fsdirOpen,                 /* xOpen - open a cursor */
947     fsdirClose,                /* xClose - close a cursor */
948     fsdirFilter,               /* xFilter - configure scan constraints */
949     fsdirNext,                 /* xNext - advance a cursor */
950     fsdirEof,                  /* xEof - check for end of scan */
951     fsdirColumn,               /* xColumn - read data */
952     fsdirRowid,                /* xRowid - read data */
953     0,                         /* xUpdate */
954     0,                         /* xBegin */
955     0,                         /* xSync */
956     0,                         /* xCommit */
957     0,                         /* xRollback */
958     0,                         /* xFindMethod */
959     0,                         /* xRename */
960     0,                         /* xSavepoint */
961     0,                         /* xRelease */
962     0,                         /* xRollbackTo */
963     0,                         /* xShadowName */
964   };
965 
966   int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
967   return rc;
968 }
969 #else         /* SQLITE_OMIT_VIRTUALTABLE */
970 # define fsdirRegister(x) SQLITE_OK
971 #endif
972 
973 #ifdef _WIN32
974 __declspec(dllexport)
975 #endif
976 int sqlite3_fileio_init(
977   sqlite3 *db,
978   char **pzErrMsg,
979   const sqlite3_api_routines *pApi
980 ){
981   int rc = SQLITE_OK;
982   SQLITE_EXTENSION_INIT2(pApi);
983   (void)pzErrMsg;  /* Unused parameter */
984   rc = sqlite3_create_function(db, "readfile", 1,
985                                SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
986                                readfileFunc, 0, 0);
987   if( rc==SQLITE_OK ){
988     rc = sqlite3_create_function(db, "writefile", -1,
989                                  SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
990                                  writefileFunc, 0, 0);
991   }
992   if( rc==SQLITE_OK ){
993     rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
994                                  lsModeFunc, 0, 0);
995   }
996   if( rc==SQLITE_OK ){
997     rc = fsdirRegister(db);
998   }
999   return rc;
1000 }
1001