char * _ti_find_cap(TBUF *tbuf, char type, short ind) { size_t n; short num; char *cap; _DIAGASSERT(tbuf != NULL); cap = tbuf->buf; for (n = tbuf->entries; n > 0; n--) { num = le16dec(cap); cap += sizeof(uint16_t); if (num == ind) return cap; switch (type) { case 'f': cap++; break; case 'n': cap += sizeof(uint16_t); break; case 's': num = le16dec(cap); cap += sizeof(uint16_t); cap += num; break; } } errno = ESRCH; return NULL; }
char * _ti_find_extra(TBUF *tbuf, const char *code) { size_t n; short num; char *cap; _DIAGASSERT(tbuf != NULL); _DIAGASSERT(code != NULL); cap = tbuf->buf; for (n = tbuf->entries; n > 0; n--) { num = le16dec(cap); cap += sizeof(uint16_t); if (strcmp(cap, code) == 0) return cap + num; cap += num; switch (*cap++) { case 'f': cap++; break; case 'n': cap += sizeof(uint16_t); break; case 's': num = le16dec(cap); cap += sizeof(uint16_t); cap += num; break; } } errno = ESRCH; return NULL; }
static void print_hgst_info_log(void *buf, uint32_t size __unused) { uint8_t *walker, *end, *subpage; int pages; uint16_t len; uint8_t subtype, res; printf("HGST Extra Info Log\n"); printf("===================\n"); walker = buf; pages = *walker++; walker++; len = le16dec(walker); walker += 2; end = walker + len; /* Length is exclusive of this header */ while (walker < end) { subpage = walker + 4; subtype = *walker++ & 0x3f; /* subtype */ res = *walker++; /* Reserved */ len = le16dec(walker); walker += len + 2; /* Length, not incl header */ if (walker > end) { printf("Ooops! Off the end of the list\n"); break; } kv_indirect(subpage, subtype, res, len, hgst_subpage, nitems(hgst_subpage)); } }
static int _ti_dbgetterm(TERMINAL *term, const char *path, const char *name, int flags) { struct cdbr *db; const void *data; char *db_name; const uint8_t *data8; size_t len, klen; int r; if (asprintf(&db_name, "%s.cdb", path) < 0) return -1; db = cdbr_open(db_name, CDBR_DEFAULT); free(db_name); if (db == NULL) return -1; klen = strlen(name) + 1; if (cdbr_find(db, name, klen, &data, &len) == -1) goto fail; data8 = data; if (len == 0) goto fail; /* Check for alias first, fall through to processing normal entries. */ if (data8[0] == 2) { if (klen + 7 > len || le16dec(data8 + 5) != klen) goto fail; if (memcmp(data8 + 7, name, klen)) goto fail; if (cdbr_get(db, le32dec(data8 + 1), &data, &len)) goto fail; data8 = data; if (data8[0] != 1) goto fail; } else if (data8[0] != 1) goto fail; else if (klen + 3 >= len || le16dec(data8 + 1) != klen) goto fail; else if (memcmp(data8 + 3, name, klen)) goto fail; snprintf(database, sizeof database, "%s", path); _ti_database = database; r = _ti_readterm(term, data, len, flags); cdbr_close(db); return r; fail: cdbr_close(db); return 0; }
void uuid_dec_le(void const *buf, struct uuid *uuid) { const uint8_t *p = buf; int i; uuid->time_low = le32dec(p); uuid->time_mid = le16dec(p + 4); uuid->time_hi_and_version = le16dec(p + 6); uuid->clock_seq_hi_and_reserved = p[8]; uuid->clock_seq_low = p[9]; for (i = 0; i < _UUID_NODE_LEN; i++) uuid->node[i] = p[10 + i]; }
/* * Format from Table 22, section 5.7 IO Command Latency Statistics. * Read and write stats pages have identical encoding. */ static void print_intel_read_write_lat_log(void *buf, uint32_t size __unused) { const char *walker = buf; int i; printf("Major: %d\n", le16dec(walker + 0)); printf("Minor: %d\n", le16dec(walker + 2)); for (i = 0; i < 32; i++) printf("%4dus-%4dus: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 4 + i * 4)); for (i = 1; i < 32; i++) printf("%4dms-%4dms: %ju\n", i, i + 1, (uintmax_t)le32dec(walker + 132 + i * 4)); for (i = 1; i < 32; i++) printf("%4dms-%4dms: %ju\n", i * 32, (i + 1) * 32, (uintmax_t)le32dec(walker + 256 + i * 4)); }
static uint64_t tdecode(int t, ...) { uint8_t buf[16]; bool be = t > 0; va_list ap; uint64_t val = 777; int i; if (t < 0) t = -t; va_start(ap, t); memset(buf, 0xC1, sizeof(buf)); for (i = 0; i < t; i++) buf[i] = va_arg(ap, int); va_end(ap); if (be) { switch (t) { case 2: val = be16dec(buf); break; case 4: val = be32dec(buf); break; case 8: val = be64dec(buf); break; } } else { switch (t) { case 2: val = le16dec(buf); break; case 4: val = le32dec(buf); break; case 8: val = le64dec(buf); break; } } return val; }
/* Read a 16bit uint & return it */ uint16_t bs_read_u16(bin_stream_t * bs) { uint16_t data = le16dec(bs->data + bs->pos); bs->pos += 2; return data; }
/* "Missing" from endian.h */ static __inline uint64_t le48dec(const void *pp) { uint8_t const *p = (uint8_t const *)pp; return (((uint64_t)le16dec(p + 4) << 32) | le32dec(p)); }
void bsd_partition_le_dec(u_char *ptr, struct partition *d) { d->p_size = le32dec(ptr + 0); d->p_offset = le32dec(ptr + 4); d->p_fsize = le32dec(ptr + 8); d->p_fstype = ptr[12]; d->p_frag = ptr[13]; d->p_cpg = le16dec(ptr + 14); }
static void le_lebuffer_copytobuf(struct lance_softc *sc, void *fromv, int off, int len) { struct le_lebuffer_softc *lesc = (struct le_lebuffer_softc *)sc; caddr_t from = fromv; for (; len >= 2; len -= 2, off += 2, from += 2) bus_write_2(lesc->sc_bres, off, le16dec(from)); if (len == 1) bus_write_1(lesc->sc_bres, off + 1, *from); }
void pc98_partition_dec(void const *pp, struct pc98_partition *d) { unsigned char const *ptr = pp; int i; d->dp_mid = ptr[0]; d->dp_sid = ptr[1]; d->dp_dum1 = ptr[2]; d->dp_dum2 = ptr[3]; d->dp_ipl_sct = ptr[4]; d->dp_ipl_head = ptr[5]; d->dp_ipl_cyl = le16dec(ptr + 6); d->dp_ssect = ptr[8]; d->dp_shd = ptr[9]; d->dp_scyl = le16dec(ptr + 10); d->dp_esect = ptr[12]; d->dp_ehd = ptr[13]; d->dp_ecyl = le16dec(ptr + 14); for (i = 0; i < sizeof (d->dp_name); i++) d->dp_name[i] = ptr[16 + i]; }
static u_int64_t elf_get_quarter(Elf32_Ehdr *e, void *base, elf_member_t member) { u_int64_t val; val = 0; switch (e->e_ident[EI_CLASS]) { case ELFCLASS32: base = (char *)base + elf32_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: val = be16dec(base); break; case ELFDATA2LSB: val = le16dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASS64: base = (char *)base + elf64_offsets[member]; switch (e->e_ident[EI_DATA]) { case ELFDATA2MSB: val = be16dec(base); break; case ELFDATA2LSB: val = le16dec(base); break; case ELFDATANONE: errx(1, "invalid data format"); } break; case ELFCLASSNONE: errx(1, "invalid class"); } return val; }
void bsd_disklabel_le_enc(u_char *ptr, struct disklabel *d) { int i; u_char *p, *pe; uint16_t sum; le32enc(ptr + 0, d->d_magic); le16enc(ptr + 4, d->d_type); le16enc(ptr + 6, d->d_subtype); bcopy(d->d_typename, ptr + 8, 16); bcopy(d->d_packname, ptr + 24, 16); le32enc(ptr + 40, d->d_secsize); le32enc(ptr + 44, d->d_nsectors); le32enc(ptr + 48, d->d_ntracks); le32enc(ptr + 52, d->d_ncylinders); le32enc(ptr + 56, d->d_secpercyl); le32enc(ptr + 60, d->d_secperunit); le16enc(ptr + 64, d->d_sparespertrack); le16enc(ptr + 66, d->d_sparespercyl); le32enc(ptr + 68, d->d_acylinders); le16enc(ptr + 72, d->d_rpm); le16enc(ptr + 74, d->d_interleave); le16enc(ptr + 76, d->d_trackskew); le16enc(ptr + 78, d->d_cylskew); le32enc(ptr + 80, d->d_headswitch); le32enc(ptr + 84, d->d_trkseek); le32enc(ptr + 88, d->d_flags); le32enc(ptr + 92, d->d_drivedata[0]); le32enc(ptr + 96, d->d_drivedata[1]); le32enc(ptr + 100, d->d_drivedata[2]); le32enc(ptr + 104, d->d_drivedata[3]); le32enc(ptr + 108, d->d_drivedata[4]); le32enc(ptr + 112, d->d_spare[0]); le32enc(ptr + 116, d->d_spare[1]); le32enc(ptr + 120, d->d_spare[2]); le32enc(ptr + 124, d->d_spare[3]); le32enc(ptr + 128, d->d_spare[4]); le32enc(ptr + 132, d->d_magic2); le16enc(ptr + 136, 0); le16enc(ptr + 138, d->d_npartitions); le32enc(ptr + 140, d->d_bbsize); le32enc(ptr + 144, d->d_sbsize); for (i = 0; i < d->d_npartitions; i++) bsd_partition_le_enc(ptr + 148 + 16 * i, &d->d_partitions[i]); pe = ptr + 148 + 16 * d->d_npartitions; sum = 0; for (p = ptr; p < pe; p += 2) sum ^= le16dec(p); le16enc(ptr + 136, sum); }
static void print_hgst_info_self_test(void *buf, uint16_t subtype __unused, uint8_t res __unused, uint32_t size) { size_t i; uint8_t *walker = buf; uint16_t code, hrs; uint32_t lba; printf("Self Test Subpage:\n"); for (i = 0; i < size / 20; i++) { /* Each entry is 20 bytes */ code = le16dec(walker); walker += 2; walker++; /* Ignore fixed flags */ if (*walker == 0) /* Last entry is zero length */ break; if (*walker++ != 0x10) { printf("Bad length for self test report\n"); return; } printf(" %-30s: %d\n", "Recent Test", code); printf(" %-28s: %#x\n", "Self-Test Results", *walker & 0xf); printf(" %-28s: %#x\n", "Self-Test Code", (*walker >> 5) & 0x7); walker++; printf(" %-28s: %#x\n", "Self-Test Number", *walker++); hrs = le16dec(walker); walker += 2; lba = le32dec(walker); walker += 4; printf(" %-28s: %u\n", "Total Power On Hrs", hrs); printf(" %-28s: %#jx (%jd)\n", "LBA", (uintmax_t)lba, (uintmax_t)lba); printf(" %-28s: %#x\n", "Sense Key", *walker++ & 0xf); printf(" %-28s: %#x\n", "Additional Sense Code", *walker++); printf(" %-28s: %#x\n", "Additional Sense Qualifier", *walker++); printf(" %-28s: %#x\n", "Vendor Specific Detail", *walker++); } }
static uint16_t x86bios_emu_rdw(struct x86emu *emu, uint32_t addr) { uint16_t *va; va = x86bios_get_pages(addr, sizeof(*va)); if (va == NULL) x86bios_set_fault(emu, addr); #ifndef __NO_STRICT_ALIGNMENT if ((addr & 1) != 0) return (le16dec(va)); else #endif return (le16toh(*va)); }
/* Print a subpage that is basically just key value pairs */ static void print_hgst_info_subpage_gen(void *buf, uint16_t subtype __unused, uint32_t size, const struct kv_name *kv, size_t kv_count) { uint8_t *wsp, *esp; uint16_t ptype; uint8_t plen; uint64_t param; int i; wsp = buf; esp = wsp + size; while (wsp < esp) { ptype = le16dec(wsp); wsp += 2; wsp++; /* Flags, just ignore */ plen = *wsp++; param = 0; for (i = 0; i < plen; i++) param |= (uint64_t)*wsp++ << (i * 8); printf(" %-30s: %jd\n", kv_lookup(kv, kv_count, ptype), (uintmax_t)param); } }
/* * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ static void kue_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct kue_chain *c = priv; struct kue_softc *sc = c->kue_sc; struct ifnet *ifp = GET_IFP(sc); struct mbuf *m; int total_len, pktlen; int s; DPRINTFN(10,("%s: %s: enter status=%d\n", device_xname(sc->kue_dev), __func__, status)); if (sc->kue_dying) return; if (!(ifp->if_flags & IFF_RUNNING)) return; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; sc->kue_rx_errs++; if (usbd_ratecheck(&sc->kue_rx_notice)) { printf("%s: %u usb errors on rx: %s\n", device_xname(sc->kue_dev), sc->kue_rx_errs, usbd_errstr(status)); sc->kue_rx_errs = 0; } if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->kue_ep[KUE_ENDPT_RX]); goto done; } usbd_get_xfer_status(xfer, NULL, NULL, &total_len, NULL); DPRINTFN(10,("%s: %s: total_len=%d len=%d\n", device_xname(sc->kue_dev), __func__, total_len, le16dec(c->kue_buf))); if (total_len <= 1) goto done; pktlen = le16dec(c->kue_buf); if (pktlen > total_len - 2) pktlen = total_len - 2; if (pktlen < ETHER_MIN_LEN - ETHER_CRC_LEN || pktlen > MCLBYTES - ETHER_ALIGN) { ifp->if_ierrors++; goto done; } /* No errors; receive the packet. */ MGETHDR(m, M_DONTWAIT, MT_DATA); if (m == NULL) { ifp->if_ierrors++; goto done; } if (pktlen > MHLEN - ETHER_ALIGN) { MCLGET(m, M_DONTWAIT); if ((m->m_flags & M_EXT) == 0) { m_freem(m); ifp->if_ierrors++; goto done; } } m->m_data += ETHER_ALIGN; /* copy data to mbuf */ memcpy(mtod(m, uint8_t *), c->kue_buf + 2, pktlen); ifp->if_ipackets++; m->m_pkthdr.len = m->m_len = pktlen; m->m_pkthdr.rcvif = ifp; s = splnet(); /* * Handle BPF listeners. Let the BPF user see the packet, but * don't pass it up to the ether_input() layer unless it's * a broadcast packet, multicast packet, matches our ethernet * address or the interface is in promiscuous mode. */ bpf_mtap(ifp, m); DPRINTFN(10,("%s: %s: deliver %d\n", device_xname(sc->kue_dev), __func__, m->m_len)); (*ifp->if_input)(ifp, m); splx(s); done: /* Setup new transfer. */ usbd_setup_xfer(c->kue_xfer, sc->kue_ep[KUE_ENDPT_RX], c, c->kue_buf, KUE_BUFSZ, USBD_SHORT_XFER_OK | USBD_NO_COPY, USBD_NO_TIMEOUT, kue_rxeof); usbd_transfer(c->kue_xfer); DPRINTFN(10,("%s: %s: start rx\n", device_xname(sc->kue_dev), __func__)); }
static void print_hgst_info_background_scan(void *buf, uint16_t subtype __unused, uint8_t res __unused, uint32_t size) { uint8_t *walker = buf; uint8_t status; uint16_t code, nscan, progress; uint32_t pom, nand; printf("Background Media Scan Subpage:\n"); /* Decode the header */ code = le16dec(walker); walker += 2; walker++; /* Ignore fixed flags */ if (*walker++ != 0x10) { printf("Bad length for background scan header\n"); return; } if (code != 0) { printf("Expceted code 0, found code %#x\n", code); return; } pom = le32dec(walker); walker += 4; walker++; /* Reserved */ status = *walker++; nscan = le16dec(walker); walker += 2; progress = le16dec(walker); walker += 2; walker += 6; /* Reserved */ printf(" %-30s: %d\n", "Power On Minutes", pom); printf(" %-30s: %x (%s)\n", "BMS Status", status, status == 0 ? "idle" : (status == 1 ? "active" : (status == 8 ? "suspended" : "unknown"))); printf(" %-30s: %d\n", "Number of BMS", nscan); printf(" %-30s: %d\n", "Progress Current BMS", progress); /* Report retirements */ if (walker - (uint8_t *)buf != 20) { printf("Coding error, offset not 20\n"); return; } size -= 20; printf(" %-30s: %d\n", "BMS retirements", size / 0x18); while (size > 0) { code = le16dec(walker); walker += 2; walker++; if (*walker++ != 0x14) { printf("Bad length parameter\n"); return; } pom = le32dec(walker); walker += 4; /* * Spec sheet says the following are hard coded, if true, just * print the NAND retirement. */ if (walker[0] == 0x41 && walker[1] == 0x0b && walker[2] == 0x01 && walker[3] == 0x00 && walker[4] == 0x00 && walker[5] == 0x00 && walker[6] == 0x00 && walker[7] == 0x00) { walker += 8; walker += 4; /* Skip reserved */ nand = le32dec(walker); walker += 4; printf(" %-30s: %d\n", "Retirement number", code); printf(" %-28s: %#x\n", "NAND (C/T)BBBPPP", nand); } else { printf("Parameter %#x entry corrupt\n", code); walker += 16; } } }
/* * Table 19. 5.4 SMART Attributes */ static void print_intel_add_smart(void *buf, uint32_t size __unused) { uint8_t *walker = buf; uint8_t *end = walker + 150; const char *name; uint64_t raw; uint8_t normalized; static struct kv_name kv[] = { { 0xab, "Program Fail Count" }, { 0xac, "Erase Fail Count" }, { 0xad, "Wear Leveling Count" }, { 0xb8, "End to End Error Count" }, { 0xc7, "CRC Error Count" }, { 0xe2, "Timed: Media Wear" }, { 0xe3, "Timed: Host Read %" }, { 0xe4, "Timed: Elapsed Time" }, { 0xea, "Thermal Throttle Status" }, { 0xf0, "Retry Buffer Overflows" }, { 0xf3, "PLL Lock Loss Count" }, { 0xf4, "NAND Bytes Written" }, { 0xf5, "Host Bytes Written" }, }; printf("Additional SMART Data Log\n"); printf("=========================\n"); /* * walker[0] = Key * walker[1,2] = reserved * walker[3] = Normalized Value * walker[4] = reserved * walker[5..10] = Little Endian Raw value * (or other represenations) * walker[11] = reserved */ while (walker < end) { name = kv_lookup(kv, nitems(kv), *walker); normalized = walker[3]; raw = le48dec(walker + 5); switch (*walker){ case 0: break; case 0xad: printf("%-32s: %3d min: %u max: %u ave: %u\n", name, normalized, le16dec(walker + 5), le16dec(walker + 7), le16dec(walker + 9)); break; case 0xe2: printf("%-32s: %3d %.3f%%\n", name, normalized, raw / 1024.0); break; case 0xea: printf("%-32s: %3d %d%% %d times\n", name, normalized, walker[5], le32dec(walker+6)); break; default: printf("%-32s: %3d %ju\n", name, normalized, (uintmax_t)raw); break; } walker += 12; } }
int bsd_disklabel_le_dec(u_char *ptr, struct disklabel *d, int maxpart) { int i; u_char *p, *pe; uint16_t sum; d->d_magic = le32dec(ptr + 0); if (d->d_magic != DISKMAGIC) return(EINVAL); d->d_magic2 = le32dec(ptr + 132); if (d->d_magic2 != DISKMAGIC) { return(EINVAL); } d->d_npartitions = le16dec(ptr + 138); if (d->d_npartitions > maxpart) { return(EINVAL); } pe = ptr + 148 + 16 * d->d_npartitions; sum = 0; for (p = ptr; p < pe; p += 2) sum ^= le16dec(p); if (sum != 0) { return(EINVAL); } d->d_type = le16dec(ptr + 4); d->d_subtype = le16dec(ptr + 6); bcopy(ptr + 8, d->d_typename, 16); bcopy(ptr + 24, d->d_packname, 16); d->d_secsize = le32dec(ptr + 40); d->d_nsectors = le32dec(ptr + 44); d->d_ntracks = le32dec(ptr + 48); d->d_ncylinders = le32dec(ptr + 52); d->d_secpercyl = le32dec(ptr + 56); d->d_secperunit = le32dec(ptr + 60); d->d_sparespertrack = le16dec(ptr + 64); d->d_sparespercyl = le16dec(ptr + 66); d->d_acylinders = le32dec(ptr + 68); d->d_rpm = le16dec(ptr + 72); d->d_interleave = le16dec(ptr + 74); d->d_trackskew = le16dec(ptr + 76); d->d_cylskew = le16dec(ptr + 78); d->d_headswitch = le32dec(ptr + 80); d->d_trkseek = le32dec(ptr + 84); d->d_flags = le32dec(ptr + 88); d->d_drivedata[0] = le32dec(ptr + 92); d->d_drivedata[1] = le32dec(ptr + 96); d->d_drivedata[2] = le32dec(ptr + 100); d->d_drivedata[3] = le32dec(ptr + 104); d->d_drivedata[4] = le32dec(ptr + 108); d->d_spare[0] = le32dec(ptr + 112); d->d_spare[1] = le32dec(ptr + 116); d->d_spare[2] = le32dec(ptr + 120); d->d_spare[3] = le32dec(ptr + 124); d->d_spare[4] = le32dec(ptr + 128); d->d_checksum = le16dec(ptr + 136); d->d_npartitions = le16dec(ptr + 138); d->d_bbsize = le32dec(ptr + 140); d->d_sbsize = le32dec(ptr + 144); for (i = 0; i < d->d_npartitions; i++) bsd_partition_le_dec(ptr + 148 + 16 * i, &d->d_partitions[i]); return(0); }
static int _ti_readterm(TERMINAL *term, const char *cap, size_t caplen, int flags) { uint8_t ver; uint16_t ind, num; size_t len; TERMUSERDEF *ud; ver = *cap++; /* Only read version 1 structures */ if (ver != 1) { errno = EINVAL; return -1; } if (allocset(&term->flags, 0, TIFLAGMAX + 1, sizeof(*term->flags)) == -1) return -1; if (allocset(&term->nums, -1, TINUMMAX + 1, sizeof(*term->nums)) == -1) return -1; if (allocset(&term->strs, 0, TISTRMAX + 1, sizeof(*term->strs)) == -1) return -1; if (term->_arealen != caplen) { term->_arealen = caplen; term->_area = realloc(term->_area, term->_arealen); if (term->_area == NULL) return -1; } memcpy(term->_area, cap, term->_arealen); cap = term->_area; len = le16dec(cap); cap += sizeof(uint16_t); term->name = cap; cap += len; len = le16dec(cap); cap += sizeof(uint16_t); if (len == 0) term->_alias = NULL; else { term->_alias = cap; cap += len; } len = le16dec(cap); cap += sizeof(uint16_t); if (len == 0) term->desc = NULL; else { term->desc = cap; cap += len; } num = le16dec(cap); cap += sizeof(uint16_t); if (num != 0) { num = le16dec(cap); cap += sizeof(uint16_t); for (; num != 0; num--) { ind = le16dec(cap); cap += sizeof(uint16_t); term->flags[ind] = *cap++; if (flags == 0 && !VALID_BOOLEAN(term->flags[ind])) term->flags[ind] = 0; } } num = le16dec(cap); cap += sizeof(uint16_t); if (num != 0) { num = le16dec(cap); cap += sizeof(uint16_t); for (; num != 0; num--) { ind = le16dec(cap); cap += sizeof(uint16_t); term->nums[ind] = le16dec(cap); if (flags == 0 && !VALID_NUMERIC(term->nums[ind])) term->nums[ind] = ABSENT_NUMERIC; cap += sizeof(uint16_t); } } num = le16dec(cap); cap += sizeof(uint16_t); if (num != 0) { num = le16dec(cap); cap += sizeof(uint16_t); for (; num != 0; num--) { ind = le16dec(cap); cap += sizeof(uint16_t); len = le16dec(cap); cap += sizeof(uint16_t); if (len > 0) term->strs[ind] = cap; else if (flags == 0) term->strs[ind] = ABSENT_STRING; else term->strs[ind] = CANCELLED_STRING; cap += len; } } num = le16dec(cap); cap += sizeof(uint16_t); if (num != 0) { num = le16dec(cap); cap += sizeof(uint16_t); if (num != term->_nuserdefs) { free(term->_userdefs); term->_userdefs = NULL; term->_nuserdefs = num; } if (allocset(&term->_userdefs, 0, term->_nuserdefs, sizeof(*term->_userdefs)) == -1) return -1; for (num = 0; num < term->_nuserdefs; num++) { ud = &term->_userdefs[num]; len = le16dec(cap); cap += sizeof(uint16_t); ud->id = cap; cap += len; ud->type = *cap++; switch (ud->type) { case 'f': ud->flag = *cap++; if (flags == 0 && !VALID_BOOLEAN(ud->flag)) ud->flag = 0; ud->num = ABSENT_NUMERIC; ud->str = ABSENT_STRING; break; case 'n': ud->flag = ABSENT_BOOLEAN; ud->num = le16dec(cap); if (flags == 0 && !VALID_NUMERIC(ud->num)) ud->num = ABSENT_NUMERIC; ud->str = ABSENT_STRING; cap += sizeof(uint16_t); break; case 's': ud->flag = ABSENT_BOOLEAN; ud->num = ABSENT_NUMERIC; len = le16dec(cap); cap += sizeof(uint16_t); if (len > 0) ud->str = cap; else if (flags == 0) ud->str = ABSENT_STRING; else ud->str = CANCELLED_STRING; cap += len; break; default: errno = EINVAL; return -1; } } } else { term->_nuserdefs = 0; if (term->_userdefs) { free(term->_userdefs); term->_userdefs = NULL; } } return 1; }