diff --git a/src/Makefile b/src/Makefile index 5f42afd04..4fd293059 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 e8b18934b..000000000 --- a/src/nix.c +++ /dev/null @@ -1,314 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include - - -#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 000000000..0c7865270 --- /dev/null +++ b/src/nix.cc @@ -0,0 +1,220 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include + +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 openDB(const string & dbname, bool readonly) +{ + auto_ptr db; + + db = auto_ptr(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 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 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 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; + } +}