File IO exceptions added and database access improved

This commit is contained in:
Christian 2006-06-06 22:17:16 +02:00
parent 7066a59eaa
commit 37eb802e14
9 changed files with 131 additions and 84 deletions

View File

@ -1,5 +1,6 @@
#include "db.h"
#include "base.h"
#include "exception.h"
#ifdef __WIN32__
#include <windows.h>
#else
@ -20,11 +21,7 @@ db::db(QString filename, int mode)
name = filename;
fd = open(CCHAR(filename), O_RDWR | O_CREAT, mode);
if (fd<0) {
errstr = QString("DB open() failed: ") + filename +" "+
strerror(errno);
dberrno = errno;
perror(CCHAR(filename));
fileIOerr("open");
} else {
first();
}
@ -36,6 +33,13 @@ db::~db()
close(fd);
}
void db::fileIOerr(QString s)
{
errstr = QString("DB ") + s + "() '" + name + "'";
dberrno = errno;
throw errorEx(errstr, strerror(errno));
}
void db::init_header(db_header_t *db, int ver, int len, enum pki_type type,
const char *name)
{
@ -74,10 +78,8 @@ bool db::verify_magic(void)
int db::find(enum pki_type type, const char *name)
{
//int len, ret=0;
if (head_offset == OFF_EOF)
return 1;
do {
while (head_offset != OFF_EOF) {
//printf("Comparing %s -> %s at %lu\n", head.name, name,
//head_offset);
if (ntohs(head.type) == type) {
@ -92,8 +94,8 @@ int db::find(enum pki_type type, const char *name)
if (!verify_magic()) {
return -1;
}
} while (next() == 0);
next();
}
//printf("Returning 1\n");
return 1;
}
@ -104,7 +106,9 @@ void db::first(void)
memset(&head, 0, sizeof(db_header_t) );
head_offset = lseek(fd, 0, SEEK_SET );
ret = read(fd, &head, sizeof(db_header_t) );
if (ret<=0) {
if (ret < 0 )
fileIOerr("read");
if (ret==0) {
head_offset = OFF_EOF;
return;
}
@ -129,7 +133,7 @@ int db::next(void)
return 1;
}
if (ret < 0) {
printf("read() failed: %s\n", strerror(errno));
fileIOerr("read");
return -1;
}
if (ret != sizeof(db_header_t)) {
@ -169,6 +173,9 @@ int db::rename(enum pki_type type, const char *name, const char *n)
head.name[NAMELEN-1] = '\0';
lseek(fd, head_offset, SEEK_SET);
ret = write(fd, &head, sizeof(head));
if (ret < 0) {
fileIOerr("write");
}
if (ret != sizeof(head)) {
printf("DB: Write error %d - %d\n", ret, sizeof(head));
return -1;
@ -203,11 +210,11 @@ int db::add(const unsigned char *p, int len, int ver, enum pki_type type,
lseek(fd, 0, SEEK_END);
if (write(fd, &db, sizeof(db)) != sizeof(db)) {
printf("write() failed\n");
fileIOerr("write");
return -1;
}
if (write(fd, p, len) != len) {
printf("write() failed\n");
fileIOerr("write");
return -1;
}
return 0;
@ -225,9 +232,9 @@ int db::set(const unsigned char *p, int len, int ver, enum pki_type type,
return add(p, len, ver, type, name);
}
if (ret == 0) {
printf("offs = %x, len=%d, head.len=%d name = %s flags=%x\n",
head_offset, len, ntohl(head.len), head.name,
ntohs(head.flags));
//printf("offs = %x, len=%d, head.len=%d name = %s flags=%x\n",
// head_offset, len, ntohl(head.len), head.name,
// ntohs(head.flags));
lseek(fd, head_offset, SEEK_SET);
if (len != ntohl(head.len) - sizeof(db_header_t)) {
//printf("## Found and len unequal %d, %d\n",
@ -239,14 +246,15 @@ int db::set(const unsigned char *p, int len, int ver, enum pki_type type,
if (write(fd, &head, sizeof(db_header_t)) !=
sizeof(db_header_t))
{
printf("erasing of %s at failed\n", head.name);
dberrno = errno;
fileIOerr("write");
return -1;
}
if (add(p, len, ver, type, name) < 0) {
lseek(fd, head_offset, SEEK_SET);
head.flags = flags;
write(fd, &head, sizeof(db_header_t));
ret = write(fd, &head, sizeof(db_header_t));
if (ret != sizeof(db_header_t))
fileIOerr("write");
}
return 0;
}
@ -254,11 +262,11 @@ int db::set(const unsigned char *p, int len, int ver, enum pki_type type,
head.version = htons(ver);
if (write(fd, &head, sizeof(db_header_t)) !=
sizeof(db_header_t)) {
printf("write() failed\n");
fileIOerr("write");
return -1;
}
if (write(fd, p, len) != len) {
printf("write() failed\n");
fileIOerr("write");
return -1;
}
}
@ -284,8 +292,8 @@ unsigned char *db::load(db_header_t *u_header)
return data;
} else {
printf("read of %u bytes failed: %d\n", size, ret);
free(data);
fileIOerr("read");
return NULL;
}
}
@ -299,8 +307,7 @@ int db::erase(void)
lseek(fd, head_offset, SEEK_SET);
if (write(fd, &head, sizeof(db_header_t)) != sizeof(db_header_t)) {
printf("erasing of %s at %u failed\n", head.name, head_offset);
dberrno = errno;
fileIOerr("write");
return -1;
}
return 0;
@ -308,15 +315,14 @@ int db::erase(void)
int db::shrink(int flags)
{
int fdn, ret, i=0;
int fdn, ret;
uint32_t offs;
char buf[BUFSIZ];
QString filename = name + "{new}";
fdn = open(CCHAR(filename), O_RDWR | O_CREAT, 0644);
if (fdn<0) {
errstr = QString("open() failed: ") + filename +" "+
strerror(errno);
fileIOerr("open");
return 1;
}
lseek(fd, 0, SEEK_SET);
@ -328,9 +334,9 @@ int db::shrink(int flags)
if ((ntohs(head.flags) & flags)) {
//printf("Skip Entry\n");
/* FF to the next entry */
offs = (int)lseek(fd, head_offset, SEEK_CUR);
offs = lseek(fd, head_offset, SEEK_CUR);
//printf("Seeking to %d\n", offs);
if (head_offset == (uint32_t)-1)
if (head_offset == -1)
break;
continue;
}

View File

@ -49,6 +49,7 @@ class db
const char *name);
bool verify_magic(void);
void convert_header(db_header_t *h);
void fileIOerr(QString s);
public:
off_t head_offset;

View File

@ -93,9 +93,7 @@ void db_base::remFromCont(QModelIndex &idx)
if (!idx.isValid())
return;
pki_base *pki = static_cast<pki_base*>(idx.internalPointer());
printf("PKI=%p\n", pki);
pki_base *parent_pki = pki->getParent();
printf("PKI=%p, parent=%p\n", pki,parent_pki);
int row = pki->row();
beginRemoveRows(parent(idx), row, row);
@ -106,7 +104,7 @@ void db_base::remFromCont(QModelIndex &idx)
void db_base::loadContainer()
{
db mydb(dbName);
unsigned char *p;
unsigned char *p = NULL;
db_header_t head;
pki_base *pb, *pki;
@ -116,14 +114,14 @@ void db_base::loadContainer()
p = mydb.load(&head);
if (!p) {
printf("Load was empty !\n");
break;
goto next;
}
//printf("load item: %s\n",head.name);
if (pb->getVersion() < head.version) {
free(p);
printf("Item[%s]: Version %d > known version: %d -> ignored\n",
head.name, head.version, pb->getVersion() );
continue;
goto next;
}
pki = newPKI();
s = head.name;
@ -133,12 +131,14 @@ void db_base::loadContainer()
pki->fromData(p, &head);
}
catch (errorEx &err) {
err.appendString(s);
mainwin->Error(err);
delete pki;
pki = NULL;
}
if (pki)
inToCont(pki);
next:
if (mydb.next())
break;
}

View File

@ -59,15 +59,32 @@ class errorEx
private:
QString msg;
public:
errorEx(QString txt, QString className = "") {
errorEx(QString txt, QString className = "")
{
msg = txt;
if (!className.isEmpty())
msg += " (" + className + ")";
}
errorEx(const errorEx &e) { msg = e.msg; }
QString getString() const {return msg;}
const char *getCString() const {return msg.toAscii();}
bool isEmpty() const { return msg.isEmpty();}
errorEx(const errorEx &e)
{
msg = e.msg;
}
void appendString(QString s)
{
msg = msg + " " + s;
}
QString getString() const
{
return msg;
}
const char *getCString() const
{
return msg.toAscii();
}
bool isEmpty() const
{
return msg.isEmpty();
}
};
#endif

View File

@ -9,7 +9,7 @@
<x>0</x>
<y>0</y>
<width>506</width>
<height>289</height>
<height>362</height>
</rect>
</property>
<property name="windowTitle" >
@ -17,7 +17,7 @@
</property>
<layout class="QHBoxLayout" >
<property name="margin" >
<number>8</number>
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
@ -35,7 +35,7 @@
</property>
<layout class="QVBoxLayout" >
<property name="margin" >
<number>8</number>
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
@ -68,6 +68,13 @@
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="butDetails" >
<property name="text" >
<string>Details</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation" >
@ -79,7 +86,7 @@
<property name="sizeHint" >
<size>
<width>204</width>
<height>16</height>
<height>21</height>
</size>
</property>
</spacer>

View File

@ -48,32 +48,27 @@
#include "MainWindow.h"
#include "lib/exception.h"
#include <Qt/qdir.h>
#include <Qt/qstatusbar.h>
void MainWindow::init_database()
{
initPass();
fprintf(stderr, "Opening database: %s\n", CCHAR(dbfile));
keys = new db_key(dbfile, this);
reqs = new db_x509req(dbfile, this);
certs = new db_x509(dbfile, this);
temps = new db_temp(dbfile, this);
crls = new db_crl(dbfile, this);
#if 0
certs = new db_x509(dbenv, dbfile, keys, global_tid, certList);
temps = new db_temp(dbenv, dbfile, global_tid, tempList);
crls = new db_crl(dbenv, dbfile, global_tid, crlList);
reqs->setKeyDb(keys);
certs->setKeyDb(keys);
keys = NULL; reqs = NULL; certs = NULL; temps = NULL; crls = NULL;
try {
initPass();
keys = new db_key(dbfile, this);
reqs = new db_x509req(dbfile, this);
certs = new db_x509(dbfile, this);
temps = new db_temp(dbfile, this);
crls = new db_crl(dbfile, this);
}
catch (errorEx &err) {
Error(err);
return;
}
keyList->setDB(keys);
reqList->setDB(reqs);
certList->setDB(certs);
tempList->setDB(temps);
crlList->setDB(crls);
#endif
connect( keys, SIGNAL(newKey(pki_key *)),
certs, SLOT(newKey(pki_key *)) );
connect( keys, SIGNAL(delKey(pki_key *)),
@ -139,21 +134,34 @@ void MainWindow::close_database()
tempView->setModel(NULL);
crlView->setModel(NULL);
delete(crls);
delete(reqs);
delete(certs);
delete(temps);
delete(keys);
if (crls)
delete(crls);
if (reqs)
delete(reqs);
if (certs)
delete(certs);
if (temps)
delete(temps);
if (keys)
delete(keys);
crls = NULL;
reqs = NULL;
certs = NULL;
temps = NULL;
keys = NULL;
settings = NULL;
db mydb(dbfile);
mydb.shrink( DBFLAG_OUTDATED | DBFLAG_DELETED );
if (!crls)
return;
crls = NULL;
try {
db mydb(dbfile);
mydb.shrink( DBFLAG_OUTDATED | DBFLAG_DELETED );
}
catch (errorEx &err) {
MainWindow::Error(err);
}
}
/* Asymetric Key buttons */
@ -182,12 +190,14 @@ void MainWindow::on_BNexportKey_clicked(void)
if(keys)
keys->storeSelectedItems(keyView);
}
#if 0
void MainWindow::on_keyView_doubleClicked(QModelIndex &m)
{
printf("Key View double clicked\n");
if (keys)
keys->showItem();
}
#endif
void MainWindow::on_BNimportPFX_clicked(void)
{
if(certs)

View File

@ -85,23 +85,24 @@ void MainWindow::load_database()
dlg->setWindowTitle(l.caption);
dlg->setFilters(l.filter);
dlg->setFileMode( QFileDialog::AnyFile );
dlg->setDirectory(getPath());
dlg->setDirectory(baseDir);
if (dlg->exec()) {
fname = dlg->selectedFiles()[0];
setPath(dlg->directory().path());
}
delete dlg;
if (fname.isEmpty())
return;
dbfile = fname;
printf("Before close\n");
close_database();
fprintf(stderr, "Dir: %s, File: %s\n", CCHAR(baseDir), CCHAR(dbfile));
printf("Before init\n");
init_database();
}
void MainWindow::load_def_database()
{
dbfile = DBFILE;
dbfile = baseDir + QDir::separator() + DBFILE;
close_database();
init_database();
}

View File

@ -92,10 +92,10 @@ MainWindow::MainWindow(QWidget *parent )
statusBar()->clearMessage();
setWindowTitle(tr(XCA_TITLE));
dbfile = DBFILE;
force_load = 0;
baseDir = getBaseDir();
dbfile = baseDir + QDir::separator() + DBFILE;
setupUi(this);
@ -118,14 +118,18 @@ MainWindow::MainWindow(QWidget *parent )
init_baseDir();
dbfile = baseDir + QDir::separator() + dbfile;
char *p;
db mydb(dbfile);
if (!mydb.find(setting, "workingdir")) {
if ((p = (char *)mydb.load(NULL))) {
workingdir = p;
free(p);
try {
db mydb(dbfile);
char *p;
if (!mydb.find(setting, "workingdir")) {
if ((p = (char *)mydb.load(NULL))) {
workingdir = p;
free(p);
}
}
} catch (errorEx &err) {
Error(err);
return;
}
init_database();
}
@ -156,7 +160,8 @@ NIDlist *MainWindow::read_nidlist(QString name)
void MainWindow::init_baseDir()
{
static bool done = false;
if (done) return;
if (done)
return;
fprintf(stderr, "base Dir: %s\n", CCHAR(baseDir));
QDir d(baseDir);
if ( ! d.exists() && !d.mkdir(baseDir)) {

View File

@ -123,7 +123,7 @@ class MainWindow: public QMainWindow, private Ui::MainWindow
void help();
private slots:
void on_keyView_doubleClicked(QModelIndex &m);
//void on_keyView_doubleClicked(QModelIndex &m);
void on_BNnewKey_clicked(void);
void on_BNdeleteKey_clicked(void);