int OS_DBSeachKeyAddress(ListRule *lrule, char *key)
{
    //char _ip[128];
    //_ip[127] = "\0";
    if (lrule->db != NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return -1;
        //snprintf(_ip,128,"%s",key);
        //XXX Breka apart string on the . boundtrys a loop over to longest match. 

        if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            return 1;
        }
        else 
        {
            char *tmpkey;
            os_strdup(key, tmpkey);
            while(strlen(tmpkey) > 0)
            {
                if(tmpkey[strlen(tmpkey) - 1] == '.')
                {
                    if( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
                        free(tmpkey);
                        return 1;
                    } 
                }
                tmpkey[strlen(tmpkey) - 1] = '\0';
            }
            free(tmpkey);
        }
    } 
    return 0;
}
Beispiel #2
0
static int OS_DBSeachKeyAddress(ListRule *lrule, char *key)
{
    if (lrule->db != NULL) {
        if (_OS_CDBOpen(lrule->db) == -1) {
            return -1;
        }

        if ( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            return 1;
        } else {
            char *tmpkey;
            os_strdup(key, tmpkey);
            while (strlen(tmpkey) > 0) {
                if (tmpkey[strlen(tmpkey) - 1] == '.') {
                    if ( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
                        free(tmpkey);
                        return 1;
                    }
                }
                tmpkey[strlen(tmpkey) - 1] = '\0';
            }
            free(tmpkey);
        }
    }
    return 0;
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
}
Beispiel #5
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);
}
Beispiel #6
0
int OS_DBSearchKeyAddressValue(ListRule *lrule, char *key)
{
    int result=-1;
    char *val;
    unsigned vlen, vpos;
    if (lrule->db!= NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return 0;

        // First lookup for a single IP address
        if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            vpos = cdb_datapos(&lrule->db->cdb);
            vlen = cdb_datalen(&lrule->db->cdb);
            val = malloc(vlen);
            cdb_read(&lrule->db->cdb, val, vlen, vpos);
            result = OSMatch_Execute(val, vlen, lrule->matcher);
            free(val);
            return result;
        } else {
            // IP address not found, look for matching subnets
            char *tmpkey;
            os_strdup(key, tmpkey);
            while(strlen(tmpkey) > 0)
            {
                if(tmpkey[strlen(tmpkey) - 1] == '.')
                {
                    if( cdb_find(&lrule->db->cdb, tmpkey, strlen(tmpkey)) > 0 ) {
                        vpos = cdb_datapos(&lrule->db->cdb);
                        vlen = cdb_datalen(&lrule->db->cdb);
                        val = malloc(vlen);
                        cdb_read(&lrule->db->cdb, val, vlen, vpos);
                        result = OSMatch_Execute(val, vlen, lrule->matcher);
                        free(val);
                        free(tmpkey);
                        return result;
                    }
                }
                tmpkey[strlen(tmpkey) - 1] = '\0';
            }
            free(tmpkey);
            return 0;
        }
    }
    return 0;
}
int OS_DBSeachKey(ListRule *lrule, char *key)
{
    if (lrule->db != NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return -1;
        if( cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) return 1;
    } 
    return 0;
}
Beispiel #8
0
int cdb_successor(struct cdb *c,char *key,unsigned int klen) {
  int r;
  uint32 kpos;
  if (key) {
	 r=cdb_find(c,key,klen);
	 if (r<1) return r;
	 kpos=c->dpos+c->dlen;
  } else
	 kpos=CDB_SIZE_HASH_TABLE_POINTER;
  return doit(c,&kpos);
}
int cdb_successor (struct cdb *c, char const *key, unsigned int klen)
{
  uint32 kpos ;
  if (key)
  {
    register int r = cdb_find(c, key, klen) ;
    if (r < 1) return r ;
    kpos = c->dpos + c->dlen ;
  }
  else cdb_traverse_init(c, &kpos) ;
  return cdb_nextkey(c, &kpos) ;
}
Beispiel #10
0
static int doit(char *q,char qtype[2],char ip[4])
{
    int r;
    uint32 dlen;
    unsigned int qlen;

    qlen = dns_domain_length(q);
    if (qlen > 255) return 0; /* impossible */

    if (byte_diff(qtype,2,DNS_T_A) && byte_diff(qtype,2,DNS_T_ANY)) goto REFUSE;

    key[0] = '%';
    byte_copy(key + 1,4,ip);

    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;

    key[0] = '+';
    byte_zero(key + 1,2);
    if (r && (cdb_datalen(&c) == 2))
        if (cdb_read(&c,key + 1,2,cdb_datapos(&c)) == -1) return 0;

    byte_copy(key + 3,qlen,q);
    case_lowerb(key + 3,qlen + 3);

    r = cdb_find(&c,key,qlen + 3);
    if (!r) {
        byte_zero(key + 1,2);
        r = cdb_find(&c,key,qlen + 3);
    }
    if (!r) goto REFUSE;
    if (r == -1) return 0;
    dlen = cdb_datalen(&c);

    if (dlen > 512) dlen = 512;
    if (cdb_read(&c,data,dlen,cdb_datapos(&c)) == -1) return 0;

    dns_sortip(data,dlen);

    if (dlen > 12) dlen = 12;
    while (dlen >= 4) {
        dlen -= 4;
        if (!response_rstart(q,DNS_T_A,"\0\0\0\5")) return 0;
        if (!response_addbytes(data + dlen,4)) return 0;
        response_rfinish(RESPONSE_ANSWER);
    }

    return 1;


REFUSE:
    response[2] &= ~4;
    response[3] &= ~15;
    response[3] |= 5;
    return 1;
}
Beispiel #11
0
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;
}
Beispiel #12
0
/* rule application ******************************************************** */
static int matches(const struct pattern* pattern,
		   const str* addr, const str* atdomain)
{
  static str domain;
  int result;
  if (pattern->cdb != 0) {
    if (pattern->pattern.s[2] == '@') {
      result = (atdomain->len == 0)
	? 0
	: cdb_find(pattern->cdb, atdomain->s+1, atdomain->len-1) != 0;
    }
    else {
      result = (cdb_find(pattern->cdb, addr->s, addr->len) != 0) ?
	1 :
	cdb_find(pattern->cdb, atdomain->s, atdomain->len) != 0;
    }
  }
  else if (pattern->file != 0) {
    if (pattern->pattern.s[2] == '@') {
      if (atdomain->len > 0) {
	str_copyb(&domain, atdomain->s+1, atdomain->len-1);
	result = dict_get(pattern->file, &domain) != 0;
      }
      else
	result = 0;
    }
    else {
      result = (dict_get(pattern->file, addr) != 0) ?
	1 : 
	dict_get(pattern->file, atdomain) != 0;
    }
  }
  else
    result = str_case_glob(addr, &pattern->pattern);
  if (pattern->negated)
    result = !result;
  return result;
}
Beispiel #13
0
static PyObject *
_cdbo_keyiter(CdbObject *self) {

  PyObject *key;
  char buf[8];
  uint32 klen, dlen;

  if (! self->eod)
    _cdbo_init_eod(self);

  while (self->iter_pos < self->eod) {
    if (cdb_read(&self->c, buf, 8, self->iter_pos) == -1)
      return CDBerr;

    uint32_unpack(buf, &klen);
    uint32_unpack(buf+4, &dlen);

    key = cdb_pyread(self, klen, self->iter_pos + 8);

    if (key == NULL)
      return NULL;

    switch(cdb_find(&self->c,PyString_AsString(key),PyString_Size(key))) {
      case -1:
        Py_DECREF(key);
        key = NULL;
        return CDBerr;
      case 0:
        /* bizarre, impossible? PyExc_RuntimeError? */
        PyErr_SetString(PyExc_KeyError, 
                        PyString_AS_STRING((PyStringObject *) key));
        Py_DECREF(key);
        key = NULL;
      default:
        if (key == NULL)  /* already raised error */
          return NULL;

        if (cdb_datapos(&self->c) == self->iter_pos + klen + 8) {
          /** first occurrence of key in the cdb **/
          self->iter_pos += 8 + klen + dlen;
          return key;
        }
        Py_DECREF(key);   /* better luck next time around */
        self->iter_pos += 8 + klen + dlen;
    }
  }

  return Py_BuildValue("");  /* iter_pos >= eod; we're done */

}
Beispiel #14
0
int cdbb_readn(struct cdbb *a, char *k, size_t ks, char *v, size_t n)
{
	int dlen;

	if (cdb_find(a->r, (unsigned char *)k, ks) <= 0)
		return -1;

	dlen = cdb_datalen(a->r);

	if (dlen > n)
		return -2;

	if (cdb_read(a->r, (unsigned char *)v, dlen, cdb_datapos(a->r)) < 0)
		return -3;

	return 1;
}
Beispiel #15
0
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;
}
Beispiel #16
0
static enum nss_status
__nss_cdb_dobyid(struct nss_cdb *dbp, unsigned long id,
                 void *result, char *buf, size_t bufl, int *errnop) {
  int r;
  unsigned len;
  const char *data;

  if ((r = cdb_find(&dbp->cdb, buf, sprintf(buf, ":%lu", id))) < 0)
    return *errnop = errno, NSS_STATUS_UNAVAIL;
  len = cdb_datalen(&dbp->cdb);
  if (!r || len < 2)
    return *errnop = ENOENT, NSS_STATUS_NOTFOUND;
  if (!(data = (const char*)cdb_get(&dbp->cdb, len, cdb_datapos(&dbp->cdb))))
    return *errnop = errno, NSS_STATUS_UNAVAIL;

  return __nss_cdb_dobyname(dbp, data, len, result, buf, bufl, errnop);
}
Beispiel #17
0
/* read data from a constant database file */
uint64_t readcontentsfromcdb (void *hint,bstring key,char *data,uint64_t dsize)
{
  cdb_t *cdb = (cdb_t *)hint;
  uint32_t vlen = 0, vpos = 0;

  if (cdb_find(cdb,btocstr(key),blength(key)) > 0) {

    vpos = cdb_datapos(cdb);
    vlen = cdb_datalen(cdb);

    cdb_read (cdb,data,(vlen < dsize) ? vlen : dsize,vpos);
    uint64_t Kb = (vlen < 1024) ? vlen : vlen / 1024;

    return (vlen < dsize) ? vlen : dsize;
  } 

  return 0;
}
Beispiel #18
0
static long cdb_getval(struct _info *info, char *keyname)
{
	unsigned keylen = strlen(keyname), vlen, vpos;
	long nval;
	char *val;

	if (cdb_find(&info->cdb, keyname, keylen) > 0) {
		vpos = cdb_datapos(&info->cdb);
		vlen = cdb_datalen(&info->cdb);
		val = malloc(vlen);
		cdb_read(&info->cdb, val, vlen, vpos);
		nval = atol(val);
		free(val);
		return (nval);
	}


	return (-1L);

}
Beispiel #19
0
static PyObject *
cdbo_subscript(CdbObject *self, PyObject *k) {
  char * key;
  int klen;

  if (! PyArg_Parse(k, "s#", &key, &klen))
    return NULL;

  switch(cdb_find(&self->c, key, (unsigned int)klen)) {
    case -1:
      return CDBerr;
    case 0:
      PyErr_SetString(PyExc_KeyError, 
                      PyString_AS_STRING((PyStringObject *) k));
      return NULL;
    default:
      return CDBO_CURDATA(self);
  }
  /* not reached */
}
Beispiel #20
0
int check_rcpt(const char* sender)
{
  char* domain;
  
  if(!opt_checkrcpt)
    return 1;

  domain = strchr(sender, '@');
  if(!domain)
    return 0;

  for(++domain; domain; domain = strchr(domain+1, '.')) {
    if (!str_copys(&strbuf, domain)) oom();
    if (dict_get(&rcpthosts, &strbuf)) return 1;
    if (morercpthosts_fd != -1 &&
	cdb_find(&morercpthosts, strbuf.s, strbuf.len) != 0)
      return 1;
  }
  return 0;
}
int OS_DBSearchKeyValue(ListRule *lrule, char *key)
{
    int result=-1;
    char *val;
    unsigned vlen, vpos;
    if (lrule->db!= NULL)
    {
        if(_OS_CDBOpen(lrule->db) == -1) return 0;
        if(cdb_find(&lrule->db->cdb, key, strlen(key)) > 0 ) {
            vpos = cdb_datapos(&lrule->db->cdb);
            vlen = cdb_datalen(&lrule->db->cdb);
            val = malloc(vlen);
            cdb_read(&lrule->db->cdb, val, vlen, vpos);
            result = OSMatch_Execute(val, vlen, lrule->matcher);
            free(val);
            return result; 
        } else {
            return 0;
        }
    } 
    return 0;
}
Beispiel #22
0
static int dorule(void (*callback)(char *,unsigned int))
{
  char *data;
  unsigned int datalen;

  switch(cdb_find(&c,rules_name.s,rules_name.len)) {
    case -1: return -1;
    case 0: return 0;
  }

  datalen = cdb_datalen(&c);
  data = alloc(datalen);
  if (!data) return -1;
  if (cdb_read(&c,data,datalen,cdb_datapos(&c)) == -1) {
    alloc_free(data);
    return -1;
  }

  callback(data,datalen);
  alloc_free(data);
  return 1;
}
Beispiel #23
0
static enum nss_status
__nss_cdb_dobyname(struct nss_cdb *dbp, const char *key, unsigned len,
                   void *result, char *buf, size_t bufl, int *errnop) {
  int r;

  if ((r = cdb_find(&dbp->cdb, key, len)) < 0)
    return *errnop = errno, NSS_STATUS_UNAVAIL;
  len = cdb_datalen(&dbp->cdb);
  if (!r || len < 2)
    return *errnop = ENOENT, NSS_STATUS_NOTFOUND;
  if (len >= bufl)
    return *errnop = ERANGE, NSS_STATUS_TRYAGAIN;
  if (cdb_read(&dbp->cdb, buf, len, cdb_datapos(&dbp->cdb)) != 0)
    return *errnop = errno, NSS_STATUS_UNAVAIL;
  buf[len] = '\0';
  if ((r = dbp->parsefn(result, buf, bufl)) < 0)
    return *errnop = ENOENT, NSS_STATUS_NOTFOUND;
  if (!r)
    return *errnop = ERANGE, NSS_STATUS_TRYAGAIN;

  return NSS_STATUS_SUCCESS;
}
Beispiel #24
0
int ipsvd_check_cdbentry(stralloc *d, stralloc *m, char *ip, int *rc) {
  switch(cdb_find(&c, m->s, m->len -1)) {
    case -1: return(-1);
    case 1:
      dlen =cdb_datalen(&c);
      if (! stralloc_ready(d, dlen)) return(-1);
      if (cdb_read(&c, d->s, dlen, cdb_datapos(&c)) == -1) return(-1);
      if (! dlen) return(-1);
      switch(d->s[dlen -1]) {
      case 'D':
        *rc =IPSVD_DENY;
        return(1);
      case 'X':
        d->s[dlen -1] =0; d->len =dlen;
        *rc =IPSVD_EXEC;
        return(1);
      case 'I':
        d->s[dlen -1] =0; d->len =dlen;
        if ((*rc =ipsvd_instruct(d, m, ip)) == -1) return(-1);
        return(1);
      }
    }
  return(0);
}
Beispiel #25
0
int cdbb_read_nentry(struct cdbb *a, char *k, size_t ks, struct nentry *n)
{
	int err, dlen;
	unsigned char *buf;

	array_catb(&n->k, k, ks);
	err = cdb_find(a->r, (unsigned char *)k, ks);

	if (err <= 0)
		return err;

	err = 0;		/* num */
	do {
		dlen = cdb_datalen(a->r);
		buf = alloca(dlen);

		if (cdb_read(a->r, buf, dlen, cdb_datapos(a->r)) < 0)
			return -2;

		array_catb(&n->e, (char *)buf, dlen);
		err++;
	} while (cdb_findnext(a->r, (unsigned char *)k, ks) > 0);
	return err;
}
Beispiel #26
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;
}
Beispiel #27
0
static shop_e
_shop_for_cmd(shopping_state_s *ssp, CCS cmdix)
{
    CCS line;
    unsigned len;
    CS cmdstate;
    CS pccode, has_tgt, agg, duration, kids, pathcode, rwd;
    int aggregated;

    line = ca_get_line(ssp->ca);

    if (cdb_find(ssp->cdbp, cmdix, strlen(cmdix)) <= 0) {
	putil_int("missing cmd at index=%s", cmdix);
	return SHOP_ERR;
    }

    len = cdb_datalen(ssp->cdbp);
    cmdstate = (CS)alloca(len + 1);
    cdb_read(ssp->cdbp, cmdstate, len, cdb_datapos(ssp->cdbp));
    cmdstate[len] = '\0';

    // This is one place where the number and order of fields is hard wired.
    // *INDENT-OFF*
    if (!(pccode = util_strsep(&cmdstate, FS1)) ||
	    !(pathcode = util_strsep(&cmdstate, FS1)) ||
	    !(has_tgt = util_strsep(&cmdstate, FS1)) ||
	    !(agg = util_strsep(&cmdstate, FS1)) ||
	    !(kids = util_strsep(&cmdstate, FS1)) ||
	    !(duration = util_strsep(&cmdstate, FS1)) ||
	    !(rwd = util_strsep(&cmdstate, FS1))) {
	cdb_read(ssp->cdbp, cmdstate, len, cdb_datapos(ssp->cdbp));
	cmdstate[len] = '\0';
	putil_int("bad format: '%s'", cmdstate);
	return SHOP_ERR;
    }
    // *INDENT-ON*

    aggregated = IS_TRUE(agg);

    vb_printf(VB_SHOP, "%sCMD MATCH: [%s] (%s) %s",
	      aggregated ? "AGGREGATED " : "", cmdix, rwd ? rwd : "", line);

    // If a command has no targets it is ineligible for
    // shopping and must run. Typically this would be
    // something like "echo blah blah".
    if (!IS_TRUE(has_tgt)) {
	CCS msg = "has no targets";

	vb_printf(VB_SHOP, "COMMAND invalidated due to '%s': [%s] %s",
	    msg, cmdix, line);

	return aggregated ? SHOP_MUSTRUN_AGG : SHOP_MUSTRUN;
    }

    // If a command has children we make it ineligible.
    // The problem is a command which both creates files
    // *and* runs children - if we recycle it then the
    // children are not run, even if they would have created
    // other (potentially recyclable) files. There may be an
    // answer in recursive shopping but it would be very complex,
    // so currently we take the easy way out and shop only at
    // the leaves of the tree.
    if (!CSV_FIELD_IS_NULL(kids)) {
	CCS msg = "has children";

	if (vb_bitmatch(VB_SHOP)) {
	    vb_printf(VB_SHOP, "COMMAND invalidated due to '%s': [%s] %s",
		msg, cmdix, line);
	} else {
	    vb_printf(VB_WHY, "COMMAND invalidated due to '%s'", msg);
	}

	return SHOP_MUSTRUN;
    }

    // Removed pccode chck here - could't see its value.

    // There is no current use for this ...
    //ca_set_duration_str(ssp->ca, strtoul(duration, NULL, 10));

    // No current use for pathcode ...

    // Make sure there are still PTXes left before we go shopping.
    if (!_shop_ptx_count(ssp)) {
	return SHOP_NOMATCH;
    }

    // We have now matched a command and parsed its metadata, and
    // still have PTXes in which it was run.
    // It's time to compare it against the current path states.
    // Look first at member prereqs, then at the general public.
    // This is because members are far more likely to change, so
    // shopping can "fail fast" if it considers them first. The
    // main thing here is to limit the number of stats and especially
    // dcode (checksumming) events because they are expensive.
    _shop_compare_prereqs(ssp, cmdix);

    if (_shop_ptx_count(ssp) && _shop_ptx_winner(ssp)) {
	snprintf(ssp->wincmd, charlen(ssp->wincmd), "%s", cmdix);
	return SHOP_RECYCLED;
    } else {
	if (aggregated) {
	    return SHOP_NOMATCH_AGG;
	} else {
	    return SHOP_NOMATCH;
	}
    }
}
Beispiel #28
0
static void
_shop_cmp_pathstate(shopping_state_s *ssp, CCS pskey, CS ptxes1)
{
    unsigned vlen;
    int ignored;
    pa_o dummy_pa;
    ps_o shopped_ps;
    CCS path, reason = NULL;
    CS csv, ptxbuf, explanation = NULL;

    if (cdb_find(ssp->cdbp, pskey, strlen(pskey)) <= 0) {
	putil_int("bad PS key in roadmap: %s", pskey);
	return;
    }

    vlen = cdb_datalen(ssp->cdbp);
    csv = (CS)alloca(vlen + 1);
    cdb_read(ssp->cdbp, csv, vlen, cdb_datapos(ssp->cdbp));
    csv[vlen] = '\0';
    shopped_ps = ps_newFromCSVString(csv);

    path = ps_get_abs(shopped_ps);

    // Figure out if this path is to be ignored per user request.
    // We may still want to do the comparison for ignored paths
    // in order to issue warnings (the user might wish to know
    // what didn't match without failing the build).
    ignored = re_match__(ssp->ignore_path_re, path) != NULL;

    if (!CurrentPS || strcmp(ps_get_abs(CurrentPS), path)) {
	ps_destroy(CurrentPS);
	CurrentPS = ps_newFromPath(path);
	if (ps_stat(CurrentPS, ps_has_dcode(shopped_ps))) {
	    asprintf(&explanation, "%s: %s", path, strerror(errno));
	}
    }

    // Do the actual comparison.
    // IDEA - choose a model here: Either we can ignore paths
    // before comparison (thus saving time) or after (allowing
    // a useful warning to be issued). Or we could add a new
    // preference allowing user choice.
    if (explanation || (reason = ps_diff(shopped_ps, CurrentPS))) {
	CS ixstr;

	// If this iteration produced a mismatch, invalidate all the
	// PTXes associated with that PS.
	if (reason) {
	    if (asprintf(&explanation, "%s mismatch on %s",
		    reason, path) < 0) {
		putil_syserr(2, NULL);
	    }
	}

	ptxbuf = (CS)alloca(strlen(ptxes1) + CHARSIZE);
	strcpy(ptxbuf, ptxes1);
	for (ixstr = util_strsep(&ptxbuf, FS2);
		 ixstr && _shop_ptx_count(ssp);
		 ixstr = util_strsep(&ptxbuf, FS2)) {
	    _shop_ptx_invalidate(ssp, ixstr, explanation, ignored);
	}

	// If the failing path is not ignored for shopping, this
	// loop iteration is finished.
	if (!ignored) {
	    ps_destroy(shopped_ps);
	    return;
	}
    }

    putil_free(explanation);

    // The current PS matched, so hold onto it. Unfortunately a
    // CA object doesn't hold PS objects, it holds PAs, so we
    // must wrap the PS in a dummy PA.
    // The only reason prereqs are saved at all is to let a
    // recycled CA generate the same signature as if it had
    // actually run.
    dummy_pa = pa_new();
    pa_set_ps(dummy_pa, ps_copy(CurrentPS));
    pa_set_op(dummy_pa, OP_READ);
    pa_set_call(dummy_pa, "dummy");
    ca_record_pa(ssp->ca, dummy_pa);

    ps_destroy(shopped_ps);
    return;
}
Beispiel #29
0
static shop_e
_shop_collect_targets(shopping_state_s *ssp, CCS cmdix)
{
    char key[64];
    struct cdb_find cdbf_tgt;
    unsigned vlen;
    shop_e rc;

    rc = SHOP_RECYCLED;

    vb_printf(VB_SHOP, "COLLECTING: [%s]", cmdix);

    // First we collect all targets of the winning command in the
    // "real" CA object ....

    snprintf(key, charlen(key), ">%s", cmdix);
    if (cdb_findinit(&cdbf_tgt, ssp->cdbp, key, strlen(key)) < 0) {
	putil_die("cdb_findinit: %s (%s)", key, ca_get_line(ssp->ca));
    }

    while (cdb_findnext(&cdbf_tgt) > 0) {
	CS buf, pskeys, csv, ptxes, ixstr;

	CCS pskey;

	vlen = cdb_datalen(ssp->cdbp);
	buf = (CS)alloca(vlen + 1);
	cdb_read(ssp->cdbp, buf, vlen, cdb_datapos(ssp->cdbp));
	buf[vlen] = '\0';

	if (!(ptxes = strstr(buf, FS1))) {
	    putil_int("bad format in roadmap: %s", buf);
	    rc = SHOP_ERR;
	    continue;
	}

	*ptxes++ = '\0';
	pskeys = buf;

	// Make sure to skip all targets not associated with the winning PTX.
	for (ixstr = util_strsep(&ptxes, FS2);
	     ixstr; ixstr = util_strsep(&ptxes, FS2)) {
	    if (!strcmp(ixstr, ssp->wix)) {
		ps_o tgt_ps;

		pa_o dummy_pa;

		for (pskey = util_strsep(&pskeys, FS2);
		     pskey && rc == SHOP_RECYCLED;
		     pskey = util_strsep(&pskeys, FS2)) {

		    if (cdb_find(ssp->cdbp, pskey, strlen(pskey)) <= 0) {
			putil_int("bad key in roadmap: %s", pskey);
			continue;
		    }

		    vlen = cdb_datalen(ssp->cdbp);
		    csv = (CS)alloca(vlen + 1);
		    cdb_read(ssp->cdbp, csv, vlen, cdb_datapos(ssp->cdbp));
		    csv[vlen] = '\0';
		    vb_printf(VB_SHOP, "COLLECTED [%s] %s", pskey, csv);
		    tgt_ps = ps_newFromCSVString(csv);

		    // Unfortunately, as noted elsewhere, a CA object
		    // doesn't hold PS objects, it holds PA objects.
		    // So we need a dummy PA to wrap the target PS in.
		    dummy_pa = pa_new();
		    pa_set_ps(dummy_pa, tgt_ps);
		    if (ps_is_link(tgt_ps)) {
			pa_set_op(dummy_pa, OP_LINK);
		    } else if (ps_is_symlink(tgt_ps)) {
			pa_set_op(dummy_pa, OP_SYMLINK);
		    } else if (ps_is_unlink(tgt_ps)) {
			pa_set_op(dummy_pa, OP_UNLINK);
		    } else {
			pa_set_op(dummy_pa, OP_CREAT);
		    }
		    pa_set_call(dummy_pa, "dummy");
		    pa_set_uploadable(dummy_pa, 1);
		    ca_record_pa(ssp->ca, dummy_pa);
		}
		// Once we've reached the winner, we're done.
		break;
	    }
	}
    }

    return rc;
}
Beispiel #30
0
/* 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);
}