Exemplo n.º 1
0
// This is going to be slow since it is a search by value. I.e. it
// walks through the entire CDB sequentially trying to map a value
// back to its key. Therefore it should only be used in debug or
// error scenarios.
static CCS
_shop_find_cmdline(shopping_state_s *ssp, CCS cmdix)
{
    unsigned loc = 0;

    cdb_seqinit(&loc, ssp->cdbp);
    while (cdb_seqnext(&loc, ssp->cdbp) > 0) {
	unsigned len;

	CS cmdstate, ix;

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

	if ((ix = util_strsep(&cmdstate, FS1)) && !strcmp(cmdix, ix)) {
	    CS line;

	    len = cdb_keylen(ssp->cdbp);
	    line = (CS)putil_malloc(len + 1);
	    cdb_read(ssp->cdbp, line, len, cdb_keypos(ssp->cdbp));
	    line[len] = '\0';
	    return line;
	}
    }

    return NULL;
}
Exemplo n.º 2
0
static int __cdbb_copy(struct cdbb *a, size_t ks, size_t vs)
{
	unsigned char k[ks];
	unsigned char v[vs];
	uint32 kp, dp;
	int found, filter;

	found = 0;

	kp = cdb_keypos(a->r);
	cdb_read(a->r, k, ks, kp);

	dp = cdb_datapos(a->r);
	/* in some cases we do not need to read e.g. when deleting
	 * or filtering but for simplicity we just do it anyways */
	cdb_read(a->r, v, vs, dp);

	found = cdbb_check_ops(a, k, ks, v, vs);
	filter = cdbb_check_filter(a, k, ks, v, vs);

	/* if an operation applied or a filter, don't copy */
	if (!found && !filter && kp) {
		cdb_make_add(a->w, k, ks, v, vs);
		return 1;
	}
	return 0;
}
Exemplo n.º 3
0
static int __cdbb_findnext(struct cdbb *a, const char *needle, struct nentry *n,
	int ignorecase)
{
	uint32 kp, dp, ks, vs;
	unsigned char *k, *v;

	if (cdb_nextkey(a->r, &a->kfindpos) != 1)
		return -1;

	kp = cdb_keypos(a->r);
	ks = cdb_keylen(a->r);
	k = alloca(ks);
	cdb_read(a->r, k, ks, kp);

	dp = cdb_datapos(a->r);
	vs = cdb_datalen(a->r);
	/* in some cases we do not need to read e.g. when deleting
	 * or filtering but for simplicity we just do it anyways */
	v = alloca(vs);
	cdb_read(a->r, v, vs, dp);

	/* search value */
	if (ignorecase) {
		if (strcasestr((char *)v, needle) == NULL)
			return 0;
	} else {
		if (strstr((char *)v, needle) == NULL)
			return 0;
	}

	array_catb(&n->k, (char *)k, ks);
	array_catb(&n->e, (char *)v, vs);

	return 1;
}
Exemplo n.º 4
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;
}