static bool siemens_meas_setup(int fd, struct hdr_s* hdr) { off_t start = 0; xseek(fd, start); xread(fd, hdr, sizeof(struct hdr_s)); // check for VD version bool vd = ((hdr->offset < 10000) && (hdr->nscans < 64)); if (vd) { debug_printf(DP_INFO, "VD Header. MeasID: %d FileID: %d Scans: %d\n", hdr->measid, hdr->fileid, hdr->nscans); start += hdr->datoff; xseek(fd, start); // reread offset xread(fd, &hdr->offset, sizeof(hdr->offset)); } else { debug_printf(DP_INFO, "VB Header.\n"); hdr->nscans = 1; } start += hdr->offset; xseek(fd, start); return vd; }
/* * Compress executable and output it in relocatable object format. */ void kgzcmp(struct kgz_hdr *kh, const char *f1, const char *f2) { struct iodesc idi, ido; struct kgz_hdr khle; if ((idi.fd = open(idi.fname = f1, O_RDONLY)) == -1) err(1, "%s", idi.fname); if ((ido.fd = open(ido.fname = f2, O_CREAT | O_TRUNC | O_WRONLY, 0666)) == -1) err(1, "%s", ido.fname); kh->ident[0] = KGZ_ID0; kh->ident[1] = KGZ_ID1; kh->ident[2] = KGZ_ID2; kh->ident[3] = KGZ_ID3; mk_data(&idi, &ido, kh, (format == F_AOUT ? sizeof(struct kgz_aouthdr0) : sizeof(struct kgz_elfhdr)) + sizeof(struct kgz_hdr)); kh->dload &= 0xffffff; kh->entry &= 0xffffff; if (format == F_AOUT) { struct kgz_aouthdr0 ahdr0 = aouthdr0; struct kgz_aouthdr1 ahdr1 = aouthdr1; unsigned x = (sizeof(struct kgz_hdr) + kh->nsize) & (16 - 1); if (x) { x = 16 - x; xzero(&ido, x); } xwrite(&ido, &ahdr1, sizeof(ahdr1)); ahdr0.a.a_data += kh->nsize + x; xseek(&ido, 0); xwrite(&ido, &ahdr0, sizeof(ahdr0)); } else { struct kgz_elfhdr ehdr = elfhdr; ehdr.st[KGZ_ST_KGZ_NDATA].st_size = htole32(kh->nsize); ehdr.sh[KGZ_SH_DATA].sh_size = htole32(le32toh(ehdr.sh[KGZ_SH_DATA].sh_size) + kh->nsize); xseek(&ido, 0); xwrite(&ido, &ehdr, sizeof(ehdr)); } khle = *kh; khle.dload = htole32(khle.dload); khle.dsize = htole32(khle.dsize); khle.isize = htole32(khle.isize); khle.entry = htole32(khle.entry); khle.nsize = htole32(khle.nsize); xwrite(&ido, &khle, sizeof(khle)); xclose(&ido); xclose(&idi); }
/* * Make encoded (compressed) data. */ static void mk_data(const struct iodesc * idi, const struct iodesc * ido, struct kgz_hdr * kh, size_t off) { union { struct exec ex; Elf32_Ehdr ee; } hdr; struct stat sb; struct iodesc idp; int fd[2]; pid_t pid; size_t n; int fmt, status, e; n = xread(idi, &hdr, sizeof(hdr), 0); fmt = 0; if (n >= sizeof(hdr.ee) && IS_ELF(hdr.ee)) fmt = F_ELF; else if (n >= sizeof(hdr.ex) && N_GETMAGIC(hdr.ex) == ZMAGIC) fmt = F_AOUT; if (!fmt) errx(1, "%s: Format not supported", idi->fname); xseek(ido, off); if (pipe(fd)) err(1, NULL); switch (pid = fork()) { case -1: err(1, NULL); case 0: close(fd[1]); dup2(fd[0], STDIN_FILENO); close(fd[0]); close(idi->fd); dup2(ido->fd, STDOUT_FILENO); close(ido->fd); execlp("gzip", "gzip", "-9n", (char *)NULL); warn(NULL); _exit(1); default: close(fd[0]); idp.fname = "(pipe)"; idp.fd = fd[1]; e = fmt == F_ELF ? ld_elf(idi, &idp, kh, &hdr.ee) : fmt == F_AOUT ? ld_aout(idi, &idp, kh, &hdr.ex) : -1; close(fd[1]); if ((pid = waitpid(pid, &status, 0)) == -1) err(1, NULL); if (WIFSIGNALED(status) || WEXITSTATUS(status)) exit(1); } if (e) errx(1, "%s: Invalid format", idi->fname); if (fstat(ido->fd, &sb)) err(1, "%s", ido->fname); kh->nsize = sb.st_size - off; }
/* * xget_object() contains the logic for extracting an individual object from a * packed buffer, which it consumes using xread() and xseek() operations * provided by the caller. flags may be set to either EUP_ALLOC, in which case * new memory is allocated for the variable length items unpacked, or * EUP_NOALLOC, in which case item data pointer indicate locations within the * buffer, using the provided xpos() function. EUP_NOALLOC is generally not * useful for callers representing interaction with actual file streams, and * should not be specified thereby. */ static ea_object_type_t xget_object( ea_file_impl_t *f, ea_object_t *obj, size_t (*xread)(ea_file_impl_t *, void *, size_t), off_t (*xseek)(ea_file_impl_t *, off_t), void *(*xpos)(ea_file_impl_t *), int flags) { ea_size_t sz; uint32_t gp_backskip, scratch32; void *buf; size_t r; /* Read the catalog tag. */ if ((r = xread(f, &obj->eo_catalog, sizeof (ea_catalog_t))) == 0) { EXACCT_SET_ERR(EXR_EOF); return (EO_ERROR); } else if (r != sizeof (ea_catalog_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_catalog); /* * If this is a record group, we treat it separately: only record * groups cause us to allocate new depth frames. */ if ((obj->eo_catalog & EXT_TYPE_MASK) == EXT_GROUP) { obj->eo_type = EO_GROUP; /* Read size field, and number of objects. */ if (xread(f, &sz, sizeof (ea_size_t)) != sizeof (ea_size_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&sz); if (xread(f, &obj->eo_group.eg_nobjs, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_group.eg_nobjs); /* Now read the group's small backskip. */ if (xread(f, &gp_backskip, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } /* Push a new depth stack frame. */ if (stack_new_group(f, obj->eo_group.eg_nobjs) != 0) { /* exacct_error set above */ return (EO_ERROR); } /* * If the group has no items, we now need to position to the * end of the group, because there will be no subsequent calls * to process the group, it being empty. */ if (obj->eo_group.eg_nobjs == 0) { if (stack_next_object(f, xread) == -1) { /* exacct_error set above. */ return (EO_ERROR); } } f->ef_advance = 0; EXACCT_SET_ERR(EXR_OK); return (obj->eo_type); } /* * Otherwise we are reading an item. */ obj->eo_type = EO_ITEM; switch (obj->eo_catalog & EXT_TYPE_MASK) { case EXT_STRING: case EXT_EXACCT_OBJECT: case EXT_RAW: if (xread(f, &sz, sizeof (ea_size_t)) != sizeof (ea_size_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&sz); /* * Subtract backskip value from size. */ sz -= sizeof (uint32_t); if ((flags & EUP_ALLOC_MASK) == EUP_NOALLOC) { buf = xpos(f); if (xseek(f, sz) == -1) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } } else { if ((buf = ea_alloc(sz)) == NULL) /* exacct_error set above. */ return (EO_ERROR); if (xread(f, buf, sz) != sz) { ea_free(buf, sz); EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } } obj->eo_item.ei_string = buf; /* * Maintain our consistent convention that string lengths * include the terminating NULL character. */ obj->eo_item.ei_size = sz; break; case EXT_UINT8: if (xread(f, &obj->eo_item.ei_uint8, sizeof (uint8_t)) != sizeof (uint8_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } obj->eo_item.ei_size = sizeof (uint8_t); break; case EXT_UINT16: if (xread(f, &obj->eo_item.ei_uint16, sizeof (uint16_t)) != sizeof (uint16_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order16(&obj->eo_item.ei_uint16); obj->eo_item.ei_size = sizeof (uint16_t); break; case EXT_UINT32: if (xread(f, &obj->eo_item.ei_uint32, sizeof (uint32_t)) != sizeof (uint32_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order32(&obj->eo_item.ei_uint32); obj->eo_item.ei_size = sizeof (uint32_t); break; case EXT_UINT64: if (xread(f, &obj->eo_item.ei_uint64, sizeof (uint64_t)) != sizeof (uint64_t)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64(&obj->eo_item.ei_uint64); obj->eo_item.ei_size = sizeof (uint64_t); break; case EXT_DOUBLE: if (xread(f, &obj->eo_item.ei_double, sizeof (double)) != sizeof (double)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } exacct_order64((uint64_t *)&obj->eo_item.ei_double); obj->eo_item.ei_size = sizeof (double); break; default: /* * We've encountered an unknown type value. Flag the error and * exit. */ EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } /* * Advance over current large backskip value, * and position at the start of the next object. */ if (xread(f, &scratch32, sizeof (scratch32)) != sizeof (scratch32)) { EXACCT_SET_ERR(EXR_CORRUPT_FILE); return (EO_ERROR); } if (stack_next_object(f, xread) == -1) { /* exacct_error set above. */ return (EO_ERROR); } f->ef_advance = 0; EXACCT_SET_ERR(EXR_OK); return (obj->eo_type); }