static int mime_getprologue(Pax_t* pax, Format_t* fp, register Archive_t* ap, File_t* f, unsigned char* buf, size_t size) { register Mime_t* mime; char* s; char* t; size_t n; s = state.tmp.buffer; if (paxread(pax, ap, s, (off_t)0, (off_t)MIME_HEADER, 0) <= 0) return 0; paxunread(pax, ap, s, MIME_HEADER); if (s[0] != '-' || s[1] != '-' || !(t = (char*)memchr(s, '\n', MIME_HEADER - 2)) || (t - s + 8) >= MIME_HEADER || strncasecmp(t + 1, "Content", 7)) return 0; n = t - s + 1; if (t > s && *(t - 1) == '\r') t--; n = t - s; if (!(mime = newof(0, Mime_t, 1, n))) { nospace(); return -1; } ap->data = mime; mime->length = n; memcpy(mime->magic, s, mime->length); message((-1, "mime magic `%s'", mime->magic)); paxread(pax, ap, NiL, (off_t)0, n, 0); return 1; }
static int tp_getprologue(Pax_t* pax, Paxformat_t* fp, register Paxarchive_t* ap, Paxfile_t* f, unsigned char* buf, size_t size) { register Ar_t* ar; register ui1* s; register ui1* e; int16_t w; size_t n; if (size < 2 * TP_BLOCK) return 0; w = 0; for (e = (s = (ui1*)buf + TP_BLOCK) + TP_BLOCK; s < e; s += 2) w += s[0] + (s[1]<<8); if (w) return 0; w = ((Dir_t*)buf)->checksum[0] + (((Dir_t*)buf)->checksum[1]<<8); if (w < 0 || w > DIRMAG) w = DIRMAG; n = (size_t)w * sizeof(Dir_t); if (!(ar = newof(0, Ar_t, 1, n - sizeof(Dir_t)))) return paxnospace(pax); if (paxread(pax, ap, NiL, PAX_BLOCK, 0, 0) != PAX_BLOCK || paxread(pax, ap, ar->dir, n, 0, 0) != n) { error(2, "%s: %s format directory read error", ap->name, fp->name); free(ar); return -1; } ar->dp = ar->dir; ar->ep = ar->dir + w; ar->pax = pax; ar->ap = ap; ap->data = ar; return 1; }
static ssize_t part_read(Sfio_t* sp, void* buf, size_t n, Sfdisc_t* disc) { register Part_t* part = (Part_t*)disc; ssize_t r; if (part->n <= 0) return part->n; if (n > part->n) n = part->n; if ((r = paxread(part->pax, part->ap, buf, n, 0, 0)) > 0) part->n -= r; return r; }
static int tp_getdata(Pax_t* pax, register Paxarchive_t* ap, register Paxfile_t* f, int fd) { Sfio_t* sp; off_t skip; ssize_t n; int r; if (!(n = f->st->st_size)) return 1; skip = roundof(f->st->st_size, TP_BLOCK); r = -1; if (fd < 0) r = 1; else if (sp = paxpart(pax, ap, f->st->st_size)) for (;;) { if ((n = sfread(sp, pax->buf, sizeof(pax->buf))) < 0) { (*pax->errorf)(NiL, pax, 2, "%s: %s: unexpected EOF", ap->name, f->name); break; } else if (n == 0) { r = 1; break; } skip -= n; if (paxdata(pax, ap, f, fd, pax->buf, n)) break; } if (skip && paxread(pax, ap, NiL, skip, 0, 0) != skip) { (*pax->errorf)(NiL, pax, 2, "%s: %s: cannot skip past %s format data", ap->name, f->name, ap->format->name); r = -1; } return r; }
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; }