const char * parse_setting_from_defs(pool_t pool, const struct setting_def *defs, void *base, const char *key, const char *value) { const struct setting_def *def; for (def = defs; def->name != NULL; def++) { if (strcmp(def->name, key) == 0) { void *ptr = STRUCT_MEMBER_P(base, def->offset); switch (def->type) { case SET_STR: *((char **)ptr) = p_strdup(pool, value); return NULL; case SET_INT: /* use %i so we can handle eg. 0600 as octal value with umasks */ return get_uint(value, (unsigned int *) ptr); case SET_BOOL: return get_bool(value, (bool *) ptr); } } } return t_strconcat("Unknown setting: ", key, NULL); }
static void sql_result_fetch(struct sql_result *result) { unsigned int i, count; const char *value; void *ptr; memset(result->fetch_dest, 0, result->fetch_dest_size); count = result->map_size; for (i = 0; i < count; i++) { if (result->map[i].offset == (size_t)-1) continue; value = sql_result_get_field_value(result, i); ptr = STRUCT_MEMBER_P(result->fetch_dest, result->map[i].offset); switch (result->map[i].type) { case SQL_TYPE_STR: { *((const char **)ptr) = value; break; } case SQL_TYPE_UINT: { if (value != NULL && str_to_uint(value, (unsigned int *)ptr) < 0) i_error("sql: Value not uint: %s", value); break; } case SQL_TYPE_ULLONG: { if (value != NULL && str_to_ullong(value, (unsigned long long *)ptr) < 0) i_error("sql: Value not ullong: %s", value); break; } case SQL_TYPE_BOOL: { if (value != NULL && (*value == 't' || *value == '1')) *((bool *)ptr) = TRUE; break; } } } }
struct UCD_info * _UCD_create(const char *filename) { union { Elf32_Ehdr h32; Elf64_Ehdr h64; } elf_header; #define elf_header32 elf_header.h32 #define elf_header64 elf_header.h64 bool _64bits; struct UCD_info *ui = memset(malloc(sizeof(*ui)), 0, sizeof(*ui)); ui->edi.di_cache.format = -1; ui->edi.di_debug.format = -1; #if UNW_TARGET_IA64 ui->edi.ktab.format = -1; #endif int fd = ui->coredump_fd = open(filename, O_RDONLY); if (fd < 0) goto err; ui->coredump_filename = strdup(filename); /* No sane ELF32 file is going to be smaller then ELF64 _header_, * so let's just read 64-bit sized one. */ if (read(fd, &elf_header64, sizeof(elf_header64)) != sizeof(elf_header64)) { Debug(0, "'%s' is not an ELF file\n", filename); goto err; } if (memcmp(&elf_header32, ELFMAG, SELFMAG) != 0) { Debug(0, "'%s' is not an ELF file\n", filename); goto err; } if (elf_header32.e_ident[EI_CLASS] != ELFCLASS32 && elf_header32.e_ident[EI_CLASS] != ELFCLASS64) { Debug(0, "'%s' is not a 32/64 bit ELF file\n", filename); goto err; } if (WE_ARE_LITTLE_ENDIAN != (elf_header32.e_ident[EI_DATA] == ELFDATA2LSB)) { Debug(0, "'%s' is endian-incompatible\n", filename); goto err; } _64bits = (elf_header32.e_ident[EI_CLASS] == ELFCLASS64); if (_64bits && sizeof(elf_header64.e_entry) > sizeof(off_t)) { Debug(0, "Can't process '%s': 64-bit file " "while only %ld bits are supported", filename, 8L * sizeof(off_t)); goto err; } /* paranoia check */ if (_64bits ? 0 /* todo: (elf_header64.e_ehsize != NN || elf_header64.e_phentsize != NN) */ : (elf_header32.e_ehsize != 52 || elf_header32.e_phentsize != 32) ) { Debug(0, "'%s' has wrong e_ehsize or e_phentsize\n", filename); goto err; } off_t ofs = (_64bits ? elf_header64.e_phoff : elf_header32.e_phoff); if (lseek(fd, ofs, SEEK_SET) != ofs) { Debug(0, "Can't read phdrs from '%s'\n", filename); goto err; } unsigned size = ui->phdrs_count = (_64bits ? elf_header64.e_phnum : elf_header32.e_phnum); coredump_phdr_t *phdrs = ui->phdrs = memset(malloc(size * sizeof(phdrs[0])), 0, size * sizeof(phdrs[0])); if (_64bits) { coredump_phdr_t *cur = phdrs; unsigned i = 0; while (i < size) { Elf64_Phdr hdr64; if (read(fd, &hdr64, sizeof(hdr64)) != sizeof(hdr64)) { Debug(0, "Can't read phdrs from '%s'\n", filename); goto err; } cur->p_type = hdr64.p_type ; cur->p_flags = hdr64.p_flags ; cur->p_offset = hdr64.p_offset; cur->p_vaddr = hdr64.p_vaddr ; /*cur->p_paddr = hdr32.p_paddr ; always 0 */ //TODO: check that and abort if it isn't? cur->p_filesz = hdr64.p_filesz; cur->p_memsz = hdr64.p_memsz ; cur->p_align = hdr64.p_align ; /* cur->backing_filename = NULL; - done by memset */ cur->backing_fd = -1; cur->backing_filesize = hdr64.p_filesz; i++; cur++; } } else { coredump_phdr_t *cur = phdrs; unsigned i = 0; while (i < size) { Elf32_Phdr hdr32; if (read(fd, &hdr32, sizeof(hdr32)) != sizeof(hdr32)) { Debug(0, "Can't read phdrs from '%s'\n", filename); goto err; } cur->p_type = hdr32.p_type ; cur->p_flags = hdr32.p_flags ; cur->p_offset = hdr32.p_offset; cur->p_vaddr = hdr32.p_vaddr ; /*cur->p_paddr = hdr32.p_paddr ; always 0 */ cur->p_filesz = hdr32.p_filesz; cur->p_memsz = hdr32.p_memsz ; cur->p_align = hdr32.p_align ; /* cur->backing_filename = NULL; - done by memset */ cur->backing_fd = -1; cur->backing_filesize = hdr32.p_memsz; i++; cur++; } } unsigned i = 0; coredump_phdr_t *cur = phdrs; while (i < size) { Debug(2, "phdr[%03d]: type:%d", i, cur->p_type); if (cur->p_type == PT_NOTE) { Elf32_Nhdr *note_hdr, *note_end; unsigned n_threads; ui->note_phdr = malloc(cur->p_filesz); if (lseek(fd, cur->p_offset, SEEK_SET) != (off_t)cur->p_offset || (uoff_t)read(fd, ui->note_phdr, cur->p_filesz) != cur->p_filesz) { Debug(0, "Can't read PT_NOTE from '%s'\n", filename); goto err; } note_end = STRUCT_MEMBER_P (ui->note_phdr, cur->p_filesz); /* Count number of threads */ n_threads = 0; note_hdr = (Elf32_Nhdr *)ui->note_phdr; while (NOTE_FITS (note_hdr, note_end)) { if (note_hdr->n_type == NT_PRSTATUS) n_threads++; note_hdr = NOTE_NEXT (note_hdr); } ui->n_threads = n_threads; ui->threads = malloc(sizeof (void *) * n_threads); n_threads = 0; note_hdr = (Elf32_Nhdr *)ui->note_phdr; while (NOTE_FITS (note_hdr, note_end)) { if (note_hdr->n_type == NT_PRSTATUS) ui->threads[n_threads++] = NOTE_DATA (note_hdr); note_hdr = NOTE_NEXT (note_hdr); } } if (cur->p_type == PT_LOAD) { Debug(2, " ofs:%08llx va:%08llx filesize:%08llx memsize:%08llx flg:%x", (unsigned long long) cur->p_offset, (unsigned long long) cur->p_vaddr, (unsigned long long) cur->p_filesz, (unsigned long long) cur->p_memsz, cur->p_flags ); if (cur->p_filesz < cur->p_memsz) Debug(2, " partial"); if (cur->p_flags & PF_X) Debug(2, " executable"); } Debug(2, "\n"); i++; cur++; } if (ui->n_threads == 0) { Debug(0, "No NT_PRSTATUS note found in '%s'\n", filename); goto err; } ui->prstatus = ui->threads[0]; return ui; err: _UCD_destroy(ui); return NULL; }