static int ar_getheader(Pax_t* pax, register Archive_t* ap, register File_t* f) { register Ar_t* ar = (Ar_t*)ap->data; off_t pos; if (!(ar->ent = ardirnext(ar->dir))) { pos = lseek(ap->io->fd, (off_t)0, SEEK_END); return (pos < 0 || paxseek(pax, ap, pos, SEEK_SET, 0) != pos) ? -1 : 0; } f->name = ar->ent->name; f->st->st_dev = 0; f->st->st_ino = 0; f->st->st_mode = X_IFREG|(ar->ent->mode&X_IPERM); f->st->st_uid = ar->ent->uid; f->st->st_gid = ar->ent->gid; f->st->st_nlink = 1; IDEVICE(f->st, 0); f->st->st_mtime = ar->ent->mtime; f->st->st_size = ar->ent->size; f->linktype = NOLINK; f->linkpath = 0; f->uidname = 0; f->gidname = 0; return 1; }
static int mime_getheader(Pax_t* pax, Archive_t* ap, register File_t* f) { register Mime_t* mime = (Mime_t*)ap->data; register char* s; register char* t; register char* v; off_t m; off_t b; size_t n; int loop; if (paxread(pax, ap, s = state.tmp.buffer, mime->length + 2, mime->length + 2, 1) <= 0 || memcmp(s, mime->magic, mime->length)) error(3, "%s: corrupt %s format member header -- separator not found", ap->name, ap->format->name); else if (*(s += mime->length) == '-' && *(s + 1) == '-') { while (paxread(pax, ap, s, 1, 1, 1) > 0 && *s != '\n'); return 0; } else if (*s == '\n') paxunread(pax, ap, s + 1, 1); else if (*s != '\r' && *(s + 1) != '\n') error(3, "%s: corrupt %s format member header -- separator line not found", ap->name, ap->format->name); f->name = 0; for (;;) { for (t = (s = state.tmp.buffer) + state.buffersize - 1; s < t; s++) if (paxread(pax, ap, s, 1, 1, 1) <= 0) error(3, "%s: unexpected %s format EOF", ap->name, ap->format->name); else if (*s == '\n') { if (s > state.tmp.buffer && *(s - 1) == '\r') s--; *s = 0; break; } s = state.tmp.buffer; if (!*s) break; if (strncasecmp(s, "content-", 8)) error(3, "%s: corrupt %s format member header", ap->name, ap->format->name); if (t = strchr(s, ':')) s = t + 1; while (isspace(*s)) s++; for (;;) { for (t = s; *s && *s != ';' && *s != '='; s++); if (!(n = s - t)) break; if (*s == '=') { if (*++s == '"') for (v = ++s; *s && *s != '"'; s++); else for (v = s; *s && *s != ';'; s++); } else v = s; m = s - v; if (*s) *s++ = 0; for (; *s == ';' || isspace(*s); s++); if (!f->name && n == 4 && !strncasecmp(t, "name", 4) || n == 8 && !strncasecmp(t, "filename", 8)) f->name = paxstash(pax, &ap->stash.head, v, m); } } if (!f->name) { if (s = strrchr(ap->name, '/')) s++; else s = ap->name; f->name = paxstash(pax, &ap->stash.head, s, strlen(s) + 16); sfsprintf(f->name, ap->stash.head.size, "%s-%d", s, ap->entries + 1); } if (!ap->io->seekable) seekable(ap); f->st->st_size = 0; loop = 0; b = paxseek(pax, ap, 0, SEEK_CUR, 0); while (s = paxget(pax, ap, 0, &m)) { if (m < mime->length) { if (loop++) error(3, "%s: corrupt %s format member header [too short]", ap->name, ap->format->name); paxseek(pax, ap, -m, SEEK_CUR, 0); paxsync(pax, ap, 0); continue; } v = s; for (t = s + m - mime->length; s = memchr(s, '-', t - s); s++) if (!memcmp(s, mime->magic, mime->length)) { paxseek(pax, ap, b, SEEK_CUR, 0); paxsync(pax, ap, 0); if (s > v && *(s - 1) == '\n') { mime->fill++; if (s > (v + 1) && *(s - 2) == '\r') mime->fill++; } f->st->st_size += (s - v) - mime->fill; f->st->st_mtime = NOW; f->st->st_mode = X_IFREG|X_IRUSR|X_IRGRP|X_IROTH; f->st->st_uid = state.uid; f->st->st_gid = state.gid; f->st->st_dev = 0; f->st->st_ino = 0; f->st->st_nlink = 1; IDEVICE(f->st, 0); f->linktype = NOLINK; f->linkpath = 0; f->uidname = 0; f->gidname = 0; return 1; } paxseek(pax, ap, -(off_t)mime->length, SEEK_CUR, 0); paxsync(pax, ap, 0); f->st->st_size += m; } return 0; }
static int flash_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size) { unsigned char* s; unsigned char* e; unsigned char* t; char* v; int i; off_t n; char version[16]; if (size < sizeof(FLASH_MAGIC) - 1 || memcmp(buf, FLASH_MAGIC, sizeof(FLASH_MAGIC) - 1)) return 0; /* * get the flash format version */ s = buf + sizeof(FLASH_MAGIC) - 1; e = buf + size; v = version; while (v < &version[sizeof(version) - 1] && s < e && *s != '\n') *v++ = *s++; *v = 0; /* * skip over the flash headers to the embedded archive */ s = e; for (;;) { if (s >= e) { if (!(buf = (unsigned char*)paxget(pax, ap, -PAX_DEFBUFFER * PAX_BLOCK, &n))) return -1; s = buf; e = buf + n; } if (t = (unsigned char*)memchr(s, '\n', e - s)) { if ((t - s) == (sizeof(FLASH_DATA) - 1) && !memcmp(s, FLASH_DATA, sizeof(FLASH_DATA) - 1)) { if (paxseek(pax, ap, -(e - t - 1), SEEK_CUR, 0) < 0) return -1; break; } if (t < e) { s = t + 1; continue; } } if (paxseek(pax, ap, -(e - s), SEEK_CUR, 0) < 0) return -1; s = e; } ap->entry = 0; ap->swap = 0; ap->swapio = 0; ap->volume--; i = state.volume[0]; if (getprologue(ap) <= 0) { error(2, "%s: %s format embedded archive expected", ap->name, fp->name); return -1; } state.volume[0] = i; ap->package = strdup(sfprints("%s %s", fp->name, version)); return 1; }
static int paxcorrupt(Pax_t* pax, Paxarchive_t* ap, Paxfile_t* f, const char* msg) { (*pax->errorf)(NiL, pax, 2, "%s%s%s: %s archive corrupt at %I*u%s%s", ap->name, TXT(f, f->name), ap->format->name, sizeof(off_t), paxseek(pax, ap, 0, SEEK_CUR, 0), TXT(msg, msg)); return -1; }