⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 puredb_read.c

📁 pure-ftpd-1.0.21.tar.gz 配置pure-ftp的源码
💻 C
字号:
/* (C)opyleft 2001-2006 Frank DENIS <j@pureftpd.org> */#include <config.h>#include "puredb_p.h"#include "puredb_read.h"static puredb_u32_t puredb_hash(const char * const msg, size_t len){    puredb_u32_t j = (puredb_u32_t) 5381U;        while (len != 0) {        len--;        j += (j << 5);        j ^= ((unsigned char) msg[len]);            }    j &= 0xffffffff;        return j;}static ssize_t safe_read(const int fd, void * const buf_, size_t maxlen){    unsigned char *buf = (unsigned char *) buf_;    ssize_t readen;        do {        while ((readen = read(fd, buf, maxlen)) < (ssize_t) 0 &&                errno == EINTR);        if (readen < (ssize_t) 0 || readen > (ssize_t) maxlen) {            return readen;        }        if (readen == (ssize_t) 0) {            ret:            return (ssize_t) (buf - (unsigned char *) buf_);        }        maxlen -= readen;        buf += readen;    } while (maxlen > (ssize_t) 0);    goto ret;}static int read_be_long(const PureDB * const db,                        const puredb_u32_t offset,                        puredb_u32_t * const result){    unsigned char mapoffsetbuf[4];            unsigned char *mapoffset;    #ifdef USE_MAPPED_IO    if (db->map != NULL) {        mapoffset = db->map + offset;            } else #endif    {        if (lseek(db->fd, offset, SEEK_SET) == (off_t) -1) {            return -1;        }                if (safe_read(db->fd, mapoffsetbuf, sizeof mapoffsetbuf) !=             (ssize_t) sizeof mapoffsetbuf) {            return -1;        }        mapoffset = mapoffsetbuf;    }    *result = mapoffset[0] << 24 | mapoffset[1] << 16 |         mapoffset[2] << 8 | mapoffset[3];        return 0;}static int read_memcmp(const PureDB * const db, const puredb_u32_t offset,                        const unsigned char *str, const puredb_u32_t len){    unsigned char *mapoffsetbuf;    int cmp;    #ifdef USE_MAPPED_IO    if (db->map != NULL) {        return memcmp(db->map + offset, str, (size_t) len) != 0;    }#endif    if ((mapoffsetbuf = (unsigned char *) ALLOCA(len)) == NULL) {        return -2;    }    if (lseek(db->fd, offset, SEEK_SET) == (off_t) -1) {        err:        ALLOCA_FREE(mapoffsetbuf);        return -2;    }            if (safe_read(db->fd, mapoffsetbuf, (size_t) len) != (ssize_t) len) {        goto err;    }    cmp = memcmp(mapoffsetbuf, str, (size_t) len) != 0;    ALLOCA_FREE(mapoffsetbuf);        return cmp;}int puredb_open(PureDB * const db, const char *dbfile){    struct stat st;        db->map = NULL;    if ((db->fd = open(dbfile, O_RDONLY | O_BINARY)) == -1) {        return -1;    }    if (fstat(db->fd, &st) < 0 ||         (db->size = (puredb_u32_t) st.st_size) > (size_t) 0xffffffff ||        db->size < ((size_t) (256U + 1U) * sizeof(puredb_u32_t) +                    sizeof PUREDB_VERSION - (size_t) 1U)) {        close(db->fd);                return -2;    }   #ifdef HAVE_MMAP    if ((char *) (db->map =                   (unsigned char *) mmap(NULL, db->size, PROT_READ,                                         MAP_FILE | MAP_SHARED, db->fd,                                          (off_t) 0)) == (char *) MAP_FAILED) {        db->map = NULL;    }#elif defined(HAVE_MAPVIEWOFFILE)    {        HANDLE fileh;                fileh = (HANDLE) _get_osfhandle(db->fd);        if (fileh != (HANDLE) -1) {            HANDLE fmh;                        fmh = CreateFileMapping(fileh, 0, PAGE_READONLY, 0, 0, 0);            if (fmh) {                db->map = MapViewOfFile(fmh, FILE_MAP_READ, 0, 0, db->size);                CloseHandle(fmh);            }        }    }    #endif        if (read_memcmp(db, (puredb_u32_t) 0U,                     (const unsigned char *) PUREDB_VERSION,                     sizeof PUREDB_VERSION - (size_t) 1U) != 0) {                return -3;    }            return 0;}int puredb_find(PureDB * const db, const char * const tofind,                const size_t tofind_len, off_t * const retpos,                 size_t * const retlen){    puredb_u32_t hash;    puredb_u32_t scanned_hash;        puredb_u32_t hash0;    puredb_u32_t hash1;    puredb_u32_t hash1e;    puredb_u32_t lastslot;    puredb_u32_t slotlo;    puredb_u32_t slothi;    puredb_u32_t sno;    *retpos = (off_t) -1;    *retlen = (size_t) 0U;    hash = puredb_hash(tofind, tofind_len);    hash0 = sizeof PUREDB_VERSION - (size_t) 1U +        (hash & 0xff) * sizeof(puredb_u32_t);    if ((hash0 + sizeof(puredb_u32_t) * 2U) > db->size) {        return -2;                     /* corrupted table */    }    if (read_be_long(db, hash0, &hash1) < 0) {        return -3;                     /* read error */    }    if (read_be_long(db, hash0 + sizeof(puredb_u32_t), &hash1e) < 0) {        return -3;                     /* read error */    }    if (hash1e <= hash1) {        return -2;                     /* corrupted table */            }        if (hash1 == (puredb_u32_t) 0U) {        return -1;                     /* not found (first table) */    }    if (hash1 > db->size) {        return -2;                     /* corrupted table */    }    lastslot = (hash1e - hash1) / (sizeof(puredb_u32_t) + sizeof(puredb_u32_t));    if (lastslot <= 0U) {        return -2;                     /* corrupted table */            }    lastslot--;#if !defined(MINIMAL) && !defined(NO_BINARY_LOOKUP)    slotlo = 0U;    slothi = lastslot;    sno = slothi / 2U;        while (slotlo <= slothi) {        if (read_be_long(db, hash1 + sno *                          (sizeof(puredb_u32_t) + sizeof(puredb_u32_t)),                         &scanned_hash) < 0) {            return -3;        }        if (scanned_hash == hash) {            while (sno > 0U) {                sno--;                if (read_be_long(db, hash1 + sno *                                  (sizeof(puredb_u32_t) + sizeof(puredb_u32_t)),                                 &scanned_hash) < 0) {                        return -3;                }                if (scanned_hash != hash) {                    sno++;                    break;                }            }            hash1 += sno * (sizeof(puredb_u32_t) + sizeof(puredb_u32_t));            goto shortcut;        }        if (scanned_hash > hash) {            if (sno <= 0U) {                break;            }            slothi = sno - 1;        } else {            if (sno >= lastslot) {                break;            }            slotlo = sno + 1;        }        sno = (slothi + slotlo) / 2U;            }    hash1 += sno * (sizeof(puredb_u32_t) + sizeof(puredb_u32_t));#endif    for(;;) {        if (read_be_long(db, hash1, &scanned_hash) < 0) {            return -3;        }                if (scanned_hash > hash) {            return -1;                     /* not found (too late) */        }        if (scanned_hash == hash) {                        puredb_u32_t data;            puredb_u32_t key_size;            puredb_u32_t data_size;            shortcut:            if (read_be_long(db, hash1 + 4, &data) < 0) {                return -3;            }            if (data > db->size) {                return -2;             /* incorrect pointer */            }            if (read_be_long(db, data, &key_size) < 0) {                return -3;            }            if (key_size != (puredb_u32_t) tofind_len) {                goto trynext;            }            if (read_memcmp(db, data + sizeof(puredb_u32_t),                            (const unsigned char *) tofind, tofind_len) != 0) {                goto trynext;            }            data += sizeof(puredb_u32_t) + tofind_len;            if (read_be_long(db, data, &data_size) < 0) {                return -3;            }            data += sizeof(puredb_u32_t);            *retpos = (off_t) data;            *retlen = (size_t) data_size;                        return 0;        }        trynext:        hash1 += sizeof(puredb_u32_t) + sizeof(puredb_u32_t);        if (lastslot == 0U) {            break;        }        lastslot--;    }        return -1;                     /* not found (end of table) */}int puredb_find_s(PureDB * const db, const char * const tofind,                  off_t * const retpos, size_t * const retlen){    return puredb_find(db, tofind, strlen(tofind), retpos, retlen);}void *puredb_read(PureDB * const db, const off_t offset, const size_t len){    void *buf;        if ((buf = malloc(len + (size_t) 1U)) == NULL) {        return NULL;    }#ifdef USE_MAPPED_IO    if (db->map != NULL) {        memcpy(buf, db->map + offset, len);    } else#endif    {        if (lseek(db->fd, offset, SEEK_SET) == (off_t) -1 ||            safe_read(db->fd, buf, len) != (ssize_t) len) {            free(buf);            return NULL;        }    }    ((unsigned char *) buf)[len] = 0U;        return buf;}int puredb_close(PureDB * const db){    int ret = 0;    #ifdef HAVE_MMAP    if (db->map != NULL) {# ifdef HAVE_MUNMAP        (void) munmap((void *) db->map, db->size);# endif        db->map = NULL;    }#elif defined(HAVE_MAPVIEWOFFILE)    if (db->map != NULL) {        (void) UnmapViewOfFile(db->map);        db->map = NULL;    }#endif        if (db->fd != -1) {        ret = close(db->fd);        db->fd = -1;    }        return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -