fileio.c 30 KB

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