00001
00018 #ifdef linux
00019 #define _GNU_SOURCE
00020 #endif
00021
00022 #ifdef STANDALONE
00023 #include <sqlite3.h>
00024 #else
00025 #include <sqlite3ext.h>
00026 static SQLITE_EXTENSION_INIT1
00027 #endif
00028
00029 #if defined(_WIN32) || defined(_WIN64)
00030 #include <windows.h>
00031 #else
00032 #include <sys/mman.h>
00033 #include <fcntl.h>
00034 #include <unistd.h>
00035 #include <errno.h>
00036 #endif
00037
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <limits.h>
00042
00043 #include <zlib.h>
00044
00045 #undef snprintf
00046
00047 #define ZIP_SIG_LEN 4
00048
00049 #define ZIP_LOCAL_HEADER_SIG 0x04034b50
00050 #define ZIP_LOCAL_HEADER_FLAGS 6
00051 #define ZIP_LOCAL_PATHLEN_OFFS 26
00052 #define ZIP_LOCAL_EXTRA_OFFS 28
00053 #define ZIP_LOCAL_HEADER_LEN 30
00054
00055 #define ZIP_CENTRAL_HEADER_SIG 0x02014b50
00056 #define ZIP_CENTRAL_HEADER_FLAGS 8
00057 #define ZIP_CENTRAL_HEADER_LEN 46
00058 #define ZIP_CENTRAL_COMPMETH_OFFS 10
00059 #define ZIP_CENTRAL_MTIME_OFFS 12
00060 #define ZIP_CENTRAL_MDATE_OFFS 14
00061 #define ZIP_CENTRAL_CRC32_OFFS 16
00062 #define ZIP_CENTRAL_COMPLEN_OFFS 20
00063 #define ZIP_CENTRAL_UNCOMPLEN_OFFS 24
00064 #define ZIP_CENTRAL_PATHLEN_OFFS 28
00065 #define ZIP_CENTRAL_EXTRALEN_OFFS 30
00066 #define ZIP_CENTRAL_COMMENTLEN_OFFS 32
00067 #define ZIP_CENTRAL_LOCALHDR_OFFS 42
00068
00069 #define ZIP_CENTRAL_END_SIG 0x06054b50
00070 #define ZIP_CENTRAL_END_LEN 22
00071 #define ZIP_CENTRAL_ENTS_OFFS 8
00072 #define ZIP_CENTRAL_DIRSIZE_OFFS 12
00073 #define ZIP_CENTRAL_DIRSTART_OFFS 16
00074
00075 #define ZIP_COMPMETH_STORED 0
00076 #define ZIP_COMPMETH_DEFLATED 8
00077
00078 #define zip_read_int(p) \
00079 ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
00080 #define zip_read_short(p) \
00081 ((p)[0] | ((p)[1] << 8))
00082
00089 typedef struct zip_file {
00090 off_t length;
00091 unsigned char *data;
00092 #if defined(_WIN32) || defined(_WIN64)
00093 HANDLE h;
00094 HANDLE mh;
00095 #endif
00096 int baseoffs;
00097 int nentries;
00098 unsigned char *entries[1];
00099 } zip_file;
00100
00107 typedef struct zip_vtab {
00108 sqlite3_vtab vtab;
00109 sqlite3 *db;
00110 zip_file *zip;
00111 int sorted;
00112 char tblname[1];
00113 } zip_vtab;
00114
00121 typedef struct {
00122 sqlite3_vtab_cursor cursor;
00123 int pos;
00124 int usematches;
00125 int nmatches;
00126 int *matches;
00127 } zip_cursor;
00128
00129 #ifdef SQLITE_OPEN_URI
00130
00137 typedef struct mem_blk {
00138 #define MEM_MAGIC "MVFS"
00139 char magic[4];
00140 int opened;
00141 #if defined(_WIN32) || defined(_WIN64)
00142 HANDLE mh;
00143 #else
00144 long psize;
00145 #ifdef linux
00146 sqlite3_mutex *mutex;
00147 int lcnt;
00148 #endif
00149 #endif
00150 unsigned long size;
00151 unsigned long length;
00152 unsigned char *data;
00153 } mem_blk;
00154
00161 typedef struct mem_file {
00162 sqlite3_file base;
00163 #ifdef linux
00164 int lock;
00165 #endif
00166 mem_blk *mb;
00167 } mem_file;
00168
00169
00170
00171
00172
00173 static char mem_vfs_name[64];
00174
00175 #endif
00176
00183 static zip_file *
00184 zip_open(const char *filename)
00185 {
00186 #if defined(_WIN32) || defined(_WIN64)
00187 HANDLE h, mh = INVALID_HANDLE_VALUE;
00188 DWORD length;
00189 unsigned char *data = 0;
00190 #else
00191 int fd;
00192 off_t length;
00193 unsigned char *data = MAP_FAILED;
00194 #endif
00195 int nentries, baseoffs = 0, i;
00196 zip_file *zip = 0;
00197 unsigned char *p, *q;
00198
00199 if (!filename) {
00200 return 0;
00201 }
00202 #if defined(_WIN32) || defined(_WIN64)
00203 h = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
00204 if (h == INVALID_HANDLE_VALUE) {
00205 goto error;
00206 }
00207 length = GetFileSize(h, 0);
00208 if ((length == INVALID_FILE_SIZE) || (length < ZIP_CENTRAL_END_LEN)) {
00209 goto error;
00210 }
00211 mh = CreateFileMapping(h, 0, PAGE_READONLY, 0, length, 0);
00212 if (mh == INVALID_HANDLE_VALUE) {
00213 goto error;
00214 }
00215 data = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, length);
00216 if (!data) {
00217 goto error;
00218 }
00219 #else
00220 fd = open(filename, O_RDONLY);
00221 if (fd < 0) {
00222 goto error;
00223 }
00224 length = lseek(fd, 0, SEEK_END);
00225 if ((length == -1) || (length < ZIP_CENTRAL_END_LEN)) {
00226 goto error;
00227 }
00228 data = (unsigned char *) mmap(0, length, PROT_READ,
00229 MAP_FILE | MAP_PRIVATE, fd, 0);
00230 if (data == MAP_FAILED) {
00231 goto error;
00232 }
00233 close(fd);
00234 fd = -1;
00235 #endif
00236 p = data + length - ZIP_CENTRAL_END_LEN;
00237 while (p >= data) {
00238 if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) {
00239 if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) {
00240 break;
00241 }
00242 p -= ZIP_SIG_LEN;
00243 } else {
00244 --p;
00245 }
00246 }
00247 if (p < data) {
00248 goto error;
00249 }
00250 nentries = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS);
00251 if (nentries == 0) {
00252 goto error;
00253 }
00254 q = data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS);
00255 p -= zip_read_int(p + ZIP_CENTRAL_DIRSIZE_OFFS);
00256 if (p < data || p > data + length || q < data || q > data + length) {
00257 goto error;
00258 }
00259 baseoffs = p - q;
00260 q = p;
00261 for (i = 0; i < nentries; i++) {
00262 int pathlen, comlen, extra;
00263
00264 if ((q + ZIP_CENTRAL_HEADER_LEN) > (data + length)) {
00265 goto error;
00266 }
00267 if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) {
00268 goto error;
00269 }
00270 pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS);
00271 comlen = zip_read_short(q + ZIP_CENTRAL_COMMENTLEN_OFFS);
00272 extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS);
00273 q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN;
00274 }
00275 zip = sqlite3_malloc(sizeof (zip_file) +
00276 nentries * sizeof (unsigned char *));
00277 if (!zip) {
00278 goto error;
00279 }
00280 #if defined(_WIN32) || defined(_WIN64)
00281 zip->h = zip->mh = INVALID_HANDLE_VALUE;
00282 #endif
00283 zip->length = length;
00284 zip->data = data;
00285 zip->baseoffs = baseoffs;
00286 zip->nentries = nentries;
00287 q = p;
00288 for (i = 0; i < nentries; i++) {
00289 int pathlen, comlen, extra;
00290
00291 if ((q + ZIP_CENTRAL_HEADER_LEN) > (data + length)) {
00292 goto error;
00293 }
00294 if (zip_read_int(q) != ZIP_CENTRAL_HEADER_SIG) {
00295 goto error;
00296 }
00297 zip->entries[i] = q;
00298 pathlen = zip_read_short(q + ZIP_CENTRAL_PATHLEN_OFFS);
00299 comlen = zip_read_short(q + ZIP_CENTRAL_COMMENTLEN_OFFS);
00300 extra = zip_read_short(q + ZIP_CENTRAL_EXTRALEN_OFFS);
00301 q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN;
00302 }
00303 zip->entries[i] = 0;
00304 #if defined(_WIN32) || defined(_WIN64)
00305 zip->h = h;
00306 zip->mh = mh;
00307 #endif
00308 return zip;
00309 error:
00310 if (zip) {
00311 sqlite3_free(zip);
00312 }
00313 #if defined(_WIN32) || defined(_WIN64)
00314 if (data) {
00315 UnmapViewOfFile(data);
00316 }
00317 if (mh != INVALID_HANDLE_VALUE) {
00318 CloseHandle(mh);
00319 }
00320 if (h != INVALID_HANDLE_VALUE) {
00321 CloseHandle(h);
00322 }
00323 #else
00324 if (data != MAP_FAILED) {
00325 munmap(data, length);
00326 }
00327 if (fd >= 0) {
00328 close(fd);
00329 }
00330 #endif
00331 return 0;
00332 }
00333
00339 static void
00340 zip_close(zip_file *zip)
00341 {
00342 if (zip) {
00343 #if defined(_WIN32) || defined(_WIN64)
00344 if (zip->data) {
00345 UnmapViewOfFile(zip->data);
00346 }
00347 if (zip->mh != INVALID_HANDLE_VALUE) {
00348 CloseHandle(zip->mh);
00349 }
00350 if (zip->h != INVALID_HANDLE_VALUE) {
00351 CloseHandle(zip->h);
00352 }
00353 #else
00354 if (zip->data) {
00355 munmap(zip->data, zip->length);
00356 }
00357 #endif
00358 zip->length = 0;
00359 zip->data = 0;
00360 zip->nentries = 0;
00361 sqlite3_free(zip);
00362 }
00363 }
00364
00371 static char *
00372 unquote(char const *in)
00373 {
00374 char c, *ret;
00375 int i;
00376
00377 ret = sqlite3_malloc(strlen(in) + 1);
00378 if (ret) {
00379 c = in[0];
00380 if ((c == '"') || (c == '\'')) {
00381 i = strlen(in + 1);
00382 if ((i > 0) && (in[i] == c)) {
00383 strcpy(ret, in + 1);
00384 ret[i - 1] = '\0';
00385 return ret;
00386 }
00387 }
00388 strcpy(ret, in);
00389 }
00390 return ret;
00391 }
00392
00411 static int
00412 zip_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
00413 sqlite3_vtab **vtabp, char **errp)
00414 {
00415 zip_file *zip = 0;
00416 int rc = SQLITE_ERROR;
00417 char *filename;
00418 zip_vtab *vtab;
00419
00420 if (argc < 4) {
00421 *errp = sqlite3_mprintf("input file name missing");
00422 return SQLITE_ERROR;
00423 }
00424 filename = unquote(argv[3]);
00425 if (filename) {
00426 zip = zip_open(filename);
00427 sqlite3_free(filename);
00428 }
00429 if (!zip) {
00430 *errp = sqlite3_mprintf("unable to open input file");
00431 return rc;
00432 }
00433 vtab = sqlite3_malloc(sizeof(zip_vtab) + 6 +
00434 strlen(argv[1]) + strlen(argv[2]));
00435 if (!vtab) {
00436 zip_close(zip);
00437 *errp = sqlite3_mprintf("out of memory");
00438 return rc;
00439 }
00440 memset(vtab, 0, sizeof (*vtab));
00441 strcpy(vtab->tblname, "\"");
00442 strcat(vtab->tblname, argv[1]);
00443 strcat(vtab->tblname, "\".\"");
00444 strcat(vtab->tblname, argv[2]);
00445 strcat(vtab->tblname, "\"");
00446 vtab->db = db;
00447 vtab->zip = zip;
00448 rc = sqlite3_declare_vtab(db, "CREATE TABLE x(path, comp, mtime, "
00449 "crc32, length, data, clength, cdata, isdir)");
00450 if (rc != SQLITE_OK) {
00451 zip_close(zip);
00452 sqlite3_free(vtab);
00453 *errp = sqlite3_mprintf("table definition failed (error %d)", rc);
00454 return rc;
00455 }
00456 *vtabp = &vtab->vtab;
00457 *errp = 0;
00458 return SQLITE_OK;
00459 }
00460
00472 static int
00473 zip_vtab_create(sqlite3* db, void *aux, int argc,
00474 const char *const *argv,
00475 sqlite3_vtab **vtabp, char **errp)
00476 {
00477 return zip_vtab_connect(db, aux, argc, argv, vtabp, errp);
00478 }
00479
00486 static int
00487 zip_vtab_disconnect(sqlite3_vtab *vtab)
00488 {
00489 zip_vtab *tab = (zip_vtab *) vtab;
00490
00491 zip_close(tab->zip);
00492 sqlite3_free(tab);
00493 return SQLITE_OK;
00494 }
00495
00502 static int
00503 zip_vtab_destroy(sqlite3_vtab *vtab)
00504 {
00505 return zip_vtab_disconnect(vtab);
00506 }
00507
00515 static int
00516 zip_vtab_bestindex(sqlite3_vtab *vtab, sqlite3_index_info *info)
00517 {
00518 zip_vtab *tab = (zip_vtab *) vtab;
00519 int i;
00520
00521 info->idxNum = 0;
00522 if (tab->sorted == 0) {
00523 char *sql = 0;
00524 unsigned char **entries = 0;
00525 sqlite3_stmt *stmt = 0;
00526 int rc, count, i;
00527 size_t tmp;
00528
00529
00530 tab->sorted = -1;
00531 entries = sqlite3_malloc(tab->zip->nentries * sizeof (entries));
00532 sql = sqlite3_mprintf("SELECT rowid FROM %s ORDER BY path",
00533 tab->tblname);
00534 if (sql && entries) {
00535 rc = sqlite3_prepare_v2(tab->db, sql, -1, &stmt, 0);
00536 if ((rc == SQLITE_OK) && stmt) {
00537 count = 0;
00538 while (1) {
00539 rc = sqlite3_step(stmt);
00540 if (rc != SQLITE_ROW) {
00541 break;
00542 }
00543 tmp = sqlite3_column_int(stmt, 0);
00544 entries[count++] = (unsigned char *) tmp;
00545 }
00546 if ((rc == SQLITE_DONE) && (count == tab->zip->nentries)) {
00547 for (i = 0; i < count; i++) {
00548 tmp = (size_t) entries[i];
00549 tmp = (size_t) tab->zip->entries[tmp];
00550 entries[i] = (unsigned char *) tmp;
00551 }
00552 memcpy(tab->zip->entries, entries, i * sizeof (entries));
00553 tab->sorted = 1;
00554 }
00555 }
00556 }
00557 if (stmt) {
00558 sqlite3_finalize(stmt);
00559 }
00560 if (sql) {
00561 sqlite3_free(sql);
00562 }
00563 if (entries) {
00564 sqlite3_free(entries);
00565 }
00566 }
00567
00568 if (tab->sorted != 1) {
00569 return SQLITE_OK;
00570 }
00571
00572 for (i = 0; i < info->nConstraint; i++) {
00573 if (info->aConstraint[i].usable &&
00574 (info->aConstraint[i].iColumn == 0)) {
00575 if (info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_EQ) {
00576 info->idxNum = 1;
00577 info->aConstraintUsage[i].argvIndex = 1;
00578 info->aConstraintUsage[i].omit = 1;
00579 info->estimatedCost = 1.0;
00580 break;
00581 } else if (info->aConstraint[i].op ==
00582 SQLITE_INDEX_CONSTRAINT_MATCH) {
00583 info->idxNum = 2;
00584 info->aConstraintUsage[i].argvIndex = 1;
00585 info->aConstraintUsage[i].omit = 1;
00586 info->estimatedCost = 2.0;
00587 break;
00588 }
00589 }
00590 }
00591
00592 if (info->nOrderBy > 0) {
00593 if ((info->aOrderBy[0].iColumn == 0) && !info->aOrderBy[0].desc) {
00594 info->orderByConsumed = 1;
00595 }
00596 }
00597 return SQLITE_OK;
00598 }
00599
00607 static int
00608 zip_vtab_open(sqlite3_vtab *vtab, sqlite3_vtab_cursor **cursorp)
00609 {
00610 zip_cursor *cur = sqlite3_malloc(sizeof(*cur));
00611
00612 if (!cur) {
00613 return SQLITE_ERROR;
00614 }
00615 cur->cursor.pVtab = vtab;
00616 cur->pos = -1;
00617 cur->usematches = 0;
00618 cur->nmatches = 0;
00619 cur->matches = 0;
00620 *cursorp = &cur->cursor;
00621 return SQLITE_OK;
00622 }
00623
00630 static int
00631 zip_vtab_close(sqlite3_vtab_cursor *cursor)
00632 {
00633 zip_cursor *cur = (zip_cursor *) cursor;
00634
00635 if (cur->matches) {
00636 sqlite3_free(cur->matches);
00637 }
00638 sqlite3_free(cur);
00639 return SQLITE_OK;
00640 }
00641
00648 static int
00649 zip_vtab_next(sqlite3_vtab_cursor *cursor)
00650 {
00651 zip_cursor *cur = (zip_cursor *) cursor;
00652
00653 if (cur->nmatches >= 0) {
00654 cur->pos++;
00655 }
00656 return SQLITE_OK;
00657 }
00658
00669 static int
00670 zip_vtab_filter(sqlite3_vtab_cursor *cursor, int idxNum,
00671 const char *idxStr, int argc, sqlite3_value **argv)
00672 {
00673 zip_cursor *cur = (zip_cursor *) cursor;
00674 zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
00675
00676 if (cur->matches) {
00677 sqlite3_free(cur->matches);
00678 cur->matches = 0;
00679 }
00680 cur->usematches = 0;
00681 cur->nmatches = 0;
00682
00683 if (idxNum && (argc > 0)) {
00684 int i, k, d, found, leneq, len;
00685 unsigned char *eq;
00686
00687 eq = (unsigned char *) sqlite3_value_text(argv[0]);
00688 if (!eq) {
00689 cur->nmatches = -1;
00690 goto done;
00691 }
00692 if (idxNum > 1) {
00693 unsigned char *p = (unsigned char *) strrchr((char *) eq, '*');
00694
00695 if (!p || (p[1] != '\0')) {
00696 return SQLITE_ERROR;
00697 }
00698 leneq = p - eq;
00699 } else {
00700 leneq = sqlite3_value_bytes(argv[0]);
00701 if (leneq == 0) {
00702 cur->nmatches = -1;
00703 goto done;
00704 }
00705 }
00706 cur->matches = sqlite3_malloc(tab->zip->nentries * sizeof (int));
00707 if (!cur->matches) {
00708 return SQLITE_NOMEM;
00709 }
00710 cur->usematches = 1;
00711 memset(cur->matches, 0, tab->zip->nentries * sizeof (int));
00712 for (k = found = 0; k < tab->zip->nentries; k++) {
00713 len = zip_read_short(tab->zip->entries[k] +
00714 ZIP_CENTRAL_PATHLEN_OFFS);
00715 if (idxNum > 1) {
00716 if (len < leneq) {
00717 continue;
00718 }
00719 } else if (len != leneq) {
00720 if (found) {
00721 break;
00722 }
00723 continue;
00724 }
00725 d = memcmp(tab->zip->entries[k] + ZIP_CENTRAL_HEADER_LEN,
00726 eq, leneq);
00727 if (d == 0) {
00728 found++;
00729 cur->matches[k] = 1;
00730 } else if (d > 0) {
00731 break;
00732 }
00733 }
00734 for (i = k = 0; i < tab->zip->nentries; i++) {
00735 if (cur->matches[i]) {
00736 cur->matches[k++] = i;
00737 }
00738 }
00739 cur->nmatches = k;
00740 }
00741 done:
00742 cur->pos = -1;
00743 return zip_vtab_next(cursor);
00744 }
00745
00752 static int
00753 zip_vtab_eof(sqlite3_vtab_cursor *cursor)
00754 {
00755 zip_cursor *cur = (zip_cursor *) cursor;
00756 zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
00757
00758 if (cur->nmatches < 0) {
00759 return 1;
00760 }
00761 if (cur->usematches) {
00762 return cur->pos >= cur->nmatches;
00763 }
00764 return cur->pos >= tab->zip->nentries;
00765 }
00766
00775 static int
00776 zip_vtab_column(sqlite3_vtab_cursor *cursor, sqlite3_context *ctx, int n)
00777 {
00778 zip_cursor *cur = (zip_cursor *) cursor;
00779 zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
00780 unsigned char *data = 0;
00781 unsigned char *dest = 0;
00782 int length;
00783
00784 if (cur->usematches) {
00785 int pos;
00786
00787 if ((cur->pos < 0) || (cur->pos >= cur->nmatches)) {
00788 sqlite3_result_error(ctx, "out of bounds", -1);
00789 return SQLITE_ERROR;
00790 }
00791 pos = cur->matches[cur->pos];
00792 data = tab->zip->entries[pos];
00793 } else {
00794 if ((cur->pos < 0) || (cur->pos >= tab->zip->nentries)) {
00795 sqlite3_result_error(ctx, "out of bounds", -1);
00796 return SQLITE_ERROR;
00797 }
00798 data = tab->zip->entries[cur->pos];
00799 }
00800 switch (n) {
00801 case 0:
00802 length = zip_read_short(data + ZIP_CENTRAL_PATHLEN_OFFS);
00803 data += ZIP_CENTRAL_HEADER_LEN;
00804 sqlite3_result_text(ctx, (char *) data, length, SQLITE_TRANSIENT);
00805 return SQLITE_OK;
00806 case 1:
00807 length = zip_read_short(data + ZIP_CENTRAL_COMPMETH_OFFS);
00808 sqlite3_result_int(ctx, length);
00809 return SQLITE_OK;
00810 case 2:
00811 {
00812 int time = zip_read_short(data + ZIP_CENTRAL_MTIME_OFFS);
00813 int date = zip_read_short(data + ZIP_CENTRAL_MDATE_OFFS);
00814 char mtbuf[64];
00815
00816 sprintf(mtbuf, "%04d-%02d-%02d %02d:%02d:%02d",
00817 (date >> 9) + 1980, (date >> 5) & 0xf, date & 0x1f,
00818 time >> 11, (time >> 5) & 0x3f, (time & 0x1f) << 1);
00819 sqlite3_result_text(ctx, mtbuf, -1, SQLITE_TRANSIENT);
00820 return SQLITE_OK;
00821 }
00822 case 3:
00823 length = zip_read_int(data + ZIP_CENTRAL_CRC32_OFFS);
00824 sqlite3_result_int(ctx, length);
00825 return SQLITE_OK;
00826 case 4:
00827 length = zip_read_int(data + ZIP_CENTRAL_UNCOMPLEN_OFFS);
00828 sqlite3_result_int(ctx, length);
00829 return SQLITE_OK;
00830 case 5:
00831 {
00832 int clength, offs, extra, pathlen, cmeth;
00833
00834 offs = tab->zip->baseoffs +
00835 zip_read_int(data + ZIP_CENTRAL_LOCALHDR_OFFS);
00836 if ((offs + ZIP_LOCAL_HEADER_LEN) > tab->zip->length) {
00837 goto donull;
00838 }
00839 extra = zip_read_short(tab->zip->data + offs +
00840 ZIP_LOCAL_EXTRA_OFFS);
00841 pathlen = zip_read_short(tab->zip->data + offs +
00842 ZIP_LOCAL_PATHLEN_OFFS);
00843 length = zip_read_int(data + ZIP_CENTRAL_UNCOMPLEN_OFFS);
00844 clength = zip_read_int(data + ZIP_CENTRAL_COMPLEN_OFFS);
00845 cmeth = zip_read_short(data + ZIP_CENTRAL_COMPMETH_OFFS);
00846 offs += ZIP_LOCAL_HEADER_LEN + pathlen + extra;
00847 if ((offs + clength) > tab->zip->length) {
00848 goto donull;
00849 }
00850 data = tab->zip->data + offs;
00851 if (cmeth == ZIP_COMPMETH_STORED) {
00852 sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
00853 return SQLITE_OK;
00854 } else if (cmeth == ZIP_COMPMETH_DEFLATED) {
00855 z_stream stream;
00856 int err;
00857
00858 stream.zalloc = Z_NULL;
00859 stream.zfree = Z_NULL;
00860 stream.next_in = data;
00861 stream.avail_in = clength;
00862 stream.next_out = dest = sqlite3_malloc(length);
00863 stream.avail_out = length;
00864 stream.opaque = 0;
00865 if (!dest) {
00866 goto donull;
00867 }
00868 if (inflateInit2(&stream, -15) != Z_OK) {
00869 goto donull;
00870 }
00871 err = inflate(&stream, Z_SYNC_FLUSH);
00872 inflateEnd(&stream);
00873 if ((err == Z_STREAM_END) ||
00874 ((err == Z_OK) && (stream.avail_in == 0))) {
00875 sqlite3_result_blob(ctx, dest, length, sqlite3_free);
00876 return SQLITE_OK;
00877 }
00878 }
00879 donull:
00880 if (dest) {
00881 sqlite3_free(dest);
00882 }
00883 sqlite3_result_null(ctx);
00884 return SQLITE_OK;
00885 }
00886 case 6:
00887 length = zip_read_int(data + ZIP_CENTRAL_COMPLEN_OFFS);
00888 sqlite3_result_int(ctx, length);
00889 return SQLITE_OK;
00890 case 7:
00891 {
00892 int clength, offs, extra, pathlen;
00893
00894 offs = tab->zip->baseoffs +
00895 zip_read_int(data + ZIP_CENTRAL_LOCALHDR_OFFS);
00896 if ((offs + ZIP_LOCAL_HEADER_LEN) > tab->zip->length) {
00897 goto donull;
00898 }
00899 extra = zip_read_short(tab->zip->data + offs +
00900 ZIP_LOCAL_EXTRA_OFFS);
00901 pathlen = zip_read_short(tab->zip->data + offs +
00902 ZIP_LOCAL_PATHLEN_OFFS);
00903 length = zip_read_int(data + ZIP_CENTRAL_UNCOMPLEN_OFFS);
00904 clength = zip_read_int(data + ZIP_CENTRAL_COMPLEN_OFFS);
00905 offs += ZIP_LOCAL_HEADER_LEN + pathlen + extra;
00906 if ((offs + clength) > tab->zip->length) {
00907 goto donull;
00908 }
00909 data = tab->zip->data + offs;
00910 sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
00911 return SQLITE_OK;
00912 }
00913 case 8:
00914 length = zip_read_short(data + ZIP_CENTRAL_PATHLEN_OFFS);
00915 data += ZIP_CENTRAL_HEADER_LEN;
00916 sqlite3_result_int(ctx, (length > 0 && data[length - 1] == '/'));
00917 return SQLITE_OK;
00918 }
00919 sqlite3_result_error(ctx, "invalid column number", -1);
00920 return SQLITE_ERROR;
00921 }
00922
00930 static int
00931 zip_vtab_rowid(sqlite3_vtab_cursor *cursor, sqlite_int64 *rowidp)
00932 {
00933 zip_cursor *cur = (zip_cursor *) cursor;
00934
00935 if (cur->nmatches < 0) {
00936 *rowidp = -1;
00937 } else if ((cur->pos >= 0) && (cur->usematches > 0)) {
00938 if (cur->pos < cur->nmatches) {
00939 *rowidp = cur->matches[cur->pos];
00940 } else {
00941 *rowidp = -1;
00942 }
00943 } else {
00944 *rowidp = cur->pos;
00945 }
00946 return SQLITE_OK;
00947 }
00948
00956 static void
00957 zip_vtab_matchfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv)
00958 {
00959 int ret = 0;
00960
00961 if (argc == 2) {
00962 unsigned char *q = (unsigned char *) sqlite3_value_text(argv[0]);
00963 unsigned char *p = (unsigned char *) sqlite3_value_text(argv[1]);
00964
00965 if (p && q) {
00966 unsigned char *eq = (unsigned char *) strrchr((char *) q, '*');
00967 int lenq, lenp;
00968
00969 if (eq && (eq[1] == '\0')) {
00970 lenq = eq - q;
00971 if (lenq) {
00972 lenp = strlen((char *) p);
00973 if ((lenp >= lenq) && !memcmp(p, q, lenq)) {
00974 ret = 1;
00975 }
00976 }
00977 }
00978 }
00979 }
00980 sqlite3_result_int(ctx, ret);
00981 }
00982
00993 static int
00994 zip_vtab_findfunc(sqlite3_vtab *vtab, int narg, const char *name,
00995 void (**pfunc)(sqlite3_context *, int, sqlite3_value **),
00996 void **parg)
00997 {
00998 if ((narg == 2) && !strcmp(name, "match")) {
00999 *pfunc = zip_vtab_matchfunc;
01000 *parg = 0;
01001 return 1;
01002 }
01003 return 0;
01004 }
01005
01006 #if (SQLITE_VERSION_NUMBER > 3004000)
01007
01014 static int
01015 zip_vtab_rename(sqlite3_vtab *vtab, const char *newname)
01016 {
01017 return SQLITE_OK;
01018 }
01019
01020 #endif
01021
01026 static const sqlite3_module zip_vtab_mod = {
01027 1,
01028 zip_vtab_create,
01029 zip_vtab_connect,
01030 zip_vtab_bestindex,
01031 zip_vtab_disconnect,
01032 zip_vtab_destroy,
01033 zip_vtab_open,
01034 zip_vtab_close,
01035 zip_vtab_filter,
01036 zip_vtab_next,
01037 zip_vtab_eof,
01038 zip_vtab_column,
01039 zip_vtab_rowid,
01040 0,
01041 0,
01042 0,
01043 0,
01044 0,
01045 zip_vtab_findfunc,
01046 #if (SQLITE_VERSION_NUMBER > 3004000)
01047 zip_vtab_rename,
01048 #endif
01049 };
01050
01058 static void
01059 zip_crc32_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
01060 {
01061 int crc, length;
01062 unsigned char *data;
01063
01064 if (argc != 1) {
01065 sqlite3_result_error(ctx, "need one argument", -1);
01066 }
01067 data = (unsigned char *) sqlite3_value_blob(argv[0]);
01068 length = sqlite3_value_bytes(argv[0]);
01069 crc = crc32(0, 0, 0);
01070 if (data && (length > 0)) {
01071 crc = crc32(crc, data, length);
01072 }
01073 sqlite3_result_int(ctx, crc);
01074 }
01075
01083 static void
01084 zip_inflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
01085 {
01086 int err, length, dlength, avail;
01087 unsigned char *data, *dest, *newdest;
01088 z_stream stream;
01089
01090 if (argc != 1) {
01091 sqlite3_result_error(ctx, "need one argument", -1);
01092 return;
01093 }
01094 data = (unsigned char *) sqlite3_value_blob(argv[0]);
01095 length = sqlite3_value_bytes(argv[0]);
01096 stream.zalloc = Z_NULL;
01097 stream.zfree = Z_NULL;
01098 stream.next_in = data;
01099 stream.avail_in = length;
01100 avail = length;
01101 stream.next_out = dest = sqlite3_malloc(avail);
01102 stream.avail_out = avail;
01103 stream.opaque = 0;
01104 if (!dest) {
01105 goto oom;
01106 }
01107 if (inflateInit2(&stream, -15) != Z_OK) {
01108 goto nomem;
01109 }
01110 dlength = 0;
01111 while (1) {
01112 err = inflate(&stream, Z_SYNC_FLUSH);
01113 if ((err == Z_STREAM_END) ||
01114 ((err == Z_OK) && (stream.avail_in == 0))) {
01115 dlength += length - stream.avail_out;
01116 newdest = sqlite3_realloc(dest, dlength);
01117 inflateEnd(&stream);
01118 if (!newdest) {
01119 nomem:
01120 if (dest) {
01121 sqlite3_free(dest);
01122 }
01123 oom:
01124 sqlite3_result_error_nomem(ctx);
01125 return;
01126 }
01127 sqlite3_result_blob(ctx, newdest, dlength, sqlite3_free);
01128 return;
01129 }
01130 if ((err == Z_BUF_ERROR) || (err == Z_OK)) {
01131 newdest = sqlite3_realloc(dest, avail + length);
01132 dlength += length - stream.avail_out;
01133 if (!newdest) {
01134 inflateEnd(&stream);
01135 goto nomem;
01136 }
01137 avail += length;
01138 stream.next_out = newdest + (stream.next_out - dest);
01139 dest = newdest;
01140 stream.avail_out += length;
01141 } else {
01142 inflateEnd(&stream);
01143 sqlite3_free(dest);
01144 sqlite3_result_error(ctx, "inflate error", -1);
01145 return;
01146 }
01147 }
01148 }
01149
01157 static void
01158 zip_deflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
01159 {
01160 int err, level = 9;
01161 unsigned long avail, length;
01162 unsigned char *data, *dest = 0;
01163 z_stream stream;
01164
01165 if ((argc < 1) || (argc > 2)) {
01166 sqlite3_result_error(ctx, "need one or two arguments", -1);
01167 return;
01168 }
01169 if (argc > 1) {
01170 level = sqlite3_value_int(argv[1]);
01171 }
01172 data = (unsigned char *) sqlite3_value_blob(argv[0]);
01173 length = sqlite3_value_bytes(argv[0]);
01174 stream.zalloc = Z_NULL;
01175 stream.zfree = Z_NULL;
01176 stream.next_in = data;
01177 stream.avail_in = length;
01178 stream.next_out = 0;
01179 stream.avail_out = 0;
01180 stream.opaque = 0;
01181 if (deflateInit2(&stream, level, Z_DEFLATED, -15, 8,
01182 Z_DEFAULT_STRATEGY) != Z_OK) {
01183 goto deflerr;
01184 }
01185 avail = deflateBound(&stream, length);
01186 if (avail == 0) {
01187 sqlite3_result_null(ctx);
01188 return;
01189 }
01190 stream.next_out = dest = sqlite3_malloc(avail);
01191 stream.avail_out = avail;
01192 if (!dest) {
01193 sqlite3_result_error_nomem(ctx);
01194 return;
01195 }
01196 err = deflate(&stream, Z_FINISH);
01197 if (err != Z_STREAM_END) {
01198 deflateEnd(&stream);
01199 deflerr:
01200 if (dest) {
01201 sqlite3_free(dest);
01202 }
01203 sqlite3_result_error(ctx, "deflate error", -1);
01204 return;
01205 }
01206 length = stream.total_out;
01207 err = deflateEnd(&stream);
01208 if (err != Z_OK) {
01209 goto deflerr;
01210 }
01211 sqlite3_result_blob(ctx, dest, length, sqlite3_free);
01212 }
01213
01221 static void
01222 zip_compress_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
01223 {
01224 int err, level = 9;
01225 unsigned long length, dlength;
01226 unsigned char *data, *dest;
01227
01228 if ((argc < 1) || (argc > 2)) {
01229 sqlite3_result_error(ctx, "need one or two arguments", -1);
01230 return;
01231 }
01232 if (argc > 1) {
01233 level = sqlite3_value_int(argv[1]);
01234 }
01235 data = (unsigned char *) sqlite3_value_blob(argv[0]);
01236 length = sqlite3_value_bytes(argv[0]);
01237 dlength = compressBound(length);
01238 dest = sqlite3_malloc(dlength);
01239 if (!dest) {
01240 sqlite3_result_error_nomem(ctx);
01241 return;
01242 }
01243 err = compress2(dest, &dlength, data, length, level);
01244 if (err == Z_OK) {
01245 sqlite3_result_blob(ctx, dest, dlength, sqlite3_free);
01246 return;
01247 }
01248 if (err == Z_MEM_ERROR) {
01249 sqlite3_result_error(ctx, "memory error", -1);
01250 } else if (err == Z_BUF_ERROR) {
01251 sqlite3_result_error(ctx, "buffer error", -1);
01252 } else {
01253 sqlite3_result_error(ctx, "compress error", -1);
01254 }
01255 sqlite3_free(dest);
01256 }
01257
01258 #ifdef SQLITE_OPEN_URI
01259
01267 static mem_blk *
01268 mem_createmb(const unsigned char *data, unsigned long length)
01269 {
01270 mem_blk *mb;
01271 #if defined(_WIN32) || defined(_WIN64)
01272 HANDLE mh;
01273 #else
01274 long psize;
01275 #endif
01276 unsigned long size;
01277
01278 #if defined(_WIN32) || defined(_WIN64)
01279 size = sizeof (mem_blk) + length;
01280 mh = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
01281 0, size, 0);
01282 if (mh == INVALID_HANDLE_VALUE) {
01283 return 0;
01284 }
01285 mb = (mem_blk *) MapViewOfFile(mh, FILE_MAP_ALL_ACCESS, 0, 0, length);
01286 if (!mb) {
01287 return 0;
01288 }
01289 #else
01290 psize = sysconf(_SC_PAGESIZE);
01291 #ifdef linux
01292 mb = (mem_blk *) sqlite3_malloc(sizeof (mem_blk));
01293 if (!mb) {
01294 return 0;
01295 }
01296 size = length + 1;
01297 mb->data = (unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE,
01298 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
01299 if (mb->data == MAP_FAILED) {
01300 sqlite3_free(mb);
01301 return 0;
01302 }
01303 #else
01304 size = sizeof (mem_blk) + psize + length + 1;
01305 mb = (mem_blk *) mmap(0, size, PROT_READ | PROT_WRITE,
01306 MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
01307 if (mb == MAP_FAILED) {
01308 return 0;
01309 }
01310 #endif
01311 #endif
01312 if (mb) {
01313 memcpy(mb->magic, MEM_MAGIC, 4);
01314 mb->opened = 1;
01315 mb->size = size;
01316 mb->length = length;
01317 #if defined(_WIN32) || defined(_WIN64)
01318 mb->mh = mh;
01319 mb->data = (unsigned char *) (mb + 1);
01320 memcpy(mb->data, data, length);
01321 #else
01322 mb->psize = psize;
01323 #ifdef linux
01324 mb->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
01325 sqlite3_mutex_enter(mb->mutex);
01326 mb->lcnt = 0;
01327 memcpy(mb->data, data, length);
01328 #else
01329 if (psize >= sizeof (mem_blk)) {
01330 mb->data = (unsigned char *) mb + psize;
01331 memcpy(mb->data, data, length);
01332 #ifndef linux
01333 mprotect(mb->data, length, PROT_READ);
01334 #endif
01335 } else {
01336 mb->data = (unsigned char *) (mb + 1);
01337 memcpy(mb->data, data, length);
01338 }
01339 #endif
01340 #endif
01341 }
01342 return mb;
01343 }
01344
01350 static void
01351 mem_destroymb(mem_blk *mb)
01352 {
01353 #if defined(_WIN32) || defined(_WIN64)
01354 HANDLE mh;
01355 #endif
01356
01357 if (mb) {
01358 memset(mb->magic, 0, 4);
01359 #if defined(_WIN32) || defined(_WIN64)
01360 mh = mb->mh;
01361 UnmapViewOfFile(mb);
01362 CloseHandle(mh);
01363 #else
01364 #ifdef linux
01365 munmap(mb->data, mb->size);
01366 sqlite3_mutex_leave(mb->mutex);
01367 sqlite3_mutex_free(mb->mutex);
01368 sqlite3_free(mb);
01369 #else
01370 munmap(mb, mb->size);
01371 #endif
01372 #endif
01373 }
01374 }
01375
01382 static int
01383 mem_close(sqlite3_file *file)
01384 {
01385 mem_file *mf = (mem_file *) file;
01386 mem_blk *mb = mf->mb;
01387
01388 if (mb) {
01389 #ifdef linux
01390 sqlite3_mutex_enter(mb->mutex);
01391 if (mf->lock > 0) {
01392 mb->lcnt = 0;
01393 }
01394 #endif
01395 mb->opened--;
01396 if (mb->opened <= 0) {
01397 mem_destroymb(mb);
01398 }
01399 #ifdef linux
01400 else {
01401 sqlite3_mutex_leave(mb->mutex);
01402 }
01403 #endif
01404 mf->mb = 0;
01405 }
01406 return SQLITE_OK;
01407 }
01408
01418 static int
01419 mem_read(sqlite3_file *file, void *buf, int len, sqlite_int64 offs)
01420 {
01421 mem_file *mf = (mem_file *) file;
01422 mem_blk *mb = mf->mb;
01423 int rc = SQLITE_IOERR_READ;
01424
01425 #ifdef linux
01426 if (mb) {
01427 sqlite3_mutex_enter(mb->mutex);
01428 }
01429 #endif
01430 if (mb && (offs <= mb->length)) {
01431 rc = SQLITE_OK;
01432 if (offs + len > mb->length) {
01433 rc = SQLITE_IOERR_SHORT_READ;
01434 len = mb->length - offs;
01435 }
01436 memcpy(buf, mb->data + offs, len);
01437 }
01438 #ifdef linux
01439 if (mb) {
01440 sqlite3_mutex_leave(mb->mutex);
01441 }
01442 #endif
01443 return rc;
01444 }
01445
01453 static int
01454 #ifdef linux
01455 mem_truncate_unlocked(sqlite3_file *file, sqlite_int64 offs)
01456 #else
01457 mem_truncate(sqlite3_file *file, sqlite_int64 offs)
01458 #endif
01459 {
01460 #ifdef linux
01461 mem_file *mf = (mem_file *) file;
01462 mem_blk *mb = mf->mb;
01463 unsigned char *p;
01464 long psize = mb->psize;
01465 unsigned long length = offs;
01466 unsigned long size;
01467
01468 size = length + 1;
01469 if ((psize > 0) && (size / psize == mb->size / psize)) {
01470 p = mb->data;
01471 } else {
01472 p = mremap(mb->data, mb->size, size, MREMAP_MAYMOVE);
01473 }
01474 if (p == MAP_FAILED) {
01475 return SQLITE_IOERR_TRUNCATE;
01476 }
01477 mb->size = size;
01478 mb->length = length;
01479 mb->data = p;
01480 return SQLITE_OK;
01481 #else
01482 return SQLITE_IOERR_TRUNCATE;
01483 #endif
01484 }
01485
01486 #ifdef linux
01487 static int
01488 mem_truncate(sqlite3_file *file, sqlite_int64 offs)
01489 {
01490 mem_file *mf = (mem_file *) file;
01491 mem_blk *mb = mf->mb;
01492 int rc = SQLITE_IOERR_TRUNCATE;
01493
01494 if (mb) {
01495 sqlite3_mutex_enter(mb->mutex);
01496 rc = mem_truncate_unlocked(file, offs);
01497 sqlite3_mutex_leave(mb->mutex);
01498 }
01499 return rc;
01500 }
01501 #endif
01502
01512 static int
01513 mem_write(sqlite3_file *file, const void *buf, int len, sqlite_int64 offs)
01514 {
01515 #ifdef linux
01516 mem_file *mf = (mem_file *) file;
01517 mem_blk *mb = mf->mb;
01518
01519 sqlite3_mutex_enter(mb->mutex);
01520 if (offs + len > mb->length) {
01521 if (mem_truncate_unlocked(file, offs + len) != SQLITE_OK) {
01522 sqlite3_mutex_leave(mb->mutex);
01523 return SQLITE_IOERR_WRITE;
01524 }
01525 }
01526 memcpy(mb->data + offs, buf, len);
01527 sqlite3_mutex_leave(mb->mutex);
01528 return SQLITE_OK;
01529 #else
01530 return SQLITE_IOERR_WRITE;
01531 #endif
01532 }
01533
01541 static int
01542 mem_sync(sqlite3_file *file, int flags)
01543 {
01544 #ifdef linux
01545 return SQLITE_OK;
01546 #else
01547 return SQLITE_IOERR_FSYNC;
01548 #endif
01549 }
01550
01558 static int
01559 mem_filesize(sqlite3_file *file, sqlite_int64 *size)
01560 {
01561 mem_file *mf = (mem_file *) file;
01562 mem_blk *mb = mf->mb;
01563
01564 if (mb) {
01565 #ifdef linux
01566 sqlite3_mutex_enter(mb->mutex);
01567 #endif
01568 *size = mb->length;
01569 #ifdef linux
01570 sqlite3_mutex_leave(mb->mutex);
01571 #endif
01572 return SQLITE_OK;
01573 }
01574 return SQLITE_IOERR_FSTAT;
01575 }
01576
01584 static int
01585 mem_lock(sqlite3_file *file, int lck)
01586 {
01587 #ifdef linux
01588 mem_file *mf = (mem_file *) file;
01589 mem_blk *mb = mf->mb;
01590 int rc = SQLITE_IOERR_LOCK;
01591
01592 if (mb) {
01593 sqlite3_mutex_enter(mb->mutex);
01594 if (lck > 0) {
01595 rc = SQLITE_BUSY;
01596 if ((mf->lock == 0) && (mb->lcnt == 0)) {
01597 mb->lcnt = 1;
01598 mf->lock = lck;
01599 rc = SQLITE_OK;
01600 } else if ((mf->lock > 0) && (mb->lcnt == 1)) {
01601 mf->lock = lck;
01602 rc = SQLITE_OK;
01603 }
01604 }
01605 sqlite3_mutex_leave(mb->mutex);
01606 }
01607 return rc;
01608 #else
01609 return SQLITE_OK;
01610 #endif
01611 }
01612
01620 static int
01621 mem_unlock(sqlite3_file *file, int lck)
01622 {
01623 #ifdef linux
01624 mem_file *mf = (mem_file *) file;
01625 mem_blk *mb = mf->mb;
01626 int rc = SQLITE_IOERR_UNLOCK;
01627
01628 if (mb) {
01629 sqlite3_mutex_enter(mb->mutex);
01630 if (mf->lock == lck) {
01631 rc = SQLITE_OK;
01632 } else if (lck == 0) {
01633 if (mf->lock) {
01634 mb->lcnt = 0;
01635 mf->lock = 0;
01636 }
01637 rc = SQLITE_OK;
01638 } else if ((lck < mf->lock) && (mb->lcnt != 0)) {
01639 mf->lock = lck;
01640 rc = SQLITE_OK;
01641 }
01642 sqlite3_mutex_leave(mb->mutex);
01643 }
01644 return rc;
01645 #else
01646 return SQLITE_OK;
01647 #endif
01648 }
01649
01657 static int
01658 mem_checkreservedlock(sqlite3_file *file, int *out)
01659 {
01660 #ifdef linux
01661 mem_file *mf = (mem_file *) file;
01662 mem_blk *mb = mf->mb;
01663 int rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
01664
01665 if (mb) {
01666 sqlite3_mutex_enter(mb->mutex);
01667 *out = mf->lock >= 2;
01668 sqlite3_mutex_leave(mb->mutex);
01669 rc = SQLITE_OK;
01670 } else {
01671 *out = 0;
01672 }
01673 return rc;
01674 #else
01675 *out = 0;
01676 return SQLITE_OK;
01677 #endif
01678 }
01679
01688 static int
01689 mem_filecontrol(sqlite3_file *file, int op, void *arg)
01690 {
01691 #ifdef SQLITE_FCNTL_PRAGMA
01692 if (op == SQLITE_FCNTL_PRAGMA) {
01693 return SQLITE_NOTFOUND;
01694 }
01695 #endif
01696 return SQLITE_OK;
01697 }
01698
01705 static int
01706 mem_sectorsize(sqlite3_file *file)
01707 {
01708 return 4096;
01709 }
01710
01717 static int
01718 mem_devicecharacteristics(sqlite3_file *file)
01719 {
01720 return 0;
01721 }
01722
01727 static sqlite3_io_methods mem_methods = {
01728 1,
01729 mem_close,
01730 mem_read,
01731 mem_write,
01732 mem_truncate,
01733 mem_sync,
01734 mem_filesize,
01735 mem_lock,
01736 mem_unlock,
01737 mem_checkreservedlock,
01738 mem_filecontrol,
01739 mem_sectorsize,
01740 mem_devicecharacteristics
01741 };
01742
01753 static int
01754 mem_open(sqlite3_vfs *vfs, const char *name, sqlite3_file *file,
01755 int flags, int *outflags)
01756 {
01757 mem_file *mf = (mem_file *) file;
01758 mem_blk *mb = 0;
01759 #ifdef _WIN64
01760 unsigned long long t = 0;
01761 #else
01762 unsigned long t = 0;
01763 #endif
01764 #if !defined(_WIN32) && !defined(_WIN64)
01765 mem_blk mb0;
01766 int pfd[2];
01767 int n;
01768 #endif
01769
01770 if (!name) {
01771 return SQLITE_IOERR;
01772 }
01773 if (flags & (SQLITE_OPEN_MAIN_JOURNAL |
01774 SQLITE_OPEN_WAL |
01775 #ifndef linux
01776 SQLITE_OPEN_READWRITE |
01777 #endif
01778 SQLITE_OPEN_CREATE)) {
01779 return SQLITE_CANTOPEN;
01780 }
01781 #ifdef _WIN64
01782 sscanf(name + 1, "%I64x", &t);
01783 #else
01784 t = strtoul(name + 1, 0, 16);
01785 #endif
01786 mb = (mem_blk *) t;
01787 if (!mb) {
01788 return SQLITE_CANTOPEN;
01789 }
01790 #if !defined(_WIN32) && !defined(_WIN64)
01791 if (pipe(pfd) < 0) {
01792 return SQLITE_CANTOPEN;
01793 }
01794 n = (write(pfd[1], (char *) mb, sizeof (mem_blk)) < 0) ? errno : 0;
01795 if (n == EFAULT) {
01796 cantopen:
01797 close(pfd[0]);
01798 close(pfd[1]);
01799 return SQLITE_CANTOPEN;
01800 }
01801 n = read(pfd[0], (char *) &mb0, sizeof (mem_blk));
01802 if (n != sizeof (mem_blk)) {
01803 goto cantopen;
01804 }
01805 if (memcmp(mb0.magic, MEM_MAGIC, 4) == 0) {
01806 #ifdef linux
01807 n = (write(pfd[1], (char *) mb0.data, 1) < 0) ? errno : 0;
01808 if (n == EFAULT) {
01809 goto cantopen;
01810 }
01811 #endif
01812 if (mb0.length > 0) {
01813 n = (write(pfd[1], (char *) mb0.data + mb0.length - 1, 1) < 0)
01814 ? errno : 0;
01815 if (n == EFAULT) {
01816 goto cantopen;
01817 }
01818 }
01819 close(pfd[0]);
01820 close(pfd[1]);
01821 #ifdef linux
01822 sqlite3_mutex_enter(mb->mutex);
01823 #endif
01824 mb->opened++;
01825 #ifdef linux
01826 sqlite3_mutex_leave(mb->mutex);
01827 #endif
01828 } else {
01829 goto cantopen;
01830 }
01831 #else
01832 if (memcmp(mb->magic, MEM_MAGIC, 4) == 0) {
01833 mb->opened++;
01834 } else {
01835 return SQLITE_CANTOPEN;
01836 }
01837 #endif
01838 memset(mf, 0, sizeof (mem_file));
01839 mf->mb = mb;
01840 mf->base.pMethods = &mem_methods;
01841 if (outflags) {
01842 *outflags = flags;
01843 }
01844 return SQLITE_OK;
01845 }
01846
01855 static int
01856 mem_delete(sqlite3_vfs *vfs, const char *name, int sync)
01857 {
01858 return SQLITE_IOERR_DELETE;
01859 }
01860
01870 static int
01871 mem_access(sqlite3_vfs *vfs, const char *name, int flags, int *outflags)
01872 {
01873 char *endp = 0;
01874 unsigned long t;
01875
01876 t = strtol(name + 1, &endp, 16);
01877 if ((t == 0) ||
01878 #ifndef linux
01879 (flags == SQLITE_ACCESS_READWRITE) ||
01880 #endif
01881 !endp || endp[0]) {
01882 *outflags = 0;
01883 } else {
01884 *outflags = 1;
01885 }
01886 return SQLITE_OK;
01887 }
01888
01898 static int
01899 mem_fullpathname(sqlite3_vfs *vfs, const char *name, int len, char *out)
01900 {
01901 strncpy(out, name, len);
01902 out[len - 1] = '\0';
01903 return SQLITE_OK;
01904 }
01905
01913 static void *
01914 mem_dlopen(sqlite3_vfs *vfs, const char *name)
01915 {
01916 return 0;
01917 }
01918
01926 static void
01927 mem_dlerror(sqlite3_vfs *vfs, int len, char *out)
01928 {
01929 static const char *errtxt = "Loadable extensions are not supported";
01930
01931 strncpy(out, errtxt, strlen(errtxt));
01932 out[len - 1] = '\0';
01933 }
01934
01943 static void
01944 (*mem_dlsym(sqlite3_vfs *vfs, void *handle, const char *sym))(void)
01945 {
01946 return 0;
01947 }
01948
01955 static void
01956 mem_dlclose(sqlite3_vfs *vfs, void *handle)
01957 {
01958 }
01959
01968 static int
01969 mem_randomness(sqlite3_vfs *vfs, int len, char *out)
01970 {
01971 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
01972
01973 return ovfs->xRandomness(ovfs, len, out);
01974 }
01975
01983 static int
01984 mem_sleep(sqlite3_vfs *vfs, int micro)
01985 {
01986 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
01987
01988 return ovfs->xSleep(ovfs, micro);
01989 }
01990
01998 static int
01999 mem_currenttime(sqlite3_vfs *vfs, double *out)
02000 {
02001 sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
02002
02003 return ovfs->xCurrentTime(ovfs, out);
02004 }
02005
02010 static sqlite3_vfs mem_vfs = {
02011 1,
02012 sizeof (mem_file),
02013 256,
02014 0,
02015 mem_vfs_name,
02016 0,
02017 mem_open,
02018 mem_delete,
02019 mem_access,
02020 mem_fullpathname,
02021 mem_dlopen,
02022 mem_dlerror,
02023 mem_dlsym,
02024 mem_dlclose,
02025 mem_randomness,
02026 mem_sleep,
02027 mem_currenttime
02028 };
02029
02054 static void
02055 blob_attach_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
02056 {
02057 unsigned long length;
02058 const unsigned char *data;
02059 mem_blk *mb = 0;
02060 char *sql = 0;
02061 int sqllen = 0;
02062 #ifdef linux
02063 int isrw = 0;
02064 #endif
02065
02066 if (argc != 2) {
02067 sqlite3_result_error(ctx, "need two arguments", -1);
02068 return;
02069 }
02070 data = (const unsigned char *) sqlite3_value_blob(argv[0]);
02071 length = sqlite3_value_bytes(argv[0]);
02072 if (!data || !length) {
02073 sqlite3_result_error(ctx, "empty blob", -1);
02074 return;
02075 }
02076 mb = mem_createmb(data, length);
02077 if (!mb) {
02078 sqlite3_result_error(ctx, "cannot map blob", -1);
02079 return;
02080 }
02081 sql = sqlite3_mprintf("ATTACH "
02082 #ifdef _WIN64
02083 "'file:/%llX"
02084 #else
02085 "'file:/%lX"
02086 #endif
02087 "?vfs=%s&"
02088 #ifdef linux
02089 "mode=rw&"
02090 #else
02091 "mode=ro&"
02092 #endif
02093 "cache=private' AS %Q",
02094 #ifdef _WIN64
02095 (unsigned long long) mb,
02096 #else
02097 (unsigned long) mb,
02098 #endif
02099 mem_vfs_name,
02100 (char *) sqlite3_value_text(argv[1]));
02101 if (!sql) {
02102 sqlite3_result_error(ctx, "cannot map blob", -1);
02103 mem_destroymb(mb);
02104 return;
02105 }
02106 #ifdef linux
02107 sqlite3_mutex_leave(mb->mutex);
02108 #endif
02109 if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
02110 != SQLITE_OK) {
02111 sqlite3_free(sql);
02112 sqlite3_result_error(ctx, "cannot attach blob", -1);
02113 #ifdef linux
02114 sqlite3_mutex_enter(mb->mutex);
02115 #endif
02116 mem_destroymb(mb);
02117 return;
02118 }
02119 sqllen = strlen(sql);
02120 sqlite3_snprintf(sqllen, sql, "PRAGMA %Q.synchronous = OFF",
02121 (char *) sqlite3_value_text(argv[1]));
02122 sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
02123 #ifdef linux
02124 sqlite3_snprintf(sqllen, sql, "PRAGMA %Q.journal_mode = OFF",
02125 (char *) sqlite3_value_text(argv[1]));
02126 if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
02127 == SQLITE_OK) {
02128 isrw = 1;
02129 }
02130 #endif
02131 #ifdef linux
02132 sqlite3_mutex_enter(mb->mutex);
02133 #endif
02134 if (--mb->opened < 1) {
02135 sqlite3_snprintf(sqllen, sql, "DETACH %Q",
02136 (char *) sqlite3_value_text(argv[1]));
02137 sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
02138 sqlite3_free(sql);
02139 sqlite3_result_error(ctx, "cannot attach blob", -1);
02140 mem_destroymb(mb);
02141 return;
02142 }
02143 #ifdef linux
02144 sqlite3_mutex_leave(mb->mutex);
02145 if (isrw) {
02146 sqlite3_snprintf(sqllen, sql,
02147 "file:/%lX?vfs=%s&mode=rw&cache=private",
02148 (unsigned long) mb, mem_vfs_name);
02149 sqlite3_result_text(ctx, sql, -1, sqlite3_free);
02150 return;
02151 }
02152 #endif
02153 sqlite3_free(sql);
02154 sqlite3_result_null(ctx);
02155 }
02156
02174 static void
02175 blob_dump_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
02176 {
02177 char *uri, vfs[64];
02178 #ifdef _WIN64
02179 unsigned long long addr = 0;
02180 #else
02181 unsigned long addr = 0;
02182 #endif
02183 #ifdef linux
02184 int pfd[2], n;
02185 mem_blk *mb;
02186 #endif
02187
02188 if (argc != 1) {
02189 sqlite3_result_error(ctx, "need one argument", -1);
02190 return;
02191 }
02192 uri = (char *) sqlite3_value_text(argv[0]);
02193 vfs[0] = '\0';
02194 if (!uri || (sscanf(uri,
02195 #ifdef _WIN64
02196 "file:/%I64X?vfs=%63[^&]",
02197 #else
02198 "file:/%lX?vfs=%63[^&]",
02199 #endif
02200 &addr, vfs) != 2)) {
02201 inval:
02202 sqlite3_result_error(ctx, "invalid object", -1);
02203 return;
02204 }
02205 vfs[63] = '\0';
02206 if ((strcmp(mem_vfs_name, vfs) != 0) || (addr == 0)) {
02207 goto inval;
02208 }
02209 #ifdef linux
02210 if (pipe(pfd) < 0) {
02211 goto inval;
02212 }
02213 n = (write(pfd[1], (char *) addr, 1) < 0) ? errno : 0;
02214 close(pfd[0]);
02215 close(pfd[1]);
02216 if (n == EFAULT) {
02217 goto inval;
02218 }
02219 mb = (mem_blk *) addr;
02220 if (memcmp(mb->magic, MEM_MAGIC, 4) != 0) {
02221 goto inval;
02222 }
02223 sqlite3_mutex_enter(mb->mutex);
02224 sqlite3_result_blob(ctx, mb->data, mb->length, SQLITE_STATIC);
02225 sqlite3_mutex_leave(mb->mutex);
02226 #else
02227 sqlite3_result_error(ctx, "unsupported function", -1);
02228 #endif
02229 }
02230
02231 #endif
02232
02239 #ifndef STANDALONE
02240 static
02241 #endif
02242 int
02243 zip_vtab_init(sqlite3 *db)
02244 {
02245 sqlite3_create_function(db, "crc32", 1, SQLITE_UTF8,
02246 (void *) db, zip_crc32_func, 0, 0);
02247 sqlite3_create_function(db, "inflate", 1, SQLITE_UTF8,
02248 (void *) db, zip_inflate_func, 0, 0);
02249 sqlite3_create_function(db, "deflate", 1, SQLITE_UTF8,
02250 (void *) db, zip_deflate_func, 0, 0);
02251 sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8,
02252 (void *) db, zip_inflate_func, 0, 0);
02253 sqlite3_create_function(db, "compress", -1, SQLITE_UTF8,
02254 (void *) db, zip_compress_func, 0, 0);
02255 #ifdef SQLITE_OPEN_URI
02256 if (!mem_vfs.pAppData) {
02257 sqlite3_vfs *parent = sqlite3_vfs_find(0);
02258
02259 if (parent) {
02260 sqlite3_snprintf(sizeof (mem_vfs_name), mem_vfs_name,
02261 #ifdef _WIN64
02262 "mem_vfs_%llX", (unsigned long long) &mem_vfs
02263 #else
02264 "mem_vfs_%lX", (unsigned long) &mem_vfs
02265 #endif
02266 );
02267 if (sqlite3_vfs_register(&mem_vfs, 0) == SQLITE_OK) {
02268 mem_vfs.pAppData = (void *) parent;
02269 }
02270 }
02271 }
02272 if (mem_vfs.pAppData) {
02273 sqlite3_create_function(db, "blob_attach", 2, SQLITE_UTF8,
02274 (void *) db, blob_attach_func, 0, 0);
02275 sqlite3_create_function(db, "blob_dump", 1, SQLITE_UTF8,
02276 (void *) db, blob_dump_func, 0, 0);
02277 }
02278 #endif
02279 return sqlite3_create_module(db, "zipfile", &zip_vtab_mod, 0);
02280 }
02281
02282 #ifndef STANDALONE
02283
02292 int
02293 sqlite3_extension_init(sqlite3 *db, char **errmsg,
02294 const sqlite3_api_routines *api)
02295 {
02296 SQLITE_EXTENSION_INIT2(api);
02297 return zip_vtab_init(db);
02298 }
02299
02300 #endif