Beispiel #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;
}
Beispiel #2
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;
}