static DICT *dict_cdbq_open(const char *path, int dict_flags) { DICT_CDBQ *dict_cdbq; struct stat st; char *cdb_path; int fd; cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0); if ((fd = open(cdb_path, O_RDONLY)) < 0) return (dict_surrogate(DICT_TYPE_CDB, path, O_RDONLY, dict_flags, "open database %s: %m", cdb_path)); dict_cdbq = (DICT_CDBQ *) dict_alloc(DICT_TYPE_CDB, cdb_path, sizeof(*dict_cdbq)); #if defined(TINYCDB_VERSION) if (cdb_init(&(dict_cdbq->cdb), fd) != 0) msg_fatal("dict_cdbq_open: unable to init %s: %m", cdb_path); #else cdb_init(&(dict_cdbq->cdb), fd); #endif dict_cdbq->dict.lookup = dict_cdbq_lookup; dict_cdbq->dict.close = dict_cdbq_close; dict_cdbq->dict.stat_fd = fd; if (fstat(fd, &st) < 0) msg_fatal("dict_dbq_open: fstat: %m"); dict_cdbq->dict.mtime = st.st_mtime; dict_cdbq->dict.owner.uid = st.st_uid; dict_cdbq->dict.owner.status = (st.st_uid != 0); close_on_exec(fd, CLOSE_ON_EXEC); /* * Warn if the source file is newer than the indexed file, except when * the source file changed only seconds ago. */ if (stat(path, &st) == 0 && st.st_mtime > dict_cdbq->dict.mtime && st.st_mtime < time((time_t *) 0) - 100) msg_warn("database %s is older than source file %s", cdb_path, path); /* * If undecided about appending a null byte to key and value, choose to * try both in query mode. */ if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0) dict_flags |= DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL; dict_cdbq->dict.flags = dict_flags | DICT_FLAG_FIXED; if (dict_flags & DICT_FLAG_FOLD_FIX) dict_cdbq->dict.fold_buf = vstring_alloc(10); myfree(cdb_path); return (&dict_cdbq->dict); }
// TODO: use mmap instead of read.. much faster! SDB_VISIBLE Sdb* sdb_new (const char *dir, int lock) { Sdb* s; if (lock && !sdb_lock (sdb_lockfile (dir))) return NULL; s = malloc (sizeof (Sdb)); if (dir && *dir) { s->dir = strdup (dir); s->fd = open (dir, O_RDONLY|O_BINARY); // if (s->fd == -1) // must fail if we cant open for write in sync } else { s->dir = NULL; s->fd = -1; } s->fdump = -1; s->ndump = NULL; s->ns = ls_new (); s->ht = ht_new (); s->lock = lock; s->expire = 0LL; //s->ht->list->free = (SdbListFree)sdb_kv_free; // if open fails ignore cdb_init (&s->db, s->fd); cdb_findstart (&s->db); return s; }
int main(int argc, char **argv, char **envp) { uint8_t buf[1024]; cdb_t cdb; char *key; uint32_t len; uint32_t r; uint32_t pos; uint32_t skip = 0; char *skip_str; if (!*argv || !*++argv) usage(); key = *argv; skip_str = *++argv; if (skip_str) { if (sscanf(skip_str, "%" PRIu32, &skip) != strlen(skip_str)) usage(); } /* Initialize the cdb struct using stdin as it's file descriptor. */ if (cdb_init(&cdb, 0) == -1) strerr_die2x(111, FATAL, "failed to initialize cdb"); for (;;) { r = cdb_find_next(&cdb, key, strlen(key)); if (r == -1) strerr_die2sys(111, FATAL, "unable to read input: "); if (!r) _exit(100); if (!skip) break; skip--; } /* If there's a record in the cdb file, then the cdb structs dlen property * will be set to a non-zero value and it's position will be set to the * offset in the file containing the data. Read the data in chunks and send * it to stdout. */ len = cdb.dlen; pos = cdb.dpos; while (len > 0) { r = sizeof(buf); if (r > len) r = len; if (cdb_read(buf, r, &cdb, pos) == -1) strerr_die2sys(111, FATAL, "unable to read input: "); if (bio_put(bio_1, buf, r) == -1) strerr_die2sys(111, FATAL, "unable to write output: "); pos += r; len -= r; } if (bio_flush(bio_1) == -1) strerr_die2sys(111, FATAL, "unable to write output: "); cdb_free(&cdb); return 0; }
int main(int argc, char* argv[]) { int fd; static struct cdb c; errmsg_iam("cdbget"); if(argc < 3) die(1, "usage: cdbget data.cdb key"); fd = open(argv[1], O_RDONLY | O_BINARY); if(fd == -1) diesys(1, "open"); cdb_init(&c, fd); if(cdb_find(&c, argv[2], str_len(argv[2])) > 0) { do { char* x = malloc(cdb_datalen(&c)); if(!x) die(1, "out of memory"); if(cdb_read(&c, x, cdb_datalen(&c), cdb_datapos(&c)) == -1) diesys(1, "cdb_read"); buffer_put(buffer_1, x, cdb_datalen(&c)); buffer_put(buffer_1, "\n", 1); free(x); } while(cdb_findnext(&c, argv[2], str_len(argv[2])) > 0); } buffer_flush(buffer_1); }
int respond(char *q,char qtype[2],char ip[4]) { int fd; int r; char key[6]; tai_now(&now); fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; byte_copy(key + 2,4,ip); r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; r = doit(q,qtype); cdb_free(&c); close(fd); return r; }
int main (int argc, char *argv[]) { const char *p; const char *end; struct cdb c; struct stat st; int fd; const unsigned int klen = 8; /* input stream must have keys of constant len 8 */ if (argc < 3) return -1; /* open mcdb */ if ((fd = open(argv[1], O_RDONLY, 0777)) == -1) {perror("open"); return -1;} memset(&c, '\0', sizeof(struct cdb)); cdb_init(&c, fd); /* open input file */ if ((fd = open(argv[2], O_RDONLY, 0777)) == -1) {perror("open"); return -1;} if (fstat(fd, &st) != 0) {perror("fstat");return -1;} p = (const char *)mmap(0, st.st_size, PROT_READ, MAP_SHARED, fd, 0); if (p == MAP_FAILED) {perror("mmap"); return -1;} close(fd); /* read each key from input mmap and query mcdb * (no error checking since key might not exist) */ for (end = p+st.st_size; p < end; p += klen) cdb_find(&c, p, klen); return 0; }
int rules(void (*callback)(char *,unsigned int),int fd,char *ip,char *host,char *info) { int r; cdb_init(&c,fd); r = doit(callback,ip,host,info); cdb_free(&c); return r; }
static struct cdb* open_cdb(const str* filename) { int fd; struct cdb* c; if ((c = malloc(sizeof *c)) == 0) return 0; fd = open(filename->s, O_RDONLY); cdb_init(c, fd); if (!dict_add(&cdb_files, filename, c)) return 0; return c; }
int respond(char *q,char qtype[2],char ip[4]) { int fd; int result; fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); result = doit(q,qtype,ip); cdb_free(&c); close(fd); return result; }
static int _OS_CDBOpen(ListNode *lnode) { int fd; if (lnode->loaded != 1) { if ((fd = open(lnode->cdb_filename, O_RDONLY)) == -1) { merror(OPEN_ERROR, ARGV0, lnode->cdb_filename, errno, strerror (errno)); return -1; } cdb_init(&lnode->cdb, fd); lnode->loaded = 1; } return 0; }
static int dbl_init (void) { extern struct cdb bl; /* dns block list */ int fd = open_read ("dnsbl.cdb"); if (fd == -1) return 0; cdb_init (&bl, fd); close (fd); return 1; }
static int __nss_cdb_dosetent(struct nss_cdb *dbp) { int fd; fd = open(dbp->dbname, O_RDONLY); if (fd < 0) return 0; if (cdb_init(&dbp->cdb, fd) != 0) { close(fd); return 0; } close(fd); dbp->lastpos = 2048; /* cdb_seqinit() */ return 1; }
VALUE mCDB_Reader_get(VALUE self, VALUE key) { struct cdb db; VALUE value; StringValue(key); int fd = open_cdb_fd(self); size_t vlen; cdb_init(&db,fd); if(cdb_find(&db,RSTRING_PTR(key),RSTRING_LEN(key)) > 0) { vlen = cdb_datalen(&db); value = rb_str_buf_new(vlen); cdb_read(&db,RSTRING_PTR(value),vlen,cdb_datapos(&db)); rb_str_set_len(value,vlen); return value; } close(fd); return Qnil; }
main() { uint32 eod; uint32 klen; uint32 dlen; seek_pos rest; int r; cdb_init(&c,0); getnum(&eod); numrecords = (c.size - eod) / 8; putnum(numrecords); putflush(); _exit(0); }
static PyObject * _wrap_cdb_init(int fd) { /* constructor implementation */ CdbObject *self; self = PyObject_NEW(CdbObject, &CdbType); if (self == NULL) return NULL; self->c.map = 0; /* break encapsulation -- cdb struct init'd to zero */ cdb_init(&self->c, fd); self->iter_pos = 2048; self->each_pos = 2048; self->numrecords = 0; self->eod = 0; self->getkey = NULL; return (PyObject *) self; }
VALUE mCDB_Reader_each_for_key(VALUE self,VALUE key) { struct cdb db; VALUE value; struct cdb_find find; StringValue(key); int fd = open_cdb_fd(self); size_t vlen; cdb_init(&db,fd); cdb_findinit(&find,&db,RSTRING_PTR(key),RSTRING_LEN(key)); while(cdb_findnext(&find) > 0) { vlen = cdb_datalen(&db); value = rb_str_buf_new(vlen); cdb_read(&db,RSTRING_PTR(value),vlen,cdb_datapos(&db)); rb_str_set_len(value,vlen); rb_yield(value); } close(fd); return Qnil; }
/* LEVEL 0 - FILE */ int cdbb_open_read(struct cdbb *a, const char *f) { int fd = open_read(f); if (fd < 0) return fd; a->r = malloc(sizeof(struct cdb)); if (a->r == NULL) { close(fd); return -1; } /* suppress valgrind warning: * "Uninitialised value was created by a heap allocation" in cdb_free */ a->r->map = 0; cdb_init(a->r, fd); return fd; }
main(int argc,char **argv) { char *key; int r; uint32 pos; uint32 len; unsigned long u = 0; if (!*argv) die_usage(); if (!*++argv) die_usage(); key = *argv; if (*++argv) { scan_ulong(*argv,&u); } cdb_init(&c,0); cdb_findstart(&c); for (;;) { r = cdb_findnext(&c,key,str_len(key)); if (r == -1) die_read(); if (!r) _exit(100); if (!u) break; --u; } pos = cdb_datapos(&c); len = cdb_datalen(&c); while (len > 0) { r = sizeof buf; if (r > len) r = len; if (cdb_read(&c,buf,r,pos) == -1) die_read(); if (buffer_put(buffer_1small,buf,r) == -1) die_write(); pos += r; len -= r; } if (buffer_flush(buffer_1small) == -1) die_write(); _exit(0); }
int checks(char *key, char *buf) { struct cdb cdb; struct cdb_find cdbf; int fd; char *data; unsigned keylen = strlen(key), datalen, vpos; if (((fd = open(DB, O_RDONLY)) == -1) || (cdb_init(&cdb, fd) != 0)) { printf("Can't open database: %s\n", strerror(errno)); return (-1); } if (cdb_findinit(&cdbf, &cdb, key, keylen) <= 0) { return (-1); } while (cdb_findnext(&cdbf) > 0) { char *pattern, *subject; int m; vpos = cdb_datapos(&cdb); datalen = cdb_datalen(&cdb); data = malloc(datalen + 1); cdb_read(&cdb, data, datalen, vpos); data[datalen] = '\0'; pattern = data; subject = buf; m = match(pattern, subject); printf("*** match %s ", m ? "TRUE " : "false"); printf("%s\n", data); free(data); } cdb_free(&cdb); close(fd); return (0); }
int find_client_loc(char loc[2],const char ip[16]) { int r, fd; char key[32+3]; static struct cdb c; fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); byte_zero(loc,2); key[0] = 0; key[1] = '%'; if (byte_equal(ip,12,V4mappedprefix)) { key[2] = 'f'; byte_copy(key + 3,4,ip+12); r = cdb_find(&c,key,7); if (!r) r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,loc,2,cdb_datapos(&c)) == -1) return 0; } else { unsigned int n; key[2] = 's'; ip6_fmt_flat(key+3,ip); for (n=19; n>3; --n) { r = cdb_find(&c,key,n); if (r) break; } if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,loc,2,cdb_datapos(&c)) == -1) return 0; } cdb_free(&c); close(fd); return r; }
int respond(char *q,char qtype[2],char ip[4]) { static struct tai cdb_valid = { 0 }; static int fd = -1; struct tai one_second; int r; char key[6]; tai_now(&now); if (tai_less(&cdb_valid, &now)) { if (fd != -1) { cdb_free(&c); close(fd); } fd = open_read("data.cdb"); if (fd == -1) return 0; cdb_init(&c,fd); tai_uint(&one_second, 1); tai_add(&cdb_valid, &now, &one_second); } byte_zero(clientloc,2); key[0] = 0; key[1] = '%'; byte_copy(key + 2,4,ip); r = cdb_find(&c,key,6); if (!r) r = cdb_find(&c,key,5); if (!r) r = cdb_find(&c,key,4); if (!r) r = cdb_find(&c,key,3); if (!r) r = cdb_find(&c,key,2); if (r == -1) return 0; if (r && (cdb_datalen(&c) == 2)) if (cdb_read(&c,clientloc,2,cdb_datapos(&c)) == -1) return 0; r = doit(q,qtype); return r; }
static Dictionary * open_dictionary(char *path) { Dictionary *dic; if ((dic = calloc(1, sizeof(Dictionary))) == NULL) { err_message_fnc("No enough memory.\n"); return NULL; } if ((dic->path = strdup(path)) == NULL) return NULL; if ((dic->fd = open(path, O_RDONLY)) == -1) { perror(PROGNAME ": open"); return NULL; } cdb_init(&dic->cdb, dic->fd); pthread_mutex_init(&dic->mutex, NULL); return dic; }
static my_bool checkpart_init(UDF_INIT *iid, UDF_ARGS *args, char *message) { struct _info *info; if (args->arg_count != 2) { strmov(message,"Need two STRING args"); return (1); } if ((args->arg_type[0] != STRING_RESULT) || (args->arg_type[1] != STRING_RESULT)) { strmov(message,"args must be STRING"); return (1); } args->arg_type[0] = STRING_RESULT; args->arg_type[1] = STRING_RESULT; info = (struct _info *)malloc(sizeof(struct _info)); info->msg = strdup("Hello JP"); info->buf = calloc(sizeof(char), BLEN); info->reason = calloc(sizeof(char), BLEN); if (((info->fd = open(DB, O_RDONLY)) == -1) || (cdb_init(&info->cdb, info->fd) != 0)) { fprintf(stderr, "Can't open CDB database at %s: %s\n", DB, strerror(errno)); return (1); } iid->ptr = (char *)info; iid->max_length = BLEN; iid->maybe_null = 0; iid->const_item = 0; return 0; }
static void load_rcpthosts(void) { char* rh = read_file(0, "rcpthosts"); if (!dict_init(&rcpthosts)) oom(); if (rh) { const char* curr = rh; while (*curr) { const char* end; const char* next; if ((end = strchr(curr, '\n')) != 0) next = end + 1; else next = end = curr + strlen(curr); if (*curr != '#') { if (!str_copyb(&strbuf, curr, end-curr)) oom(); if (!dict_add(&rcpthosts, &strbuf, 0)) oom(); } curr = next; } free(rh); } if ((morercpthosts_fd = open_file(0, "morercpthosts.cdb")) != -1) cdb_init(&morercpthosts, morercpthosts_fd); }
SDB_API bool sdb_disk_finish (Sdb* s) { int reopen = 0, ret = true; IFRET (!cdb_make_finish (&s->m)); #if USE_MMAN IFRET (fsync (s->fdump)); #endif IFRET (close (s->fdump)); s->fdump = -1; // close current fd to avoid sharing violations if (s->fd != -1) { close (s->fd); s->fd = -1; reopen = 1; } #if __SDB_WINDOWS__ if (MoveFileEx (s->ndump, s->dir, MOVEFILE_REPLACE_EXISTING)) { //eprintf ("Error 0x%02x\n", GetLastError ()); } #else if (s->ndump && s->dir) { IFRET (rename (s->ndump, s->dir)); } #endif free (s->ndump); s->ndump = NULL; // reopen if was open before reopen = 1; // always reopen if possible if (reopen) { int rr = sdb_open (s, s->dir); if (ret && rr < 0) { ret = false; } cdb_init (&s->db, s->fd); } return ret; }
/// Initializes shopping data structures. void shop_init(void) { CCS rmap; int fd; // Convenience. if (vb_bitmatch(VB_SHOP)) { vb_addbit(VB_WHY); } // Open the roadmap file, and initialize the CDB infrastructure. if ((rmap = prop_get_str(P_ROADMAPFILE))) { fd = open64(rmap, O_RDONLY, 0); if (fd == -1) { putil_syserr(0, rmap); } else { struct stat64 stbuf; // Optimization: if the roadmap is zero-length, remove it // now and turn off shopping completely. if (fstat64(fd, &stbuf)) { putil_syserr(2, rmap); } if (stbuf.st_size > 0) { ShopCDB = (struct cdb *)putil_malloc(sizeof(*ShopCDB)); cdb_init(ShopCDB, fd); close(fd); } else { close(fd); vb_printf(VB_SHOP, "NO ROADMAP, NO SHOPPING", rmap); shop_fini(); } } } }
void doaxfr (char id[2]) { int r = 0; char num[4]; char key[512]; uint32 klen = 0; uint32 eod = 0, pos = 0; axfrcheck (zone); tai_now (&now); cdb_init (&c, fdcdb); byte_zero (clientloc, 2); key[0] = 0; key[1] = '%'; byte_copy (key + 2, 4, ip); r = cdb_find (&c, key, 6); if (!r) r = cdb_find (&c, key, 5); if (!r) r = cdb_find (&c, key, 4); if (!r) r = cdb_find (&c, key, 3); if (!r) r = cdb_find (&c, key, 2); if (r == -1) errx (-1, "could not read from file `data.cdb'"); if (r && (cdb_datalen (&c) == 2)) if (cdb_read (&c, clientloc, 2, cdb_datapos (&c)) == -1) err (-1, "could not read from file `data.cdb'"); cdb_findstart (&c); for (;;) { r = cdb_findnext (&c, zone, zonelen); if (r == -1) errx (-1, "could not read from file `data.cdb'"); if (!r) errx (-1, "could not find information in `data.cdb'"); dlen = cdb_datalen (&c); if (dlen > sizeof data) errx (-1, "could not read from file `data.cdb': format error"); if (cdb_read (&c, data, dlen, cdb_datapos (&c)) == -1) errx (-1, "could not read from file `data.cdb': format error"); if (build (&soa, zone, 1, id)) break; } cdb_free (&c); print (soa.s, soa.len); seek_begin (fdcdb); buffer_init (&bcdb, buffer_unixread, fdcdb, bcdbspace, sizeof (bcdbspace)); pos = 0; get (num, 4); pos += 4; uint32_unpack (num, &eod); while (pos < 2048) { get (num, 4); pos += 4; } while (pos < eod) { if (eod - pos < 8) errx (-1, "could not read from file `data.cdb': format error"); get (num, 4); pos += 4; uint32_unpack (num, &klen); get (num,4); pos += 4; uint32_unpack (num, &dlen); if (eod - pos < klen) errx (-1, "could not read from file `data.cdb': format error"); pos += klen; if (eod - pos < dlen) errx (-1, "could not read from file `data.cdb': format error"); pos += dlen; if (klen > sizeof key) errx (-1, "could not read from file `data.cdb': format error"); get (key, klen); if (dlen > sizeof data) errx (-1, "could not read from file `data.cdb': format error"); get (data, dlen); if ((klen > 1) && (key[0] == 0)) continue; /* location */ if (klen < 1) errx (-1, "could not read from file `data.cdb': format error"); if (dns_packet_getname (key, klen, 0, &q) != klen) errx (-1, "could not read from file `data.cdb': format error"); if (!dns_domain_suffix (q, zone)) continue; if (!build (&message, q, 0, id)) continue; print (message.s, message.len); } print (soa.s, soa.len); }
int chdir_long (char *dir) { int e = chdir (dir); if (e == 0 || errno != ENAMETOOLONG) return e; { size_t len = strlen (dir); char *dir_end = dir + len; struct cd_buf cdb; size_t n_leading_slash; cdb_init (&cdb); /* If DIR is the empty string, then the chdir above must have failed and set errno to ENOENT. */ assert (0 < len); assert (PATH_MAX <= len); /* Count leading slashes. */ n_leading_slash = strspn (dir, "/"); /* Handle any leading slashes as well as any name that matches the regular expression, m!^//hostname[/]*! . Handling this prefix separately usually results in a single additional cdb_advance_fd call, but it's worthwhile, since it makes the code in the following loop cleaner. */ if (n_leading_slash == 2) { int err; /* Find next slash. We already know that dir[2] is neither a slash nor '\0'. */ char *slash = memchr (dir + 3, '/', dir_end - (dir + 3)); if (slash == NULL) { errno = ENAMETOOLONG; return -1; } *slash = '\0'; err = cdb_advance_fd (&cdb, dir); *slash = '/'; if (err != 0) goto Fail; dir = find_non_slash (slash + 1); } else if (n_leading_slash) { if (cdb_advance_fd (&cdb, "/") != 0) goto Fail; dir += n_leading_slash; } assert (*dir != '/'); assert (dir <= dir_end); while (PATH_MAX <= dir_end - dir) { int err; /* Find a slash that is PATH_MAX or fewer bytes away from dir. I.e. see if there is a slash that will give us a name of length PATH_MAX-1 or less. */ char *slash = memrchr (dir, '/', PATH_MAX); if (slash == NULL) { errno = ENAMETOOLONG; return -1; } *slash = '\0'; assert (slash - dir < PATH_MAX); err = cdb_advance_fd (&cdb, dir); *slash = '/'; if (err != 0) goto Fail; dir = find_non_slash (slash + 1); } if (dir < dir_end) { if (cdb_advance_fd (&cdb, dir) != 0) goto Fail; } if (cdb_fchdir (&cdb) != 0) goto Fail; cdb_free (&cdb); return 0; Fail: { int saved_errno = errno; cdb_free (&cdb); errno = saved_errno; return -1; } } }
/* main program */ int main(int argc, char *argv[]) { char combuf[BUFSIZE], data[DATASIZE]; char *pbuf, *key, *p; struct cdb diccdb; int dicfd, ex, length; unsigned int keylen, datalen; /* open dictionary cdb file */ if ((dicfd = open(JISYO_FILE, O_RDONLY, S_IRUSR)) < 0) { exit(EX_CONFIG); } /* init cdb */ cdb_init(&diccdb, dicfd); /* To exit, set ex to non-zero */ ex = 0; /* command loop */ while (!ex) { /* Read from stdin */ length = read(STDIN, &combuf[0], BUFSIZE - 1); if (length < 0) { exit(EX_NOINPUT); } else if (length == 0) { /* EOF detected */ /* exit from the while loop */ ex = 1; break; } /* parse request code */ switch (combuf[0]) { case CLIENT_END: /* End of conversion requested*/ /* exit from the while loop */ ex = 1; break; case CLIENT_VERSION: if (write(STDOUT, VERSION, sizeof(VERSION) - 1) < 0) { exit(EX_IOERR); } break; case CLIENT_HOST: if (write(STDOUT, DUMMYHOSTNAME, sizeof(DUMMYHOSTNAME) - 1) < 0) { exit(EX_IOERR); } break; case CLIENT_REQUEST: /* get size of key */ key = &combuf[1]; for (pbuf = &combuf[1]; *pbuf != ' ' && pbuf != &combuf[length - 1]; pbuf++) { } keylen = pbuf - &combuf[1]; if (keylen <= 0) { /* invalid keysize */ exit(EX_PROTOCOL); } /* lookup the cdb database */ switch (cdb_find(&diccdb, key, keylen)) { case -1: /* fatal error on cdb_find() */ exit(EX_SOFTWARE); break; case 1: /* found */ if ((datalen = cdb_datalen(&diccdb)) >= DATASIZE - 2) { exit(EX_PROTOCOL); } /* generate the answer string */ p = data; *p++ = SERVER_FOUND; if (cdb_read(&diccdb, p, datalen, cdb_datapos(&diccdb)) < 0) { exit(EX_SOFTWARE); } p += datalen; *p = '\n'; /* sending found code and the result data string with LF */ if (write(STDOUT, data, datalen + 2) < 0) { exit(EX_IOERR); } break; case 0: /* NOT found */ /* generate the answer string */ combuf[0] = SERVER_NOT_FOUND; *pbuf = '\n'; /* sending error code and the key string with LF */ /* this action is required by skkinput */ if (write(STDOUT, combuf, keylen + 2) < 0) { exit(EX_IOERR); } break; default: /* unknown cdb return value */ exit(EX_SOFTWARE); break; } break; /* end CLIENT_REQUEST switch clause */ /* unknown request code */ default: exit(EX_PROTOCOL); } /* end request code parsing */ } /* end while loop */ /* close dictionary db file */ cdb_free(&diccdb); if (close(dicfd) != 0) { exit(EX_IOERR); } /* normal exit, finally */ exit(EX_OK); }
/* initialize XMAP */ XMAP *xmap_init(char *basedir) { char path[XM_PATH_MAX]; struct stat st = {0}; XMAP *xmap = NULL; int i = 0, k = 0, v = 0; unsigned int id = 0; if(basedir && (xmap = (XMAP *)xmm_mnew(sizeof(XMAP)))) { //xmap->mtrie = mtrie_init(); MUTEX_INIT(xmap->mutex); /* logger */ sprintf(path, "%s/%s", basedir, "xmap.log"); xmap_mkdir(path); LOGGER_INIT(xmap->logger, path); /* tree */ sprintf(path, "%s/%s", basedir, "xmap.tree"); xmap->tree = mmtree_init(path); sprintf(path, "%s/%s", basedir, "xmap.tree64"); xmap->tree64 = mmtree64_init(path); /* kmap */ sprintf(path, "%s/%s", basedir, "xmap.kmap"); xmap->kmap = mmtrie_init(path); /* queue */ sprintf(path, "%s/%s", basedir, "xmap.queue"); xmap->queue = mmqueue_init(path); /* db */ sprintf(path, "%s/%s", basedir, "cache/"); xmap->db = cdb_init(path, CDB_USE_MMAP); /* state */ sprintf(path, "%s/%s", basedir, "xmap.state"); if((xmap->stateio.fd = open(path, O_CREAT|O_RDWR, 0644)) > 0 && fstat(xmap->stateio.fd, &st) == 0) { if((xmap->stateio.map = mmap(NULL, sizeof(XMSTATE), PROT_READ|PROT_WRITE, MAP_SHARED, xmap->stateio.fd, 0)) == NULL || xmap->stateio.map == (void *)-1) { FATAL_LOGGER(xmap->logger, "mmap state:%s failed, %s", path, strerror(errno)); _exit(-1); } xmap->state = (XMSTATE *)(xmap->stateio.map); xmap->stateio.end = st.st_size; if(st.st_size == 0) { xmap->stateio.end = xmap->stateio.size = sizeof(XMSTATE); if(ftruncate(xmap->stateio.fd, xmap->stateio.end) != 0) { FATAL_LOGGER(xmap->logger, "ftruncate state %s failed, %s", path, strerror(errno)); _exit(-1); } memset(xmap->state, 0, sizeof(XMSTATE)); } for(i = 0; i < DBASE_MASK_MAX; i++) { if(xmap->state->masks[i].root == 0) xmap->state->masks[i].root = mmtree64_new_tree(xmap->tree64); } } /* disk */ sprintf(path, "%s/%s", basedir, "xmap.disk"); if((xmap->diskio.fd = open(path, O_CREAT|O_RDWR, 0644)) > 0 && fstat(xmap->diskio.fd, &st) == 0) { if((xmap->diskio.map = mmap(NULL, sizeof(MDISK) * XM_DISK_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, xmap->diskio.fd, 0)) == NULL || xmap->diskio.map == (void *)-1) { FATAL_LOGGER(xmap->logger, "mmap disk:%s failed, %s", path, strerror(errno)); _exit(-1); } xmap->disks = (MDISK *)(xmap->diskio.map); xmap->diskio.end = st.st_size; } /* meta */ sprintf(path, "%s/%s", basedir, "xmap.meta"); if((xmap->metaio.fd = open(path, O_CREAT|O_RDWR, 0644)) > 0 && fstat(xmap->metaio.fd, &st) == 0) { if((xmap->metaio.map = mmap(NULL, sizeof(XMMETA) * XM_META_MAX, PROT_READ|PROT_WRITE, MAP_SHARED, xmap->metaio.fd, 0)) == NULL || xmap->metaio.map == (void *)-1) { FATAL_LOGGER(xmap->logger, "mmap meta:%s failed, %s", path, strerror(errno)); _exit(-1); } xmap->metas = (XMMETA *)(xmap->metaio.map); xmap->metaio.end = st.st_size; xmap->start_time = time(NULL); } if(!xmap->state->qwait) xmap->state->qwait = mmtree_new_tree(xmap->tree); if(!xmap->state->qleft) xmap->state->qleft = mmqueue_new(xmap->queue); xmap->state->id_wait = 0; while((id = mmtree_min(xmap->tree, xmap->state->qwait, &k, &v))) { mmtree_remove(xmap->tree, xmap->state->qwait, id, NULL, NULL); } while(mmqueue_pop(xmap->queue, xmap->state->qleft, (int *)&id) > 0); } return xmap; }