|
|
@@ -0,0 +1,186 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <db.h>
|
|
|
+#include <fcntl.h>
|
|
|
+#include <limits.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <err.h>
|
|
|
+#include <string.h>
|
|
|
+#include <sys/types.h>
|
|
|
+#include <malloc_np.h>
|
|
|
+#include <getopt.h>
|
|
|
+#include <sys/stat.h>
|
|
|
+#include "bcompare.h"
|
|
|
+
|
|
|
+/* yacc */
|
|
|
+int yyparse(void);
|
|
|
+extern int yyin;
|
|
|
+int btreeparse(const char *line);
|
|
|
+int do_quit = 0;
|
|
|
+/* MALLOC_CONF=stats_print:true,junk:true */
|
|
|
+static DB * btreedb;
|
|
|
+#define KEYDATA_MAX 64
|
|
|
+
|
|
|
+
|
|
|
+static struct option longopts[] = {
|
|
|
+ { "db", required_argument, NULL, 'd' },
|
|
|
+ { NULL, 0, NULL, 0 }
|
|
|
+};
|
|
|
+
|
|
|
+__attribute__((noreturn)) static int usage(void)
|
|
|
+{
|
|
|
+ fputs("bprompt [--db filename]\n", stderr);
|
|
|
+ exit (EXIT_SUCCESS);
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * insert key/val pair in database
|
|
|
+ *
|
|
|
+ * @key: key id
|
|
|
+ * @data: cargo
|
|
|
+ *
|
|
|
+ * return 0 on success, -1 otherwise
|
|
|
+ */
|
|
|
+int dbinsert(size_t key, char *data)
|
|
|
+{
|
|
|
+ DBT k = {};
|
|
|
+ DBT d = {};
|
|
|
+ int rc = 0;
|
|
|
+ size_t l =strnlen(data, KEYDATA_MAX);
|
|
|
+
|
|
|
+ k.data = &key;
|
|
|
+ k.size = sizeof key;
|
|
|
+ d.size = l + 1;
|
|
|
+ d.data = malloc(KEYDATA_MAX);
|
|
|
+
|
|
|
+ *((char *) mempcpy (d.data, data, l)) = '\0';
|
|
|
+
|
|
|
+ rc = btreedb->put(btreedb, &k, &d, R_NOOVERWRITE);
|
|
|
+ if (rc == -1) {
|
|
|
+ warn("Failed to insert record %zu:", key);
|
|
|
+ goto dbinsert_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ warnx("This record can't be ovewritten.");
|
|
|
+ rc = -1;
|
|
|
+ goto dbinsert_out;
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("Record inserted with key %zu.\n", key);
|
|
|
+
|
|
|
+dbinsert_out:
|
|
|
+ free(d.data);
|
|
|
+ return rc;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * delete key/val pair from database
|
|
|
+ *
|
|
|
+ * @key: key id
|
|
|
+ *
|
|
|
+ * return 0 on success, -1 otherwise
|
|
|
+ */
|
|
|
+int dbdelete(size_t key)
|
|
|
+{
|
|
|
+ DBT k = {};
|
|
|
+ k.data = &key;
|
|
|
+ k.size = sizeof key;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = btreedb->del(btreedb, &k, 0);
|
|
|
+
|
|
|
+ if (rc == -1) {
|
|
|
+ warn("Failed to delete record %zu:", key);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+ if (rc) {
|
|
|
+ warnx("record key %zu was not found.", key);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("Record %zu deleted.\n", key);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+/*
|
|
|
+ * display key/val pair from database
|
|
|
+ *
|
|
|
+ * @key: key id
|
|
|
+ *
|
|
|
+ * return 0 on success, -1 otherwise
|
|
|
+ */
|
|
|
+int dbget(size_t key)
|
|
|
+{
|
|
|
+ DBT k = {};
|
|
|
+ DBT d = {};
|
|
|
+ k.data = &key;
|
|
|
+ k.size = sizeof key;
|
|
|
+ int rc;
|
|
|
+
|
|
|
+ rc = btreedb->get(btreedb, &k, &d, 0);
|
|
|
+
|
|
|
+ if (rc == -1) {
|
|
|
+ warn("Failed to grab record %zu.", key);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rc) {
|
|
|
+ warnx("record %zu was not found.", key);
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ printf("-> %s.\n", (char *)d.data);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ char *dbname = NULL;
|
|
|
+ char buf[PATH_MAX];
|
|
|
+ /* btree */
|
|
|
+ BTREEINFO type = {};
|
|
|
+
|
|
|
+ /* opt */
|
|
|
+ int ch;
|
|
|
+ while ((ch = getopt_long(argc, argv, "d:", longopts, NULL)) != -1) {
|
|
|
+ switch (ch) {
|
|
|
+ case 'd':
|
|
|
+ dbname = optarg;
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ /* long option */
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ usage();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (optind != argc)
|
|
|
+ usage();
|
|
|
+
|
|
|
+ if (dbname == NULL) {
|
|
|
+ const char *t = getenv("TMPDIR");
|
|
|
+ if (t == NULL)
|
|
|
+ t = "/tmp";
|
|
|
+ (void)snprintf(buf, sizeof(buf), "%s/david", t);
|
|
|
+ dbname = buf;
|
|
|
+ }
|
|
|
+
|
|
|
+ type.compare = compare;
|
|
|
+ btreedb= dbopen(dbname, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR, DB_BTREE, &type);
|
|
|
+
|
|
|
+ if (!btreedb)
|
|
|
+ err(EXIT_FAILURE, "Database unreachable:");
|
|
|
+
|
|
|
+ while (!do_quit) {
|
|
|
+ yyparse();
|
|
|
+ }
|
|
|
+
|
|
|
+ btreedb->close(btreedb);
|
|
|
+
|
|
|
+ printf("Data stored into %s.\n", dbname);
|
|
|
+}
|
|
|
+
|