about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/Makefile4
-rw-r--r--src/nix.c314
-rw-r--r--src/nix.cc220
3 files changed, 222 insertions, 316 deletions
diff --git a/src/Makefile b/src/Makefile
index 5f42afd04476..4fd29305978a 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,2 +1,2 @@
-nix: nix.c
-	gcc -g -Wall -o nix nix.c -ldb-4
+nix: nix.cc
+	g++ -g -Wall -o nix nix.cc -ldb_cxx-4
diff --git a/src/nix.c b/src/nix.c
deleted file mode 100644
index e8b18934b9c8..000000000000
--- a/src/nix.c
+++ /dev/null
@@ -1,314 +0,0 @@
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-#include <db4/db.h>
-
-
-#define PKGINFO_PATH "/pkg/sys/var/pkginfo"
-
-
-typedef enum {true = 1, false = 0} bool;
-
-
-static char * prog;
-static char * dbfile = PKGINFO_PATH;
-
-
-DB * openDB(char * dbname, bool readonly)
-{
-    int err;
-    DB * db;
-
-    err = db_create(&db, 0, 0);
-    if (err) {
-        fprintf(stderr, "error creating db handle: %s\n",
-            db_strerror(err));
-        return 0;
-    }
-        
-    err = db->open(db, dbfile, dbname,
-        DB_HASH, readonly ? DB_RDONLY : DB_CREATE, 0666);
-    if (err) {
-        fprintf(stderr, "creating opening %s: %s\n",
-            dbfile, db_strerror(err));
-        db->close(db, 0);
-        return 0;
-    }
-
-    return db;
-}
-
-
-bool queryDB(char * dbname, char * key, char * * data)
-{
-    DB * db = 0;
-    DBT kt, dt;
-    int err;
-
-    db = openDB(dbname, true);
-    if (!db) goto bad;
-
-    *data = 0;
-
-    memset(&kt, 0, sizeof(kt));
-    memset(&dt, 0, sizeof(dt));
-    kt.size = strlen(key);
-    kt.data = key;
-
-    err = db->get(db, 0, &kt, &dt, 0);
-    if (!err) {
-        *data = malloc(dt.size + 1);
-        memcpy(*data, dt.data, dt.size);
-        (*data)[dt.size] = 0;
-    } else if (err != DB_NOTFOUND) {
-        fprintf(stderr, "creating opening %s: %s\n",
-            dbfile, db_strerror(err));
-        goto bad;
-    }
-
-    db->close(db, 0);
-    return true;
-
- bad:
-    if (db) db->close(db, 0);
-    return false;
-}
-
-
-bool setDB(char * dbname, char * key, char * data)
-{
-    DB * db = 0;
-    DBT kt, dt;
-    int err;
-
-    db = openDB(dbname, false);
-    if (!db) goto bad;
-
-    memset(&kt, 0, sizeof(kt));
-    memset(&dt, 0, sizeof(dt));
-    kt.size = strlen(key);
-    kt.data = key;
-    dt.size = strlen(data);
-    dt.data = data;
-
-    err = db->put(db, 0, &kt, &dt, 0);
-    if (err) {
-        fprintf(stderr, "error storing data in %s: %s\n",
-            dbfile, db_strerror(err));
-        goto bad;
-    }
-
-    db->close(db, 0);
-    return true;
-
- bad:
-    if (db) db->close(db, 0);
-    return false;
-}
-
-
-bool delDB(char * dbname, char * key)
-{
-    DB * db = 0;
-    DBT kt;
-    int err;
-
-    db = openDB(dbname, false);
-    if (!db) goto bad;
-
-    memset(&kt, 0, sizeof(kt));
-    kt.size = strlen(key);
-    kt.data = key;
-
-    err = db->del(db, 0, &kt, 0);
-    if (err) {
-        fprintf(stderr, "error deleting data from %s: %s\n",
-            dbfile, db_strerror(err));
-        goto bad;
-    }
-
-    db->close(db, 0);
-    return true;
-
- bad:
-    if (db) db->close(db, 0);
-    return false;
-}
-
-
-bool getPkg(int argc, char * * argv)
-{
-    char * pkg;
-    char * src = 0;
-    char * inst = 0;
-    char inst2[1024];
-    char cmd[2048];
-    int res;
-
-    if (argc != 1) {
-        fprintf(stderr, "arguments missing in get-pkg\n");
-        return false;
-    }
-
-    pkg = argv[0];
-
-    if (!queryDB("pkginst", pkg, &inst)) return false;
-    
-    if (inst) {
-        printf("%s\n", inst);
-        free(inst);
-    } else {
-
-        fprintf(stderr, "package %s is not yet installed\n", pkg);
-        
-        if (!queryDB("pkgsrc", pkg, &src)) return false;
-
-        if (!src) {
-            fprintf(stderr, "source of package %s is not known\n", pkg);
-            return false;
-        }
-
-        if (snprintf(inst2, sizeof(inst2), "/pkg/%s", pkg) >= sizeof(inst2)) {
-            fprintf(stderr, "buffer overflow\n");
-            free(src);
-            return false;
-        }
-
-        if (snprintf(cmd, sizeof(cmd), "rsync -a \"%s\"/ \"%s\"",
-                src, inst2) >= sizeof(cmd)) 
-        {
-            fprintf(stderr, "buffer overflow\n");
-            free(src);
-            return false;
-        }
-        
-        res = system(cmd);
-        if (!WIFEXITED(res) || WEXITSTATUS(res) != 0) {
-            fprintf(stderr, "unable to copy sources\n");
-            free(src);
-            return false;
-        }
-
-        if (chdir(inst2)) {
-            fprintf(stderr, "unable to chdir to package directory\n");
-            free(src);
-            return false;
-        }
-
-        /* Prepare for building.  Clean the environment so that the
-           build process does not inherit things it shouldn't. */
-        setenv("PATH", "/pkg/sys/bin", 1);
-
-        res = system("./buildme");
-        if (!WIFEXITED(res) || WEXITSTATUS(res) != 0) {
-            fprintf(stderr, "unable to build package\n");
-            free(src);
-            return false;
-        }
-
-        setDB("pkginst", pkg, inst2);
-
-        free(src);
-
-        printf("%s\n", inst2);
-    }
-
-    return true;
-}
-
-
-bool registerPkg(int argc, char * * argv)
-{
-    char * pkg;
-    char * src;
-    
-    if (argc != 2) {
-        fprintf(stderr, "arguments missing in register-pkg\n");
-        return false;
-    }
-
-    pkg = argv[0];
-    src = argv[1];
-
-    return setDB("pkgsrc", pkg, src);
-}
-
-
-/* This is primarily used for bootstrapping. */
-bool registerInstalledPkg(int argc, char * * argv)
-{
-    char * pkg;
-    char * inst;
-    
-    if (argc != 2) {
-        fprintf(stderr, "arguments missing in register-installed-pkg\n");
-        return false;
-    }
-
-    pkg = argv[0];
-    inst = argv[1];
-    
-    if (strcmp(inst, "") == 0)
-        return delDB("pkginst", pkg);
-    else
-        return setDB("pkginst", pkg, inst);
-}
-
-
-bool run(int argc, char * * argv)
-{
-    char * cmd;
-
-    if (argc < 1) {
-        fprintf(stderr, "command not specified\n");
-        return false;
-    }
-
-    cmd = argv[0];
-    argc--, argv++;
-
-    if (strcmp(cmd, "get-pkg") == 0)
-        return getPkg(argc, argv);
-    else if (strcmp(cmd, "register-pkg") == 0)
-        return registerPkg(argc, argv);
-    else if (strcmp(cmd, "register-installed-pkg") == 0)
-        return registerInstalledPkg(argc, argv);
-    else {
-        fprintf(stderr, "unknown command: %s\n", cmd);
-        return false;
-    }
-}
-    
-    
-int main(int argc, char * * argv)
-{
-    int c;
-
-    prog = argv[0];
-
-    while ((c = getopt(argc, argv, "d:")) != EOF) {
-        
-        switch (c) {
-
-        case 'd':
-            dbfile = optarg;
-            break;
-
-        default:
-            fprintf(stderr, "unknown option\n");
-            break;
-        }
-
-    }
-
-    argc -= optind, argv += optind;
-
-    if (!run(argc, argv)) 
-        return 1;
-    else
-        return 0;
-}
diff --git a/src/nix.cc b/src/nix.cc
new file mode 100644
index 000000000000..0c786527082c
--- /dev/null
+++ b/src/nix.cc
@@ -0,0 +1,220 @@
+#include <iostream>
+#include <memory>
+#include <string>
+
+#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+
+#include <db4/db_cxx.h>
+
+using namespace std;
+
+
+#define PKGINFO_PATH "/pkg/sys/var/pkginfo"
+
+
+static string prog;
+static string dbfile = PKGINFO_PATH;
+
+
+class Db2 : public Db 
+{
+public:
+    Db2(DbEnv *env, u_int32_t flags)
+        : Db(env, flags)
+    {
+    }
+
+    ~Db2()
+    {
+        close(0);
+    }
+};
+
+
+auto_ptr<Db2> openDB(const string & dbname, bool readonly)
+{
+    auto_ptr<Db2> db;
+
+    db = auto_ptr<Db2>(new Db2(0, 0));
+
+    db->open(dbfile.c_str(), dbname.c_str(),
+        DB_HASH, readonly ? DB_RDONLY : DB_CREATE, 0666);
+
+    return db;
+}
+
+
+bool queryDB(const string & dbname, const string & key, string & data)
+{
+    int err;
+    auto_ptr<Db2> db = openDB(dbname, true);
+
+    Dbt kt((void *) key.c_str(), key.length());
+    Dbt dt;
+
+    err = db->get(0, &kt, &dt, 0);
+    if (err) return false;
+
+    data = string((char *) dt.get_data(), dt.get_size());
+    
+    return true;
+}
+
+
+void setDB(const string & dbname, const string & key, const string & data)
+{
+    auto_ptr<Db2> db = openDB(dbname, false);
+    Dbt kt((void *) key.c_str(), key.length());
+    Dbt dt((void *) data.c_str(), data.length());
+    db->put(0, &kt, &dt, 0);
+}
+
+
+void delDB(const string & dbname, const string & key)
+{
+    auto_ptr<Db2> db = openDB(dbname, false);
+    Dbt kt((void *) key.c_str(), key.length());
+    db->del(0, &kt, 0);
+}
+
+
+void getPkg(int argc, char * * argv)
+{
+    string pkg;
+    string src;
+    string inst;
+    string cmd;
+    int res;
+
+    if (argc != 1)
+        throw string("arguments missing in get-pkg");
+
+    pkg = argv[0];
+
+    if (queryDB("pkginst", pkg, inst)) {
+        cout << inst << endl;
+        return;
+    }
+    
+    cerr << "package " << pkg << " is not yet installed\n";
+        
+    if (!queryDB("pkgsrc", pkg, src)) 
+        throw string("source of package " + string(pkg) + " is not known");
+
+    inst = "/pkg/" + pkg;
+
+    cmd = "rsync -a \"" + src + "\"/ \"" + inst + "\"";
+        
+    res = system(cmd.c_str());
+    if (!WIFEXITED(res) || WEXITSTATUS(res) != 0)
+        throw string("unable to copy sources");
+
+    if (chdir(inst.c_str()))
+        throw string("unable to chdir to package directory");
+
+    /* Prepare for building.  Clean the environment so that the
+       build process does not inherit things it shouldn't. */
+    setenv("PATH", "/pkg/sys/bin", 1);
+
+    res = system("./buildme");
+    if (!WIFEXITED(res) || WEXITSTATUS(res) != 0)
+        throw string("unable to build package");
+
+    setDB("pkginst", pkg, inst);
+
+    cout << inst << endl;
+}
+
+
+void registerPkg(int argc, char * * argv)
+{
+    char * pkg;
+    char * src;
+    
+    if (argc != 2)
+        throw string("arguments missing in register-pkg");
+
+    pkg = argv[0];
+    src = argv[1];
+
+    setDB("pkgsrc", pkg, src);
+}
+
+
+/* This is primarily used for bootstrapping. */
+void registerInstalledPkg(int argc, char * * argv)
+{
+    string pkg;
+    string inst;
+    
+    if (argc != 2)
+        throw string("arguments missing in register-installed-pkg");
+
+    pkg = argv[0];
+    inst = argv[1];
+    
+    if (inst == "")
+        delDB("pkginst", pkg);
+    else
+        setDB("pkginst", pkg, inst);
+}
+
+
+void run(int argc, char * * argv)
+{
+    string cmd;
+
+    if (argc < 1)
+        throw string("command not specified\n");
+
+    cmd = argv[0];
+    argc--, argv++;
+
+    if (cmd == "get-pkg")
+        getPkg(argc, argv);
+    else if (cmd == "register-pkg")
+        registerPkg(argc, argv);
+    else if (cmd == "register-installed-pkg")
+        registerInstalledPkg(argc, argv);
+    else
+        throw string("unknown command: " + string(cmd));
+}
+    
+    
+int main(int argc, char * * argv)
+{
+    int c;
+
+    prog = argv[0];
+
+    while ((c = getopt(argc, argv, "d:")) != EOF) {
+        
+        switch (c) {
+
+        case 'd':
+            dbfile = optarg;
+            break;
+
+        default:
+            cerr << "unknown option\n";
+            break;
+        }
+
+    }
+
+    argc -= optind, argv += optind;
+
+    try {
+        run(argc, argv);
+        return 0;
+    } catch (DbException e) {
+        cerr << "db exception: " << e.what() << endl;
+        return 1;
+    } catch (string s) {
+        cerr << s << endl;
+        return 1;
+    }
+}