Example #1
0
SDB_API bool sdb_disk_create(Sdb* s) {
	int nlen;
	char *str;
	const char *dir;
	if (!s || s->fdump >= 0) {
		return false; // cannot re-create
	}
	if (!s->dir && s->name) {
		s->dir = strdup (s->name);
	}
	dir = s->dir ? s->dir : "./";
	R_FREE (s->ndump);
	nlen = strlen (dir);
	str = malloc (nlen + 5);
	if (!str) {
		return false;
	}
	memcpy (str, dir, nlen + 1);
	r_sys_mkdirp (str);
	memcpy (str + nlen, ".tmp", 5);
	if (s->fdump != -1) {
		close (s->fdump);
	}
	s->fdump = open (str, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, SDB_MODE);
	if (s->fdump == -1) {
		eprintf ("sdb: Cannot open '%s' for writing.\n", str);
		free (str);
		return false;
	}
	cdb_make_start (&s->m, s->fdump);
	s->ndump = str;
	return true;
}
Example #2
0
int main(int argc, char **argv)
{
    if(argc < 3) {
        fprintf(stderr, "%s out.db file1.json file2.json ... fileN.json\n", 
                argv[0]);
        return 0;
    }

    struct cdb_make cdbm;
    int fd;
    fd = open("tmp.db", O_RDWR | O_CREAT, 0644);
    cdb_make_start(&cdbm, fd);

    argv++;
    argc--;
    char *dbname = *argv;
    argv++;
    argc--;

    int i;
    for(i = 0; i < argc; i++) {
        parse_json(&cdbm, argv[0]); 
        argv++;
    }

    cdb_make_finish(&cdbm);
    rename("tmp.db", dbname);
    close(fd);
    return 0;
}
Example #3
0
static PyObject *
new_cdbmake(PyObject *ignore, PyObject *args) {

  cdbmakeobject *self;
  PyObject *fn, *fntmp;
  FILE * f;

  if (! PyArg_ParseTuple(args, "SS|i", &fn, &fntmp))
    return NULL;

  f = fopen(PyString_AsString(fntmp), "w+b");
  if (f == NULL) {
    return CDBMAKEerr;
  }

  self = PyObject_NEW(cdbmakeobject, &CdbMakeType);
  if (self == NULL) return NULL;

  self->fn = fn;
  Py_INCREF(self->fn);

  self->fntmp = fntmp;
  Py_INCREF(fntmp);

  if (cdb_make_start(&self->cm, f) == -1) {
    Py_DECREF(self);
    CDBMAKEerr;
    return NULL;
  }

  return (PyObject *) self;
}
Example #4
0
static void createdb(const char *f) {
    char line[SDB_VALUESIZE];
    struct cdb_make c;
    char *eq, *ftmp = malloc (strlen (f)+5);
    sprintf (ftmp, "%s.tmp", f);
    int fd = open (ftmp, O_RDWR|O_CREAT|O_TRUNC, 0644);
    if (fd == -1) {
        printf ("cannot create %s\n", ftmp);
        exit (1);
    }
    cdb_make_start (&c, fd);
    for (;;) {
        fgets (line, sizeof line, stdin);
        if (feof (stdin))
            break;
        line[strlen (line)-1] = 0;
        if ((eq = strchr (line, '='))) {
            *eq = 0;
            sdb_add (&c, line, eq+1);
        }
    }
    cdb_make_finish (&c);
    //fsync (fd);
    close (fd);
    rename (ftmp, f);
    free (ftmp);
}
Example #5
0
SDB_API int sdb_disk_create (Sdb* s) {
	int nlen;
	char *str;
	if (!s || !s->dir || s->fdump >=0) {
		return 0; // cannot re-create
	}
	free (s->ndump);
	s->ndump = NULL;
	nlen = strlen (s->dir);
	str = malloc (nlen+5);
	if (!str) return 0;
	memcpy (str, s->dir, nlen+1);
	r_sys_rmkdir (str);
	memcpy (str+nlen, ".tmp", 5);
	close (s->fdump);
	s->fdump = open (str, O_BINARY|O_RDWR|O_CREAT|O_TRUNC, SDB_MODE);
	if (s->fdump == -1) {
		eprintf ("sdb: Cannot open '%s' for writing.\n", str);
		free (str);
		return 0;
	}
	cdb_make_start (&s->m, s->fdump);
	s->ndump = str;
	return 1;
}
Example #6
0
int vmailmgr_autoconvert(void)
{
  int writefd = -1;
  ibuf reader;
  struct cdb_make writer;
  int error = 0;
  int readall = 0;
  int writerr = 0;
  if ((writefd = path_mktemp(pwfile, &tmppwfile)) != -1) {

    if (cdb_make_start(&writer, writefd) != 0)
      error = CVME_IO | CVME_FATAL;
    else {

      if (ibuf_open(&reader, pwfile, 0)) {

	uint32 end;
	struct stat st;
	if (fstat(reader.io.fd, &st) == 0
	    && fchmod(writefd, st.st_mode) == 0
	    && fchown(writefd, st.st_uid, st.st_gid) == 0
	    && read_start(&reader, &end)) {
	  while (ibuf_tell(&reader) < end) {
	    if (!read_cdb_pair(&reader, &key, &data))
	      break;
	    if (str_diff(&key, &virtuser) == 0)
	      if (!convert_data()) {
		writerr = 1;
		break;
	      }
	    if (cdb_make_add(&writer, key.s, key.len, data.s, data.len) != 0) {
	      writerr = 1;
	      break;
	    }
	  }
	  readall = ibuf_tell(&reader) == end;
	}
	ibuf_close(&reader);
      }
      if (cdb_make_finish(&writer) != 0)
	error |= CVME_FATAL;
      else
	if (readall && !writerr)
	  rename(tmppwfile.s, pwfile);
    }
    close(writefd);
    unlink(tmppwfile.s);
  }
  return error;
}
Example #7
0
int main(int argc,char **argv)
{
  int fd;
  unsigned long loop;

  if (!*argv) _exit(0);
  if (!*++argv) _exit(0);
  scan_ulong(*argv,&loop);

  if (cdb_make_start(&c,1) == -1) die_write();

  while (loop) {
    uint32_pack(key,--loop);
    if (cdb_make_add(&c,key,4,data,sizeof data) == -1) die_write();
  }

  if (cdb_make_finish(&c) == -1) die_write();
  _exit(0);
}
Example #8
0
int cdbb_open_write(struct cdbb *a, const char *f)
{
	int fp;

	unlink(f);
	fp = open_write(f);

	if (fp < 0)
		return -1;

	a->w = malloc(sizeof(struct cdb_make));
	if (a->w == NULL) {
		close(fp);
		return -1;
	}

	cdb_make_start(a->w, fp);
	a->fnum = 0;
	a->tnum = 0;
	return fp;
}
Example #9
0
int main()
{
  umask(033);
  if (chdir(auto_qmail) == -1)
    strerr_die4sys(111,FATAL,"unable to chdir to ",auto_qmail,": ");

  fd = open_read("control/morercpthosts");
  if (fd == -1) die_read();

  substdio_fdbuf(&ssin,subread,fd,inbuf,sizeof inbuf);

  fdtemp = open_trunc("control/morercpthosts.tmp");
  if (fdtemp == -1) die_write();

  if (cdb_make_start(&cdbm,fdtemp) == -1) die_write();

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdb_make_add(&cdbm,line.s,line.len,"",0) == -1)
	  die_write();
      break;
    }
    if (!match) break;
  }

  if (cdb_make_finish(&cdbm) == -1) die_write();
  if (fsync(fdtemp) == -1) die_write();
  if (close(fdtemp) == -1) die_write(); /* NFS stupidity */
  if (rename("control/morercpthosts.tmp","control/morercpthosts.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move control/morercpthosts.tmp to control/morercpthosts.cdb");

  return 0;
}
Example #10
0
static int cdb_write_attrs(const char *filename, const attrs_type&attributes)
{
    FILE           *cdbfile;
    t_hlist	   *curr;
    t_attr         *attr;
    struct cdb_make cdbm;

    if ((cdbfile = fopen(filename, "w+b")) == NULL) {
	eventlog(eventlog_level_error, __FUNCTION__, "unable to open file \"%s\" for writing ",filename);
	return -1;
    }

    cdb_make_start(&cdbm, cdbfile);

	BEGIN(_attr,attributes)
	{
		attr=*_attr;
//    hlist_for_each(curr,attributes) {
//	attr = hlist_entry(curr, t_attr, link);

	if (attr_get_key(attr) && attr_get_val(attr)) {
	    if (strncmp("BNET\\CharacterDefault\\", attr_get_key(attr), 20) == 0) {
		eventlog(eventlog_level_debug, __FUNCTION__, "skipping attribute key=\"%s\"",attr_get_key(attr));
	    } else {
		eventlog(eventlog_level_debug, __FUNCTION__, "saving attribute key=\"%s\" val=\"%s\"",attr_get_key(attr),attr_get_val(attr));
		if (cdb_make_add(&cdbm, attr_get_key(attr), strlen(attr_get_key(attr)), attr_get_val(attr), strlen(attr_get_val(attr)))<0)
		{
		    eventlog(eventlog_level_error, __FUNCTION__, "got error on cdb_make_add ('%s' = '%s')", attr_get_key(attr), attr_get_val(attr));
		    cdb_make_finish(&cdbm); /* try to bail out nicely */
		    fclose(cdbfile);
		    return -1;
		}
	    }
	} else eventlog(eventlog_level_error, __FUNCTION__,"could not save attribute key=\"%s\"",attr_get_key(attr));

	attr_clear_dirty(attr);
    }
Example #11
0
int main(int argc, char **argv)
{
  umask(033);

  if (argc != 3)
    strerr_die1sys(111,"qmail-cdb: usage: qmail-cdb rules.cdb rules.tmp");

  substdio_fdbuf(&ssin,subread,0,inbuf,sizeof inbuf);

  fdtemp = open_trunc(argv[2]);
  if (fdtemp == -1) die_write(argv[2]);

  if (cdb_make_start(&cdbm,fdtemp) == -1) die_write(argv[2]);

  for (;;) {
    if (getln(&ssin,&line,&match,'\n') != 0) die_read();
    case_lowerb(line.s,line.len);
    while (line.len) {
      if (line.s[line.len - 1] == ' ') { --line.len; continue; }
      if (line.s[line.len - 1] == '\n') { --line.len; continue; }
      if (line.s[line.len - 1] == '\t') { --line.len; continue; }
      if (line.s[0] != '#')
	if (cdb_make_add(&cdbm,line.s,line.len,"",0) == -1)
	  die_write(argv[2]);
      break;
    }
    if (!match) break;
  }

  if (cdb_make_finish(&cdbm) == -1) die_write(argv[2]);
  if (fsync(fdtemp) == -1) die_write(argv[2]);
  if (close(fdtemp) == -1) die_write(argv[2]); /* NFS stupidity */
  if (rename(argv[2],argv[1]) == -1)
    strerr_die5sys(111, FATAL, "unable to move ", argv[2], " to ", argv[1]);

  return 0;
}
Example #12
0
static ERL_NIF_TERM cdbwriter_new(ErlNifEnv* env, int argc,
                                 const ERL_NIF_TERM argv[])
{
    char * path = get_str(env, argv[0], NULL);
    int tmp_len;
    ERL_NIF_TERM result;
    if(path==NULL)
        return enif_make_atom(env, "invalid_path");
    cdbwriter_handle* handle = enif_alloc_resource(cdbwriter_RESOURCE,
                                                sizeof(cdbwriter_handle));
    handle->fd = -1;
    handle->target = path;
    handle->tmpfile = get_str(env, argv[1], &tmp_len);
    if(!handle->tmpfile || tmp_len<6)
        return enif_make_atom(env, "invalid_tmp_path");
    result = enif_make_resource(env, handle);
    enif_release_resource(handle);
    handle->fd = mkstemp(handle->tmpfile);
    if(handle->fd <0)
        return enif_make_atom(env, "open_error");
    if(cdb_make_start(&(handle->cdbm), handle->fd) < 0 )
        return enif_make_atom(env, "cant_start_write");
    return enif_make_tuple2(env, enif_make_atom(env, "ok"), result);
}
Example #13
0
int main()
{
    char ip[4];
    unsigned long u;
    unsigned int j;
    unsigned int k;
    char ch;

    umask(022);

    fd = open_read("data");
    if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
    buffer_init(&b,buffer_unixread,fd,bspace,sizeof bspace);

    fdcdb = open_trunc("data.tmp");
    if (fdcdb == -1) die_datatmp();
    if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

    while (match) {
        ++linenum;
        if (getln(&b,&line,&match,'\n') == -1)
            strerr_die2sys(111,FATAL,"unable to read line: ");

        while (line.len) {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
            --line.len;
        }
        if (!line.len) continue;

        switch(line.s[0]) {
        default:
            syntaxerror(": unrecognized leading character");
        case '#':
            break;
        case ':':
            j = byte_chr(line.s + 1,line.len - 1,':');
            if (j >= line.len - 1) syntaxerror(": missing colon");
            if (ip4_scan(line.s + 1,ip) != j) syntaxerror(": malformed IP address");
            if (!stralloc_copyb(&tmp,ip,4)) nomem();
            if (!stralloc_catb(&tmp,line.s + j + 2,line.len - j - 2)) nomem();
            if (cdb_make_add(&cdb,"",0,tmp.s,tmp.len) == -1)
                die_datatmp();
            break;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            if (!stralloc_0(&line)) nomem();
            j = 0;
            if (!stralloc_copys(&tmp,"")) nomem();
            for (;;) {
                k = scan_ulong(line.s + j,&u);
                if (!k) break;
                ch = u;
                if (!stralloc_catb(&tmp,&ch,1)) nomem();
                j += k;
                if (line.s[j] != '.') break;
                ++j;
            }
            if (!stralloc_catb(&tmp,"\0\0\0\0",4)) nomem();
            tmp.len = 4;
            if (line.s[j] == '/')
                scan_ulong(line.s + j + 1,&u);
            else
                u = 32;
            if (u > 32) u = 32;
            ch = u;
            if (!stralloc_catb(&tmp,&ch,1)) nomem();
            if (cdb_make_add(&cdb,tmp.s,tmp.len,"",0) == -1)
                die_datatmp();
            break;
        }
    }

    if (cdb_make_finish(&cdb) == -1) die_datatmp();
    if (fsync(fdcdb) == -1) die_datatmp();
    if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
    if (rename("data.tmp","data.cdb") == -1)
        strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

    return 0;
}
Example #14
0
void Lists_OP_MakeCDB(char *txt_filename, char *cdb_filename, int force)
{
    /*
    struct stat cdb_stat;
    struct stat txt_stat;
    */
    struct cdb_make cdbm;
    FILE *tmp_fd;
    FILE *txt_fd;
    char *tmp_str;
    char *key, *val;
    char str[OS_MAXSTR+1];

    str[OS_MAXSTR]= '\0';
    char tmp_filename[OS_MAXSTR];
    tmp_filename[OS_MAXSTR - 2] = '\0';
    snprintf(tmp_filename, OS_MAXSTR - 2, "%s.tmp", txt_filename);

    /*
    if((stat(txt_filename, &txt_stat)) == -1)
        debug1("%s: stat of file %s failed", ARGV0, txt_filename);
    if((stat(cdb_filename, &cdb_stat)) == -1)
        debug1("%s: stat of file %s failed", ARGV0, cdb_filename);
        */
    if(File_DateofChange(txt_filename) > File_DateofChange(cdb_filename) ||
       force)
    {
        printf(" * File %s need to be updated\n", cdb_filename);
        tmp_fd = fopen(tmp_filename, "w+");
        cdb_make_start(&cdbm, tmp_fd);
        if(!(txt_fd = fopen(txt_filename, "r")))
        {
            merror(FOPEN_ERROR, ARGV0, txt_filename);
            return;
        }
        while((fgets(str, OS_MAXSTR-1,txt_fd)) != NULL)
        {
            /* Removing new lines or carriage returns. */
            tmp_str = strchr(str, '\r');
            if(tmp_str)
                *tmp_str = '\0';
            tmp_str = strchr(str, '\n');
            if(tmp_str)
                *tmp_str = '\0';
            if((val = strchr(str, ':')))
            {
                *val = '\0';
                val++;
            }
            else
            {
                continue;
            }
            key = str;
            cdb_make_add(&cdbm, key, strlen(key), val, strlen(val));
            if(force) print_out("  * adding - key: %s value: %s",key,val);
        }
        cdb_make_finish(&cdbm);
        rename(tmp_filename,cdb_filename);
    }
    else
    {
        printf(" * File %s does not need to be compiled\n", cdb_filename);
    }
}
Example #15
0
int
main(int argc, char **argv) {
	int c, fd, fdtemp;
	size_t klen, len = 0;
	char *dbfile, *dbnewfile, *dbtemp, *dirname = NULL;
	char *key;
	unsigned cpos;
	struct cdb cdbm;
	struct cdb_make cdbn;

	struct record rec;

	progname = basename(argv[0]);

	struct option long_options[] = {
		{ "help",		no_argument,		0, 'h' },
		{ "dbpath",		required_argument,	0, 'D' },
		{ 0, 0, 0, 0 }
	};

	if (argc == 1)
		print_help(EXIT_SUCCESS);

	while ((c = getopt_long (argc, argv, "hD:", long_options, NULL)) != -1) {
		switch (c) {
			case 'D':
				db_path = optarg;
				break;
			default:
			case 'h':
				print_help(EXIT_SUCCESS);
				break;
		}
	}

	if (db_path == NULL)
		db_path = def_db_path;

	if (optind == argc)
		print_help(EXIT_FAILURE);

	dbfile = argv[optind];

	// Open old database
	if ((fd = open(dbfile, O_RDONLY | O_NOFOLLOW | O_NOCTTY)) == -1)
		osec_fatal(EXIT_FAILURE, errno, "%s: open", dbfile);

	if (compat_db_version(fd)) {
		printf("%s: Database already in new format\n", dbfile);
		return EXIT_SUCCESS;
	}

	if (cdb_init(&cdbm, fd) < 0)
		osec_fatal(EXIT_FAILURE, errno, "cdb_init(cdbm)");

	// Generate new state database
	len = strlen(dbfile) + 11;
	dbtemp = (char *) xmalloc(sizeof(char) * len);
	sprintf(dbtemp, "%s.XXXXXXXXX", dbfile);

	// Open new database
	if ((fdtemp = mkstemp(dbtemp)) == -1)
		osec_fatal(EXIT_FAILURE, errno, "%s: mkstemp", dbtemp);

	if (cdb_make_start(&cdbn, fdtemp) < 0)
		osec_fatal(EXIT_FAILURE, errno, "cdb_make_start");

	// Allocate buffer for reading files.
	read_bufsize = (size_t) (sysconf(_SC_PAGE_SIZE) - 1);
	read_buf = xmalloc(read_bufsize);

	/*
	 * Set default data buffer. This value will increase in the process of
	 * creating a database.
	 */
	rec.len  = 1024;
	rec.data = xmalloc(rec.len);

	cdb_seqinit(&cpos, &cdbm);
	while(cdb_seqnext(&cpos, &cdbm) > 0) {
		char *type;

		klen = cdb_keylen(&cdbm);
		key = (char *) xmalloc((size_t) (klen + 1));

		if (cdb_read(&cdbm, key, (unsigned) klen, cdb_keypos(&cdbm)) < 0)
			osec_fatal(EXIT_FAILURE, errno, "cdb_read");

		key[klen] = '\0';

		if ((type = strchr(key, '\0')) == (key + klen))
			osec_fatal(EXIT_FAILURE, errno, "strchr: Cant find type\n");

		klen = strlen(key);

		type += 1;
		if (strcmp(type, "stat") == 0) {
			struct stat st;

			rec.offset = 0;

			if (cdb_read(&cdbm, &st, (unsigned) sizeof(st), cdb_datapos(&cdbm)) < 0)
				osec_fatal(EXIT_FAILURE, errno, "cdb_read");

			osec_empty_digest(&rec);
			osec_empty_symlink(&rec);
			osec_state(&rec, &st);

			if (cdb_make_add(&cdbn, key, (unsigned) klen+1, rec.data, (unsigned) rec.offset) != 0)
				osec_fatal(EXIT_FAILURE, errno, "%s: cdb_make_add", key);
		}

		xfree(key);
	}

	write_db_version(&cdbn);

	xfree(rec.data);

	if (cdb_make_finish(&cdbn) < 0)
		osec_fatal(EXIT_FAILURE, errno, "cdb_make_finish");

	if (close(fdtemp) == -1)
		osec_fatal(EXIT_FAILURE, errno, "%s: close", dbtemp);

	if (close(fd) == -1)
		osec_fatal(EXIT_FAILURE, errno, "%s: close", dbfile);

	dirname = decode_dirname(dbfile);
	gen_db_name(dirname, &dbnewfile);

	rename(dbtemp, dbnewfile);
	remove(dbfile);

	xfree(dbtemp);
	xfree(dirname);
	xfree(dbnewfile);

	return EXIT_SUCCESS;
}
Example #16
0
int
main(int argc, char *argv[])
{
    int fddata = 0;
    unsigned int i = 0, j = 0, k = 0;

    unsigned long u = 0;
    unsigned long ttl = 0;

    char ch = 0;
    char *x = NULL;
    char ttd[8], loc[2];
    char ip[4], type[2];
    char soa[20], buf[4];

    prog = strdup ((x = strrchr (argv[0], '/')) != NULL ? x + 1 : argv[0]);
    i = check_option (argc, argv);
    argv += i;
    argc -= i;

    umask(022);

    if ((fddata = open_read ("data")) == -1)
        err (-1, "could not open file `data'");
    defaultsoa_init (fddata);

    buffer_init (&b, buffer_unixread, fddata, bspace, sizeof bspace);

    if ((fdcdb = open_trunc ("data.tmp")) == -1)
        err (-1, "could not create file `data.tmp'");
    if (cdb_make_start (&cdb, fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");

    while (match)
    {
        linenum++;
        if (getln (&b, &line, &match, '\n') == -1)
            err (-1, "could not read line: %ld", linenum);

        while (line.len)
        {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n'))
                break;

            --line.len;
        }
        if (!line.len)
            continue;
        if (line.s[0] == '#')
            continue;
        if (line.s[0] == '-')
            continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; i++)
        {
            if (j >= line.len)
            {
                if (!stralloc_copys (&f[i], ""))
                    err (-1, "could not allocate enough memory");
            }
            else
            {
                k = byte_chr (line.s + j, line.len - j, ':');
                if (!stralloc_copyb (&f[i], line.s + j, k))
                    err (-1, "could not allocate enough memory");
                j += k + 1;
            }
        }

        switch (line.s[0])
        {
        case '%':
            locparse (&f[0], loc);

            if (!stralloc_copyb (&key, "\0%", 2))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            ipprefix_cat (&key, f[1].s);

            if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
                err (-1, "could not create file `data.tmp'");

            break;

        case 'Z':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                uint32_unpack_big (defaultsoa, (uint32 *)&u);
            uint32_pack_big (soa, u);

            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &u))
                uint32_unpack_big (defaultsoa + 4, (uint32 *)&u);
            uint32_pack_big (soa + 4, u);

            if (!stralloc_0 (&f[5]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[5].s, &u))
                uint32_unpack_big (defaultsoa + 8, (uint32 *)&u);
            uint32_pack_big (soa + 8, u);

            if (!stralloc_0 (&f[6]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[6].s, &u))
                uint32_unpack_big (defaultsoa + 12, (uint32 *)&u);
            uint32_pack_big (soa + 12, u);

            if (!stralloc_0 (&f[7]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[7].s, &u))
                uint32_unpack_big (defaultsoa + 16, (uint32 *)&u);
            uint32_pack_big (soa + 16, u);

            if (!stralloc_0 (&f[8]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong(f[8].s,&ttl))
                ttl = TTL_NEGATIVE;

            ttdparse (&f[9], ttd);
            locparse (&f[10], loc);

            rr_start (DNS_T_SOA, ttl, ttd, loc);
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            rr_addname (d2);
            rr_add (soa, 20);
            rr_finish (d1);

            break;

        case '.':
        case '&':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_NS;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".ns."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (line.s[0] == '.')
            {
                rr_start (DNS_T_SOA, ttl ? TTL_NEGATIVE : 0, ttd, loc);
                rr_addname (d2);

                rr_add ("\12hostmaster", 11);
                rr_addname (d1);

                rr_add (defaultsoa, 20);
                rr_finish (d1);
            }

            rr_start (DNS_T_NS, ttl, ttd, loc);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }

            break;

        case '+':
        case '=':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");

            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d1);

                if (line.s[0] == '=')
                {
                    dns_name4_domain (dptr,ip);
                    rr_start (DNS_T_PTR, ttl, ttd, loc);
                    rr_addname (d1);
                    rr_finish (dptr);
                }
            }
            break;

        case '@':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[4]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[4].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[5], ttd);
            locparse (&f[6], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");

            if (byte_chr (f[2].s, f[2].len, '.') >= f[2].len)
            {
                if (!stralloc_cats (&f[2], ".mx."))
                    err (-1, "could not allocate enough memory");
                if (!stralloc_catb (&f[2], f[0].s, f[0].len))
                    err (-1, "could not allocate enough memory");
            }
            if (!dns_domain_fromdot (&d2, f[2].s, f[2].len))
                err (-1, "could not allocate enough memory");

            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &u))
                u = 0;

            rr_start (DNS_T_MX, ttl, ttd, loc);
            uint16_pack_big (buf, u);
            rr_add (buf, 2);
            rr_addname (d2);
            rr_finish (d1);

            if (ip4_scan (f[1].s, ip))
            {
                rr_start (DNS_T_A, ttl, ttd, loc);
                rr_add (ip, 4);
                rr_finish (d2);
            }
            break;

        case '^':
        case 'C':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!dns_domain_fromdot (&d2, f[1].s, f[1].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            if (line.s[0] == 'C')
                rr_start (DNS_T_CNAME, ttl, ttd, loc);
            else
                rr_start (DNS_T_PTR, ttl, ttd, loc);

            rr_addname (d2);
            rr_finish (d1);

            break;

        case '\'':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[2]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[2].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[3], ttd);
            locparse (&f[4], loc);

            rr_start (DNS_T_TXT, ttl, ttd, loc);

            txtparse (&f[1]);
            i = 0;
            while (i < f[1].len)
            {
                k = f[1].len - i;
                if (k > 127)
                    k = 127;
                ch = k;
                rr_add (&ch, 1);
                rr_add (f[1].s + i, k);
                i += k;
            }

            rr_finish (d1);
            break;

        case ':':
            if (!dns_domain_fromdot (&d1, f[0].s, f[0].len))
                err (-1, "could not allocate enough memory");
            if (!stralloc_0 (&f[3]))
                err (-1, "could not allocate enough memory");
            if (!scan_ulong (f[3].s, &ttl))
                ttl = TTL_POSITIVE;

            ttdparse (&f[4], ttd);
            locparse (&f[5], loc);

            if (!stralloc_0 (&f[1]))
                err (-1, "could not allocate enough memory");
            scan_ulong (f[1].s, &u);
            uint16_pack_big (type, u);
            if (byte_equal (type, 2, DNS_T_AXFR))
                syntaxerror (": type AXFR prohibited");
            if (byte_equal (type, 2, "\0\0"))
              syntaxerror (": type 0 prohibited");
            if (byte_equal (type, 2, DNS_T_SOA))
              syntaxerror (": type SOA prohibited");
            if (byte_equal (type, 2, DNS_T_NS))
              syntaxerror (": type NS prohibited");
            if (byte_equal (type, 2, DNS_T_CNAME))
              syntaxerror (": type CNAME prohibited");
            if (byte_equal (type, 2, DNS_T_PTR))
              syntaxerror (": type PTR prohibited");
            if (byte_equal (type, 2, DNS_T_MX))
              syntaxerror (": type MX prohibited");

            txtparse (&f[2]);

            rr_start (type, ttl, ttd, loc);
            rr_add (f[2].s, f[2].len);
            rr_finish (d1);

            break;

        default:
            syntaxerror (": unrecognized leading character");
        }
    }

    if (cdb_make_finish (&cdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (fsync (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'");
    if (close (fdcdb) == -1)
        err (-1, "could not create file `data.tmp'"); /* NFS stupidity */
    if (rename ("data.tmp", "data.cdb") == -1)
        err (-1, "could not move `data.tmp' to `data.cdb'");

    return 0;
}
Example #17
0
int main(int argc, char **argv)
{
  int fddata;
	uint32 loc;
	//int v;
	char ipa[4];
	//char ipb[4];
	//ip4_cidr_t *subnets = (ip4_cidr_t *)NULL;
	//unsigned int slen = 0;
	uint32 ipinta = 0U;
	//unsigned int ipintb = 0;
	unsigned short mask;
	uint32 uid = 0;
	uint32  mid = 0;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  //uint32 loc;
	unsigned char keyloc[15];
  unsigned long u;
  char ip[4];
	char locp[4];
	//char map[9];
  char type[2];
  char soa[20];
  char buf[4];
  //int namlen = 0;
  umask(022);
  fddata = STDIN_FILENO;
	if (argc != 3) {
    fddata = open_read("data");
		if (fddata == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
		if ( (fdcdb = open_trunc("data.tmp")) == -1) die_datatmp();
	} else {
		fddata = STDIN_FILENO;
		if ( (fdcdb = open_trunc(argv[1])) == -1) die_datatmp();
	}
	
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;
		//write(1,line.s,line.len);
		//write(1,"\n",1);
    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
				if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
				if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
				j += k + 1;
      }
    }

	switch(line.s[0]) {
#ifdef USE_LOCMAPS
	case '%':
		//locparse(&f[0],loc);
		loc = gethash(f[0].s,f[0].len);
		uint32_pack(locp,loc);
		if (!stralloc_0(&f[1])) nomem();
		if (!stralloc_0(&f[2])) nomem();
		ip4_scan(f[1].s,ipa);
		//ip4_scan(f[2].s,ipb);
		scan_ushort(f[2].s,&mask);
		ip4_num(&ipinta,ipa);
		//ip4_num(&ipintb,ipb);
		//if (ipintb<ipinta) nomem();
		//if (ip4_deaggregate(ipinta,ipintb,&subnets,&slen) <= 0) nomem();
		mid = gethash(f[3].s,f[3].len);
		uid = gethash(f[4].s,f[4].len);
		//for (v = 0; v < slen; v++) {
		ipdb_key4build(keyloc,ipinta,(unsigned char )mask&0xff,mid,uid);
		//ipdb_key_from_uint(keyloc,ipinta,(unsigned char )mask&0xff,0,mid,uid);
		cdb_make_add(&cdb,keyloc,15,locp,4);
		//}
		uid = 0;
		//alloc_free(subnets);
		//subnets = NULL;
		//slen = 0;
		byte_zero(ipa,4);ipinta=0; //byte_zero(ipb,4);ipinta=0;ipintb=0;
		break;
#endif
 	case 'Z':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
		uint32_pack_big(soa,u);
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
		uint32_pack_big(soa + 4,u);
		if (!stralloc_0(&f[5])) nomem();
		if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
		uint32_pack_big(soa + 8,u);
		if (!stralloc_0(&f[6])) nomem();
		if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
		uint32_pack_big(soa + 12,u);
		if (!stralloc_0(&f[7])) nomem();
		if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
		uint32_pack_big(soa + 16,u);

		if (!stralloc_0(&f[8])) nomem();
		if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
		ttdparse(&f[9],ttd);
		loc = gethash(f[10].s,f[10].len);
		mid = gethash(f[11].s,f[11].len);
		uid = gethash(f[12].s,f[12].len);
		rr_addloq(DNS_T_SOA,d1,loc,mid,uid);

		rr_start(DNS_T_SOA,ttl,ttd,loc);
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		rr_addname(d2);
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
		rr_addname(d2);
		rr_add(soa,20);
		rr_finish(d1);
		break;

	case '.': case '&':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".ns.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (line.s[0] == '.') {
			rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
			rr_addloq(DNS_T_SOA,d1,loc,mid,uid);
			rr_addname(d2);
			rr_add("\12hostmaster",11);
			rr_addname(d1);
			rr_add(defaultsoa,20);
			rr_finish(d1);
		}

		rr_start(DNS_T_NS,ttl,ttd,loc);
		rr_addname(d2);
		rr_addloq(DNS_T_NS,d2,loc,mid,uid);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
	  	rr_start(DNS_T_A,ttl,ttd,loc);
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_add(ip,4);
			rr_finish(d2);
		}

		break;

	case '+': case '=':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (!stralloc_0(&f[1])) nomem();

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			//dbger("+addloq:d=%s,loc=%u,uid=%u,mid=%u",d1,loc,uid,mid);
			rr_add(ip,4);
			rr_finish(d1);

			if (line.s[0] == '=') {
				rr_addloq(DNS_T_PTR,d1,loc,mid,uid); //??????????????????/ TODO: checkthis
				dns_name4_domain(dptr,ip);
				rr_start(DNS_T_PTR,ttl,ttd,loc);
				rr_addname(d1);
				rr_finish(dptr);
			}
		}
		break;

	case '@':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[4])) nomem();
		if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[5],ttd);
		loc = gethash(f[6].s,f[6].len);
		mid = gethash(f[7].s,f[7].len);
		uid = gethash(f[8].s,f[8].len);

		if (!stralloc_0(&f[1])) nomem();

		if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
			if (!stralloc_cats(&f[2],".mx.")) nomem();
			if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
		}
		if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&u)) u = 0;

		rr_addloq(DNS_T_MX,d1,loc,mid,uid);
		rr_start(DNS_T_MX,ttl,ttd,loc);
		uint16_pack_big(buf,u);
		rr_add(buf,2);
		rr_addname(d2);
		rr_finish(d1);

		if (ip4_scan(f[1].s,ip)) {
			rr_addloq(DNS_T_A,d2,loc,mid,uid);
			rr_start(DNS_T_A,ttl,ttd,loc);
			rr_add(ip,4);
			rr_finish(d2);
		}
		break;

	case '^': case 'C':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		if (line.s[0] == 'C') {
			//rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			//dbger("add loq for cname!");
			rr_addloq(DNS_T_A,d1,loc,mid,uid);
			rr_addloq(DNS_T_CNAME,d1,loc,mid,uid);
			rr_start(DNS_T_CNAME,ttl,ttd,loc);
		} else {
			rr_addloq(DNS_T_PTR,d1,loc,mid,uid);
			rr_start(DNS_T_PTR,ttl,ttd,loc);
		}
		rr_addname(d2);
		rr_finish(d1);
		break;

	case '\'':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[2])) nomem();
		if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[3],ttd);
		loc = gethash(f[4].s,f[4].len);
		mid = gethash(f[5].s,f[5].len);
		uid = gethash(f[6].s,f[6].len);

		rr_addloq(DNS_T_TXT,d1,loc,mid,uid);
		rr_start(DNS_T_TXT,ttl,ttd,loc);
		txtparse(&f[1]);
		i = 0;
		while (i < f[1].len) {
			k = f[1].len - i;
			if (k > 127) k = 127;
			ch = k;
			rr_add(&ch,1);
			rr_add(f[1].s + i,k);
			i += k;
		}

		rr_finish(d1);
		break;

	case ':':
		if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
		if (!stralloc_0(&f[3])) nomem();
		if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
		ttdparse(&f[4],ttd);
		loc = gethash(f[5].s,f[5].len);
		mid = gethash(f[6].s,f[6].len);
		uid = gethash(f[7].s,f[7].len);

		if (!stralloc_0(&f[1])) nomem();
		scan_ulong(f[1].s,&u);
		uint16_pack_big(type,u);
		if (byte_equal(type,2,DNS_T_AXFR))
			syntaxerror(": type AXFR prohibited");
		if (byte_equal(type,2,"\0\0"))
			syntaxerror(": type 0 prohibited");
		if (byte_equal(type,2,DNS_T_SOA))
			syntaxerror(": type SOA prohibited");
		if (byte_equal(type,2,DNS_T_NS))
			syntaxerror(": type NS prohibited");
		if (byte_equal(type,2,DNS_T_CNAME))
			syntaxerror(": type CNAME prohibited");
		if (byte_equal(type,2,DNS_T_PTR))
			syntaxerror(": type PTR prohibited");
		if (byte_equal(type,2,DNS_T_MX))
			syntaxerror(": type MX prohibited");
		txtparse(&f[2]);
		rr_addloq(type,d1,loc,mid,uid);
		rr_start(type,ttl,ttd,loc);
		rr_add(f[2].s,f[2].len);
		rr_finish(d1);
		break;
	default:
		dienow("error here: %s\n", line.s);
		syntaxerror(": unrecognized leading character");
}
}

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
	if (argc  == 3) {
		if (rename(argv[1],argv[2]) == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	} else {
		if (rename("data.tmp","data.cdb") == -1) strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");
	}

  _exit(0);
}
Example #18
0
int main()
{
  int fddata;
  int i;
  int j;
  int k;
  char ch;
  unsigned long ttl;
  char ttd[8];
  char loc[2];
  unsigned long u;
  char ip[4];
  char ip6[16];
  char type[2];
  char soa[20];
  char buf[4];

  umask(022);

  fddata = open_read("data");
  if (fddata == -1)
    strerr_die2sys(111,FATAL,"unable to open data: ");
  defaultsoa_init(fddata);

  buffer_init(&b,buffer_unixread,fddata,bspace,sizeof bspace);

  fdcdb = open_trunc("data.tmp");
  if (fdcdb == -1) die_datatmp();
  if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

  while (match) {
    ++linenum;
    if (getln(&b,&line,&match,'\n') == -1)
      strerr_die2sys(111,FATAL,"unable to read line: ");

    while (line.len) {
      ch = line.s[line.len - 1];
      if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
      --line.len;
    }
    if (!line.len) continue;
    if (line.s[0] == '#') continue;
    if (line.s[0] == '-') continue;

    j = 1;
    for (i = 0;i < NUMFIELDS;++i) {
      if (j >= line.len) {
	if (!stralloc_copys(&f[i],"")) nomem();
      }
      else {
        k = byte_chr(line.s + j,line.len - j,':');
	if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
	j += k + 1;
      }
    }

    switch(line.s[0]) {

      case '%':
	locparse(&f[0],loc);
	if (!stralloc_copyb(&key,"\0%",2)) nomem();
	if (!stralloc_0(&f[1])) nomem();
	ipprefix_cat(&key,f[1].s);
        if (cdb_make_add(&cdb,key.s,key.len,loc,2) == -1)
          die_datatmp();
	break;

      case 'Z':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) uint32_unpack_big(defaultsoa,&u);
	uint32_pack_big(soa,u);
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&u)) uint32_unpack_big(defaultsoa + 4,&u);
	uint32_pack_big(soa + 4,u);
	if (!stralloc_0(&f[5])) nomem();
	if (!scan_ulong(f[5].s,&u)) uint32_unpack_big(defaultsoa + 8,&u);
	uint32_pack_big(soa + 8,u);
	if (!stralloc_0(&f[6])) nomem();
	if (!scan_ulong(f[6].s,&u)) uint32_unpack_big(defaultsoa + 12,&u);
	uint32_pack_big(soa + 12,u);
	if (!stralloc_0(&f[7])) nomem();
	if (!scan_ulong(f[7].s,&u)) uint32_unpack_big(defaultsoa + 16,&u);
	uint32_pack_big(soa + 16,u);

	if (!stralloc_0(&f[8])) nomem();
	if (!scan_ulong(f[8].s,&ttl)) ttl = TTL_NEGATIVE;
	ttdparse(&f[9],ttd);
	locparse(&f[10],loc);

	rr_start(DNS_T_SOA,ttl,ttd,loc);
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	rr_addname(d2);
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();
	rr_addname(d2);
	rr_add(soa,20);
	rr_finish(d1);
	break;

      case '.': case '&':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_NS;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".ns.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (line.s[0] == '.') {
	  rr_start(DNS_T_SOA,ttl ? TTL_NEGATIVE : 0,ttd,loc);
	  rr_addname(d2);
	  rr_add("\12hostmaster",11);
	  rr_addname(d1);
	  rr_add(defaultsoa,20);
	  rr_finish(d1);
	}

	rr_start(DNS_T_NS,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}

	break;

      case '+': case '=':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d1);

	  if (line.s[0] == '=') {
	    dns_name4_domain(dptr,ip);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(dptr);
	  }
	}
	break;

      case '6': case '3':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (!stralloc_0(&f[1])) nomem();
	if (ip6_scan_flat(f[1].s,ip6)) {
	  rr_start(DNS_T_AAAA,ttl,ttd,loc);
	  rr_add(ip6,16);
	  rr_finish(d1);

	  if (line.s[0] == '6') {	/* emit both .ip6.arpa and .ip6.int */
	    dns_name6_domain(d6ptr,ip6,DNS_IP6_ARPA);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);

	    dns_name6_domain(d6ptr,ip6,DNS_IP6_INT);
	    rr_start(DNS_T_PTR,ttl,ttd,loc);
	    rr_addname(d1);
	    rr_finish(d6ptr);
	  }
	}
	break;

      case '@':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[4])) nomem();
	if (!scan_ulong(f[4].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[5],ttd);
	locparse(&f[6],loc);

	if (!stralloc_0(&f[1])) nomem();

	if (byte_chr(f[2].s,f[2].len,'.') >= f[2].len) {
	  if (!stralloc_cats(&f[2],".mx.")) nomem();
	  if (!stralloc_catb(&f[2],f[0].s,f[0].len)) nomem();
	}
	if (!dns_domain_fromdot(&d2,f[2].s,f[2].len)) nomem();

	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&u)) u = 0;

	rr_start(DNS_T_MX,ttl,ttd,loc);
	uint16_pack_big(buf,u);
	rr_add(buf,2);
	rr_addname(d2);
	rr_finish(d1);

	if (ip4_scan(f[1].s,ip)) {
	  rr_start(DNS_T_A,ttl,ttd,loc);
	  rr_add(ip,4);
	  rr_finish(d2);
	}
	break;

      case '^': case 'C':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!dns_domain_fromdot(&d2,f[1].s,f[1].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	if (line.s[0] == 'C')
	  rr_start(DNS_T_CNAME,ttl,ttd,loc);
	else
	  rr_start(DNS_T_PTR,ttl,ttd,loc);
	rr_addname(d2);
	rr_finish(d1);
	break;

      case '\'':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[2])) nomem();
	if (!scan_ulong(f[2].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[3],ttd);
	locparse(&f[4],loc);

	rr_start(DNS_T_TXT,ttl,ttd,loc);

	txtparse(&f[1]);
	i = 0;
	while (i < f[1].len) {
	  k = f[1].len - i;
	  if (k > 127) k = 127;
	  ch = k;
	  rr_add(&ch,1);
	  rr_add(f[1].s + i,k);
	  i += k;
	}

	rr_finish(d1);
	break;

      case ':':
	if (!dns_domain_fromdot(&d1,f[0].s,f[0].len)) nomem();
	if (!stralloc_0(&f[3])) nomem();
	if (!scan_ulong(f[3].s,&ttl)) ttl = TTL_POSITIVE;
	ttdparse(&f[4],ttd);
	locparse(&f[5],loc);

	if (!stralloc_0(&f[1])) nomem();
	scan_ulong(f[1].s,&u);
	uint16_pack_big(type,u);
	if (byte_equal(type,2,DNS_T_AXFR))
	  syntaxerror(": type AXFR prohibited");
	if (byte_equal(type,2,"\0\0"))
	  syntaxerror(": type 0 prohibited");
	if (byte_equal(type,2,DNS_T_SOA))
	  syntaxerror(": type SOA prohibited");
	if (byte_equal(type,2,DNS_T_NS))
	  syntaxerror(": type NS prohibited");
	if (byte_equal(type,2,DNS_T_CNAME))
	  syntaxerror(": type CNAME prohibited");
	if (byte_equal(type,2,DNS_T_PTR))
	  syntaxerror(": type PTR prohibited");
	if (byte_equal(type,2,DNS_T_MX))
	  syntaxerror(": type MX prohibited");

	txtparse(&f[2]);

	rr_start(type,ttl,ttd,loc);
	rr_add(f[2].s,f[2].len);
	rr_finish(d1);
	break;

      default:
        syntaxerror(": unrecognized leading character");
    }
  }

  if (cdb_make_finish(&cdb) == -1) die_datatmp();
  if (fsync(fdcdb) == -1) die_datatmp();
  if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
  if (rename("data.tmp","data.cdb") == -1)
    strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

  _exit(0);
}
Example #19
0
main()
{
    struct address t;
    int i;
    int j;
    int k;
    char ch;

    umask(022);

    if (!address_alloc_readyplus(&x,0)) nomem();

    fd = open_read("data");
    if (fd == -1) strerr_die2sys(111,FATAL,"unable to open data: ");
    buffer_init(&b,read,fd,bspace,sizeof bspace);

    fdcdb = open_trunc("data.tmp");
    if (fdcdb == -1) die_datatmp();
    if (cdb_make_start(&cdb,fdcdb) == -1) die_datatmp();

    while (match) {
        ++linenum;
        if (getln(&b,&line,&match,'\n') == -1)
            strerr_die2sys(111,FATAL,"unable to read line: ");

        while (line.len) {
            ch = line.s[line.len - 1];
            if ((ch != ' ') && (ch != '\t') && (ch != '\n')) break;
            --line.len;
        }
        if (!line.len) continue;

        j = 1;
        for (i = 0; i < NUMFIELDS; ++i) {
            if (j >= line.len) {
                if (!stralloc_copys(&f[i],"")) nomem();
            }
            else {
                k = byte_chr(line.s + j,line.len - j,':');
                if (!stralloc_copyb(&f[i],line.s + j,k)) nomem();
                j += k + 1;
            }
        }

        switch(line.s[0]) {
        default:
            syntaxerror(": unrecognized leading character");
        case '#':
            break;
        case '-':
            break;
        case '+':
            byte_zero(&t,sizeof t);
            if (!dns_domain_fromdot(&t.name,f[0].s,f[0].len)) nomem();
            t.namelen = dns_domain_length(t.name);
            case_lowerb(t.name,t.namelen);
            if (!stralloc_0(&f[1])) nomem();
            if (!ip4_scan(f[1].s,t.ip)) syntaxerror(": malformed IP address");
            if (!stralloc_0(&f[2])) nomem();
            if (!stralloc_0(&f[2])) nomem();
            byte_copy(t.location,2,f[2].s);
            if (!address_alloc_append(&x,&t)) nomem();
            break;
        case '%':
            if (!stralloc_0(&f[0])) nomem();
            if (!stralloc_0(&f[0])) nomem();
            if (!stralloc_copyb(&result,f[0].s,2)) nomem();
            if (!stralloc_0(&f[1])) nomem();
            if (!stralloc_copys(&key,"%")) nomem();
            ipprefix_cat(&key,f[1].s);
            if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
                die_datatmp();
            break;
        }
    }

    close(fd);
    address_sort(x.s,x.len);

    i = 0;
    while (i < x.len) {
        for (j = i + 1; j < x.len; ++j)
            if (address_diff(x.s + i,x.s + j))
                break;
        if (!stralloc_copys(&key,"+")) nomem();
        if (!stralloc_catb(&key,x.s[i].location,2)) nomem();
        if (!stralloc_catb(&key,x.s[i].name,x.s[i].namelen)) nomem();
        if (!stralloc_copys(&result,"")) nomem();
        while (i < j)
            if (!stralloc_catb(&result,x.s[i++].ip,4)) nomem();
        if (cdb_make_add(&cdb,key.s,key.len,result.s,result.len) == -1)
            die_datatmp();
    }

    if (cdb_make_finish(&cdb) == -1) die_datatmp();
    if (fsync(fdcdb) == -1) die_datatmp();
    if (close(fdcdb) == -1) die_datatmp(); /* NFS stupidity */
    if (rename("data.tmp","data.cdb") == -1)
        strerr_die2sys(111,FATAL,"unable to move data.tmp to data.cdb: ");

    _exit(0);
}
Example #20
0
int make_cdb()
{
 FILE *fs;
 int fdout;
 char *key;
 char *data;
 char *tmpptr;
 static char input[MAX_LINE];
 uint32 h;


  if ( (fs = fopen(ClearFile,"r")) == NULL) {
    printf("Not building simcontrol.cdb file. No %s/simcontrol text file\n",
      CONTROLDIR);
    return(-1);
  }
 
  if ( (fdout = open(CdbTmpFile, O_CREAT | O_TRUNC | O_WRONLY)) < 0) {
     printf("error on open tmp file\n");
    return(-1);
  }

  if (cdb_make_start(&c,fdout) == -1) {
    printf("error on cdb_make_start\n");
    return(-1);
  } 

  while(fgets(input,sizeof(input), fs)!=NULL) { 

    if ( input[0] == ':' ) {
      key = "";
      data = strtok(&input[1],"\r\n");
    } else {
      key = strtok(input,TOKENS);
      if ( key == NULL ) continue;
      data = strtok(NULL,"\r\n");
    }

    if ( data == NULL ) data="";

    /*snprintf(key,sizeof(key),"%s", data);*/

    if (cdb_make_addbegin(&c,strlen(key),strlen(data)) == -1) {
      printf("error on cdb_make_addbegin)\n");
      return(-1);
    } 
    h = CDB_HASHSTART;
    
    for(tmpptr=key;*tmpptr!=0;++tmpptr) {
      if (buffer_PUTC(&c.b,*tmpptr) == -1) {
        printf("error in buffer_PUTC\n");
        return(-1);
      }
      h = cdb_hashadd(h,*tmpptr);
    }

    for(tmpptr=data;*tmpptr!=0;++tmpptr) {
      if (buffer_PUTC(&c.b,*tmpptr) == -1) {
        printf("error in buffer_PUTC\n");
        return(-1);
      }
    }
    if (cdb_make_addend(&c,strlen(key),strlen(data),h) == -1) {
      printf("error in cdb_make_addend\n");
      return(-1);
    }
  }
  if (cdb_make_finish(&c) == -1) {
    printf("error in cdb_make_finish\n"); 
    return(-1);
  }

  /*fprintf(fsout"\n");*/
  fclose(fs);
  close(fdout);

  if (rename(CdbTmpFile, CdbFile)==-1) {
    printf("error: could not rename %s to %s\n", CdbTmpFile, CdbFile);
    return(-1);
  }
  chmod(CdbFile, 0644);
  printf("simscan cdb file built. %s/simcontrol.cdb\n", CONTROLDIR);
  return(0);
}
Example #21
0
int make_version_cdb() {
  int fdout;
  char key[MAX_KEY];
  char data[MAX_DATA];
  pid_t pid;
  int pin[2],rmstat,r,f;
  char input[MAX_LINE];
  char dbpath[MAX_LINE];
  char *pos;
#if ENABLE_SPAM==1 || ENABLE_TROPHIE==1
  int fnd_vsvers;
#endif
#if ENABLE_TROPHIE==1
  int fnd_patvers;
#endif

  if ( (fdout = open(CdbTmpFile, O_CREAT | O_TRUNC | O_WRONLY)) < 0) {
    printf("error on open tmp file\n");
    return(-1);
  }
  
  if (cdb_make_start(&c,fdout) == -1) {
    printf("error on cdb_make_start\n");
    return(-1);
  } 

  /* now add a check for every enabled scanner, and add the scanner to the cdb */
#ifdef ENABLE_ATTACH
  memset(data,'\0',MAX_DATA);
  strncpy(key,RCVD_ATTACH_KEY,MAX_KEY);
  strncpy(data,VERSION,MAX_DATA);
  add_cdb_key(&c,key,data);
#endif
#ifdef ENABLE_REGEX
  memset(data,'\0',MAX_DATA);
  strncpy(key,RCVD_REGEX_KEY,MAX_KEY);
  strncpy(data,VERSION,MAX_DATA);
  add_cdb_key(&c,key,data);
#endif
#ifdef ENABLE_TROPHIE
  memset(data,'\0',MAX_DATA);
  data[0]='\0';
  fnd_vsvers=0;
  fnd_patvers=0;
  strncpy(key,RCVD_TROPHIE_KEY,MAX_KEY);
  if (pipe(pin)){
    printf("error opening pipe for trophie\n");
  }
  pid=vfork();
  if (pid==0){
      /* in the child */
      close(pin[0]);
      dup2(pin[1],2); /* stderr goes to the pipe */
      execl(TROPHIEBINARY,TROPHIEBINARY,"-v",NULL);
      printf("error running trophie\n");
      _exit(-1); /* we should never get here! */
  } else if (pid){
    /* in the parent */
    close(pin[1]);
    while((r=read(pin[0],input,MAX_LINE))){
      /* we are looking for those two lines:
          Initializing    : VSAPI version 6.150-1001
          Initializing    : Pattern version 218 (pattern number 51417)
        and we want 6.150-1001/218/51417 in the string at the end */

      input[r]='\0';
      if ( (pos=strstr(input,"version ")) && (!fnd_vsvers || !fnd_patvers)){
        if (!fnd_vsvers && !fnd_patvers){
          /* this line is the vsapi version */
          strncpy(data,pos+8,strlen(pos)-9);
          strcat(data,"/");
          fnd_vsvers=1;
        } else if (!fnd_patvers){
          /* this line is the pattern version */
          for(f=0;*(pos+8+f)!=' ' && *(pos+8+f)!='\0';f++);
          strncpy(data+strlen(data),pos+8,f);
          if ( (pos=strstr(input,"number ")) ) {
            strcat(data,"/");
            for(f=0;*(pos+7+f)!=')' && *(pos+7+f)!='\0';f++);
            strncpy(data+strlen(data),pos+7,f);
          }
          fnd_patvers=1;
        }
      }
    }
    waitpid(pid,&rmstat,0);
    add_cdb_key(&c,key,data);
  } else {
    printf("error forking for trophie\n");
  }
  close(pin[0]); close(pin[1]);
#endif
#ifdef ENABLE_SPAM
  memset(data,'\0',MAX_DATA);
  fnd_vsvers=0;
  strncpy(key,RCVD_SPAM_KEY,MAX_KEY);
  if (pipe(pin)){
    printf("error opening pipe for spamassassin\n");
  }
  pid=vfork();
  if (pid==0){
      /* in the child */
      close(pin[0]);
      dup2(pin[1],1); /* stdout goes to the pipe */
      execl(SPAMASSASSINPATH,SPAMASSASSINPATH,"-V",NULL);
      printf("error running spamassassin\n");
      _exit(-1); /* we should never get here! */
  } else if (pid){
    /* in the parent */
    close(pin[1]);
    while((r=read(pin[0],input,MAX_LINE))){
      /* we are looking for this line:
          SpamAssassin version 2.63
          and have 2.63 as version
        */
      input[r]='\0';
      if ( (pos=strstr(input,"version ")) && !fnd_vsvers ){
        /* this line is the sa version */
        for(f=0;*(pos+8+f)!='\n' && *(pos+8+f)!='\0';f++);
        strncpy(data,pos+8,f);
        fnd_vsvers=1;
      }
    }
    waitpid(pid,&rmstat,0);
    add_cdb_key(&c,key,data);
  } else {
    printf("error forking for trophie\n");
  }
  close(pin[0]); close(pin[1]);
#endif
#ifdef ENABLE_CLAMAV
  memset(data,'\0',MAX_DATA);
  strncpy(key,RCVD_CLAM_KEY,MAX_KEY);
  if (pipe(pin)){
    printf("error opening pipe for sigtool\n");
  }
  pid=vfork();
  if (pid==0){
      /* in the child */
      close(pin[0]);
      dup2(pin[1],1); /* stdout goes to the pipe */
      execl(CLAMDSCAN,CLAMDSCAN,"--stdout","-V",NULL);
      printf("error running clamdscan\n");
      _exit(-1); /* we should never get here! */
  } else if (pid){
    /* in the parent */
    close(pin[1]);
    while((r=read(pin[0],input,MAX_LINE))){
      /* we are looking for this line:
         Version: 27
        */
      input[r]='\0';
      if ( (pos=strstr(input,"ClamAV "))){
        /* this line is the db version */
        for(f=0;*(pos+7+f)!='/' && *(pos+7+f)!='\0';f++);
        strncat(data,pos+7,f);
        strcat(data,"/");
      }
    }
    waitpid(pid,&rmstat,0);
    close(pin[0]); close(pin[1]);
  }
  strncpy(dbpath,CLAMAVDBPATH,MAX_DATA);
  strcat(dbpath,"/main.cvd");
  strcat(data,"m:");
  if (pipe(pin)){
    printf("error opening pipe for sigtool\n");
  }
  pid=vfork();
  if (pid==0){
      /* in the child */
      close(pin[0]);
      dup2(pin[1],1); /* stdout goes to the pipe */
      execl(SIGTOOLPATH,SIGTOOLPATH,"--stdout","-i",dbpath,NULL);
      printf("error running sigtool\n");
      _exit(-1); /* we should never get here! */
  } else if (pid){
    /* in the parent */
    close(pin[1]);
    while((r=read(pin[0],input,MAX_LINE))){
      /* we are looking for this line:
         Version: 27
        */
      input[r]='\0';
      if ( (pos=strstr(input,"Version: "))){
        /* this line is the db version */
        for(f=0;*(pos+9+f)!='\n' && *(pos+9+f)!='\0';f++);
        strncat(data,pos+9,f);
      }
    }
    waitpid(pid,&rmstat,0);
    close(pin[0]); close(pin[1]);
    strncpy(dbpath,CLAMAVDBPATH,MAX_DATA);
    strcat(dbpath,"/daily.cvd");
    if (pipe(pin)){
     printf("error opening pipe for sigtool\n");
    }
    pid=vfork();
    if (pid==0){
      /* in the child */
      close(pin[0]);
      dup2(pin[1],1); /* stdout goes to the pipe */
      execl(SIGTOOLPATH,SIGTOOLPATH,"--stdout","-i",dbpath,NULL);
      printf("error running sigtool\n");
      _exit(-1); /* we should never get here! */
    } else if (pid){
      /* in the parent */
      close(pin[1]);
      while((r=read(pin[0],input,MAX_LINE))){
        /* we are looking for this line:
           Version: 27
          */
        input[r]='\0';
        if ( (pos=strstr(input,"Version: "))){
          /* this line is the db version */
          for(f=0;*(pos+9+f)!='\n' && *(pos+9+f)!='\0';f++);
          strcat(data,"/d:");
          strncat(data,pos+9,f);
        }
      }
      waitpid(pid,&rmstat,0);
      add_cdb_key(&c,key,data);
    }
  } else {
    printf("error forking for trophie\n");
  }
  close(pin[0]); close(pin[1]);
#endif
  if (cdb_make_finish(&c) == -1) {
    printf("error in cdb_make_finish\n"); 
    return(-1);
  }

  close(fdout);

  if (rename(CdbTmpFile, CdbVersFile)==-1) {
    printf("error: could not rename %s to %s\n", CdbTmpFile, CdbFile);
    return(-1);
  }
  chmod(CdbVersFile, 0644);
  printf("simscan versions cdb file built. %s\n", CdbVersFile);
  return(0);
}
Example #22
0
static DICT *dict_cdbm_open(const char *path, int dict_flags)
{
    DICT_CDBM *dict_cdbm;
    char   *cdb_path;
    char   *tmp_path;
    int     fd;
    struct stat st0, st1;

    cdb_path = concatenate(path, CDB_SUFFIX, (char *) 0);
    tmp_path = concatenate(path, CDB_TMP_SUFFIX, (char *) 0);

    /*
     * Repeat until we have opened *and* locked *existing* file. Since the
     * new (tmp) file will be renamed to be .cdb file, locking here is
     * somewhat funny to work around possible race conditions.  Note that we
     * can't open a file with O_TRUNC as we can't know if another process
     * isn't creating it at the same time.
     */
    for (;;) {
	if ((fd = open(tmp_path, O_RDWR | O_CREAT, 0644)) < 0)
	    return (dict_surrogate(DICT_TYPE_CDB, path, O_RDWR, dict_flags,
				   "open database %s: %m", tmp_path));
	if (fstat(fd, &st0) < 0)
	    msg_fatal("fstat(%s): %m", tmp_path);

	/*
	 * Get an exclusive lock - we're going to change the database so we
	 * can't have any spectators.
	 */
	if (myflock(fd, INTERNAL_LOCK, MYFLOCK_OP_EXCLUSIVE) < 0)
	    msg_fatal("lock %s: %m", tmp_path);

	if (stat(tmp_path, &st1) < 0)
	    msg_fatal("stat(%s): %m", tmp_path);

	/*
	 * Compare file's state before and after lock: should be the same,
	 * and nlinks should be >0, or else we opened non-existing file...
	 */
	if (st0.st_ino == st1.st_ino && st0.st_dev == st1.st_dev
	    && st0.st_rdev == st1.st_rdev && st0.st_nlink == st1.st_nlink
	    && st0.st_nlink > 0)
	    break;				/* successefully opened */

	close(fd);

    }

#ifndef NO_FTRUNCATE
    if (st0.st_size)
	ftruncate(fd, 0);
#endif

    dict_cdbm = (DICT_CDBM *) dict_alloc(DICT_TYPE_CDB, path,
					 sizeof(*dict_cdbm));
    if (cdb_make_start(&dict_cdbm->cdbm, fd) < 0)
	msg_fatal("initialize database %s: %m", tmp_path);
    dict_cdbm->dict.close = dict_cdbm_close;
    dict_cdbm->dict.update = dict_cdbm_update;
    dict_cdbm->cdb_path = cdb_path;
    dict_cdbm->tmp_path = tmp_path;
    dict_cdbm->dict.owner.uid = st1.st_uid;
    dict_cdbm->dict.owner.status = (st1.st_uid != 0);
    close_on_exec(fd, CLOSE_ON_EXEC);

    /*
     * If undecided about appending a null byte to key and value, choose a
     * default to not append a null byte when creating a cdb.
     */
    if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0)
	dict_flags |= DICT_FLAG_TRY0NULL;
    else if ((dict_flags & DICT_FLAG_TRY1NULL)
	     && (dict_flags & DICT_FLAG_TRY0NULL))
	dict_flags &= ~DICT_FLAG_TRY0NULL;
    dict_cdbm->dict.flags = dict_flags | DICT_FLAG_FIXED;
    if (dict_flags & DICT_FLAG_FOLD_FIX)
	dict_cdbm->dict.fold_buf = vstring_alloc(10);

    return (&dict_cdbm->dict);
}