forked from lix-project/lix
* Some refactoring.
This commit is contained in:
parent
f8d91f20e6
commit
8b930a0c94
|
@ -1,13 +0,0 @@
|
||||||
#! /bin/sh
|
|
||||||
|
|
||||||
export PATH=$sys1/bin:$sys2/bin
|
|
||||||
export LIBRARY_PATH=$glibc/lib
|
|
||||||
export CC=$gcc/bin/gcc
|
|
||||||
export CFLAGS="-isystem $glibc/include -isystem $kernel/include"
|
|
||||||
|
|
||||||
top=`pwd`
|
|
||||||
tar xvfz $src
|
|
||||||
cd aterm-2.0
|
|
||||||
./configure --prefix=$top
|
|
||||||
make
|
|
||||||
make install
|
|
|
@ -1,12 +0,0 @@
|
||||||
# Dependencies.
|
|
||||||
sys1 <- 1e80cb7e0fbfc9f5c0509a465ecdf6cf # sys1-bootstrap
|
|
||||||
sys2 <- 7512824c50c61ea8d89d0f193a4f72d1 # sys2-bootstrap
|
|
||||||
gcc <- 02212b3dc4e50349376975367d433929 # gcc-bootstrap
|
|
||||||
glibc <- c0ce03ee0bab298babbe7e3b6159d36c # glibc-bootstrap
|
|
||||||
kernel <- 3dc8333a2c2b4d627b892755417acf89 # kernel-bootstrap
|
|
||||||
|
|
||||||
# Original sources.
|
|
||||||
src = 853474e4bcf4a85f7d38a0676b36bded # aterm-2.0.tar.gz
|
|
||||||
|
|
||||||
# Build script.
|
|
||||||
build = ee7ae4ade69f846d2385871bf532ef7e # aterm-2.0-build.sh
|
|
|
@ -1,11 +1,11 @@
|
||||||
bin_PROGRAMS = nix fix
|
bin_PROGRAMS = nix fix
|
||||||
|
|
||||||
nix_SOURCES = nix.cc md5.c
|
CXXFLAGS = -DSYSTEM=\"@host@\" -Wall
|
||||||
nix_CXXFLAGS = -DSYSTEM=\"@host@\" -Wall
|
|
||||||
|
nix_SOURCES = nix.cc db.cc util.cc md5.c
|
||||||
nix_LDADD = -ldb_cxx-4 -lATerm
|
nix_LDADD = -ldb_cxx-4 -lATerm
|
||||||
|
|
||||||
fix_SOURCES = fix.cc md5.c
|
fix_SOURCES = fix.cc util.cc md5.c
|
||||||
fix_CXXFLAGS = -DSYSTEM=\"@host@\" -Wall
|
|
||||||
fix_LDADD = -lATerm
|
fix_LDADD = -lATerm
|
||||||
|
|
||||||
install-data-local:
|
install-data-local:
|
||||||
|
|
116
src/db.cc
Normal file
116
src/db.cc
Normal file
|
@ -0,0 +1,116 @@
|
||||||
|
#include "db.hh"
|
||||||
|
#include "util.hh"
|
||||||
|
|
||||||
|
#include <db_cxx.h>
|
||||||
|
|
||||||
|
|
||||||
|
/* Wrapper classes that ensures that the database is closed upon
|
||||||
|
object destruction. */
|
||||||
|
class Db2 : public Db
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Db2(DbEnv *env, u_int32_t flags) : Db(env, flags) { }
|
||||||
|
~Db2() { close(0); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class DbcClose
|
||||||
|
{
|
||||||
|
Dbc * cursor;
|
||||||
|
public:
|
||||||
|
DbcClose(Dbc * c) : cursor(c) { }
|
||||||
|
~DbcClose() { cursor->close(); }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static auto_ptr<Db2> openDB(const string & filename, const string & dbname,
|
||||||
|
bool readonly)
|
||||||
|
{
|
||||||
|
auto_ptr<Db2> db(new Db2(0, 0));
|
||||||
|
|
||||||
|
db->open(filename.c_str(), dbname.c_str(),
|
||||||
|
DB_HASH, readonly ? DB_RDONLY : DB_CREATE, 0666);
|
||||||
|
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void rethrow(DbException & e)
|
||||||
|
{
|
||||||
|
throw Error(e.what());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void createDB(const string & filename, const string & dbname)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
openDB(filename, dbname, false);
|
||||||
|
} catch (DbException e) { rethrow(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool queryDB(const string & filename, const string & dbname,
|
||||||
|
const string & key, string & data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
int err;
|
||||||
|
auto_ptr<Db2> db = openDB(filename, 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());
|
||||||
|
|
||||||
|
} catch (DbException e) { rethrow(e); }
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void setDB(const string & filename, const string & dbname,
|
||||||
|
const string & key, const string & data)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto_ptr<Db2> db = openDB(filename, dbname, false);
|
||||||
|
Dbt kt((void *) key.c_str(), key.length());
|
||||||
|
Dbt dt((void *) data.c_str(), data.length());
|
||||||
|
db->put(0, &kt, &dt, 0);
|
||||||
|
} catch (DbException e) { rethrow(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void delDB(const string & filename, const string & dbname,
|
||||||
|
const string & key)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
auto_ptr<Db2> db = openDB(filename, dbname, false);
|
||||||
|
Dbt kt((void *) key.c_str(), key.length());
|
||||||
|
db->del(0, &kt, 0);
|
||||||
|
} catch (DbException e) { rethrow(e); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void enumDB(const string & filename, const string & dbname,
|
||||||
|
DBPairs & contents)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
|
||||||
|
auto_ptr<Db2> db = openDB(filename, dbname, false);
|
||||||
|
|
||||||
|
Dbc * cursor;
|
||||||
|
db->cursor(0, &cursor, 0);
|
||||||
|
DbcClose cursorCloser(cursor);
|
||||||
|
|
||||||
|
Dbt kt, dt;
|
||||||
|
while (cursor->get(&kt, &dt, DB_NEXT) != DB_NOTFOUND) {
|
||||||
|
string key((char *) kt.get_data(), kt.get_size());
|
||||||
|
string data((char *) dt.get_data(), dt.get_size());
|
||||||
|
contents.push_back(DBPair(key, data));
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (DbException e) { rethrow(e); }
|
||||||
|
}
|
26
src/db.hh
Normal file
26
src/db.hh
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef __DB_H
|
||||||
|
#define __DB_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
typedef pair<string, string> DBPair;
|
||||||
|
typedef list<DBPair> DBPairs;
|
||||||
|
|
||||||
|
void createDB(const string & filename, const string & dbname);
|
||||||
|
|
||||||
|
bool queryDB(const string & filename, const string & dbname,
|
||||||
|
const string & key, string & data);
|
||||||
|
|
||||||
|
void setDB(const string & filename, const string & dbname,
|
||||||
|
const string & key, const string & data);
|
||||||
|
|
||||||
|
void delDB(const string & filename, const string & dbname,
|
||||||
|
const string & key);
|
||||||
|
|
||||||
|
void enumDB(const string & filename, const string & dbname,
|
||||||
|
DBPairs & contents);
|
||||||
|
|
||||||
|
#endif /* !__DB_H */
|
140
src/nix.cc
140
src/nix.cc
|
@ -11,13 +11,12 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include <db_cxx.h>
|
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#include <aterm1.h>
|
#include <aterm1.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
#include "db.hh"
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
|
@ -30,91 +29,7 @@ static string dbNetSources = "netsources";
|
||||||
|
|
||||||
|
|
||||||
static string nixSourcesDir;
|
static string nixSourcesDir;
|
||||||
|
static string nixDB;
|
||||||
|
|
||||||
/* Wrapper classes that ensures that the database is closed upon
|
|
||||||
object destruction. */
|
|
||||||
class Db2 : public Db
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Db2(DbEnv *env, u_int32_t flags) : Db(env, flags) { }
|
|
||||||
~Db2() { close(0); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
class DbcClose
|
|
||||||
{
|
|
||||||
Dbc * cursor;
|
|
||||||
public:
|
|
||||||
DbcClose(Dbc * c) : cursor(c) { }
|
|
||||||
~DbcClose() { cursor->close(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
auto_ptr<Db2> openDB(const string & dbname, bool readonly)
|
|
||||||
{
|
|
||||||
auto_ptr<Db2> db(new Db2(0, 0));
|
|
||||||
|
|
||||||
db->open((nixHomeDir + "/var/nix/pkginfo.db").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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
typedef pair<string, string> DBPair;
|
|
||||||
typedef list<DBPair> DBPairs;
|
|
||||||
|
|
||||||
|
|
||||||
void enumDB(const string & dbname, DBPairs & contents)
|
|
||||||
{
|
|
||||||
auto_ptr<Db2> db = openDB(dbname, false);
|
|
||||||
|
|
||||||
Dbc * cursor;
|
|
||||||
db->cursor(0, &cursor, 0);
|
|
||||||
DbcClose cursorCloser(cursor);
|
|
||||||
|
|
||||||
Dbt kt, dt;
|
|
||||||
while (cursor->get(&kt, &dt, DB_NEXT) != DB_NOTFOUND) {
|
|
||||||
string key((char *) kt.get_data(), kt.get_size());
|
|
||||||
string data((char *) dt.get_data(), dt.get_size());
|
|
||||||
contents.push_back(DBPair(key, data));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Download object referenced by the given URL into the sources
|
/* Download object referenced by the given URL into the sources
|
||||||
|
@ -150,7 +65,7 @@ string getFile(string hash)
|
||||||
|
|
||||||
string fn, url;
|
string fn, url;
|
||||||
|
|
||||||
if (queryDB(dbRefs, hash, fn)) {
|
if (queryDB(nixDB, dbRefs, hash, fn)) {
|
||||||
|
|
||||||
/* Verify that the file hasn't changed. !!! race */
|
/* Verify that the file hasn't changed. !!! race */
|
||||||
if (hashFile(fn) != hash)
|
if (hashFile(fn) != hash)
|
||||||
|
@ -163,7 +78,7 @@ string getFile(string hash)
|
||||||
throw Error("consistency problem: file fetched from " + url +
|
throw Error("consistency problem: file fetched from " + url +
|
||||||
" should have hash " + hash + ", but it doesn't");
|
" should have hash " + hash + ", but it doesn't");
|
||||||
|
|
||||||
if (!queryDB(dbNetSources, hash, url))
|
if (!queryDB(nixDB, dbNetSources, hash, url))
|
||||||
throw Error("a file with hash " + hash + " is requested, "
|
throw Error("a file with hash " + hash + " is requested, "
|
||||||
"but it is not known to exist locally or on the network");
|
"but it is not known to exist locally or on the network");
|
||||||
|
|
||||||
|
@ -171,7 +86,7 @@ string getFile(string hash)
|
||||||
|
|
||||||
fn = fetchURL(url);
|
fn = fetchURL(url);
|
||||||
|
|
||||||
setDB(dbRefs, hash, fn);
|
setDB(nixDB, dbRefs, hash, fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -332,7 +247,7 @@ void installPkg(string hash)
|
||||||
|
|
||||||
/* Try to use a prebuilt. */
|
/* Try to use a prebuilt. */
|
||||||
string prebuiltHash, prebuiltFile;
|
string prebuiltHash, prebuiltFile;
|
||||||
if (queryDB(dbPrebuilts, hash, prebuiltHash)) {
|
if (queryDB(nixDB, dbPrebuilts, hash, prebuiltHash)) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
prebuiltFile = getFile(prebuiltHash);
|
prebuiltFile = getFile(prebuiltHash);
|
||||||
|
@ -398,7 +313,7 @@ build:
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
setDB(dbInstPkgs, hash, path);
|
setDB(nixDB, dbInstPkgs, hash, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -406,7 +321,7 @@ string getPkg(string hash)
|
||||||
{
|
{
|
||||||
string path;
|
string path;
|
||||||
checkHash(hash);
|
checkHash(hash);
|
||||||
while (!queryDB(dbInstPkgs, hash, path))
|
while (!queryDB(nixDB, dbInstPkgs, hash, path))
|
||||||
installPkg(hash);
|
installPkg(hash);
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
@ -470,9 +385,9 @@ void delPkg(string hash)
|
||||||
{
|
{
|
||||||
string path;
|
string path;
|
||||||
checkHash(hash);
|
checkHash(hash);
|
||||||
if (queryDB(dbInstPkgs, hash, path)) {
|
if (queryDB(nixDB, dbInstPkgs, hash, path)) {
|
||||||
int res = system(("chmod -R +w " + path + " && rm -rf " + path).c_str()); // !!! escaping
|
int res = system(("chmod -R +w " + path + " && rm -rf " + path).c_str()); // !!! escaping
|
||||||
delDB(dbInstPkgs, hash); // not a bug ???
|
delDB(nixDB, dbInstPkgs, hash); // not a bug ???
|
||||||
if (WEXITSTATUS(res) != 0)
|
if (WEXITSTATUS(res) != 0)
|
||||||
cerr << "errors deleting " + path + ", ignoring" << endl;
|
cerr << "errors deleting " + path + ", ignoring" << endl;
|
||||||
}
|
}
|
||||||
|
@ -509,7 +424,7 @@ void registerPrebuilt(string pkgHash, string prebuiltHash)
|
||||||
{
|
{
|
||||||
checkHash(pkgHash);
|
checkHash(pkgHash);
|
||||||
checkHash(prebuiltHash);
|
checkHash(prebuiltHash);
|
||||||
setDB(dbPrebuilts, pkgHash, prebuiltHash);
|
setDB(nixDB, dbPrebuilts, pkgHash, prebuiltHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -517,7 +432,7 @@ string registerFile(string filename)
|
||||||
{
|
{
|
||||||
filename = absPath(filename);
|
filename = absPath(filename);
|
||||||
string hash = hashFile(filename);
|
string hash = hashFile(filename);
|
||||||
setDB(dbRefs, hash, filename);
|
setDB(nixDB, dbRefs, hash, filename);
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,7 +440,7 @@ string registerFile(string filename)
|
||||||
void registerURL(string hash, string url)
|
void registerURL(string hash, string url)
|
||||||
{
|
{
|
||||||
checkHash(hash);
|
checkHash(hash);
|
||||||
setDB(dbNetSources, hash, url);
|
setDB(nixDB, dbNetSources, hash, url);
|
||||||
/* !!! currently we allow only one network source per hash */
|
/* !!! currently we allow only one network source per hash */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,18 +450,18 @@ void registerInstalledPkg(string hash, string path)
|
||||||
{
|
{
|
||||||
checkHash(hash);
|
checkHash(hash);
|
||||||
if (path == "")
|
if (path == "")
|
||||||
delDB(dbInstPkgs, hash);
|
delDB(nixDB, dbInstPkgs, hash);
|
||||||
else
|
else
|
||||||
setDB(dbInstPkgs, hash, path);
|
setDB(nixDB, dbInstPkgs, hash, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void initDB()
|
void initDB()
|
||||||
{
|
{
|
||||||
openDB(dbRefs, false);
|
createDB(nixDB, dbRefs);
|
||||||
openDB(dbInstPkgs, false);
|
createDB(nixDB, dbInstPkgs);
|
||||||
openDB(dbPrebuilts, false);
|
createDB(nixDB, dbPrebuilts);
|
||||||
openDB(dbNetSources, false);
|
createDB(nixDB, dbNetSources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -555,7 +470,7 @@ void verifyDB()
|
||||||
/* Check that all file references are still valid. */
|
/* Check that all file references are still valid. */
|
||||||
DBPairs fileRefs;
|
DBPairs fileRefs;
|
||||||
|
|
||||||
enumDB(dbRefs, fileRefs);
|
enumDB(nixDB, dbRefs, fileRefs);
|
||||||
|
|
||||||
for (DBPairs::iterator it = fileRefs.begin();
|
for (DBPairs::iterator it = fileRefs.begin();
|
||||||
it != fileRefs.end(); it++)
|
it != fileRefs.end(); it++)
|
||||||
|
@ -563,18 +478,18 @@ void verifyDB()
|
||||||
try {
|
try {
|
||||||
if (hashFile(it->second) != it->first) {
|
if (hashFile(it->second) != it->first) {
|
||||||
cerr << "file " << it->second << " has changed\n";
|
cerr << "file " << it->second << " has changed\n";
|
||||||
delDB(dbRefs, it->first);
|
delDB(nixDB, dbRefs, it->first);
|
||||||
}
|
}
|
||||||
} catch (BadRefError e) { /* !!! better error check */
|
} catch (BadRefError e) { /* !!! better error check */
|
||||||
cerr << "file " << it->second << " has disappeared\n";
|
cerr << "file " << it->second << " has disappeared\n";
|
||||||
delDB(dbRefs, it->first);
|
delDB(nixDB, dbRefs, it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that all installed packages are still there. */
|
/* Check that all installed packages are still there. */
|
||||||
DBPairs instPkgs;
|
DBPairs instPkgs;
|
||||||
|
|
||||||
enumDB(dbInstPkgs, instPkgs);
|
enumDB(nixDB, dbInstPkgs, instPkgs);
|
||||||
|
|
||||||
for (DBPairs::iterator it = instPkgs.begin();
|
for (DBPairs::iterator it = instPkgs.begin();
|
||||||
it != instPkgs.end(); it++)
|
it != instPkgs.end(); it++)
|
||||||
|
@ -582,7 +497,7 @@ void verifyDB()
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (stat(it->second.c_str(), &st) == -1) {
|
if (stat(it->second.c_str(), &st) == -1) {
|
||||||
cerr << "package " << it->first << " has disappeared\n";
|
cerr << "package " << it->first << " has disappeared\n";
|
||||||
delDB(dbInstPkgs, it->first);
|
delDB(nixDB, dbInstPkgs, it->first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,7 +510,7 @@ void listInstalledPkgs()
|
||||||
{
|
{
|
||||||
DBPairs instPkgs;
|
DBPairs instPkgs;
|
||||||
|
|
||||||
enumDB(dbInstPkgs, instPkgs);
|
enumDB(nixDB, dbInstPkgs, instPkgs);
|
||||||
|
|
||||||
for (DBPairs::iterator it = instPkgs.begin();
|
for (DBPairs::iterator it = instPkgs.begin();
|
||||||
it != instPkgs.end(); it++)
|
it != instPkgs.end(); it++)
|
||||||
|
@ -777,6 +692,7 @@ void run(Strings::iterator argCur, Strings::iterator argEnd)
|
||||||
if (homeDir) nixHomeDir = homeDir;
|
if (homeDir) nixHomeDir = homeDir;
|
||||||
|
|
||||||
nixSourcesDir = nixHomeDir + "/var/nix/sources";
|
nixSourcesDir = nixHomeDir + "/var/nix/sources";
|
||||||
|
nixDB = nixHomeDir + "/var/nix/pkginfo.db";
|
||||||
|
|
||||||
/* Parse the global flags. */
|
/* Parse the global flags. */
|
||||||
for ( ; argCur != argEnd; argCur++) {
|
for ( ; argCur != argEnd; argCur++) {
|
||||||
|
@ -855,12 +771,8 @@ int main(int argc, char * * argv)
|
||||||
|
|
||||||
argCur++;
|
argCur++;
|
||||||
|
|
||||||
try {
|
|
||||||
try {
|
try {
|
||||||
run(argCur, argEnd);
|
run(argCur, argEnd);
|
||||||
} catch (DbException e) {
|
|
||||||
throw Error(e.what());
|
|
||||||
}
|
|
||||||
} catch (UsageError & e) {
|
} catch (UsageError & e) {
|
||||||
cerr << "error: " << e.what() << endl
|
cerr << "error: " << e.what() << endl
|
||||||
<< "Try `nix -h' for more information.\n";
|
<< "Try `nix -h' for more information.\n";
|
||||||
|
|
94
src/util.cc
Normal file
94
src/util.cc
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
#include "util.hh"
|
||||||
|
|
||||||
|
|
||||||
|
string thisSystem = SYSTEM;
|
||||||
|
string nixHomeDir = "/nix";
|
||||||
|
string nixHomeDirEnvVar = "NIX";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
string absPath(string filename, string dir)
|
||||||
|
{
|
||||||
|
if (filename[0] != '/') {
|
||||||
|
if (dir == "") {
|
||||||
|
char buf[PATH_MAX];
|
||||||
|
if (!getcwd(buf, sizeof(buf)))
|
||||||
|
throw Error("cannot get cwd");
|
||||||
|
dir = buf;
|
||||||
|
}
|
||||||
|
filename = dir + "/" + filename;
|
||||||
|
/* !!! canonicalise */
|
||||||
|
char resolved[PATH_MAX];
|
||||||
|
if (!realpath(filename.c_str(), resolved))
|
||||||
|
throw Error("cannot canonicalise path " + filename);
|
||||||
|
filename = resolved;
|
||||||
|
}
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static string printHash(unsigned char * buf)
|
||||||
|
{
|
||||||
|
ostringstream str;
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
str.fill('0');
|
||||||
|
str.width(2);
|
||||||
|
str << hex << (int) buf[i];
|
||||||
|
}
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Verify that a reference is valid (that is, is a MD5 hash code). */
|
||||||
|
bool isHash(const string & s)
|
||||||
|
{
|
||||||
|
if (s.length() != 32) return false;
|
||||||
|
for (int i = 0; i < 32; i++) {
|
||||||
|
char c = s[i];
|
||||||
|
if (!((c >= '0' && c <= '9') ||
|
||||||
|
(c >= 'a' && c <= 'f')))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkHash(const string & s)
|
||||||
|
{
|
||||||
|
if (!isHash(s)) throw BadRefError("invalid reference: " + s);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Compute the MD5 hash of a file. */
|
||||||
|
string hashFile(string filename)
|
||||||
|
{
|
||||||
|
unsigned char hash[16];
|
||||||
|
FILE * file = fopen(filename.c_str(), "rb");
|
||||||
|
if (!file)
|
||||||
|
throw BadRefError("file `" + filename + "' does not exist");
|
||||||
|
int err = md5_stream(file, hash);
|
||||||
|
fclose(file);
|
||||||
|
if (err) throw BadRefError("cannot hash file");
|
||||||
|
return printHash(hash);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the directory part of the given path, i.e., everything
|
||||||
|
before the final `/'. */
|
||||||
|
string dirOf(string s)
|
||||||
|
{
|
||||||
|
unsigned int pos = s.rfind('/');
|
||||||
|
if (pos == string::npos) throw Error("invalid file name");
|
||||||
|
return string(s, 0, pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Return the base name of the given path, i.e., everything following
|
||||||
|
the final `/'. */
|
||||||
|
string baseNameOf(string s)
|
||||||
|
{
|
||||||
|
unsigned int pos = s.rfind('/');
|
||||||
|
if (pos == string::npos) throw Error("invalid file name");
|
||||||
|
return string(s, pos + 1);
|
||||||
|
}
|
100
src/util.hh
100
src/util.hh
|
@ -39,104 +39,22 @@ public:
|
||||||
typedef vector<string> Strings;
|
typedef vector<string> Strings;
|
||||||
|
|
||||||
|
|
||||||
/* !!! the following shouldn't be here; abuse of the preprocessor */
|
|
||||||
|
|
||||||
|
|
||||||
/* The canonical system name, as returned by config.guess. */
|
/* The canonical system name, as returned by config.guess. */
|
||||||
static string thisSystem = SYSTEM;
|
extern string thisSystem;
|
||||||
|
|
||||||
|
|
||||||
/* The prefix of the Nix installation, and the environment variable
|
/* The prefix of the Nix installation, and the environment variable
|
||||||
that can be used to override the default. */
|
that can be used to override the default. */
|
||||||
static string nixHomeDir = "/nix";
|
extern string nixHomeDir;
|
||||||
static string nixHomeDirEnvVar = "NIX";
|
extern string nixHomeDirEnvVar;
|
||||||
|
|
||||||
|
|
||||||
string absPath(string filename, string dir = "")
|
string absPath(string filename, string dir = "");
|
||||||
{
|
bool isHash(const string & s);
|
||||||
if (filename[0] != '/') {
|
void checkHash(const string & s);
|
||||||
if (dir == "") {
|
string hashFile(string filename);
|
||||||
char buf[PATH_MAX];
|
string dirOf(string s);
|
||||||
if (!getcwd(buf, sizeof(buf)))
|
string baseNameOf(string s);
|
||||||
throw Error("cannot get cwd");
|
|
||||||
dir = buf;
|
|
||||||
}
|
|
||||||
filename = dir + "/" + filename;
|
|
||||||
/* !!! canonicalise */
|
|
||||||
char resolved[PATH_MAX];
|
|
||||||
if (!realpath(filename.c_str(), resolved))
|
|
||||||
throw Error("cannot canonicalise path " + filename);
|
|
||||||
filename = resolved;
|
|
||||||
}
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
string printHash(unsigned char * buf)
|
|
||||||
{
|
|
||||||
ostringstream str;
|
|
||||||
for (int i = 0; i < 16; i++) {
|
|
||||||
str.fill('0');
|
|
||||||
str.width(2);
|
|
||||||
str << hex << (int) buf[i];
|
|
||||||
}
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Verify that a reference is valid (that is, is a MD5 hash code). */
|
|
||||||
bool isHash(const string & s)
|
|
||||||
{
|
|
||||||
if (s.length() != 32) return false;
|
|
||||||
for (int i = 0; i < 32; i++) {
|
|
||||||
char c = s[i];
|
|
||||||
if (!((c >= '0' && c <= '9') ||
|
|
||||||
(c >= 'a' && c <= 'f')))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void checkHash(const string & s)
|
|
||||||
{
|
|
||||||
if (!isHash(s)) throw BadRefError("invalid reference: " + s);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Compute the MD5 hash of a file. */
|
|
||||||
string hashFile(string filename)
|
|
||||||
{
|
|
||||||
unsigned char hash[16];
|
|
||||||
FILE * file = fopen(filename.c_str(), "rb");
|
|
||||||
if (!file)
|
|
||||||
throw BadRefError("file `" + filename + "' does not exist");
|
|
||||||
int err = md5_stream(file, hash);
|
|
||||||
fclose(file);
|
|
||||||
if (err) throw BadRefError("cannot hash file");
|
|
||||||
return printHash(hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the directory part of the given path, i.e., everything
|
|
||||||
before the final `/'. */
|
|
||||||
string dirOf(string s)
|
|
||||||
{
|
|
||||||
unsigned int pos = s.rfind('/');
|
|
||||||
if (pos == string::npos) throw Error("invalid file name");
|
|
||||||
return string(s, 0, pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return the base name of the given path, i.e., everything following
|
|
||||||
the final `/'. */
|
|
||||||
string baseNameOf(string s)
|
|
||||||
{
|
|
||||||
unsigned int pos = s.rfind('/');
|
|
||||||
if (pos == string::npos) throw Error("invalid file name");
|
|
||||||
return string(s, pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* !__UTIL_H */
|
#endif /* !__UTIL_H */
|
||||||
|
|
Loading…
Reference in a new issue