zipfile.c
Go to the documentation of this file.
1 
18 #ifdef linux
19 #define _GNU_SOURCE
20 #endif
21 
22 #ifdef STANDALONE
23 #include <sqlite3.h>
24 #else
25 #include <sqlite3ext.h>
26 static SQLITE_EXTENSION_INIT1
27 #endif
28 
29 #if defined(_WIN32) || defined(_WIN64)
30 #include <windows.h>
31 #else
32 #include <sys/mman.h>
33 #include <fcntl.h>
34 #include <unistd.h>
35 #include <errno.h>
36 #endif
37 
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <limits.h>
42 
43 #include <zlib.h>
44 
45 #undef snprintf
46 
47 #define ZIP_SIG_LEN 4
48 
49 #define ZIP_LOCAL_HEADER_SIG 0x04034b50
50 #define ZIP_LOCAL_HEADER_FLAGS 6
51 #define ZIP_LOCAL_PATHLEN_OFFS 26
52 #define ZIP_LOCAL_EXTRA_OFFS 28
53 #define ZIP_LOCAL_HEADER_LEN 30
54 
55 #define ZIP_CENTRAL_HEADER_SIG 0x02014b50
56 #define ZIP_CENTRAL_HEADER_FLAGS 8
57 #define ZIP_CENTRAL_HEADER_LEN 46
58 #define ZIP_CENTRAL_COMPMETH_OFFS 10
59 #define ZIP_CENTRAL_MTIME_OFFS 12
60 #define ZIP_CENTRAL_MDATE_OFFS 14
61 #define ZIP_CENTRAL_CRC32_OFFS 16
62 #define ZIP_CENTRAL_COMPLEN_OFFS 20
63 #define ZIP_CENTRAL_UNCOMPLEN_OFFS 24
64 #define ZIP_CENTRAL_PATHLEN_OFFS 28
65 #define ZIP_CENTRAL_EXTRALEN_OFFS 30
66 #define ZIP_CENTRAL_COMMENTLEN_OFFS 32
67 #define ZIP_CENTRAL_LOCALHDR_OFFS 42
68 
69 #define ZIP_CENTRAL_END_SIG 0x06054b50
70 #define ZIP_CENTRAL_END_LEN 22
71 #define ZIP_CENTRAL_ENTS_OFFS 8
72 #define ZIP_CENTRAL_DIRSIZE_OFFS 12
73 #define ZIP_CENTRAL_DIRSTART_OFFS 16
74 
75 #define ZIP_COMPMETH_STORED 0
76 #define ZIP_COMPMETH_DEFLATED 8
77 
78 #define zip_read_int(p) \
79  ((p)[0] | ((p)[1] << 8) | ((p)[2] << 16) | ((p)[3] << 24))
80 #define zip_read_short(p) \
81  ((p)[0] | ((p)[1] << 8))
82 
89 typedef struct zip_file {
90  off_t length;
91  unsigned char *data;
92 #if defined(_WIN32) || defined(_WIN64)
93  HANDLE h;
94  HANDLE mh;
95 #endif
96  int baseoffs;
97  int nentries;
98  unsigned char *entries[1];
99 } zip_file;
100 
107 typedef struct zip_vtab {
108  sqlite3_vtab vtab;
109  sqlite3 *db;
111  int sorted;
112  char tblname[1];
113 } zip_vtab;
114 
121 typedef struct {
122  sqlite3_vtab_cursor cursor;
123  int pos;
125  int nmatches;
126  int *matches;
127 } zip_cursor;
128 
129 #ifdef SQLITE_OPEN_URI
130 
137 typedef struct mem_blk {
138 #define MEM_MAGIC "MVFS"
139  char magic[4];
140  int opened;
141 #if defined(_WIN32) || defined(_WIN64)
142  HANDLE mh;
143 #else
144  long psize;
145 #ifdef linux
146  sqlite3_mutex *mutex;
147  int lcnt;
148 #endif
149 #endif
150  unsigned long size;
151  unsigned long length;
152  unsigned char *data;
153 } mem_blk;
154 
161 typedef struct mem_file {
162  sqlite3_file base;
163 #ifdef linux
164  int lock;
165 #endif
166  mem_blk *mb;
167 } mem_file;
168 
169 /*
170  * Private VFS name
171  */
172 
173 static char mem_vfs_name[64];
174 
175 #endif /* SQLITE_OPEN_URI */
176 
183 static zip_file *
184 zip_open(const char *filename)
185 {
186 #if defined(_WIN32) || defined(_WIN64)
187  HANDLE h, mh = INVALID_HANDLE_VALUE;
188  DWORD length;
189  unsigned char *data = 0;
190 #else
191  int fd;
192  off_t length;
193  unsigned char *data = MAP_FAILED;
194 #endif
195  int nentries, baseoffs = 0, i;
196  zip_file *zip = 0;
197  unsigned char *p, *q;
198 
199  if (!filename) {
200  return 0;
201  }
202 #if defined(_WIN32) || defined(_WIN64)
203  h = CreateFile(filename, GENERIC_READ, 0, 0, OPEN_EXISTING, 0, 0);
204  if (h == INVALID_HANDLE_VALUE) {
205  goto error;
206  }
207  length = GetFileSize(h, 0);
208  if ((length == INVALID_FILE_SIZE) || (length < ZIP_CENTRAL_END_LEN)) {
209  goto error;
210  }
211  mh = CreateFileMapping(h, 0, PAGE_READONLY, 0, length, 0);
212  if (mh == INVALID_HANDLE_VALUE) {
213  goto error;
214  }
215  data = MapViewOfFile(mh, FILE_MAP_READ, 0, 0, length);
216  if (!data) {
217  goto error;
218  }
219 #else
220  fd = open(filename, O_RDONLY);
221  if (fd < 0) {
222  goto error;
223  }
224  length = lseek(fd, 0, SEEK_END);
225  if ((length == -1) || (length < ZIP_CENTRAL_END_LEN)) {
226  goto error;
227  }
228  data = (unsigned char *) mmap(0, length, PROT_READ,
229  MAP_FILE | MAP_PRIVATE, fd, 0);
230  if (data == MAP_FAILED) {
231  goto error;
232  }
233  close(fd);
234  fd = -1;
235 #endif
236  p = data + length - ZIP_CENTRAL_END_LEN;
237  while (p >= data) {
238  if (*p == (ZIP_CENTRAL_END_SIG & 0xFF)) {
239  if (zip_read_int(p) == ZIP_CENTRAL_END_SIG) {
240  break;
241  }
242  p -= ZIP_SIG_LEN;
243  } else {
244  --p;
245  }
246  }
247  if (p < data) {
248  goto error;
249  }
250  nentries = zip_read_short(p + ZIP_CENTRAL_ENTS_OFFS);
251  if (nentries == 0) {
252  goto error;
253  }
254  q = data + zip_read_int(p + ZIP_CENTRAL_DIRSTART_OFFS);
256  if (p < data || p > data + length || q < data || q > data + length) {
257  goto error;
258  }
259  baseoffs = p - q;
260  q = p;
261  for (i = 0; i < nentries; i++) {
262  int pathlen, comlen, extra;
263 
264  if ((q + ZIP_CENTRAL_HEADER_LEN) > (data + length)) {
265  goto error;
266  }
268  goto error;
269  }
273  q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN;
274  }
275  zip = sqlite3_malloc(sizeof (zip_file) +
276  nentries * sizeof (unsigned char *));
277  if (!zip) {
278  goto error;
279  }
280 #if defined(_WIN32) || defined(_WIN64)
281  zip->h = zip->mh = INVALID_HANDLE_VALUE;
282 #endif
283  zip->length = length;
284  zip->data = data;
285  zip->baseoffs = baseoffs;
286  zip->nentries = nentries;
287  q = p;
288  for (i = 0; i < nentries; i++) {
289  int pathlen, comlen, extra;
290 
291  if ((q + ZIP_CENTRAL_HEADER_LEN) > (data + length)) {
292  goto error;
293  }
295  goto error;
296  }
297  zip->entries[i] = q;
301  q += pathlen + comlen + extra + ZIP_CENTRAL_HEADER_LEN;
302  }
303  zip->entries[i] = 0;
304 #if defined(_WIN32) || defined(_WIN64)
305  zip->h = h;
306  zip->mh = mh;
307 #endif
308  return zip;
309 error:
310  if (zip) {
311  sqlite3_free(zip);
312  }
313 #if defined(_WIN32) || defined(_WIN64)
314  if (data) {
315  UnmapViewOfFile(data);
316  }
317  if (mh != INVALID_HANDLE_VALUE) {
318  CloseHandle(mh);
319  }
320  if (h != INVALID_HANDLE_VALUE) {
321  CloseHandle(h);
322  }
323 #else
324  if (data != MAP_FAILED) {
325  munmap(data, length);
326  }
327  if (fd >= 0) {
328  close(fd);
329  }
330 #endif
331  return 0;
332 }
333 
339 static void
341 {
342  if (zip) {
343 #if defined(_WIN32) || defined(_WIN64)
344  if (zip->data) {
345  UnmapViewOfFile(zip->data);
346  }
347  if (zip->mh != INVALID_HANDLE_VALUE) {
348  CloseHandle(zip->mh);
349  }
350  if (zip->h != INVALID_HANDLE_VALUE) {
351  CloseHandle(zip->h);
352  }
353 #else
354  if (zip->data) {
355  munmap(zip->data, zip->length);
356  }
357 #endif
358  zip->length = 0;
359  zip->data = 0;
360  zip->nentries = 0;
361  sqlite3_free(zip);
362  }
363 }
364 
371 static char *
372 unquote(char const *in)
373 {
374  char c, *ret;
375  int i;
376 
377  ret = sqlite3_malloc(strlen(in) + 1);
378  if (ret) {
379  c = in[0];
380  if ((c == '"') || (c == '\'')) {
381  i = strlen(in + 1);
382  if ((i > 0) && (in[i] == c)) {
383  strcpy(ret, in + 1);
384  ret[i - 1] = '\0';
385  return ret;
386  }
387  }
388  strcpy(ret, in);
389  }
390  return ret;
391 }
392 
411 static int
412 zip_vtab_connect(sqlite3* db, void *aux, int argc, const char * const *argv,
413  sqlite3_vtab **vtabp, char **errp)
414 {
415  zip_file *zip = 0;
416  int rc = SQLITE_ERROR;
417  char *filename;
418  zip_vtab *vtab;
419 
420  if (argc < 4) {
421  *errp = sqlite3_mprintf("input file name missing");
422  return SQLITE_ERROR;
423  }
424  filename = unquote(argv[3]);
425  if (filename) {
426  zip = zip_open(filename);
427  sqlite3_free(filename);
428  }
429  if (!zip) {
430  *errp = sqlite3_mprintf("unable to open input file");
431  return rc;
432  }
433  vtab = sqlite3_malloc(sizeof(zip_vtab) + 6 +
434  strlen(argv[1]) + strlen(argv[2]));
435  if (!vtab) {
436  zip_close(zip);
437  *errp = sqlite3_mprintf("out of memory");
438  return rc;
439  }
440  memset(vtab, 0, sizeof (*vtab));
441  strcpy(vtab->tblname, "\"");
442  strcat(vtab->tblname, argv[1]);
443  strcat(vtab->tblname, "\".\"");
444  strcat(vtab->tblname, argv[2]);
445  strcat(vtab->tblname, "\"");
446  vtab->db = db;
447  vtab->zip = zip;
448  rc = sqlite3_declare_vtab(db, "CREATE TABLE x(path, comp, mtime, "
449  "crc32, length, data, clength, cdata, isdir)");
450  if (rc != SQLITE_OK) {
451  zip_close(zip);
452  sqlite3_free(vtab);
453  *errp = sqlite3_mprintf("table definition failed (error %d)", rc);
454  return rc;
455  }
456  *vtabp = &vtab->vtab;
457  *errp = 0;
458  return SQLITE_OK;
459 }
460 
472 static int
473 zip_vtab_create(sqlite3* db, void *aux, int argc,
474  const char *const *argv,
475  sqlite3_vtab **vtabp, char **errp)
476 {
477  return zip_vtab_connect(db, aux, argc, argv, vtabp, errp);
478 }
479 
486 static int
487 zip_vtab_disconnect(sqlite3_vtab *vtab)
488 {
489  zip_vtab *tab = (zip_vtab *) vtab;
490 
491  zip_close(tab->zip);
492  sqlite3_free(tab);
493  return SQLITE_OK;
494 }
495 
502 static int
503 zip_vtab_destroy(sqlite3_vtab *vtab)
504 {
505  return zip_vtab_disconnect(vtab);
506 }
507 
515 static int
516 zip_vtab_bestindex(sqlite3_vtab *vtab, sqlite3_index_info *info)
517 {
518  zip_vtab *tab = (zip_vtab *) vtab;
519  int i;
520 
521  info->idxNum = 0;
522  if (tab->sorted == 0) {
523  char *sql = 0;
524  unsigned char **entries = 0;
525  sqlite3_stmt *stmt = 0;
526  int rc, count, i;
527  size_t tmp;
528 
529  /* perform sorting on 0th column (path, string) */
530  tab->sorted = -1;
531  entries = sqlite3_malloc(tab->zip->nentries * sizeof (entries));
532  sql = sqlite3_mprintf("SELECT rowid FROM %s ORDER BY path",
533  tab->tblname);
534  if (sql && entries) {
535  rc = sqlite3_prepare_v2(tab->db, sql, -1, &stmt, 0);
536  if ((rc == SQLITE_OK) && stmt) {
537  count = 0;
538  while (1) {
539  rc = sqlite3_step(stmt);
540  if (rc != SQLITE_ROW) {
541  break;
542  }
543  tmp = sqlite3_column_int(stmt, 0);
544  entries[count++] = (unsigned char *) tmp;
545  }
546  if ((rc == SQLITE_DONE) && (count == tab->zip->nentries)) {
547  for (i = 0; i < count; i++) {
548  tmp = (size_t) entries[i];
549  tmp = (size_t) tab->zip->entries[tmp];
550  entries[i] = (unsigned char *) tmp;
551  }
552  memcpy(tab->zip->entries, entries, i * sizeof (entries));
553  tab->sorted = 1;
554  }
555  }
556  }
557  if (stmt) {
558  sqlite3_finalize(stmt);
559  }
560  if (sql) {
561  sqlite3_free(sql);
562  }
563  if (entries) {
564  sqlite3_free(entries);
565  }
566  }
567  /* no optimization while table is being sorted or is unsorted */
568  if (tab->sorted != 1) {
569  return SQLITE_OK;
570  }
571  /* support EQ or simple MATCH constraint on 0th column (path) */
572  for (i = 0; i < info->nConstraint; i++) {
573  if (info->aConstraint[i].usable &&
574  (info->aConstraint[i].iColumn == 0)) {
575  if (info->aConstraint[i].op == SQLITE_INDEX_CONSTRAINT_EQ) {
576  info->idxNum = 1;
577  info->aConstraintUsage[i].argvIndex = 1;
578  info->aConstraintUsage[i].omit = 1;
579  info->estimatedCost = 1.0;
580  break;
581  } else if (info->aConstraint[i].op ==
582  SQLITE_INDEX_CONSTRAINT_MATCH) {
583  info->idxNum = 2;
584  info->aConstraintUsage[i].argvIndex = 1;
585  info->aConstraintUsage[i].omit = 1;
586  info->estimatedCost = 2.0;
587  break;
588  }
589  }
590  }
591  /* ORDER BY is ascending on 0th column (path) when table is sorted */
592  if (info->nOrderBy > 0) {
593  if ((info->aOrderBy[0].iColumn == 0) && !info->aOrderBy[0].desc) {
594  info->orderByConsumed = 1;
595  }
596  }
597  return SQLITE_OK;
598 }
599 
607 static int
608 zip_vtab_open(sqlite3_vtab *vtab, sqlite3_vtab_cursor **cursorp)
609 {
610  zip_cursor *cur = sqlite3_malloc(sizeof(*cur));
611 
612  if (!cur) {
613  return SQLITE_ERROR;
614  }
615  cur->cursor.pVtab = vtab;
616  cur->pos = -1;
617  cur->usematches = 0;
618  cur->nmatches = 0;
619  cur->matches = 0;
620  *cursorp = &cur->cursor;
621  return SQLITE_OK;
622 }
623 
630 static int
631 zip_vtab_close(sqlite3_vtab_cursor *cursor)
632 {
633  zip_cursor *cur = (zip_cursor *) cursor;
634 
635  if (cur->matches) {
636  sqlite3_free(cur->matches);
637  }
638  sqlite3_free(cur);
639  return SQLITE_OK;
640 }
641 
648 static int
649 zip_vtab_next(sqlite3_vtab_cursor *cursor)
650 {
651  zip_cursor *cur = (zip_cursor *) cursor;
652 
653  if (cur->nmatches >= 0) {
654  cur->pos++;
655  }
656  return SQLITE_OK;
657 }
658 
669 static int
670 zip_vtab_filter(sqlite3_vtab_cursor *cursor, int idxNum,
671  const char *idxStr, int argc, sqlite3_value **argv)
672 {
673  zip_cursor *cur = (zip_cursor *) cursor;
674  zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
675 
676  if (cur->matches) {
677  sqlite3_free(cur->matches);
678  cur->matches = 0;
679  }
680  cur->usematches = 0;
681  cur->nmatches = 0;
682  /* if EQ or MATCH constraint is active, add match array to cursor */
683  if (idxNum && (argc > 0)) {
684  int i, k, d, found, leneq, len;
685  unsigned char *eq;
686 
687  eq = (unsigned char *) sqlite3_value_text(argv[0]);
688  if (!eq) {
689  cur->nmatches = -1;
690  goto done;
691  }
692  if (idxNum > 1) {
693  unsigned char *p = (unsigned char *) strrchr((char *) eq, '*');
694 
695  if (!p || (p[1] != '\0')) {
696  return SQLITE_ERROR;
697  }
698  leneq = p - eq;
699  } else {
700  leneq = sqlite3_value_bytes(argv[0]);
701  if (leneq == 0) {
702  cur->nmatches = -1;
703  goto done;
704  }
705  }
706  cur->matches = sqlite3_malloc(tab->zip->nentries * sizeof (int));
707  if (!cur->matches) {
708  return SQLITE_NOMEM;
709  }
710  cur->usematches = 1;
711  memset(cur->matches, 0, tab->zip->nentries * sizeof (int));
712  for (k = found = 0; k < tab->zip->nentries; k++) {
713  len = zip_read_short(tab->zip->entries[k] +
715  if (idxNum > 1) {
716  if (len < leneq) {
717  continue;
718  }
719  } else if (len != leneq) {
720  if (found) {
721  break;
722  }
723  continue;
724  }
725  d = memcmp(tab->zip->entries[k] + ZIP_CENTRAL_HEADER_LEN,
726  eq, leneq);
727  if (d == 0) {
728  found++;
729  cur->matches[k] = 1;
730  } else if (d > 0) {
731  break;
732  }
733  }
734  for (i = k = 0; i < tab->zip->nentries; i++) {
735  if (cur->matches[i]) {
736  cur->matches[k++] = i;
737  }
738  }
739  cur->nmatches = k;
740  }
741 done:
742  cur->pos = -1;
743  return zip_vtab_next(cursor);
744 }
745 
752 static int
753 zip_vtab_eof(sqlite3_vtab_cursor *cursor)
754 {
755  zip_cursor *cur = (zip_cursor *) cursor;
756  zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
757 
758  if (cur->nmatches < 0) {
759  return 1;
760  }
761  if (cur->usematches) {
762  return cur->pos >= cur->nmatches;
763  }
764  return cur->pos >= tab->zip->nentries;
765 }
766 
775 static int
776 zip_vtab_column(sqlite3_vtab_cursor *cursor, sqlite3_context *ctx, int n)
777 {
778  zip_cursor *cur = (zip_cursor *) cursor;
779  zip_vtab *tab = (zip_vtab *) cur->cursor.pVtab;
780  unsigned char *data = 0;
781  unsigned char *dest = 0;
782  int length;
783 
784  if (cur->usematches) {
785  int pos;
786 
787  if ((cur->pos < 0) || (cur->pos >= cur->nmatches)) {
788  sqlite3_result_error(ctx, "out of bounds", -1);
789  return SQLITE_ERROR;
790  }
791  pos = cur->matches[cur->pos];
792  data = tab->zip->entries[pos];
793  } else {
794  if ((cur->pos < 0) || (cur->pos >= tab->zip->nentries)) {
795  sqlite3_result_error(ctx, "out of bounds", -1);
796  return SQLITE_ERROR;
797  }
798  data = tab->zip->entries[cur->pos];
799  }
800  switch (n) {
801  case 0: /* "path": pathname */
804  sqlite3_result_text(ctx, (char *) data, length, SQLITE_TRANSIENT);
805  return SQLITE_OK;
806  case 1: /* "comp": compression method */
808  sqlite3_result_int(ctx, length);
809  return SQLITE_OK;
810  case 2: /* "mtime": modification time/date */
811  {
814  char mtbuf[64];
815 
816  sprintf(mtbuf, "%04d-%02d-%02d %02d:%02d:%02d",
817  (date >> 9) + 1980, (date >> 5) & 0xf, date & 0x1f,
818  time >> 11, (time >> 5) & 0x3f, (time & 0x1f) << 1);
819  sqlite3_result_text(ctx, mtbuf, -1, SQLITE_TRANSIENT);
820  return SQLITE_OK;
821  }
822  case 3: /* "crc32": CRC32 of uncompress data */
824  sqlite3_result_int(ctx, length);
825  return SQLITE_OK;
826  case 4: /* "length": uncompress length of data */
828  sqlite3_result_int(ctx, length);
829  return SQLITE_OK;
830  case 5: /* "data": uncompressed data */
831  {
832  int clength, offs, extra, pathlen, cmeth;
833 
834  offs = tab->zip->baseoffs +
836  if ((offs + ZIP_LOCAL_HEADER_LEN) > tab->zip->length) {
837  goto donull;
838  }
839  extra = zip_read_short(tab->zip->data + offs +
841  pathlen = zip_read_short(tab->zip->data + offs +
846  offs += ZIP_LOCAL_HEADER_LEN + pathlen + extra;
847  if ((offs + clength) > tab->zip->length) {
848  goto donull;
849  }
850  data = tab->zip->data + offs;
851  if (cmeth == ZIP_COMPMETH_STORED) {
852  sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
853  return SQLITE_OK;
854  } else if (cmeth == ZIP_COMPMETH_DEFLATED) {
855  z_stream stream;
856  int err;
857 
858  stream.zalloc = Z_NULL;
859  stream.zfree = Z_NULL;
860  stream.next_in = data;
861  stream.avail_in = clength;
862  stream.next_out = dest = sqlite3_malloc(length);
863  stream.avail_out = length;
864  stream.opaque = 0;
865  if (!dest) {
866  goto donull;
867  }
868  if (inflateInit2(&stream, -15) != Z_OK) {
869  goto donull;
870  }
871  err = inflate(&stream, Z_SYNC_FLUSH);
872  inflateEnd(&stream);
873  if ((err == Z_STREAM_END) ||
874  ((err == Z_OK) && (stream.avail_in == 0))) {
875  sqlite3_result_blob(ctx, dest, length, sqlite3_free);
876  return SQLITE_OK;
877  }
878  }
879  donull:
880  if (dest) {
881  sqlite3_free(dest);
882  }
883  sqlite3_result_null(ctx);
884  return SQLITE_OK;
885  }
886  case 6: /* "clength": compressed length */
888  sqlite3_result_int(ctx, length);
889  return SQLITE_OK;
890  case 7: /* "cdata": raw data */
891  {
892  int clength, offs, extra, pathlen;
893 
894  offs = tab->zip->baseoffs +
896  if ((offs + ZIP_LOCAL_HEADER_LEN) > tab->zip->length) {
897  goto donull;
898  }
899  extra = zip_read_short(tab->zip->data + offs +
901  pathlen = zip_read_short(tab->zip->data + offs +
905  offs += ZIP_LOCAL_HEADER_LEN + pathlen + extra;
906  if ((offs + clength) > tab->zip->length) {
907  goto donull;
908  }
909  data = tab->zip->data + offs;
910  sqlite3_result_blob(ctx, data, clength, SQLITE_TRANSIENT);
911  return SQLITE_OK;
912  }
913  case 8: /* "isdir": directory indicator */
916  sqlite3_result_int(ctx, (length > 0 && data[length - 1] == '/'));
917  return SQLITE_OK;
918  }
919  sqlite3_result_error(ctx, "invalid column number", -1);
920  return SQLITE_ERROR;
921 }
922 
930 static int
931 zip_vtab_rowid(sqlite3_vtab_cursor *cursor, sqlite_int64 *rowidp)
932 {
933  zip_cursor *cur = (zip_cursor *) cursor;
934 
935  if (cur->nmatches < 0) {
936  *rowidp = -1;
937  } else if ((cur->pos >= 0) && (cur->usematches > 0)) {
938  if (cur->pos < cur->nmatches) {
939  *rowidp = cur->matches[cur->pos];
940  } else {
941  *rowidp = -1;
942  }
943  } else {
944  *rowidp = cur->pos;
945  }
946  return SQLITE_OK;
947 }
948 
956 static void
957 zip_vtab_matchfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv)
958 {
959  int ret = 0;
960 
961  if (argc == 2) {
962  unsigned char *q = (unsigned char *) sqlite3_value_text(argv[0]);
963  unsigned char *p = (unsigned char *) sqlite3_value_text(argv[1]);
964 
965  if (p && q) {
966  unsigned char *eq = (unsigned char *) strrchr((char *) q, '*');
967  int lenq, lenp;
968 
969  if (eq && (eq[1] == '\0')) {
970  lenq = eq - q;
971  if (lenq) {
972  lenp = strlen((char *) p);
973  if ((lenp >= lenq) && !memcmp(p, q, lenq)) {
974  ret = 1;
975  }
976  }
977  }
978  }
979  }
980  sqlite3_result_int(ctx, ret);
981 }
982 
993 static int
994 zip_vtab_findfunc(sqlite3_vtab *vtab, int narg, const char *name,
995  void (**pfunc)(sqlite3_context *, int, sqlite3_value **),
996  void **parg)
997 {
998  if ((narg == 2) && !strcmp(name, "match")) {
999  *pfunc = zip_vtab_matchfunc;
1000  *parg = 0;
1001  return 1;
1002  }
1003  return 0;
1004 }
1005 
1006 #if (SQLITE_VERSION_NUMBER > 3004000)
1007 
1014 static int
1015 zip_vtab_rename(sqlite3_vtab *vtab, const char *newname)
1016 {
1017  return SQLITE_OK;
1018 }
1019 
1020 #endif
1021 
1026 static const sqlite3_module zip_vtab_mod = {
1027  1, /* iVersion */
1028  zip_vtab_create, /* xCreate */
1029  zip_vtab_connect, /* xConnect */
1030  zip_vtab_bestindex, /* xBestIndex */
1031  zip_vtab_disconnect, /* xDisconnect */
1032  zip_vtab_destroy, /* xDestroy */
1033  zip_vtab_open, /* xOpen */
1034  zip_vtab_close, /* xClose */
1035  zip_vtab_filter, /* xFilter */
1036  zip_vtab_next, /* xNext */
1037  zip_vtab_eof, /* xEof */
1038  zip_vtab_column, /* xColumn */
1039  zip_vtab_rowid, /* xRowid */
1040  0, /* xUpdate */
1041  0, /* xBegin */
1042  0, /* xSync */
1043  0, /* xCommit */
1044  0, /* xRollback */
1045  zip_vtab_findfunc, /* xFindFunction */
1046 #if (SQLITE_VERSION_NUMBER > 3004000)
1047  zip_vtab_rename, /* xRename */
1048 #endif
1049 };
1050 
1058 static void
1059 zip_crc32_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
1060 {
1061  int crc, length;
1062  unsigned char *data;
1063 
1064  if (argc != 1) {
1065  sqlite3_result_error(ctx, "need one argument", -1);
1066  }
1067  data = (unsigned char *) sqlite3_value_blob(argv[0]);
1068  length = sqlite3_value_bytes(argv[0]);
1069  crc = crc32(0, 0, 0);
1070  if (data && (length > 0)) {
1071  crc = crc32(crc, data, length);
1072  }
1073  sqlite3_result_int(ctx, crc);
1074 }
1075 
1083 static void
1084 zip_inflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
1085 {
1086  int err, length, dlength, avail;
1087  unsigned char *data, *dest, *newdest;
1088  z_stream stream;
1089 
1090  if (argc != 1) {
1091  sqlite3_result_error(ctx, "need one argument", -1);
1092  return;
1093  }
1094  data = (unsigned char *) sqlite3_value_blob(argv[0]);
1095  length = sqlite3_value_bytes(argv[0]);
1096  stream.zalloc = Z_NULL;
1097  stream.zfree = Z_NULL;
1098  stream.next_in = data;
1099  stream.avail_in = length;
1100  avail = length;
1101  stream.next_out = dest = sqlite3_malloc(avail);
1102  stream.avail_out = avail;
1103  stream.opaque = 0;
1104  if (!dest) {
1105  goto oom;
1106  }
1107  if (inflateInit2(&stream, -15) != Z_OK) {
1108  goto nomem;
1109  }
1110  dlength = 0;
1111  while (1) {
1112  err = inflate(&stream, Z_SYNC_FLUSH);
1113  if ((err == Z_STREAM_END) ||
1114  ((err == Z_OK) && (stream.avail_in == 0))) {
1115  dlength += length - stream.avail_out;
1116  newdest = sqlite3_realloc(dest, dlength);
1117  inflateEnd(&stream);
1118  if (!newdest) {
1119 nomem:
1120  if (dest) {
1121  sqlite3_free(dest);
1122  }
1123 oom:
1124  sqlite3_result_error_nomem(ctx);
1125  return;
1126  }
1127  sqlite3_result_blob(ctx, newdest, dlength, sqlite3_free);
1128  return;
1129  }
1130  if ((err == Z_BUF_ERROR) || (err == Z_OK)) {
1131  newdest = sqlite3_realloc(dest, avail + length);
1132  dlength += length - stream.avail_out;
1133  if (!newdest) {
1134  inflateEnd(&stream);
1135  goto nomem;
1136  }
1137  avail += length;
1138  stream.next_out = newdest + (stream.next_out - dest);
1139  dest = newdest;
1140  stream.avail_out += length;
1141  } else {
1142  inflateEnd(&stream);
1143  sqlite3_free(dest);
1144  sqlite3_result_error(ctx, "inflate error", -1);
1145  return;
1146  }
1147  }
1148 }
1149 
1157 static void
1158 zip_deflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
1159 {
1160  int err, level = 9;
1161  unsigned long avail, length;
1162  unsigned char *data, *dest = 0;
1163  z_stream stream;
1164 
1165  if ((argc < 1) || (argc > 2)) {
1166  sqlite3_result_error(ctx, "need one or two arguments", -1);
1167  return;
1168  }
1169  if (argc > 1) {
1170  level = sqlite3_value_int(argv[1]);
1171  }
1172  data = (unsigned char *) sqlite3_value_blob(argv[0]);
1173  length = sqlite3_value_bytes(argv[0]);
1174  stream.zalloc = Z_NULL;
1175  stream.zfree = Z_NULL;
1176  stream.next_in = data;
1177  stream.avail_in = length;
1178  stream.next_out = 0;
1179  stream.avail_out = 0;
1180  stream.opaque = 0;
1181  if (deflateInit2(&stream, level, Z_DEFLATED, -15, 8,
1182  Z_DEFAULT_STRATEGY) != Z_OK) {
1183  goto deflerr;
1184  }
1185  avail = deflateBound(&stream, length);
1186  if (avail == 0) {
1187  sqlite3_result_null(ctx);
1188  return;
1189  }
1190  stream.next_out = dest = sqlite3_malloc(avail);
1191  stream.avail_out = avail;
1192  if (!dest) {
1193  sqlite3_result_error_nomem(ctx);
1194  return;
1195  }
1196  err = deflate(&stream, Z_FINISH);
1197  if (err != Z_STREAM_END) {
1198  deflateEnd(&stream);
1199 deflerr:
1200  if (dest) {
1201  sqlite3_free(dest);
1202  }
1203  sqlite3_result_error(ctx, "deflate error", -1);
1204  return;
1205  }
1206  length = stream.total_out;
1207  err = deflateEnd(&stream);
1208  if (err != Z_OK) {
1209  goto deflerr;
1210  }
1211  sqlite3_result_blob(ctx, dest, length, sqlite3_free);
1212 }
1213 
1221 static void
1222 zip_compress_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
1223 {
1224  int err, level = 9;
1225  unsigned long length, dlength;
1226  unsigned char *data, *dest;
1227 
1228  if ((argc < 1) || (argc > 2)) {
1229  sqlite3_result_error(ctx, "need one or two arguments", -1);
1230  return;
1231  }
1232  if (argc > 1) {
1233  level = sqlite3_value_int(argv[1]);
1234  }
1235  data = (unsigned char *) sqlite3_value_blob(argv[0]);
1236  length = sqlite3_value_bytes(argv[0]);
1237  dlength = compressBound(length);
1238  dest = sqlite3_malloc(dlength);
1239  if (!dest) {
1240  sqlite3_result_error_nomem(ctx);
1241  return;
1242  }
1243  err = compress2(dest, &dlength, data, length, level);
1244  if (err == Z_OK) {
1245  sqlite3_result_blob(ctx, dest, dlength, sqlite3_free);
1246  return;
1247  }
1248  if (err == Z_MEM_ERROR) {
1249  sqlite3_result_error(ctx, "memory error", -1);
1250  } else if (err == Z_BUF_ERROR) {
1251  sqlite3_result_error(ctx, "buffer error", -1);
1252  } else {
1253  sqlite3_result_error(ctx, "compress error", -1);
1254  }
1255  sqlite3_free(dest);
1256 }
1257 
1258 #ifdef SQLITE_OPEN_URI
1259 
1267 static mem_blk *
1268 mem_createmb(const unsigned char *data, unsigned long length)
1269 {
1270  mem_blk *mb;
1271 #if defined(_WIN32) || defined(_WIN64)
1272  HANDLE mh;
1273 #else
1274  long psize;
1275 #endif
1276  unsigned long size;
1277 
1278 #if defined(_WIN32) || defined(_WIN64)
1279  size = sizeof (mem_blk) + length;
1280  mh = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE,
1281  0, size, 0);
1282  if (mh == INVALID_HANDLE_VALUE) {
1283  return 0;
1284  }
1285  mb = (mem_blk *) MapViewOfFile(mh, FILE_MAP_ALL_ACCESS, 0, 0, length);
1286  if (!mb) {
1287  return 0;
1288  }
1289 #else
1290  psize = sysconf(_SC_PAGESIZE);
1291 #ifdef linux
1292  mb = (mem_blk *) sqlite3_malloc(sizeof (mem_blk));
1293  if (!mb) {
1294  return 0;
1295  }
1296  size = length + 1;
1297  mb->data = (unsigned char *) mmap(0, size, PROT_READ | PROT_WRITE,
1298  MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1299  if (mb->data == MAP_FAILED) {
1300  sqlite3_free(mb);
1301  return 0;
1302  }
1303 #else
1304  size = sizeof (mem_blk) + psize + length + 1;
1305  mb = (mem_blk *) mmap(0, size, PROT_READ | PROT_WRITE,
1306  MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
1307  if (mb == MAP_FAILED) {
1308  return 0;
1309  }
1310 #endif
1311 #endif
1312  if (mb) {
1313  memcpy(mb->magic, MEM_MAGIC, 4);
1314  mb->opened = 1;
1315  mb->size = size;
1316  mb->length = length;
1317 #if defined(_WIN32) || defined(_WIN64)
1318  mb->mh = mh;
1319  mb->data = (unsigned char *) (mb + 1);
1320  memcpy(mb->data, data, length);
1321 #else
1322  mb->psize = psize;
1323 #ifdef linux
1324  mb->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
1325  sqlite3_mutex_enter(mb->mutex);
1326  mb->lcnt = 0;
1327  memcpy(mb->data, data, length);
1328 #else
1329  if (psize >= sizeof (mem_blk)) {
1330  mb->data = (unsigned char *) mb + psize;
1331  memcpy(mb->data, data, length);
1332 #ifndef linux
1333  mprotect(mb->data, length, PROT_READ);
1334 #endif
1335  } else {
1336  mb->data = (unsigned char *) (mb + 1);
1337  memcpy(mb->data, data, length);
1338  }
1339 #endif
1340 #endif
1341  }
1342  return mb;
1343 }
1344 
1350 static void
1351 mem_destroymb(mem_blk *mb)
1352 {
1353 #if defined(_WIN32) || defined(_WIN64)
1354  HANDLE mh;
1355 #endif
1356 
1357  if (mb) {
1358  memset(mb->magic, 0, 4);
1359 #if defined(_WIN32) || defined(_WIN64)
1360  mh = mb->mh;
1361  UnmapViewOfFile(mb);
1362  CloseHandle(mh);
1363 #else
1364 #ifdef linux
1365  munmap(mb->data, mb->size);
1366  sqlite3_mutex_leave(mb->mutex);
1367  sqlite3_mutex_free(mb->mutex);
1368  sqlite3_free(mb);
1369 #else
1370  munmap(mb, mb->size);
1371 #endif
1372 #endif
1373  }
1374 }
1375 
1382 static int
1383 mem_close(sqlite3_file *file)
1384 {
1385  mem_file *mf = (mem_file *) file;
1386  mem_blk *mb = mf->mb;
1387 
1388  if (mb) {
1389 #ifdef linux
1390  sqlite3_mutex_enter(mb->mutex);
1391  if (mf->lock > 0) {
1392  mb->lcnt = 0;
1393  }
1394 #endif
1395  mb->opened--;
1396  if (mb->opened <= 0) {
1397  mem_destroymb(mb);
1398  }
1399 #ifdef linux
1400  else {
1401  sqlite3_mutex_leave(mb->mutex);
1402  }
1403 #endif
1404  mf->mb = 0;
1405  }
1406  return SQLITE_OK;
1407 }
1408 
1418 static int
1419 mem_read(sqlite3_file *file, void *buf, int len, sqlite_int64 offs)
1420 {
1421  mem_file *mf = (mem_file *) file;
1422  mem_blk *mb = mf->mb;
1423  int rc = SQLITE_IOERR_READ;
1424 
1425 #ifdef linux
1426  if (mb) {
1427  sqlite3_mutex_enter(mb->mutex);
1428  }
1429 #endif
1430  if (mb && (offs <= mb->length)) {
1431  rc = SQLITE_OK;
1432  if (offs + len > mb->length) {
1433  rc = SQLITE_IOERR_SHORT_READ;
1434  len = mb->length - offs;
1435  }
1436  memcpy(buf, mb->data + offs, len);
1437  }
1438 #ifdef linux
1439  if (mb) {
1440  sqlite3_mutex_leave(mb->mutex);
1441  }
1442 #endif
1443  return rc;
1444 }
1445 
1453 static int
1454 #ifdef linux
1455 mem_truncate_unlocked(sqlite3_file *file, sqlite_int64 offs)
1456 #else
1457 mem_truncate(sqlite3_file *file, sqlite_int64 offs)
1458 #endif
1459 {
1460 #ifdef linux
1461  mem_file *mf = (mem_file *) file;
1462  mem_blk *mb = mf->mb;
1463  unsigned char *p;
1464  long psize = mb->psize;
1465  unsigned long length = offs;
1466  unsigned long size;
1467 
1468  size = length + 1;
1469  if ((psize > 0) && (size / psize == mb->size / psize)) {
1470  p = mb->data;
1471  } else {
1472  p = mremap(mb->data, mb->size, size, MREMAP_MAYMOVE);
1473  }
1474  if (p == MAP_FAILED) {
1475  return SQLITE_IOERR_TRUNCATE;
1476  }
1477  mb->size = size;
1478  mb->length = length;
1479  mb->data = p;
1480  return SQLITE_OK;
1481 #else
1482  return SQLITE_IOERR_TRUNCATE;
1483 #endif
1484 }
1485 
1486 #ifdef linux
1487 static int
1488 mem_truncate(sqlite3_file *file, sqlite_int64 offs)
1489 {
1490  mem_file *mf = (mem_file *) file;
1491  mem_blk *mb = mf->mb;
1492  int rc = SQLITE_IOERR_TRUNCATE;
1493 
1494  if (mb) {
1495  sqlite3_mutex_enter(mb->mutex);
1496  rc = mem_truncate_unlocked(file, offs);
1497  sqlite3_mutex_leave(mb->mutex);
1498  }
1499  return rc;
1500 }
1501 #endif
1502 
1512 static int
1513 mem_write(sqlite3_file *file, const void *buf, int len, sqlite_int64 offs)
1514 {
1515 #ifdef linux
1516  mem_file *mf = (mem_file *) file;
1517  mem_blk *mb = mf->mb;
1518 
1519  sqlite3_mutex_enter(mb->mutex);
1520  if (offs + len > mb->length) {
1521  if (mem_truncate_unlocked(file, offs + len) != SQLITE_OK) {
1522  sqlite3_mutex_leave(mb->mutex);
1523  return SQLITE_IOERR_WRITE;
1524  }
1525  }
1526  memcpy(mb->data + offs, buf, len);
1527  sqlite3_mutex_leave(mb->mutex);
1528  return SQLITE_OK;
1529 #else
1530  return SQLITE_IOERR_WRITE;
1531 #endif
1532 }
1533 
1541 static int
1542 mem_sync(sqlite3_file *file, int flags)
1543 {
1544 #ifdef linux
1545  return SQLITE_OK;
1546 #else
1547  return SQLITE_IOERR_FSYNC;
1548 #endif
1549 }
1550 
1558 static int
1559 mem_filesize(sqlite3_file *file, sqlite_int64 *size)
1560 {
1561  mem_file *mf = (mem_file *) file;
1562  mem_blk *mb = mf->mb;
1563 
1564  if (mb) {
1565 #ifdef linux
1566  sqlite3_mutex_enter(mb->mutex);
1567 #endif
1568  *size = mb->length;
1569 #ifdef linux
1570  sqlite3_mutex_leave(mb->mutex);
1571 #endif
1572  return SQLITE_OK;
1573  }
1574  return SQLITE_IOERR_FSTAT;
1575 }
1576 
1584 static int
1585 mem_lock(sqlite3_file *file, int lck)
1586 {
1587 #ifdef linux
1588  mem_file *mf = (mem_file *) file;
1589  mem_blk *mb = mf->mb;
1590  int rc = SQLITE_IOERR_LOCK;
1591 
1592  if (mb) {
1593  sqlite3_mutex_enter(mb->mutex);
1594  if (lck > 0) {
1595  rc = SQLITE_BUSY;
1596  if ((mf->lock == 0) && (mb->lcnt == 0)) {
1597  mb->lcnt = 1;
1598  mf->lock = lck;
1599  rc = SQLITE_OK;
1600  } else if ((mf->lock > 0) && (mb->lcnt == 1)) {
1601  mf->lock = lck;
1602  rc = SQLITE_OK;
1603  }
1604  }
1605  sqlite3_mutex_leave(mb->mutex);
1606  }
1607  return rc;
1608 #else
1609  return SQLITE_OK;
1610 #endif
1611 }
1612 
1620 static int
1621 mem_unlock(sqlite3_file *file, int lck)
1622 {
1623 #ifdef linux
1624  mem_file *mf = (mem_file *) file;
1625  mem_blk *mb = mf->mb;
1626  int rc = SQLITE_IOERR_UNLOCK;
1627 
1628  if (mb) {
1629  sqlite3_mutex_enter(mb->mutex);
1630  if (mf->lock == lck) {
1631  rc = SQLITE_OK;
1632  } else if (lck == 0) {
1633  if (mf->lock) {
1634  mb->lcnt = 0;
1635  mf->lock = 0;
1636  }
1637  rc = SQLITE_OK;
1638  } else if ((lck < mf->lock) && (mb->lcnt != 0)) {
1639  mf->lock = lck;
1640  rc = SQLITE_OK;
1641  }
1642  sqlite3_mutex_leave(mb->mutex);
1643  }
1644  return rc;
1645 #else
1646  return SQLITE_OK;
1647 #endif
1648 }
1649 
1657 static int
1658 mem_checkreservedlock(sqlite3_file *file, int *out)
1659 {
1660 #ifdef linux
1661  mem_file *mf = (mem_file *) file;
1662  mem_blk *mb = mf->mb;
1663  int rc = SQLITE_IOERR_CHECKRESERVEDLOCK;
1664 
1665  if (mb) {
1666  sqlite3_mutex_enter(mb->mutex);
1667  *out = mf->lock >= 2;
1668  sqlite3_mutex_leave(mb->mutex);
1669  rc = SQLITE_OK;
1670  } else {
1671  *out = 0;
1672  }
1673  return rc;
1674 #else
1675  *out = 0;
1676  return SQLITE_OK;
1677 #endif
1678 }
1679 
1688 static int
1689 mem_filecontrol(sqlite3_file *file, int op, void *arg)
1690 {
1691 #ifdef SQLITE_FCNTL_PRAGMA
1692  if (op == SQLITE_FCNTL_PRAGMA) {
1693  return SQLITE_NOTFOUND;
1694  }
1695 #endif
1696  return SQLITE_OK;
1697 }
1698 
1705 static int
1706 mem_sectorsize(sqlite3_file *file)
1707 {
1708  return 4096;
1709 }
1710 
1717 static int
1718 mem_devicecharacteristics(sqlite3_file *file)
1719 {
1720  return 0;
1721 }
1722 
1727 static sqlite3_io_methods mem_methods = {
1728  1, /* iVersion */
1729  mem_close, /* xClose */
1730  mem_read, /* xRead */
1731  mem_write, /* xWrite */
1732  mem_truncate, /* xTruncate */
1733  mem_sync, /* xSync */
1734  mem_filesize, /* xFileSize */
1735  mem_lock, /* xLock */
1736  mem_unlock, /* xUnlock */
1737  mem_checkreservedlock, /* xCheckReservedLock */
1738  mem_filecontrol, /* xFileControl */
1739  mem_sectorsize, /* xSectorSize */
1740  mem_devicecharacteristics /* xDeviceCharacteristics */
1741 };
1742 
1753 static int
1754 mem_open(sqlite3_vfs *vfs, const char *name, sqlite3_file *file,
1755  int flags, int *outflags)
1756 {
1757  mem_file *mf = (mem_file *) file;
1758  mem_blk *mb = 0;
1759 #ifdef _WIN64
1760  unsigned long long t = 0;
1761 #else
1762  unsigned long t = 0;
1763 #endif
1764 #if !defined(_WIN32) && !defined(_WIN64)
1765  mem_blk mb0;
1766  int pfd[2];
1767  int n;
1768 #endif
1769 
1770  if (!name) {
1771  return SQLITE_IOERR;
1772  }
1773  if (flags & (SQLITE_OPEN_MAIN_JOURNAL |
1774  SQLITE_OPEN_WAL |
1775 #ifndef linux
1776  SQLITE_OPEN_READWRITE |
1777 #endif
1778  SQLITE_OPEN_CREATE)) {
1779  return SQLITE_CANTOPEN;
1780  }
1781 #ifdef _WIN64
1782  sscanf(name + 1, "%I64x", &t);
1783 #else
1784  t = strtoul(name + 1, 0, 16);
1785 #endif
1786  mb = (mem_blk *) t;
1787  if (!mb) {
1788  return SQLITE_CANTOPEN;
1789  }
1790 #if !defined(_WIN32) && !defined(_WIN64)
1791  if (pipe(pfd) < 0) {
1792  return SQLITE_CANTOPEN;
1793  }
1794  n = (write(pfd[1], (char *) mb, sizeof (mem_blk)) < 0) ? errno : 0;
1795  if (n == EFAULT) {
1796 cantopen:
1797  close(pfd[0]);
1798  close(pfd[1]);
1799  return SQLITE_CANTOPEN;
1800  }
1801  n = read(pfd[0], (char *) &mb0, sizeof (mem_blk));
1802  if (n != sizeof (mem_blk)) {
1803  goto cantopen;
1804  }
1805  if (memcmp(mb0.magic, MEM_MAGIC, 4) == 0) {
1806 #ifdef linux
1807  n = (write(pfd[1], (char *) mb0.data, 1) < 0) ? errno : 0;
1808  if (n == EFAULT) {
1809  goto cantopen;
1810  }
1811 #endif
1812  if (mb0.length > 0) {
1813  n = (write(pfd[1], (char *) mb0.data + mb0.length - 1, 1) < 0)
1814  ? errno : 0;
1815  if (n == EFAULT) {
1816  goto cantopen;
1817  }
1818  }
1819  close(pfd[0]);
1820  close(pfd[1]);
1821 #ifdef linux
1822  sqlite3_mutex_enter(mb->mutex);
1823 #endif
1824  mb->opened++;
1825 #ifdef linux
1826  sqlite3_mutex_leave(mb->mutex);
1827 #endif
1828  } else {
1829  goto cantopen;
1830  }
1831 #else
1832  if (memcmp(mb->magic, MEM_MAGIC, 4) == 0) {
1833  mb->opened++;
1834  } else {
1835  return SQLITE_CANTOPEN;
1836  }
1837 #endif
1838  memset(mf, 0, sizeof (mem_file));
1839  mf->mb = mb;
1840  mf->base.pMethods = &mem_methods;
1841  if (outflags) {
1842  *outflags = flags;
1843  }
1844  return SQLITE_OK;
1845 }
1846 
1855 static int
1856 mem_delete(sqlite3_vfs *vfs, const char *name, int sync)
1857 {
1858  return SQLITE_IOERR_DELETE;
1859 }
1860 
1870 static int
1871 mem_access(sqlite3_vfs *vfs, const char *name, int flags, int *outflags)
1872 {
1873  char *endp = 0;
1874  unsigned long t;
1875 
1876  t = strtol(name + 1, &endp, 16);
1877  if ((t == 0) ||
1878 #ifndef linux
1879  (flags == SQLITE_ACCESS_READWRITE) ||
1880 #endif
1881  !endp || endp[0]) {
1882  *outflags = 0;
1883  } else {
1884  *outflags = 1;
1885  }
1886  return SQLITE_OK;
1887 }
1888 
1898 static int
1899 mem_fullpathname(sqlite3_vfs *vfs, const char *name, int len, char *out)
1900 {
1901  strncpy(out, name, len);
1902  out[len - 1] = '\0';
1903  return SQLITE_OK;
1904 }
1905 
1913 static void *
1914 mem_dlopen(sqlite3_vfs *vfs, const char *name)
1915 {
1916  return 0;
1917 }
1918 
1926 static void
1927 mem_dlerror(sqlite3_vfs *vfs, int len, char *out)
1928 {
1929  static const char *errtxt = "Loadable extensions are not supported";
1930 
1931  strncpy(out, errtxt, strlen(errtxt));
1932  out[len - 1] = '\0';
1933 }
1934 
1943 static void
1944 (*mem_dlsym(sqlite3_vfs *vfs, void *handle, const char *sym))(void)
1945 {
1946  return 0;
1947 }
1948 
1955 static void
1956 mem_dlclose(sqlite3_vfs *vfs, void *handle)
1957 {
1958 }
1959 
1968 static int
1969 mem_randomness(sqlite3_vfs *vfs, int len, char *out)
1970 {
1971  sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
1972 
1973  return ovfs->xRandomness(ovfs, len, out);
1974 }
1975 
1983 static int
1984 mem_sleep(sqlite3_vfs *vfs, int micro)
1985 {
1986  sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
1987 
1988  return ovfs->xSleep(ovfs, micro);
1989 }
1990 
1998 static int
1999 mem_currenttime(sqlite3_vfs *vfs, double *out)
2000 {
2001  sqlite3_vfs *ovfs = (sqlite3_vfs *) vfs->pAppData;
2002 
2003  return ovfs->xCurrentTime(ovfs, out);
2004 }
2005 
2010 static sqlite3_vfs mem_vfs = {
2011  1, /* iVersion */
2012  sizeof (mem_file), /* szOsFile */
2013  256, /* mxPathname */
2014  0, /* pNext */
2015  mem_vfs_name, /* zName */
2016  0, /* pAppData */
2017  mem_open, /* xOpen */
2018  mem_delete, /* xDelete */
2019  mem_access, /* xAccess */
2020  mem_fullpathname, /* xFullPathname */
2021  mem_dlopen, /* xDlOpen */
2022  mem_dlerror, /* xDlError */
2023  mem_dlsym, /* xDlSym */
2024  mem_dlclose, /* xDlClose */
2025  mem_randomness, /* xDlError */
2026  mem_sleep, /* xDlSym */
2027  mem_currenttime /* xDlClose */
2028 };
2029 
2054 static void
2055 blob_attach_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
2056 {
2057  unsigned long length;
2058  const unsigned char *data;
2059  mem_blk *mb = 0;
2060  char *sql = 0;
2061  int sqllen = 0;
2062 #ifdef linux
2063  int isrw = 0;
2064 #endif
2065 
2066  if (argc != 2) {
2067  sqlite3_result_error(ctx, "need two arguments", -1);
2068  return;
2069  }
2070  data = (const unsigned char *) sqlite3_value_blob(argv[0]);
2071  length = sqlite3_value_bytes(argv[0]);
2072  if (!data || !length) {
2073  sqlite3_result_error(ctx, "empty blob", -1);
2074  return;
2075  }
2076  mb = mem_createmb(data, length);
2077  if (!mb) {
2078  sqlite3_result_error(ctx, "cannot map blob", -1);
2079  return;
2080  }
2081  sql = sqlite3_mprintf("ATTACH "
2082 #ifdef _WIN64
2083  "'file:/%llX"
2084 #else
2085  "'file:/%lX"
2086 #endif
2087  "?vfs=%s&"
2088 #ifdef linux
2089  "mode=rw&"
2090 #else
2091  "mode=ro&"
2092 #endif
2093  "cache=private' AS %Q",
2094 #ifdef _WIN64
2095  (unsigned long long) mb,
2096 #else
2097  (unsigned long) mb,
2098 #endif
2099  mem_vfs_name,
2100  (char *) sqlite3_value_text(argv[1]));
2101  if (!sql) {
2102  sqlite3_result_error(ctx, "cannot map blob", -1);
2103  mem_destroymb(mb);
2104  return;
2105  }
2106 #ifdef linux
2107  sqlite3_mutex_leave(mb->mutex);
2108 #endif
2109  if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
2110  != SQLITE_OK) {
2111  sqlite3_free(sql);
2112  sqlite3_result_error(ctx, "cannot attach blob", -1);
2113 #ifdef linux
2114  sqlite3_mutex_enter(mb->mutex);
2115 #endif
2116  mem_destroymb(mb);
2117  return;
2118  }
2119  sqllen = strlen(sql);
2120  sqlite3_snprintf(sqllen, sql, "PRAGMA %Q.synchronous = OFF",
2121  (char *) sqlite3_value_text(argv[1]));
2122  sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
2123 #ifdef linux
2124  sqlite3_snprintf(sqllen, sql, "PRAGMA %Q.journal_mode = OFF",
2125  (char *) sqlite3_value_text(argv[1]));
2126  if (sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0)
2127  == SQLITE_OK) {
2128  isrw = 1;
2129  }
2130 #endif
2131 #ifdef linux
2132  sqlite3_mutex_enter(mb->mutex);
2133 #endif
2134  if (--mb->opened < 1) {
2135  sqlite3_snprintf(sqllen, sql, "DETACH %Q",
2136  (char *) sqlite3_value_text(argv[1]));
2137  sqlite3_exec(sqlite3_context_db_handle(ctx), sql, 0, 0, 0);
2138  sqlite3_free(sql);
2139  sqlite3_result_error(ctx, "cannot attach blob", -1);
2140  mem_destroymb(mb);
2141  return;
2142  }
2143 #ifdef linux
2144  sqlite3_mutex_leave(mb->mutex);
2145  if (isrw) {
2146  sqlite3_snprintf(sqllen, sql,
2147  "file:/%lX?vfs=%s&mode=rw&cache=private",
2148  (unsigned long) mb, mem_vfs_name);
2149  sqlite3_result_text(ctx, sql, -1, sqlite3_free);
2150  return;
2151  }
2152 #endif
2153  sqlite3_free(sql);
2154  sqlite3_result_null(ctx);
2155 }
2156 
2174 static void
2175 blob_dump_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
2176 {
2177  char *uri, vfs[64];
2178 #ifdef _WIN64
2179  unsigned long long addr = 0;
2180 #else
2181  unsigned long addr = 0;
2182 #endif
2183 #ifdef linux
2184  int pfd[2], n;
2185  mem_blk *mb;
2186 #endif
2187 
2188  if (argc != 1) {
2189  sqlite3_result_error(ctx, "need one argument", -1);
2190  return;
2191  }
2192  uri = (char *) sqlite3_value_text(argv[0]);
2193  vfs[0] = '\0';
2194  if (!uri || (sscanf(uri,
2195 #ifdef _WIN64
2196  "file:/%I64X?vfs=%63[^&]",
2197 #else
2198  "file:/%lX?vfs=%63[^&]",
2199 #endif
2200  &addr, vfs) != 2)) {
2201 inval:
2202  sqlite3_result_error(ctx, "invalid object", -1);
2203  return;
2204  }
2205  vfs[63] = '\0';
2206  if ((strcmp(mem_vfs_name, vfs) != 0) || (addr == 0)) {
2207  goto inval;
2208  }
2209 #ifdef linux
2210  if (pipe(pfd) < 0) {
2211  goto inval;
2212  }
2213  n = (write(pfd[1], (char *) addr, 1) < 0) ? errno : 0;
2214  close(pfd[0]);
2215  close(pfd[1]);
2216  if (n == EFAULT) {
2217  goto inval;
2218  }
2219  mb = (mem_blk *) addr;
2220  if (memcmp(mb->magic, MEM_MAGIC, 4) != 0) {
2221  goto inval;
2222  }
2223  sqlite3_mutex_enter(mb->mutex);
2224  sqlite3_result_blob(ctx, mb->data, mb->length, SQLITE_STATIC);
2225  sqlite3_mutex_leave(mb->mutex);
2226 #else
2227  sqlite3_result_error(ctx, "unsupported function", -1);
2228 #endif
2229 }
2230 
2231 #endif /* SQLITE_OPEN_URI */
2232 
2239 #ifndef STANDALONE
2240 static
2241 #endif
2242 int
2243 zip_vtab_init(sqlite3 *db)
2244 {
2245  sqlite3_create_function(db, "crc32", 1, SQLITE_UTF8,
2246  (void *) db, zip_crc32_func, 0, 0);
2247  sqlite3_create_function(db, "inflate", 1, SQLITE_UTF8,
2248  (void *) db, zip_inflate_func, 0, 0);
2249  sqlite3_create_function(db, "deflate", 1, SQLITE_UTF8,
2250  (void *) db, zip_deflate_func, 0, 0);
2251  sqlite3_create_function(db, "uncompress", 1, SQLITE_UTF8,
2252  (void *) db, zip_inflate_func, 0, 0);
2253  sqlite3_create_function(db, "compress", -1, SQLITE_UTF8,
2254  (void *) db, zip_compress_func, 0, 0);
2255 #ifdef SQLITE_OPEN_URI
2256  if (!mem_vfs.pAppData) {
2257  sqlite3_vfs *parent = sqlite3_vfs_find(0);
2258 
2259  if (parent) {
2260  sqlite3_snprintf(sizeof (mem_vfs_name), mem_vfs_name,
2261 #ifdef _WIN64
2262  "mem_vfs_%llX", (unsigned long long) &mem_vfs
2263 #else
2264  "mem_vfs_%lX", (unsigned long) &mem_vfs
2265 #endif
2266  );
2267  if (sqlite3_vfs_register(&mem_vfs, 0) == SQLITE_OK) {
2268  mem_vfs.pAppData = (void *) parent;
2269  }
2270  }
2271  }
2272  if (mem_vfs.pAppData) {
2273  sqlite3_create_function(db, "blob_attach", 2, SQLITE_UTF8,
2274  (void *) db, blob_attach_func, 0, 0);
2275  sqlite3_create_function(db, "blob_dump", 1, SQLITE_UTF8,
2276  (void *) db, blob_dump_func, 0, 0);
2277  }
2278 #endif
2279  return sqlite3_create_module(db, "zipfile", &zip_vtab_mod, 0);
2280 }
2281 
2282 #ifndef STANDALONE
2283 
2292 int
2293 sqlite3_extension_init(sqlite3 *db, char **errmsg,
2294  const sqlite3_api_routines *api)
2295 {
2296  SQLITE_EXTENSION_INIT2(api);
2297  return zip_vtab_init(db);
2298 }
2299 
2300 #endif
static SQLRETURN nomem(STMT *s)
Report S1000 (out of memory) SQL error given STMT.
Definition: sqlite3odbc.c:1845
static int zip_vtab_disconnect(sqlite3_vtab *vtab)
Disconnect virtual table.
Definition: zipfile.c:487
#define ZIP_CENTRAL_MDATE_OFFS
Definition: zipfile.c:60
int nmatches
For filter EQ.
Definition: zipfile.c:125
#define ZIP_CENTRAL_PATHLEN_OFFS
Definition: zipfile.c:64
#define ZIP_CENTRAL_DIRSTART_OFFS
Definition: zipfile.c:73
#define ZIP_CENTRAL_LOCALHDR_OFFS
Definition: zipfile.c:67
static void zip_crc32_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Compute CRC32 given blob.
Definition: zipfile.c:1059
#define ZIP_CENTRAL_COMPMETH_OFFS
Definition: zipfile.c:58
#define ZIP_CENTRAL_DIRSIZE_OFFS
Definition: zipfile.c:72
int pos
ZIP file position.
Definition: zipfile.c:123
Driver internal structure representing SQL statement (HSTMT).
Definition: sqlite3odbc.h:230
#define ZIP_CENTRAL_CRC32_OFFS
Definition: zipfile.c:61
sqlite3 * db
Open database.
Definition: zipfile.c:109
sqlite3_vtab vtab
SQLite virtual table.
Definition: zipfile.c:108
int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api)
Initializer for SQLite extension load mechanism.
Definition: zipfile.c:2293
#define zip_read_int(p)
Definition: zipfile.c:78
#define ZIP_CENTRAL_COMPLEN_OFFS
Definition: zipfile.c:62
static const sqlite3_module zip_vtab_mod
SQLite module descriptor.
Definition: zipfile.c:1026
#define ZIP_CENTRAL_UNCOMPLEN_OFFS
Definition: zipfile.c:63
static void zip_close(zip_file *zip)
Close ZIP file handle.
Definition: zipfile.c:340
#define ZIP_CENTRAL_HEADER_LEN
Definition: zipfile.c:57
#define ZIP_LOCAL_HEADER_LEN
Definition: zipfile.c:53
unsigned char * data
mmap()&#39;ed ZIP file
Definition: zipfile.c:91
static char * unquote(char const *in)
Strip off quotes given string.
Definition: zipfile.c:372
off_t length
length of ZIP file
Definition: zipfile.c:90
static int zip_vtab_close(sqlite3_vtab_cursor *cursor)
Close virtual table cursor.
Definition: zipfile.c:631
int nentries
Number of directory entries.
Definition: zipfile.c:97
#define ZIP_CENTRAL_COMMENTLEN_OFFS
Definition: zipfile.c:66
char tblname[1]
Name, format "database".
Definition: zipfile.c:112
#define ZIP_CENTRAL_END_LEN
Definition: zipfile.c:70
unsigned char * entries[1]
Pointer to first entry.
Definition: zipfile.c:98
static int zip_vtab_findfunc(sqlite3_vtab *vtab, int narg, const char *name, void(**pfunc)(sqlite3_context *, int, sqlite3_value **), void **parg)
Find overloaded function on virtual table.
Definition: zipfile.c:994
int baseoffs
Global offset for embedded ZIP files.
Definition: zipfile.c:96
static int zip_vtab_init(sqlite3 *db)
Module initializer creating SQLite module and functions.
Definition: zipfile.c:2243
#define ZIP_CENTRAL_EXTRALEN_OFFS
Definition: zipfile.c:65
#define ZIP_CENTRAL_MTIME_OFFS
Definition: zipfile.c:59
struct zip_file zip_file
#define ZIP_COMPMETH_DEFLATED
Definition: zipfile.c:76
static int zip_vtab_connect(sqlite3 *db, void *aux, int argc, const char *const *argv, sqlite3_vtab **vtabp, char **errp)
Connect to virtual table.
Definition: zipfile.c:412
static int zip_vtab_create(sqlite3 *db, void *aux, int argc, const char *const *argv, sqlite3_vtab **vtabp, char **errp)
Create virtual table.
Definition: zipfile.c:473
int sorted
1 = sorted by path, -1 = sorting, 0 = unsorted
Definition: zipfile.c:111
#define ZIP_SIG_LEN
Definition: zipfile.c:47
static int zip_vtab_column(sqlite3_vtab_cursor *cursor, sqlite3_context *ctx, int n)
Return column data of virtual table.
Definition: zipfile.c:776
Structure to describe a ZIP virtual table.
Definition: zipfile.c:107
int * matches
For filter EQ.
Definition: zipfile.c:126
static int zip_vtab_destroy(sqlite3_vtab *vtab)
Destroy virtual table.
Definition: zipfile.c:503
static int zip_vtab_rowid(sqlite3_vtab_cursor *cursor, sqlite_int64 *rowidp)
Return current rowid of virtual table cursor.
Definition: zipfile.c:931
static int zip_vtab_bestindex(sqlite3_vtab *vtab, sqlite3_index_info *info)
Determines information for filter function according to constraints.
Definition: zipfile.c:516
int usematches
For filter EQ.
Definition: zipfile.c:124
#define zip_read_short(p)
Definition: zipfile.c:80
zip_file * zip
ZIP file handle.
Definition: zipfile.c:110
static int zip_vtab_eof(sqlite3_vtab_cursor *cursor)
Return end of table state of virtual table cursor.
Definition: zipfile.c:753
struct zip_vtab zip_vtab
static int zip_vtab_filter(sqlite3_vtab_cursor *cursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv)
Filter function for virtual table.
Definition: zipfile.c:670
#define ZIP_CENTRAL_ENTS_OFFS
Definition: zipfile.c:71
static int zip_vtab_open(sqlite3_vtab *vtab, sqlite3_vtab_cursor **cursorp)
Open virtual table and return cursor.
Definition: zipfile.c:608
static zip_file * zip_open(const char *filename)
Memory map ZIP file for reading and return handle to it.
Definition: zipfile.c:184
static void zip_inflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Inflate data given blob.
Definition: zipfile.c:1084
static int zip_vtab_next(sqlite3_vtab_cursor *cursor)
Retrieve next row from virtual table cursor.
Definition: zipfile.c:649
sqlite3_vtab_cursor cursor
SQLite virtual table cursor.
Definition: zipfile.c:122
#define ZIP_CENTRAL_HEADER_SIG
Definition: zipfile.c:55
static void zip_compress_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Compress data given blob and optional compression level.
Definition: zipfile.c:1222
#define ZIP_COMPMETH_STORED
Definition: zipfile.c:75
static void zip_deflate_func(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Deflate data given blob and optional compression level.
Definition: zipfile.c:1158
Structure to implement ZIP file handle.
Definition: zipfile.c:89
#define ZIP_LOCAL_PATHLEN_OFFS
Definition: zipfile.c:51
#define ZIP_CENTRAL_END_SIG
Definition: zipfile.c:69
static void zip_vtab_matchfunc(sqlite3_context *ctx, int argc, sqlite3_value **argv)
Internal MATCH function for virtual table.
Definition: zipfile.c:957
Structure to describe ZIP virtual table cursor.
Definition: zipfile.c:121
#define ZIP_LOCAL_EXTRA_OFFS
Definition: zipfile.c:52

Generated on Mon Aug 22 2016 by doxygen.
Contact: chw@ch-werner.de