void mem_free(void *ptr) { #ifndef USE_DMT --g_mem_mem_allocs_count; free(ptr); #else dmt_free(ptr); #endif }
static void* tar_read(mount_t *mnt, const char *filename, int *size) { mtar_t *tar = mnt->udata; int err; mtar_header_t h; /* Find and load header for file */ err = tar_find(mnt, filename, &h); if (err) { return 0; } /* Allocate and read data, set size and return */ char *p = dmt_malloc(h.size); err = mtar_read_data(tar, p, h.size); if (err) { dmt_free(p); return NULL; } *size = h.size; return p; }
static int tar_mount(mount_t *mnt, const char *path) { tar_mount_t *tm = NULL; FILE *fp = NULL; /* Try to open file */ fp = fopen(path, "rb"); if (!fp) { goto fail; } /* Init tar_mount_t */ tm = dmt_calloc(1, sizeof(*tm)); tm->fp = fp; /* Init tar */ mtar_t *tar = &tm->tar; tar->read = tar_stream_read; tar->seek = tar_stream_seek; tar->close = tar_stream_close; tar->stream = tm; /* Check start of file for valid tar header */ mtar_header_t h; int err = mtar_read_header(tar, &h); /* If checking the start of the file failed then check the end of file for a * "TAR\0" tag and offset, this would have been added when packaging (see * `package.c`) to indicate the offset of the tar archive's beginning from the * file's end */ if (err) { int offset; char buf[4] = ""; fseek(fp, -8, SEEK_END); fread(buf, 1, 4, fp); fread(&offset, 1, 4, fp); if ( !memcmp(buf, "TAR\0", 4) ) { fseek(fp, -offset, SEEK_END); tm->offset = ftell(fp); } mtar_rewind(tar); err = mtar_read_header(tar, &h); if (err) { goto fail; } } /* Iterate all files and store [namehash:position] pairs; this is used by * tar_find() */ mtar_rewind(tar); int n = 0; int cap = 0; while ( (mtar_read_header(tar, &h)) == MTAR_ESUCCESS ) { /* Realloc if map capacity was reached */ if (n >= cap) { cap = cap ? (cap << 1) : 16; tm->map = dmt_realloc(tm->map, cap * sizeof(*tm->map)); } /* Store entry */ strip_trailing_slash(h.name); tm->map[n].hash = hash_string_ignore_case(h.name); tm->map[n].pos = tar->pos; /* Next */ mtar_next(tar); n++; } tm->nfiles = n; /* Init mount */ mnt->udata = tar; mnt->unmount = tar_unmount; mnt->exists = tar_exists; mnt->isFile = tar_isFile; mnt->isDirectory = tar_isDirectory; mnt->read = tar_read; /* Return ok */ return FILESYSTEM_ESUCCESS; fail: if (fp) fclose(fp); if (tm) { dmt_free(tm->map); dmt_free(tm); } return FILESYSTEM_EFAILURE; }
static void tar_unmount(mount_t *mnt) { tar_mount_t *tm = mnt->udata; mtar_close(&tm->tar); dmt_free(tm->map); dmt_free(tm); }