Snapshot of upstream SQLite 3.31.0
[sqlcipher.git] / ext / misc / fileio.c
blob1335229f9e993d0af7fd1319655c1c327d836c3f
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.
11 ******************************************************************************
13 ** This SQLite extension implements SQL functions readfile() and
14 ** writefile(), and eponymous virtual type "fsdir".
16 ** WRITEFILE(FILE, DATA [, MODE [, MTIME]]):
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.
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:
28 ** regular files: (mode & 0170000)==0100000
29 ** symbolic links: (mode & 0170000)==0120000
30 ** directories: (mode & 0170000)==0040000
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.
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.
43 ** If three or more arguments are passed to this function and an
44 ** error is encountered, an exception is raised.
46 ** READFILE(FILE):
48 ** Read and return the contents of file FILE (type blob) from disk.
50 ** FSDIR:
52 ** Used as follows:
54 ** SELECT * FROM fsdir($path [, $dir]);
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.
62 ** Each row has the following columns:
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.
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.
76 #include "sqlite3ext.h"
77 SQLITE_EXTENSION_INIT1
78 #include <stdio.h>
79 #include <string.h>
80 #include <assert.h>
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>
110 ** Structure of the fsdir() table-valued function
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 */
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.
127 ** If the file exceeds the SQLite blob size limit, through an
128 ** SQLITE_TOOBIG error.
130 ** Throw an SQLITE_IOERR if there are difficulties pulling the file
131 ** off of disk.
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;
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;
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;
155 pBuf = sqlite3_malloc64( nIn ? nIn : 1 );
156 if( pBuf==0 ){
157 sqlite3_result_error_nomem(ctx);
158 fclose(in);
159 return;
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);
167 fclose(in);
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.
175 static void readfileFunc(
176 sqlite3_context *context,
177 int argc,
178 sqlite3_value **argv
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);
188 ** Set the error message contained in context ctx to the results of
189 ** vprintf(zFmt, ...).
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);
201 #if defined(_WIN32)
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).
206 static sqlite3_uint64 fileTimeToUnixTime(
207 LPFILETIME pFileTime
209 SYSTEMTIME epochSystemTime;
210 ULARGE_INTEGER epochIntervals;
211 FILETIME epochFileTime;
212 ULARGE_INTEGER fileIntervals;
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;
222 fileIntervals.LowPart = pFileTime->dwLowDateTime;
223 fileIntervals.HighPart = pFileTime->dwHighDateTime;
225 return (fileIntervals.QuadPart - epochIntervals.QuadPart) / 10000000;
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.
233 static void statTimesToUtc(
234 const char *zPath,
235 struct stat *pStatBuf
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);
251 sqlite3_free(zUnicodeName);
254 #endif
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().
261 static int fileStat(
262 const char *zPath,
263 struct stat *pStatBuf
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
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().
279 static int fileLinkStat(
280 const char *zPath,
281 struct stat *pStatBuf
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
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.
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.
303 static int makeDirectory(
304 const char *zFile
306 char *zCopy = sqlite3_mprintf("%s", zFile);
307 int rc = SQLITE_OK;
309 if( zCopy==0 ){
310 rc = SQLITE_NOMEM;
311 }else{
312 int nCopy = (int)strlen(zCopy);
313 int i = 1;
315 while( rc==SQLITE_OK ){
316 struct stat sStat;
317 int rc2;
319 for(; zCopy[i]!='/' && i<nCopy; i++);
320 if( i==nCopy ) break;
321 zCopy[i] = '\0';
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;
329 zCopy[i] = '/';
330 i++;
333 sqlite3_free(zCopy);
336 return rc;
340 ** This function does the work for the writefile() UDF. Refer to
341 ** header comments at the top of this file for details.
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) */
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
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))
369 return 1;
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;
386 fclose(out);
387 if( rc==0 && mode && chmod(zFile, mode & 0777) ){
388 rc = 1;
390 if( rc ) return 2;
391 sqlite3_result_int64(pCtx, nWrite);
395 if( mtime>=0 ){
396 #if defined(_WIN32)
397 /* Windows */
398 FILETIME lastAccess;
399 FILETIME lastWrite;
400 SYSTEMTIME currentTime;
401 LONGLONG intervals;
402 HANDLE hFile;
403 LPWSTR zUnicodeName;
404 extern LPWSTR sqlite3_win32_utf8_to_unicode(const char*);
406 GetSystemTime(&currentTime);
407 SystemTimeToFileTime(&currentTime, &lastAccess);
408 intervals = Int32x32To64(mtime, 10000000) + 116444736000000000;
409 lastWrite.dwLowDateTime = (DWORD)intervals;
410 lastWrite.dwHighDateTime = intervals >> 32;
411 zUnicodeName = sqlite3_win32_utf8_to_unicode(zFile);
412 if( zUnicodeName==0 ){
413 return 1;
415 hFile = CreateFileW(
416 zUnicodeName, FILE_WRITE_ATTRIBUTES, 0, NULL, OPEN_EXISTING,
417 FILE_FLAG_BACKUP_SEMANTICS, NULL
419 sqlite3_free(zUnicodeName);
420 if( hFile!=INVALID_HANDLE_VALUE ){
421 BOOL bResult = SetFileTime(hFile, NULL, &lastAccess, &lastWrite);
422 CloseHandle(hFile);
423 return !bResult;
424 }else{
425 return 1;
427 #elif defined(AT_FDCWD) && 0 /* utimensat() is not universally available */
428 /* Recent unix */
429 struct timespec times[2];
430 times[0].tv_nsec = times[1].tv_nsec = 0;
431 times[0].tv_sec = time(0);
432 times[1].tv_sec = mtime;
433 if( utimensat(AT_FDCWD, zFile, times, AT_SYMLINK_NOFOLLOW) ){
434 return 1;
436 #else
437 /* Legacy unix */
438 struct timeval times[2];
439 times[0].tv_usec = times[1].tv_usec = 0;
440 times[0].tv_sec = time(0);
441 times[1].tv_sec = mtime;
442 if( utimes(zFile, times) ){
443 return 1;
445 #endif
448 return 0;
452 ** Implementation of the "writefile(W,X[,Y[,Z]]])" SQL function.
453 ** Refer to header comments at the top of this file for details.
455 static void writefileFunc(
456 sqlite3_context *context,
457 int argc,
458 sqlite3_value **argv
460 const char *zFile;
461 mode_t mode = 0;
462 int res;
463 sqlite3_int64 mtime = -1;
465 if( argc<2 || argc>4 ){
466 sqlite3_result_error(context,
467 "wrong number of arguments to function writefile()", -1
469 return;
472 zFile = (const char*)sqlite3_value_text(argv[0]);
473 if( zFile==0 ) return;
474 if( argc>=3 ){
475 mode = (mode_t)sqlite3_value_int(argv[2]);
477 if( argc==4 ){
478 mtime = sqlite3_value_int64(argv[3]);
481 res = writeFile(context, zFile, argv[1], mode, mtime);
482 if( res==1 && errno==ENOENT ){
483 if( makeDirectory(zFile)==SQLITE_OK ){
484 res = writeFile(context, zFile, argv[1], mode, mtime);
488 if( argc>2 && res!=0 ){
489 if( S_ISLNK(mode) ){
490 ctxErrorMsg(context, "failed to create symlink: %s", zFile);
491 }else if( S_ISDIR(mode) ){
492 ctxErrorMsg(context, "failed to create directory: %s", zFile);
493 }else{
494 ctxErrorMsg(context, "failed to write file: %s", zFile);
500 ** SQL function: lsmode(MODE)
502 ** Given a numberic st_mode from stat(), convert it into a human-readable
503 ** text string in the style of "ls -l".
505 static void lsModeFunc(
506 sqlite3_context *context,
507 int argc,
508 sqlite3_value **argv
510 int i;
511 int iMode = sqlite3_value_int(argv[0]);
512 char z[16];
513 (void)argc;
514 if( S_ISLNK(iMode) ){
515 z[0] = 'l';
516 }else if( S_ISREG(iMode) ){
517 z[0] = '-';
518 }else if( S_ISDIR(iMode) ){
519 z[0] = 'd';
520 }else{
521 z[0] = '?';
523 for(i=0; i<3; i++){
524 int m = (iMode >> ((2-i)*3));
525 char *a = &z[1 + i*3];
526 a[0] = (m & 0x4) ? 'r' : '-';
527 a[1] = (m & 0x2) ? 'w' : '-';
528 a[2] = (m & 0x1) ? 'x' : '-';
530 z[10] = '\0';
531 sqlite3_result_text(context, z, -1, SQLITE_TRANSIENT);
534 #ifndef SQLITE_OMIT_VIRTUALTABLE
537 ** Cursor type for recursively iterating through a directory structure.
539 typedef struct fsdir_cursor fsdir_cursor;
540 typedef struct FsdirLevel FsdirLevel;
542 struct FsdirLevel {
543 DIR *pDir; /* From opendir() */
544 char *zDir; /* Name of directory (nul-terminated) */
547 struct fsdir_cursor {
548 sqlite3_vtab_cursor base; /* Base class - must be first */
550 int nLvl; /* Number of entries in aLvl[] array */
551 int iLvl; /* Index of current entry */
552 FsdirLevel *aLvl; /* Hierarchy of directories being traversed */
554 const char *zBase;
555 int nBase;
557 struct stat sStat; /* Current lstat() results */
558 char *zPath; /* Path to current entry */
559 sqlite3_int64 iRowid; /* Current rowid */
562 typedef struct fsdir_tab fsdir_tab;
563 struct fsdir_tab {
564 sqlite3_vtab base; /* Base class - must be first */
568 ** Construct a new fsdir virtual table object.
570 static int fsdirConnect(
571 sqlite3 *db,
572 void *pAux,
573 int argc, const char *const*argv,
574 sqlite3_vtab **ppVtab,
575 char **pzErr
577 fsdir_tab *pNew = 0;
578 int rc;
579 (void)pAux;
580 (void)argc;
581 (void)argv;
582 (void)pzErr;
583 rc = sqlite3_declare_vtab(db, "CREATE TABLE x" FSDIR_SCHEMA);
584 if( rc==SQLITE_OK ){
585 pNew = (fsdir_tab*)sqlite3_malloc( sizeof(*pNew) );
586 if( pNew==0 ) return SQLITE_NOMEM;
587 memset(pNew, 0, sizeof(*pNew));
588 sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY);
590 *ppVtab = (sqlite3_vtab*)pNew;
591 return rc;
595 ** This method is the destructor for fsdir vtab objects.
597 static int fsdirDisconnect(sqlite3_vtab *pVtab){
598 sqlite3_free(pVtab);
599 return SQLITE_OK;
603 ** Constructor for a new fsdir_cursor object.
605 static int fsdirOpen(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCursor){
606 fsdir_cursor *pCur;
607 (void)p;
608 pCur = sqlite3_malloc( sizeof(*pCur) );
609 if( pCur==0 ) return SQLITE_NOMEM;
610 memset(pCur, 0, sizeof(*pCur));
611 pCur->iLvl = -1;
612 *ppCursor = &pCur->base;
613 return SQLITE_OK;
617 ** Reset a cursor back to the state it was in when first returned
618 ** by fsdirOpen().
620 static void fsdirResetCursor(fsdir_cursor *pCur){
621 int i;
622 for(i=0; i<=pCur->iLvl; i++){
623 FsdirLevel *pLvl = &pCur->aLvl[i];
624 if( pLvl->pDir ) closedir(pLvl->pDir);
625 sqlite3_free(pLvl->zDir);
627 sqlite3_free(pCur->zPath);
628 sqlite3_free(pCur->aLvl);
629 pCur->aLvl = 0;
630 pCur->zPath = 0;
631 pCur->zBase = 0;
632 pCur->nBase = 0;
633 pCur->nLvl = 0;
634 pCur->iLvl = -1;
635 pCur->iRowid = 1;
639 ** Destructor for an fsdir_cursor.
641 static int fsdirClose(sqlite3_vtab_cursor *cur){
642 fsdir_cursor *pCur = (fsdir_cursor*)cur;
644 fsdirResetCursor(pCur);
645 sqlite3_free(pCur);
646 return SQLITE_OK;
650 ** Set the error message for the virtual table associated with cursor
651 ** pCur to the results of vprintf(zFmt, ...).
653 static void fsdirSetErrmsg(fsdir_cursor *pCur, const char *zFmt, ...){
654 va_list ap;
655 va_start(ap, zFmt);
656 pCur->base.pVtab->zErrMsg = sqlite3_vmprintf(zFmt, ap);
657 va_end(ap);
662 ** Advance an fsdir_cursor to its next row of output.
664 static int fsdirNext(sqlite3_vtab_cursor *cur){
665 fsdir_cursor *pCur = (fsdir_cursor*)cur;
666 mode_t m = pCur->sStat.st_mode;
668 pCur->iRowid++;
669 if( S_ISDIR(m) ){
670 /* Descend into this directory */
671 int iNew = pCur->iLvl + 1;
672 FsdirLevel *pLvl;
673 if( iNew>=pCur->nLvl ){
674 int nNew = iNew+1;
675 sqlite3_int64 nByte = nNew*sizeof(FsdirLevel);
676 FsdirLevel *aNew = (FsdirLevel*)sqlite3_realloc64(pCur->aLvl, nByte);
677 if( aNew==0 ) return SQLITE_NOMEM;
678 memset(&aNew[pCur->nLvl], 0, sizeof(FsdirLevel)*(nNew-pCur->nLvl));
679 pCur->aLvl = aNew;
680 pCur->nLvl = nNew;
682 pCur->iLvl = iNew;
683 pLvl = &pCur->aLvl[iNew];
685 pLvl->zDir = pCur->zPath;
686 pCur->zPath = 0;
687 pLvl->pDir = opendir(pLvl->zDir);
688 if( pLvl->pDir==0 ){
689 fsdirSetErrmsg(pCur, "cannot read directory: %s", pCur->zPath);
690 return SQLITE_ERROR;
694 while( pCur->iLvl>=0 ){
695 FsdirLevel *pLvl = &pCur->aLvl[pCur->iLvl];
696 struct dirent *pEntry = readdir(pLvl->pDir);
697 if( pEntry ){
698 if( pEntry->d_name[0]=='.' ){
699 if( pEntry->d_name[1]=='.' && pEntry->d_name[2]=='\0' ) continue;
700 if( pEntry->d_name[1]=='\0' ) continue;
702 sqlite3_free(pCur->zPath);
703 pCur->zPath = sqlite3_mprintf("%s/%s", pLvl->zDir, pEntry->d_name);
704 if( pCur->zPath==0 ) return SQLITE_NOMEM;
705 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
706 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
707 return SQLITE_ERROR;
709 return SQLITE_OK;
711 closedir(pLvl->pDir);
712 sqlite3_free(pLvl->zDir);
713 pLvl->pDir = 0;
714 pLvl->zDir = 0;
715 pCur->iLvl--;
718 /* EOF */
719 sqlite3_free(pCur->zPath);
720 pCur->zPath = 0;
721 return SQLITE_OK;
725 ** Return values of columns for the row at which the series_cursor
726 ** is currently pointing.
728 static int fsdirColumn(
729 sqlite3_vtab_cursor *cur, /* The cursor */
730 sqlite3_context *ctx, /* First argument to sqlite3_result_...() */
731 int i /* Which column to return */
733 fsdir_cursor *pCur = (fsdir_cursor*)cur;
734 switch( i ){
735 case FSDIR_COLUMN_NAME: {
736 sqlite3_result_text(ctx, &pCur->zPath[pCur->nBase], -1, SQLITE_TRANSIENT);
737 break;
740 case FSDIR_COLUMN_MODE:
741 sqlite3_result_int64(ctx, pCur->sStat.st_mode);
742 break;
744 case FSDIR_COLUMN_MTIME:
745 sqlite3_result_int64(ctx, pCur->sStat.st_mtime);
746 break;
748 case FSDIR_COLUMN_DATA: {
749 mode_t m = pCur->sStat.st_mode;
750 if( S_ISDIR(m) ){
751 sqlite3_result_null(ctx);
752 #if !defined(_WIN32) && !defined(WIN32)
753 }else if( S_ISLNK(m) ){
754 char aStatic[64];
755 char *aBuf = aStatic;
756 sqlite3_int64 nBuf = 64;
757 int n;
759 while( 1 ){
760 n = readlink(pCur->zPath, aBuf, nBuf);
761 if( n<nBuf ) break;
762 if( aBuf!=aStatic ) sqlite3_free(aBuf);
763 nBuf = nBuf*2;
764 aBuf = sqlite3_malloc64(nBuf);
765 if( aBuf==0 ){
766 sqlite3_result_error_nomem(ctx);
767 return SQLITE_NOMEM;
771 sqlite3_result_text(ctx, aBuf, n, SQLITE_TRANSIENT);
772 if( aBuf!=aStatic ) sqlite3_free(aBuf);
773 #endif
774 }else{
775 readFileContents(ctx, pCur->zPath);
778 case FSDIR_COLUMN_PATH:
779 default: {
780 /* The FSDIR_COLUMN_PATH and FSDIR_COLUMN_DIR are input parameters.
781 ** always return their values as NULL */
782 break;
785 return SQLITE_OK;
789 ** Return the rowid for the current row. In this implementation, the
790 ** first row returned is assigned rowid value 1, and each subsequent
791 ** row a value 1 more than that of the previous.
793 static int fsdirRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){
794 fsdir_cursor *pCur = (fsdir_cursor*)cur;
795 *pRowid = pCur->iRowid;
796 return SQLITE_OK;
800 ** Return TRUE if the cursor has been moved off of the last
801 ** row of output.
803 static int fsdirEof(sqlite3_vtab_cursor *cur){
804 fsdir_cursor *pCur = (fsdir_cursor*)cur;
805 return (pCur->zPath==0);
809 ** xFilter callback.
811 ** idxNum==1 PATH parameter only
812 ** idxNum==2 Both PATH and DIR supplied
814 static int fsdirFilter(
815 sqlite3_vtab_cursor *cur,
816 int idxNum, const char *idxStr,
817 int argc, sqlite3_value **argv
819 const char *zDir = 0;
820 fsdir_cursor *pCur = (fsdir_cursor*)cur;
821 (void)idxStr;
822 fsdirResetCursor(pCur);
824 if( idxNum==0 ){
825 fsdirSetErrmsg(pCur, "table function fsdir requires an argument");
826 return SQLITE_ERROR;
829 assert( argc==idxNum && (argc==1 || argc==2) );
830 zDir = (const char*)sqlite3_value_text(argv[0]);
831 if( zDir==0 ){
832 fsdirSetErrmsg(pCur, "table function fsdir requires a non-NULL argument");
833 return SQLITE_ERROR;
835 if( argc==2 ){
836 pCur->zBase = (const char*)sqlite3_value_text(argv[1]);
838 if( pCur->zBase ){
839 pCur->nBase = (int)strlen(pCur->zBase)+1;
840 pCur->zPath = sqlite3_mprintf("%s/%s", pCur->zBase, zDir);
841 }else{
842 pCur->zPath = sqlite3_mprintf("%s", zDir);
845 if( pCur->zPath==0 ){
846 return SQLITE_NOMEM;
848 if( fileLinkStat(pCur->zPath, &pCur->sStat) ){
849 fsdirSetErrmsg(pCur, "cannot stat file: %s", pCur->zPath);
850 return SQLITE_ERROR;
853 return SQLITE_OK;
857 ** SQLite will invoke this method one or more times while planning a query
858 ** that uses the generate_series virtual table. This routine needs to create
859 ** a query plan for each invocation and compute an estimated cost for that
860 ** plan.
862 ** In this implementation idxNum is used to represent the
863 ** query plan. idxStr is unused.
865 ** The query plan is represented by values of idxNum:
867 ** (1) The path value is supplied by argv[0]
868 ** (2) Path is in argv[0] and dir is in argv[1]
870 static int fsdirBestIndex(
871 sqlite3_vtab *tab,
872 sqlite3_index_info *pIdxInfo
874 int i; /* Loop over constraints */
875 int idxPath = -1; /* Index in pIdxInfo->aConstraint of PATH= */
876 int idxDir = -1; /* Index in pIdxInfo->aConstraint of DIR= */
877 int seenPath = 0; /* True if an unusable PATH= constraint is seen */
878 int seenDir = 0; /* True if an unusable DIR= constraint is seen */
879 const struct sqlite3_index_constraint *pConstraint;
881 (void)tab;
882 pConstraint = pIdxInfo->aConstraint;
883 for(i=0; i<pIdxInfo->nConstraint; i++, pConstraint++){
884 if( pConstraint->op!=SQLITE_INDEX_CONSTRAINT_EQ ) continue;
885 switch( pConstraint->iColumn ){
886 case FSDIR_COLUMN_PATH: {
887 if( pConstraint->usable ){
888 idxPath = i;
889 seenPath = 0;
890 }else if( idxPath<0 ){
891 seenPath = 1;
893 break;
895 case FSDIR_COLUMN_DIR: {
896 if( pConstraint->usable ){
897 idxDir = i;
898 seenDir = 0;
899 }else if( idxDir<0 ){
900 seenDir = 1;
902 break;
906 if( seenPath || seenDir ){
907 /* If input parameters are unusable, disallow this plan */
908 return SQLITE_CONSTRAINT;
911 if( idxPath<0 ){
912 pIdxInfo->idxNum = 0;
913 /* The pIdxInfo->estimatedCost should have been initialized to a huge
914 ** number. Leave it unchanged. */
915 pIdxInfo->estimatedRows = 0x7fffffff;
916 }else{
917 pIdxInfo->aConstraintUsage[idxPath].omit = 1;
918 pIdxInfo->aConstraintUsage[idxPath].argvIndex = 1;
919 if( idxDir>=0 ){
920 pIdxInfo->aConstraintUsage[idxDir].omit = 1;
921 pIdxInfo->aConstraintUsage[idxDir].argvIndex = 2;
922 pIdxInfo->idxNum = 2;
923 pIdxInfo->estimatedCost = 10.0;
924 }else{
925 pIdxInfo->idxNum = 1;
926 pIdxInfo->estimatedCost = 100.0;
930 return SQLITE_OK;
934 ** Register the "fsdir" virtual table.
936 static int fsdirRegister(sqlite3 *db){
937 static sqlite3_module fsdirModule = {
938 0, /* iVersion */
939 0, /* xCreate */
940 fsdirConnect, /* xConnect */
941 fsdirBestIndex, /* xBestIndex */
942 fsdirDisconnect, /* xDisconnect */
943 0, /* xDestroy */
944 fsdirOpen, /* xOpen - open a cursor */
945 fsdirClose, /* xClose - close a cursor */
946 fsdirFilter, /* xFilter - configure scan constraints */
947 fsdirNext, /* xNext - advance a cursor */
948 fsdirEof, /* xEof - check for end of scan */
949 fsdirColumn, /* xColumn - read data */
950 fsdirRowid, /* xRowid - read data */
951 0, /* xUpdate */
952 0, /* xBegin */
953 0, /* xSync */
954 0, /* xCommit */
955 0, /* xRollback */
956 0, /* xFindMethod */
957 0, /* xRename */
958 0, /* xSavepoint */
959 0, /* xRelease */
960 0, /* xRollbackTo */
961 0, /* xShadowName */
964 int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0);
965 return rc;
967 #else /* SQLITE_OMIT_VIRTUALTABLE */
968 # define fsdirRegister(x) SQLITE_OK
969 #endif
971 #ifdef _WIN32
972 __declspec(dllexport)
973 #endif
974 int sqlite3_fileio_init(
975 sqlite3 *db,
976 char **pzErrMsg,
977 const sqlite3_api_routines *pApi
979 int rc = SQLITE_OK;
980 SQLITE_EXTENSION_INIT2(pApi);
981 (void)pzErrMsg; /* Unused parameter */
982 rc = sqlite3_create_function(db, "readfile", 1,
983 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
984 readfileFunc, 0, 0);
985 if( rc==SQLITE_OK ){
986 rc = sqlite3_create_function(db, "writefile", -1,
987 SQLITE_UTF8|SQLITE_DIRECTONLY, 0,
988 writefileFunc, 0, 0);
990 if( rc==SQLITE_OK ){
991 rc = sqlite3_create_function(db, "lsmode", 1, SQLITE_UTF8, 0,
992 lsModeFunc, 0, 0);
994 if( rc==SQLITE_OK ){
995 rc = fsdirRegister(db);
997 return rc;