Exemple #1
0
// 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;
}
Exemple #2
0
static void __cdb_findstart(Dictionary *dic)
{
#if defined(USE_TINYCDB)
  dic->first = 1;
#else
  cdb_findstart(&dic->cdb);
#endif
}
Exemple #3
0
static int doit(struct cdb *c,uint32 *kpos) {
  char buf[8];
  uint32 eod,klen;
  if (cdb_read(c,buf,4,0)) return -1;
  uint32_unpack(buf,&eod);
  if (eod<8 || eod-8<*kpos) return 0;
  c->kpos=*kpos+8;
  if (c->kpos<*kpos) return -1; /* wraparound */
  cdb_findstart(c);
  c->hslots=1;
  if (cdb_read(c,buf,8,*kpos) == -1) return -1;
  uint32_unpack(buf,&klen);
  uint32_unpack(buf+4,&c->dlen);
  c->dpos=c->kpos+klen;
  *kpos+=8+klen+c->dlen;
  return 1;
}
Exemple #4
0
SDB_VISIBLE int sdb_exists (Sdb* s, const char *key) {
	char ch;
	SdbKv *kv;
	int klen = strlen (key);
	ut32 pos, hash = sdb_hash (key, klen);
	kv = (SdbKv*)ht_lookup (s->ht, hash);
	if (kv) return (*kv->value)? 1: 0;
	if (s->fd == -1)
		return 0;
	cdb_findstart (&s->db);
	if (cdb_findnext (&s->db, hash, key, klen)) {
		pos = cdb_datapos (&s->db);
		cdb_read (&s->db, &ch, 1, pos);
		return ch != 0;
	}
	return 0;
}
Exemple #5
0
void cdb_init(struct cdb *c,int fd)
{
  struct stat st;
  char *x;

  cdb_free(c);
  cdb_findstart(c);
  c->fd = fd;

  if (fstat(fd,&st) == 0) {
    x = mmap(0,st.st_size,PROT_READ,MAP_SHARED,fd,0);
    if (x + 1) {
      c->size = st.st_size;
      c->map = x;
    }
  }
}
Exemple #6
0
SDB_VISIBLE char *sdb_get (Sdb* s, const char *key, ut32 *cas) {
	char *buf;
	ut32 hash, pos, len, keylen;
	SdbKv *kv;
	ut64 now = 0LL;

	if (cas) *cas = 0;
	if (!s || !key) return NULL;
	keylen = strlen (key)+1;
	hash = sdb_hash (key, keylen);

	/* search in memory */
	kv = (SdbKv*)ht_lookup (s->ht, hash);
	if (kv) {
		if (*kv->value) {
			if (kv->expire) {
				if (!now) now = sdb_now ();
				if (now > kv->expire) {
					sdb_remove (s, key, 0);
					return NULL;
				}
			}
			if (cas) *cas = kv->cas;
			return strdup (kv->value); // XXX too many mallocs
		}
		return NULL;
	}

	/* search in disk */
	if (s->fd == -1)
		return NULL;
	cdb_findstart (&s->db);

	if (!cdb_findnext (&s->db, hash, key, keylen))
		return NULL;
	len = cdb_datalen (&s->db);
	if (len == 0)
		return NULL;
	pos = cdb_datapos (&s->db);
	if (!(buf = malloc (len+1))) // XXX too many mallocs
		return NULL;
	cdb_read (&s->db, buf, len, pos);
	buf[len] = 0;
	return buf;
}
Exemple #7
0
void cdb_init(struct cdb *c, int fd) {
	struct stat st;
	c->map = NULL;
	cdb_findstart (c);
	c->fd = fd;
	if (!fstat (fd, &st) && st.st_size != UT32_MAX) {
#if USE_MMAN
		char *x = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
#else
		char *x = malloc (st.st_size);
		read (fd, x, st.st_size); // TODO: handle return value
#endif
		if (x + 1) {
			c->size = st.st_size;
			c->map = x;
		}
	}
}
Exemple #8
0
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);
}
Exemple #9
0
SDB_VISIBLE const char *sdb_getc (Sdb* s, const char *key, ut32 *cas) {
	ut32 hash, pos, len, keylen;
	SdbKv *kv;
	ut64 now = 0LL;

	if (cas) *cas = 0;
	if (!s||!key) return NULL;
	keylen = strlen (key)+1;
	hash = sdb_hash (key, keylen);

	/* search in memory */
	kv = (SdbKv*)ht_lookup (s->ht, hash);
	if (kv) {
		if (*kv->value) {
			if (kv->expire) {
				if (!now) now = sdb_now ();
				if (now > kv->expire) {
					sdb_remove (s, key, 0);
					return NULL;
				}
			}
			if (cas) *cas = kv->cas;
			return kv->value;
		}
		return NULL;
	}

	/* search in disk */
	if (s->fd == -1)
		return NULL;
	cdb_findstart (&s->db);
	if (!cdb_findnext (&s->db, hash, key, keylen))
		return NULL;
	len = cdb_datalen (&s->db);
	if (len == 0)
		return NULL;
	pos = cdb_datapos (&s->db);
	return s->db.map+pos;
}
Exemple #10
0
static PyObject *
cdbo_getall(CdbObject *self, PyObject *args) {

  PyObject * list, * data;
  char * key;
  unsigned int klen;
  int r, err;

  if (!PyArg_ParseTuple(args, "s#:getall", &key, &klen))
    return NULL;

  list = PyList_New(0);

  if (list == NULL) return NULL;

  cdb_findstart(&self->c);

  while ((r = cdb_findnext(&self->c, key, klen))) {
    if (r == -1) {
      Py_DECREF(list);
      return CDBerr;
    }
    data = CDBO_CURDATA(self);
    if (data == NULL) {
      Py_DECREF(list);
      return NULL;
    }
    err = PyList_Append(list, data);
    Py_DECREF(data);
    if (err != 0) {
      Py_DECREF(list);
      return NULL;
    }
  }

  return list;

}
Exemple #11
0
static int doit(char *q,char qtype[2])
{
  unsigned int bpos;
  unsigned int anpos;
  unsigned int aupos;
  unsigned int arpos;
  char *control;
  char *wild;
  int flaggavesoa;
  int flagfound;
  int r;
  int flagns;
  int flagauthoritative;
  char x[20];
  uint16 u16;
  char addr[8][4];
  int addrnum;
  uint32 addrttl;
  int i;

  anpos = response_len;

  control = q;
  for (;;) {
    flagns = 0;
    flagauthoritative = 0;
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) flagauthoritative = 1;
      if (byte_equal(type,2,DNS_T_NS)) flagns = 1;
    }
    if (flagns) break;
    if (!*control) return 0; /* q is not within our bailiwick */
    control += *control;
    control += 1;
  }

  if (!flagauthoritative) {
    response[2] &= ~4;
    goto AUTHORITY; /* q is in a child zone */
  }


  flaggavesoa = 0;
  flagfound = 0;
  wild = q;

  for (;;) {
    addrnum = 0;
    addrttl = 0;
    cdb_findstart(&c);
    while (r = find(wild,wild != q)) {
      if (r == -1) return 0;
      flagfound = 1;
      if (flaggavesoa && byte_equal(type,2,DNS_T_SOA)) continue;
      if (byte_diff(type,2,qtype) && byte_diff(qtype,2,DNS_T_ANY) && byte_diff(type,2,DNS_T_CNAME)) continue;
      if (byte_equal(type,2,DNS_T_A) && (dlen - dpos == 4)) {
	addrttl = ttl;
	i = dns_random(addrnum + 1);
	if (i < 8) {
	  if ((i < addrnum) && (addrnum < 8))
	    byte_copy(addr[addrnum],4,addr[i]);
	  byte_copy(addr[i],4,data + dpos);
	}
	if (addrnum < 1000000) ++addrnum;
	continue;
      }
      if (!response_rstart(q,type,ttl)) return 0;
      if (byte_equal(type,2,DNS_T_NS) || byte_equal(type,2,DNS_T_CNAME) || byte_equal(type,2,DNS_T_PTR)) {
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_MX)) {
	if (!dobytes(2)) return 0;
	if (!doname()) return 0;
      }
      else if (byte_equal(type,2,DNS_T_SOA)) {
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        flaggavesoa = 1;
      }
      else
        if (!response_addbytes(data + dpos,dlen - dpos)) return 0;
      response_rfinish(RESPONSE_ANSWER);
    }
    for (i = 0;i < addrnum;++i)
      if (i < 8) {
	if (!response_rstart(q,DNS_T_A,addrttl)) return 0;
	if (!response_addbytes(addr[i],4)) return 0;
	response_rfinish(RESPONSE_ANSWER);
      }

    if (flagfound) break;
    if (wild == control) break;
    if (!*wild) break; /* impossible */
    wild += *wild;
    wild += 1;
  }

  if (!flagfound)
    response_nxdomain();


  AUTHORITY:
  aupos = response_len;

  if (flagauthoritative && (aupos == anpos)) {
    cdb_findstart(&c);
    while (r = find(control,0)) {
      if (r == -1) return 0;
      if (byte_equal(type,2,DNS_T_SOA)) {
        if (!response_rstart(control,DNS_T_SOA,ttl)) return 0;
	if (!doname()) return 0;
	if (!doname()) return 0;
	if (!dobytes(20)) return 0;
        response_rfinish(RESPONSE_AUTHORITY);
        break;
      }
    }
  }
  else
    if (want(control,DNS_T_NS)) {
      cdb_findstart(&c);
      while (r = find(control,0)) {
        if (r == -1) return 0;
        if (byte_equal(type,2,DNS_T_NS)) {
          if (!response_rstart(control,DNS_T_NS,ttl)) return 0;
	  if (!doname()) return 0;
          response_rfinish(RESPONSE_AUTHORITY);
        }
      }
    }

  arpos = response_len;

  bpos = anpos;
  while (bpos < arpos) {
    bpos = dns_packet_skipname(response,arpos,bpos); if (!bpos) return 0;
    bpos = dns_packet_copy(response,arpos,bpos,x,10); if (!bpos) return 0;
    if (byte_equal(x,2,DNS_T_NS) || byte_equal(x,2,DNS_T_MX)) {
      if (byte_equal(x,2,DNS_T_NS)) {
        if (!dns_packet_getname(response,arpos,bpos,&d1)) return 0;
      }
      else
        if (!dns_packet_getname(response,arpos,bpos + 2,&d1)) return 0;
      case_lowerb(d1,dns_domain_length(d1));
      if (want(d1,DNS_T_A)) {
	cdb_findstart(&c);
	while (r = find(d1,0)) {
          if (r == -1) return 0;
	  if (byte_equal(type,2,DNS_T_A)) {
            if (!response_rstart(d1,DNS_T_A,ttl)) return 0;
	    if (!dobytes(4)) return 0;
            response_rfinish(RESPONSE_ADDITIONAL);
	  }
        }
      }
    }
    uint16_unpack_big(x + 8,&u16);
    bpos += u16;
  }

  if (flagauthoritative && (response_len > 512)) {
    byte_zero(response + RESPONSE_ADDITIONAL,2);
    response_len = arpos;
    if (response_len > 512) {
      byte_zero(response + RESPONSE_AUTHORITY,2);
      response_len = aupos;
    }
  }

  return 1;
}
Exemple #12
0
/* {{{ cdb_init */
void cdb_init(struct cdb *c, php_stream *fp)
{
    cdb_free(c);
    cdb_findstart(c);
    c->fp = fp;
}
Exemple #13
0
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);
}
Exemple #14
0
void doaxfr(char id[2])
{
  char key[512];
  uint32 klen;
  char num[4];
  uint32 eod;
  uint32 pos;
  int r;

  axfrcheck(zone);

  find_client_loc(clientloc, ip);

  tai_now(&now);
  cdb_init(&c,fdcdb);

  cdb_findstart(&c);
  for (;;) {
    r = cdb_findnext(&c,zone,zonelen);
    if (r == -1) die_cdbread();
    if (!r) die_outside();
    dlen = cdb_datalen(&c);
    if (dlen > sizeof data) die_cdbformat();
    if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) die_cdbformat();
    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) die_cdbformat();
    get(num,4); pos += 4;
    uint32_unpack(num,&klen);
    get(num,4); pos += 4;
    uint32_unpack(num,&dlen);
    if (eod - pos < klen) die_cdbformat();
    pos += klen;
    if (eod - pos < dlen) die_cdbformat();
    pos += dlen;

    if (klen > sizeof key) die_cdbformat();
    get(key,klen);
    if (dlen > sizeof data) die_cdbformat();
    get(data,dlen);

    if ((klen > 1) && (key[0] == 0)) continue; /* location */
    if (klen < 1) die_cdbformat();
    if (dns_packet_getname(key,klen,0,&q) != klen) die_cdbformat();
    if (!dns_domain_suffix(q,zone)) continue;
    if (!build(&message,q,0,id)) continue;
    print(message.s,message.len);
  }

  print(soa.s,soa.len);
}
Exemple #15
0
int cdb_find(struct cdb *c,char *key,unsigned int len)
{
  cdb_findstart(c);
  return cdb_findnext(c,key,len);
}
Exemple #16
0
int cdb_find(struct cdb *c,char *key,off_t len)
{
  cdb_findstart(c);
  return cdb_findnext(c,key,len);
}