/* return: 0 = not found, 1 = error, or record length */ static unsigned match(struct cdb_make *cdbmp, unsigned pos, const char *key, unsigned klen) { int len; unsigned rlen; if (lseek(cdbmp->cdb_fd, pos, SEEK_SET) < 0) return 1; if (read(cdbmp->cdb_fd, cdbmp->cdb_buf, 8) != 8) return 1; if (cdb_unpack(cdbmp->cdb_buf) != klen) return 0; /* record length; check its validity */ rlen = cdb_unpack(cdbmp->cdb_buf + 4); if (rlen > cdbmp->cdb_dpos - pos - klen - 8) return errno = EPROTO, 1; /* someone changed our file? */ rlen += klen + 8; while(klen) { len = klen > sizeof(cdbmp->cdb_buf) ? sizeof(cdbmp->cdb_buf) : klen; len = read(cdbmp->cdb_fd, cdbmp->cdb_buf, len); if (len <= 0) return 1; if (memcmp(cdbmp->cdb_buf, key, len) != 0) return 0; key += len; klen -= len; } return rlen; }
static int cdb_read_attrs(const char *filename, t_read_attr_func cb, void *data) { cdbi_t eod, klen, vlen; cdbi_t pos = 0; const char *key; const char *val; unsigned char buf[2048]; std::FILE *f; if ((f = std::fopen(filename, "rb")) == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "got error opening file '%s'", filename); return -1; } if (fget(f, buf, 2048, &pos, 2048)) goto err_fd; eod = cdb_unpack(buf); while(pos < eod) { if (fget(f, buf, 8, &pos, eod)) goto err_fd; klen = cdb_unpack(buf); vlen = cdb_unpack(buf + 4); if ((key = fcpy(f, klen, &pos, eod, buf)) == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute key"); goto err_fd; } key = xstrdup(key); if ((val = fcpy(f, vlen, &pos, eod, buf)) == NULL) { eventlog(eventlog_level_error, __FUNCTION__, "error reading attribute val"); goto err_key; } // eventlog(eventlog_level_trace, __FUNCTION__, "read atribute : '%s' -> '%s'", key, val); if (cb(key, val, data)) eventlog(eventlog_level_error, __FUNCTION__, "got error from callback on account file '%s'", filename); xfree((void *)key); } std::fclose(f); return 0; err_key: xfree((void *)key); err_fd: std::fclose(f); return -1; }
static int match(std::FILE *fd, unsigned pos, const char *key, unsigned klen) { unsigned char buf[64]; /*XXX cdb_buf may be used here instead */ if (std::fseek(fd, pos, SEEK_SET) || std::fread(buf, 1, 8, fd) != 8) return -1; if (cdb_unpack(buf) != klen) return 0; while(klen > sizeof(buf)) { if (std::fread(buf, 1, sizeof(buf), fd) != sizeof(buf)) return -1; if (std::memcmp(buf, key, sizeof(buf)) != 0) return 0; key += sizeof(buf); klen -= sizeof(buf); } if (klen) { if (std::fread(buf, 1, klen, fd) != klen) return -1; if (std::memcmp(buf, key, klen) != 0) return 0; } return 1; }
int cdb_init(struct cdb *cdbp, int fd) { struct stat st; unsigned char *mem; unsigned fsize, dend; #ifdef _WIN32 HANDLE hFile, hMapping; #endif /* get file size */ if (fstat(fd, &st) < 0) return -1; /* trivial sanity check: at least toc should be here */ if (st.st_size < 2048) return errno = EPROTO, -1; fsize = (unsigned)(st.st_size & 0xffffffffu); /* memory-map file */ #ifdef _WIN32 hFile = (HANDLE) _get_osfhandle(fd); if (hFile == (HANDLE) -1) return -1; hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (!hMapping) return -1; mem = (unsigned char *)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (!mem) return -1; #else mem = (unsigned char*)mmap(NULL, fsize, PROT_READ, MAP_SHARED, fd, 0); if (mem == MAP_FAILED) return -1; #endif /* _WIN32 */ cdbp->cdb_fd = fd; cdbp->cdb_fsize = fsize; cdbp->cdb_mem = mem; #if 0 /* XXX don't know well about madvise syscall -- is it legal to set different options for parts of one mmap() region? There is also posix_madvise() exist, with POSIX_MADV_RANDOM etc... */ #ifdef MADV_RANDOM /* set madvise() parameters. Ignore errors for now if system doesn't support it */ madvise(mem, 2048, MADV_WILLNEED); madvise(mem + 2048, cdbp->cdb_fsize - 2048, MADV_RANDOM); #endif #endif cdbp->cdb_vpos = cdbp->cdb_vlen = 0; cdbp->cdb_kpos = cdbp->cdb_klen = 0; dend = cdb_unpack(mem); if (dend < 2048) dend = 2048; else if (dend >= fsize) dend = fsize; cdbp->cdb_dend = dend; return 0; }
int cdb_seqnext(unsigned *cptr, struct cdb *cdbp) { unsigned klen, vlen; unsigned pos = *cptr; unsigned dend = cdbp->cdb_dend; const unsigned char *mem = cdbp->cdb_mem; if (pos > dend - 8) return 0; klen = cdb_unpack(mem + pos); vlen = cdb_unpack(mem + pos + 4); pos += 8; if (dend - klen < pos || dend - vlen < pos + klen) return errno = EPROTO, -1; cdbp->cdb_kpos = pos; cdbp->cdb_klen = klen; cdbp->cdb_vpos = pos + klen; cdbp->cdb_vlen = vlen; *cptr = pos + klen + vlen; return 1; }
int cdb_init(struct cdb *cdbp, FILE *fd) { unsigned char *mem; unsigned fsize, dend; /* get file size */ if (fseek(fd, 0, SEEK_END)) return -1; fsize = (unsigned)(ftell(fd)); rewind(fd); /* trivial sanity check: at least toc should be here */ if (fsize < 2048) return errno = EPROTO, -1; /* memory-map file */ if ((mem =(unsigned char *) pmmap(NULL, fsize, PROT_READ, MAP_SHARED, fileno(fd), 0)) == (unsigned char *)-1) return -1; cdbp->cdb_fd = fd; cdbp->cdb_fsize = fsize; cdbp->cdb_mem = mem; #if 0 /* XXX don't know well about madvise syscall -- is it legal to set different options for parts of one mmap() region? There is also posix_madvise() exist, with POSIX_MADV_RANDOM etc... */ #ifdef MADV_RANDOM /* set madvise() parameters. Ignore errors for now if system doesn't support it */ madvise(mem, 2048, MADV_WILLNEED); madvise(mem + 2048, cdbp->cdb_fsize - 2048, MADV_RANDOM); #endif #endif cdbp->cdb_vpos = cdbp->cdb_vlen = 0; cdbp->cdb_kpos = cdbp->cdb_klen = 0; dend = cdb_unpack(mem); if (dend < 2048) dend = 2048; else if (dend >= fsize) dend = fsize; cdbp->cdb_dend = dend; return 0; }