Manage files and directories

This commit is contained in:
Andreas Steffen
2013-06-21 23:25:21 +02:00
parent b61c78d3c2
commit 1f179c63b3
4 changed files with 213 additions and 127 deletions
+32 -5
View File
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2012 Andreas Steffen
* Copyright (C) 2011-2013 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -20,6 +20,7 @@
#include <string.h>
#include <errno.h>
#include <syslog.h>
#include <libgen.h>
#include <library.h>
#include <utils/debug.h>
@@ -81,6 +82,7 @@ static void attest_dbg(debug_t group, level_t level, char *fmt, ...)
*/
attest_db_t *attest;
/**
* atexit handler to close db on shutdown
*/
@@ -100,6 +102,7 @@ static void do_args(int argc, char *argv[])
OP_KEYS,
OP_COMPONENTS,
OP_DEVICES,
OP_DIRECTORIES,
OP_FILES,
OP_HASHES,
OP_MEASUREMENTS,
@@ -120,6 +123,8 @@ static void do_args(int argc, char *argv[])
{ "help", no_argument, NULL, 'h' },
{ "components", no_argument, NULL, 'c' },
{ "devices", no_argument, NULL, 'e' },
{ "directories", no_argument, NULL, 'd' },
{ "dirs", no_argument, NULL, 'd' },
{ "files", no_argument, NULL, 'f' },
{ "keys", no_argument, NULL, 'k' },
{ "packages", no_argument, NULL, 'g' },
@@ -127,8 +132,9 @@ static void do_args(int argc, char *argv[])
{ "hashes", no_argument, NULL, 'H' },
{ "measurements", no_argument, NULL, 'm' },
{ "add", no_argument, NULL, 'a' },
{ "delete", no_argument, NULL, 'd' },
{ "del", no_argument, NULL, 'd' },
{ "delete", no_argument, NULL, 'r' },
{ "del", no_argument, NULL, 'r' },
{ "remove", no_argument, NULL, 'r' },
{ "aik", required_argument, NULL, 'A' },
{ "blacklist", no_argument, NULL, 'B' },
{ "component", required_argument, NULL, 'C' },
@@ -171,6 +177,9 @@ static void do_args(int argc, char *argv[])
case 'c':
op = OP_COMPONENTS;
continue;
case 'd':
op = OP_DIRECTORIES;
continue;
case 'e':
op = OP_DEVICES;
continue;
@@ -195,7 +204,7 @@ static void do_args(int argc, char *argv[])
case 'a':
op = OP_ADD;
continue;
case 'd':
case 'r':
op = OP_DEL;
continue;
case 'A':
@@ -251,11 +260,26 @@ static void do_args(int argc, char *argv[])
}
continue;
case 'F':
if (!attest->set_file(attest, optarg, op == OP_ADD))
{
char *path = strdup(optarg);
char *dir = dirname(path);
char *file = basename(optarg);
if (*dir != '.')
{
if (!attest->set_directory(attest, dir, op == OP_ADD))
{
free(path);
exit(EXIT_FAILURE);
}
}
free(path);
if (!attest->set_file(attest, file, op == OP_ADD))
{
exit(EXIT_FAILURE);
}
continue;
}
case 'G':
if (!attest->set_package(attest, optarg, op == OP_ADD))
{
@@ -372,6 +396,9 @@ static void do_args(int argc, char *argv[])
case OP_DEVICES:
attest->list_devices(attest);
break;
case OP_DIRECTORIES:
attest->list_directories(attest);
break;
case OP_FILES:
attest->list_files(attest);
break;
+152 -89
View File
@@ -62,11 +62,6 @@ struct private_attest_db_t {
*/
int did;
/**
* TRUE if directory has been set
*/
bool dir_set;
/**
* Measurement file to be queried
*/
@@ -77,11 +72,6 @@ struct private_attest_db_t {
*/
int fid;
/**
* TRUE if file has been set
*/
bool file_set;
/**
* AIK to be queried
*/
@@ -304,35 +294,35 @@ METHOD(attest_db_t, set_directory, bool,
private_attest_db_t *this, char *dir, bool create)
{
enumerator_t *e;
int did;
size_t len;
if (this->dir_set)
if (this->did)
{
printf("directory has already been set\n");
return FALSE;
}
free(this->dir);
/* remove trailing '/' character */
/* remove trailing '/' character if not root directory */
len = strlen(dir);
if (len && dir[len-1] == '/')
if (len > 1 && dir[len-1] == '/')
{
dir[len-1] = '\0';
}
this->dir = strdup(dir);
e = this->db->query(this->db,
"SELECT id FROM files WHERE type = 1 AND path = ?",
"SELECT id FROM directories WHERE path = ?",
DB_TEXT, dir, DB_INT);
if (e)
{
if (e->enumerate(e, &this->did))
if (e->enumerate(e, &did))
{
this->dir_set = TRUE;
this->did = did;
}
e->destroy(e);
}
if (this->dir_set)
if (this->did)
{
return TRUE;
}
@@ -344,14 +334,15 @@ METHOD(attest_db_t, set_directory, bool,
}
/* Add a new database entry */
this->dir_set = this->db->execute(this->db, &this->did,
"INSERT INTO files (type, path) VALUES (1, ?)",
DB_TEXT, dir) == 1;
if (1 == this->db->execute(this->db, &did,
"INSERT INTO directories (path) VALUES (?)", DB_TEXT, dir))
{
this->did = did;
}
printf("directory '%s' %sinserted into database\n", dir,
this->dir_set ? "" : "could not be ");
this->did ? "" : "could not be ");
return this->dir_set;
return this->did > 0;
}
METHOD(attest_db_t, set_did, bool,
@@ -360,22 +351,20 @@ METHOD(attest_db_t, set_did, bool,
enumerator_t *e;
char *dir;
if (this->dir_set)
if (this->did)
{
printf("directory has already been set\n");
return FALSE;
}
this->did = did;
e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
e = this->db->query(this->db, "SELECT path FROM directories WHERE id = ?",
DB_UINT, did, DB_TEXT);
if (e)
{
if (e->enumerate(e, &dir))
{
free(this->dir);
this->dir = strdup(dir);
this->dir_set = TRUE;
this->did = did;
}
else
{
@@ -383,76 +372,88 @@ METHOD(attest_db_t, set_did, bool,
}
e->destroy(e);
}
return this->dir_set;
return this->did > 0;
}
METHOD(attest_db_t, set_file, bool,
private_attest_db_t *this, char *file, bool create)
{
int fid;
char *sep;
enumerator_t *e;
char *filename;
if (this->file_set)
if (this->file)
{
printf("file has already been set\n");
return FALSE;
}
this->file = strdup(file);
filename = this->relative ? basename(file) : file;
e = this->db->query(this->db, "SELECT id FROM files WHERE path = ?",
DB_TEXT, filename, DB_INT);
if (!this->did)
{
return TRUE;
}
sep = streq(this->dir, "/") ? "" : "/";
e = this->db->query(this->db, "SELECT id FROM files "
"WHERE dir = ? AND name = ?",
DB_INT, this->did, DB_TEXT, file, DB_INT);
if (e)
{
if (e->enumerate(e, &this->fid))
if (e->enumerate(e, &fid))
{
this->file_set = TRUE;
this->fid = fid;
}
e->destroy(e);
}
if (this->file_set)
if (this->fid)
{
return TRUE;
}
if (!create)
{
printf("file '%s' not found in database\n", file);
printf("file '%s%s%s' not found in database\n", this->dir, sep, file);
return FALSE;
}
/* Add a new database entry */
this->file_set = this->db->execute(this->db, &this->fid,
"INSERT INTO files (type, path) VALUES (0, ?)",
DB_TEXT, filename) == 1;
if (1 == this->db->execute(this->db, &fid,
"INSERT INTO files (dir, name) VALUES (?, ?)",
DB_INT, this->did, DB_TEXT, file))
{
this->fid = fid;
}
printf("file '%s%s%s' %sinserted into database\n", this->dir, sep, file,
this->fid ? "" : "could not be ");
printf("file '%s' %sinserted into database\n", filename,
this->file_set ? "" : "could not be ");
return this->file_set;
return this->fid > 0;
}
METHOD(attest_db_t, set_fid, bool,
private_attest_db_t *this, int fid)
{
enumerator_t *e;
int did;
char *file;
if (this->file_set)
if (this->fid)
{
printf("file has already been set\n");
return FALSE;
}
this->fid = fid;
e = this->db->query(this->db, "SELECT path FROM files WHERE id = ?",
DB_UINT, fid, DB_TEXT);
e = this->db->query(this->db, "SELECT dir, name FROM files WHERE id = ?",
DB_UINT, fid, DB_INT, DB_TEXT);
if (e)
{
if (e->enumerate(e, &file))
if (e->enumerate(e, &did, &file))
{
if (did)
{
set_did(this, did);
}
this->file = strdup(file);
this->file_set = TRUE;
this->fid = fid;
}
else
{
@@ -460,7 +461,7 @@ METHOD(attest_db_t, set_fid, bool,
}
e->destroy(e);
}
return this->file_set;
return this->fid > 0;
}
METHOD(attest_db_t, set_key, bool,
@@ -920,53 +921,92 @@ METHOD(attest_db_t, list_files, void,
private_attest_db_t *this)
{
enumerator_t *e;
char *file, *file_type[] = { " ", "d", "r" };
int fid, type, meas, meta, count = 0;
char *dir, *file;
int did, last_did = 0, fid, count = 0;
if (this->pid)
if (this->did)
{
e = this->db->query(this->db,
"SELECT f.id, f.type, f.path, pf.measurement, pf.metadata "
"FROM files AS f "
"JOIN product_file AS pf ON f.id = pf.file "
"WHERE pf.product = ? ORDER BY f.path",
DB_UINT, this->pid, DB_INT, DB_INT, DB_TEXT, DB_INT, DB_INT);
"SELECT id, name FROM files WHERE dir = ? ORDER BY name",
DB_INT, this->did, DB_INT, DB_TEXT);
if (e)
{
while (e->enumerate(e, &fid, &type, &file, &meas, &meta))
while (e->enumerate(e, &fid, &file))
{
type = (type < 0 || type > 2) ? 0 : type;
printf("%4d: |%s%s| %s %s\n", fid, meas ? "M":" ", meta ? "T":" ",
file_type[type], file);
printf("%4d: %s\n", fid, file);
count++;
}
e->destroy(e);
}
printf("%d file%s found in directory '%s'\n", count,
(count == 1) ? "" : "s", this->dir);
}
else
{
e = this->db->query(this->db,
"SELECT id, type, path FROM files "
"ORDER BY path",
DB_INT, DB_INT, DB_TEXT);
"SELECT d.id, d.path, f.id, f.name FROM files AS f "
"JOIN directories AS d ON f.dir = d.id "
"ORDER BY d.path, f.name",
DB_INT, DB_TEXT, DB_INT, DB_TEXT);
if (e)
{
while (e->enumerate(e, &fid, &type, &file))
while (e->enumerate(e, &did, &dir, &fid, &file))
{
type = (type < 0 || type > 2) ? 0 : type;
printf("%4d: %s %s\n", fid, file_type[type], file);
if (did != last_did)
{
printf("%4d: %s\n", did, dir);
last_did = did;
}
printf("%4d: %s\n", fid, file);
count++;
}
e->destroy(e);
}
printf("%d file%s found\n", count, (count == 1) ? "" : "s");
}
}
printf("%d file%s found", count, (count == 1) ? "" : "s");
if (this->product_set)
METHOD(attest_db_t, list_directories, void,
private_attest_db_t *this)
{
enumerator_t *e;
char *dir;
int did, count = 0;
if (this->file)
{
printf(" for product '%s'", this->product);
e = this->db->query(this->db,
"SELECT d.id, d.path FROM directories AS d "
"JOIN files AS f ON f.dir = d.id WHERE f.name = ? "
"ORDER BY path", DB_TEXT, this->file, DB_INT, DB_TEXT);
if (e)
{
while (e->enumerate(e, &did, &dir))
{
printf("%4d: %s\n", did, dir);
count++;
}
e->destroy(e);
}
printf("%d director%s found containing file '%s'\n", count,
(count == 1) ? "y" : "ies", this->file);
}
else
{
e = this->db->query(this->db,
"SELECT id, path FROM directories ORDER BY path",
DB_INT, DB_TEXT);
if (e)
{
while (e->enumerate(e, &did, &dir))
{
printf("%4d: %s\n", did, dir);
count++;
}
e->destroy(e);
}
printf("%d director%s found\n", count, (count == 1) ? "y" : "ies");
}
printf("\n");
}
METHOD(attest_db_t, list_packages, void,
@@ -1077,7 +1117,7 @@ METHOD(attest_db_t, list_products, void,
}
printf("%d product%s found", count, (count == 1) ? "" : "s");
if (this->file_set)
if (this->fid)
{
printf(" for file '%s'", this->file);
}
@@ -1607,6 +1647,9 @@ METHOD(attest_db_t, delete, bool,
private_attest_db_t *this)
{
bool success;
int id, count = 0;
char *name;
enumerator_t *e;
/* delete a file measurement hash for a given product */
if (this->algo && this->pid && this->fid)
@@ -1667,24 +1710,44 @@ METHOD(attest_db_t, delete, bool,
return success;
}
if (this->did)
{
success = this->db->execute(this->db, NULL,
"DELETE FROM files WHERE type = 1 AND id = ?",
DB_UINT, this->did) > 0;
printf("directory '%s' %sdeleted from database\n", this->dir,
success ? "" : "could not be ");
return success;
}
if (this->fid)
{
success = this->db->execute(this->db, NULL,
"DELETE FROM files WHERE id = ?",
DB_UINT, this->fid) > 0;
printf("file '%s' %sdeleted from database\n", this->file,
printf("file '%s%s%s' %sdeleted from database\n", this->dir,
streq(this->dir, "/") ? "" : "/", this->file,
success ? "" : "could not be ");
return success;
}
if (this->did)
{
e = this->db->query(this->db,
"SELECT id, name FROM files WHERE dir = ? ORDER BY name",
DB_INT, this->did, DB_INT, DB_TEXT);
if (e)
{
while (e->enumerate(e, &id, &name))
{
printf("%4d: %s\n", id, name);
count++;
}
e->destroy(e);
if (count)
{
printf("%d dependent file%s found, "
"directory '%s' could not deleted\n",
count, (count == 1) ? "" : "s", this->dir);
return FALSE;
}
}
success = this->db->execute(this->db, NULL,
"DELETE FROM directories WHERE id = ?",
DB_UINT, this->did) > 0;
printf("directory '%s' %sdeleted from database\n", this->dir,
success ? "" : "could not be ");
return success;
}
@@ -1760,6 +1823,7 @@ attest_db_t *attest_db_create(char *uri)
.list_packages = _list_packages,
.list_products = _list_products,
.list_files = _list_files,
.list_directories = _list_directories,
.list_components = _list_components,
.list_devices = _list_devices,
.list_keys = _list_keys,
@@ -1769,7 +1833,6 @@ attest_db_t *attest_db_create(char *uri)
.delete = _delete,
.destroy = _destroy,
},
.dir = strdup(""),
.db = lib->db->create(lib->db, uri),
);
@@ -192,6 +192,11 @@ struct attest_db_t {
*/
void (*list_products)(attest_db_t *this);
/**
* List all directories stored in the database
*/
void (*list_directories)(attest_db_t *this);
/**
* List selected files stored in the database
*/
+24 -33
View File
@@ -1,14 +1,24 @@
/* PTS SQLite database */
DROP TABLE IF EXISTS directories;
CREATE TABLE directories (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
path TEXT NOT NULL
);
DROP INDEX IF EXISTS directories_path;
CREATE INDEX directories_path ON directories (
path
);
DROP TABLE IF EXISTS files;
CREATE TABLE files (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
type INTEGER NOT NULL,
path TEXT NOT NULL
dir INTEGER DEFAULT 0,
name TEXT NOT NULL
);
DROP INDEX IF EXISTS files_path;
CREATE INDEX files_path ON files (
path
DROP INDEX IF EXISTS files_name;
CREATE INDEX files_name ON files (
name
);
DROP TABLE IF EXISTS products;
@@ -21,39 +31,20 @@ CREATE INDEX products_name ON products (
name
);
DROP TABLE IF EXISTS product_file;
CREATE TABLE product_file (
product INTEGER NOT NULL,
file INTEGER NOT NULL,
measurement INTEGER DEFAULT 0,
metadata INTEGER DEFAULT 0,
PRIMARY KEY (product, file)
DROP TABLE IF EXISTS algorithms;
CREATE TABLE algorithms (
id INTEGER PRIMARY KEY,
name TEXT not NULL
);
DROP TABLE IF EXISTS file_hashes;
CREATE TABLE file_hashes (
file INTEGER NOT NULL,
directory INTEGER DEFAULT 0,
product INTEGER NOT NULL,
key INTEGER DEFAULT 0,
algo INTEGER NOT NULL,
hash BLOB NOT NULL,
PRIMARY KEY(file, directory, product, algo)
);
DROP TABLE IF EXISTS keys;
CREATE TABLE keys (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
keyid BLOB NOT NULL,
owner TEXT NOT NULL
);
DROP INDEX IF EXISTS keys_keyid;
CREATE INDEX keys_keyid ON keys (
keyid
);
DROP INDEX IF EXISTS keys_owner;
CREATE INDEX keys_owner ON keys (
owner
file INTEGER NOT NULL,
product INTEGER NOT NULL,
device INTEGER DEFAULT 0,
algo INTEGER NOT NULL,
hash BLOB NOT NULL
);
DROP TABLE IF EXISTS components;