cdesktopenv/cde/lib/tt/bin/ttdbserverd/tt_db_server_db.C

1928 lines
52 KiB
C

/*
* CDE - Common Desktop Environment
*
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these libraries and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*/
//%% (c) Copyright 1993, 1994 Hewlett-Packard Company
//%% (c) Copyright 1993, 1994 International Business Machines Corp.
//%% (c) Copyright 1993, 1994 Sun Microsystems, Inc.
//%% (c) Copyright 1993, 1994 Novell, Inc.
//%% $TOG: tt_db_server_db.C /main/4 1999/09/23 15:12:26 mgreess $
/*
* tt_db_server_db.cc - Defines the TT DB server database.
*
* Copyright (c) 1992 by Sun Microsystems, Inc.
*/
#include <string.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <netdb.h>
#include <sys/param.h>
#include <netinet/in.h>
#include "util/tt_port.h"
#include "util/tt_gettext.h"
#include "tt_db_server_consts.h"
#include "tt_db_server_db.h"
#include "db/tt_db_create_objid.h"
#include "db/tt_db_property.h"
#include "db/tt_db_access.h"
extern FILE *errstr;
_Tt_db_server_db::_Tt_db_server_db ()
{
_Tt_string partition = "/";
connectToDB(partition);
}
_Tt_db_server_db::_Tt_db_server_db (const _Tt_string &partition)
{
connectToDB(partition);
}
void _Tt_db_server_db::connectToDB (const _Tt_string &partition)
{
dbResults = TT_DB_OK;
dbPartition = partition;
dbHostname = _tt_gethostname();
_Tt_string base_dir = partition;
if (base_dir[base_dir.len()-1] != '/') {
base_dir = base_dir.cat("/");
}
base_dir = base_dir.cat("TT_DB/");
// If mkdir fails, don't worry about it. The problem will be caught
// when NetISAM tries to open the table file.
(void)mkdir(GNU_STRCAST base_dir, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
_Tt_string file_table_file(TT_DB_FILE_TABLE_FILE);
file_table_file = base_dir.cat(file_table_file);
_Tt_string file_object_map_file(TT_DB_FILE_OBJECT_MAP_FILE);
file_object_map_file = base_dir.cat(file_object_map_file);
_Tt_string property_table_file(TT_DB_PROPERTY_TABLE_FILE);
property_table_file = base_dir.cat(property_table_file);
_Tt_string access_table_file(TT_DB_ACCESS_TABLE_FILE);
access_table_file = base_dir.cat(access_table_file);
// Create key descriptor for the file key in the file table
fileTableFileKey = new _Tt_isam_key_descriptor;
fileTableFileKey->addKeyPart(TT_DB_FIRST_KEY_OFFSET,
TT_DB_KEY_LENGTH,
BINTYPE);
fileTable = new _Tt_isam_file(file_table_file,
TT_DB_KEY_LENGTH+MAXPATHLEN,
TT_DB_KEY_LENGTH+TT_DB_MAX_KEY_LENGTH,
fileTableFileKey,
ISVARLEN+ISINOUT+ISEXCLLOCK);
dbLastFileAccessed = fileTable->getName();
int results = fileTable->getErrorStatus();
// Create key descriptor for the file path in the file table
fileTableFilePathKey = new _Tt_isam_key_descriptor;
fileTableFilePathKey->addKeyPart(TT_DB_FILE_PATH_OFFSET,
TT_DB_MAX_KEY_LENGTH,
CHARTYPE);
// If this is new file add the key as an index
if (!results && fileTable->isNew()) {
(void)fileTable->addIndex(fileTableFilePathKey);
(void)fileTable->writeMagicString(_Tt_string(TT_DB_VERSION));
}
else if (results) {
dbResults = TT_DB_ERR_DB_OPEN_FAILED;
}
if (dbResults == TT_DB_OK) {
// Create key descriptor for the object key in the file-object map
fileObjectMapObjectKey = new _Tt_isam_key_descriptor;
fileObjectMapObjectKey->addKeyPart(TT_DB_FIRST_KEY_OFFSET,
TT_DB_KEY_LENGTH,
BINTYPE);
fileObjectMap = new _Tt_isam_file(file_object_map_file,
2*TT_DB_KEY_LENGTH,
2*TT_DB_KEY_LENGTH,
fileObjectMapObjectKey,
ISFIXLEN+ISINOUT+ISEXCLLOCK);
dbLastFileAccessed = fileObjectMap->getName();
results = fileObjectMap->getErrorStatus();
// Create key descriptor for the file key in the file-object map
fileObjectMapFileKey = new _Tt_isam_key_descriptor;
fileObjectMapFileKey->addKeyPart(TT_DB_SECOND_KEY_OFFSET,
TT_DB_KEY_LENGTH,
BINTYPE);
fileObjectMapFileKey->setDuplicates(TRUE);
// If this is new file add the key as an index
if (!results && fileObjectMap->isNew()) {
(void)fileObjectMap->addIndex(fileObjectMapFileKey);
(void)fileObjectMap->writeMagicString(_Tt_string(TT_DB_VERSION));
}
else if (results) {
dbResults = TT_DB_ERR_DB_OPEN_FAILED;
}
}
if (dbResults == TT_DB_OK) {
// Create key descriptor for the object key and property name in
// the property table
propertyTablePropertyKey = new _Tt_isam_key_descriptor;
propertyTablePropertyKey->addKeyPart(TT_DB_FIRST_KEY_OFFSET,
TT_DB_KEY_LENGTH,
BINTYPE);
propertyTablePropertyKey->addKeyPart(TT_DB_PROPERTY_NAME_OFFSET,
TT_DB_MAX_PROPERTY_NAME_LENGTH,
CHARTYPE);
propertyTablePropertyKey->setDuplicates(TRUE);
propertyTable =
new _Tt_isam_file(property_table_file,
ISMAXRECLEN,
TT_DB_KEY_LENGTH+TT_DB_MAX_PROPERTY_NAME_LENGTH,
propertyTablePropertyKey,
ISVARLEN+ISINOUT+ISEXCLLOCK);
dbLastFileAccessed = propertyTable->getName();
results = propertyTable->getErrorStatus();
if (!results && propertyTable->isNew()) {
(void)propertyTable->writeMagicString(_Tt_string(TT_DB_VERSION));
}
else if (results) {
dbResults = TT_DB_ERR_DB_OPEN_FAILED;
}
}
if (dbResults == TT_DB_OK) {
// Create the key descriptor for the object key in the access table
accessTableKey = new _Tt_isam_key_descriptor;
accessTableKey->addKeyPart(TT_DB_FIRST_KEY_OFFSET,
TT_DB_KEY_LENGTH,
BINTYPE);
accessTable = new _Tt_isam_file(access_table_file,
TT_DB_KEY_LENGTH+3*TT_DB_LONG_SIZE,
TT_DB_KEY_LENGTH+3*TT_DB_LONG_SIZE,
accessTableKey,
ISFIXLEN+ISINOUT+ISEXCLLOCK);
dbLastFileAccessed = accessTable->getName();
results = accessTable->getErrorStatus();
if (!results && accessTable->isNew()) {
(void)accessTable->writeMagicString(_Tt_string(TT_DB_VERSION));
}
else if (results) {
dbResults = TT_DB_ERR_DB_OPEN_FAILED;
}
}
}
_Tt_db_server_db::~_Tt_db_server_db ()
{
}
_Tt_db_results _Tt_db_server_db::createFile (const _Tt_string &file,
const _Tt_db_access_ptr &access)
{
_Tt_db_key_ptr file_key = new _Tt_db_key;
_Tt_isam_record_ptr record_ptr = fileTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, file_key->binary());
record_ptr->setBytes(TT_DB_FILE_PATH_OFFSET, file);
int results = fileTable->writeRecord(record_ptr);
dbLastFileAccessed = fileTable->getName();
if (!results) {
dbResults = TT_DB_OK;
_Tt_string file_key_bytes(TT_DB_KEY_LENGTH);
memcpy((char *)file_key_bytes,
(char *)file_key->binary(),
TT_DB_KEY_LENGTH);
if (setAccess(file_key_bytes, access) != TT_DB_OK) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
else if (results == EDUPL) {
dbResults = TT_DB_ERR_FILE_EXISTS;
}
else if (results == ELOCKED) {
dbResults = TT_DB_ERR_DB_LOCKED;
}
else if (results == ENOSPC) {
dbResults = TT_DB_ERR_DISK_FULL;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::createObject (const _Tt_string &file,
const _Tt_string &objid,
const _Tt_db_access_ptr &object_access,
const _Tt_db_access_ptr &file_access)
{
_Tt_string file_key;
// If a file has been specified, get the key
_Tt_string real_file;
if (!file.len()) {
real_file = TT_DB_FORWARD_POINTER_FILE;
}
else {
real_file = file;
}
dbResults = getFileKey(real_file, file_key);
// If the file does not exist...
if (dbResults == TT_DB_ERR_NO_SUCH_FILE) {
_Tt_db_access_ptr real_file_access;
if (!file.len()) {
real_file_access = new _Tt_db_access;
real_file_access->user = 0;
real_file_access->group = 0;
real_file_access->mode = (mode_t)-1;
}
else {
real_file_access = file_access;
}
// Create the file
dbResults = createFile(real_file, real_file_access);
if (dbResults == TT_DB_OK) {
// Get the new file key
dbResults = getFileKey(real_file, file_key);
}
if (dbResults != TT_DB_OK) {
return dbResults;
}
}
// Else, if some sort of fatal error
else if (dbResults != TT_DB_OK) {
return dbResults;
}
// Verify access to the file
if (verifyAccess(file_key, object_access, TRUE) != TT_DB_OK) {
return dbResults;
}
if (dbResults == TT_DB_OK) {
_Tt_string object_key = getObjectKey(objid);
int results;
// Write a record to the file-object map
_Tt_isam_record_ptr record_ptr = fileObjectMap->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, object_key);
record_ptr->setKeyPartValue(1, 0, file_key);
results = fileObjectMap->writeRecord(record_ptr);
dbLastFileAccessed = fileObjectMap->getName();
if (!results) {
if (setAccess(object_key, object_access) != TT_DB_OK) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
else if (results == EDUPL) {
dbResults = TT_DB_ERR_OBJECT_EXISTS;
}
else if (results == ELOCKED) {
dbResults = TT_DB_ERR_DB_LOCKED;
}
else if (results == ENOSPC) {
dbResults = TT_DB_ERR_DISK_FULL;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::removeFile (const _Tt_string &file,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE, TRUE) != TT_DB_OK) {
return dbResults;
}
_Tt_string_list_ptr objids;
// Find and remove the file's objects
dbResults = getFileObjects(file, access, objids);
if (dbResults == TT_DB_OK) {
_Tt_string_list_cursor objids_cursor(objids);
while (objids_cursor.next()) {
dbResults = removeObject(*objids_cursor, access);
}
}
else {
return dbResults;
}
if (dbResults == TT_DB_OK) {
dbResults = deleteProperties(file_key);
if (dbResults == TT_DB_OK) {
// Remove the file from the file table
int results = fileTable->deleteCurrentRecord();
dbLastFileAccessed = fileTable->getName();
if (!results) {
// Reposition the access table at the file's access record
if (verifyAccess(file_key, access, TRUE, TRUE) != TT_DB_OK) {
return dbResults;
}
// Remove the file's access info
results = accessTable->deleteCurrentRecord();
dbLastFileAccessed = accessTable->getName();
}
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::removeObject (const _Tt_string &objid,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyUserOnlyObjectAccess (object_key, access) != TT_DB_OK) {
return dbResults;
}
dbResults = deleteProperties(object_key);
if (dbResults == TT_DB_OK) {
_Tt_isam_record_ptr record_ptr = fileObjectMap->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, object_key);
// Position the file just before the object in the file-object map
int results = fileObjectMap->findStartRecord(fileObjectMapObjectKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileObjectMap->getName();
if (!results) {
// Read the object record
(void)fileObjectMap->readRecord(ISNEXT);
results = fileObjectMap->getErrorStatus();
if (!results) {
// Delete the record
results = fileObjectMap->deleteCurrentRecord();
if (!results) {
// Delete the object's access info
results = accessTable->deleteCurrentRecord();
dbLastFileAccessed = accessTable->getName();
}
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::setFileProperty (const _Tt_string &file,
const _Tt_db_property_ptr &property,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return setProperty(file_key, property);
}
_Tt_db_results _Tt_db_server_db
::setFileProperties (const _Tt_string &file,
const _Tt_db_property_list_ptr &properties,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return setProperties(file_key, properties);
}
_Tt_db_results
_Tt_db_server_db::addFileProperty (const _Tt_string &file,
const _Tt_db_property_ptr &property,
bool_t unique,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return addProperty(file_key, property, unique);
}
_Tt_db_results
_Tt_db_server_db::deleteFileProperty (const _Tt_string &file,
const _Tt_db_property_ptr &property,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return deleteProperty(file_key, property);
}
_Tt_db_results
_Tt_db_server_db::deleteFileProperties (const _Tt_string &file,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return deleteProperties(file_key);
}
_Tt_db_results
_Tt_db_server_db::getFileProperty (const _Tt_string &file,
const _Tt_string &name,
const _Tt_db_access_ptr &access,
_Tt_db_property_ptr &property)
{
property = (_Tt_db_property *)NULL;
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access) != TT_DB_OK) {
return dbResults;
}
return getProperty(file_key, name, property);
}
_Tt_db_results _Tt_db_server_db
::getFileProperties (const _Tt_string &file,
const _Tt_db_access_ptr &access,
_Tt_db_property_list_ptr &properties)
{
properties = (_Tt_db_property_list *)NULL;
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access) != TT_DB_OK) {
return dbResults;
}
return getProperties(file_key, properties);
}
_Tt_db_results
_Tt_db_server_db::getFileObjects (const _Tt_string &file,
const _Tt_db_access_ptr &access,
_Tt_string_list_ptr &objids)
{
objids = (_Tt_string_list *)NULL;
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access) != TT_DB_OK) {
return dbResults;
}
_Tt_isam_record_ptr record_ptr = fileObjectMap->getEmptyRecord();
record_ptr->setKeyPartValue(1, 0, file_key);
// Position just before record with the specified file key in the
// file-object map
int results = fileObjectMap->findStartRecord(fileObjectMapFileKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = (char *)fileObjectMap->getName();
if (results == ENOREC) {
dbResults = TT_DB_OK;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else if (!results) {
for (;;) {
// Read the next file record
record_ptr = fileObjectMap->readRecord(ISNEXT);
results = fileObjectMap->getErrorStatus();
if (!results) {
// Extract the file key from the record just read
_Tt_string file_key_bytes = record_ptr->getKeyPartValue(1, 0);
// If the extracted key doesn't match the specified key,
// then there are no more records with this key value,
// therefore break out of the loop...
if (file_key != file_key_bytes) {
dbResults = TT_DB_OK;
break;
}
// Else the file record matches...
else {
// Extract the object key bytes and create a key object
_Tt_string object_key_bytes = record_ptr->getKeyPartValue(0, 0);
_Tt_db_key_ptr object_key = new _Tt_db_key(object_key_bytes);
// Construct the actual object ID
_Tt_string objid = _tt_db_create_objid(object_key,
"NFS",
dbHostname,
dbPartition);
if (objids.is_null()) {
objids = new _Tt_string_list;
}
objids->append(objid);
}
}
// Else if no more records match the file key...
else if ((results == ENOREC) || (results == EENDFILE)) {
dbResults = TT_DB_OK;
break;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::deleteFileObjects (const _Tt_string &file,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
// Gets the object IDs, loop through them, and remove them...
_Tt_string_list_ptr objids;
if (getFileObjects(file, access, objids) == TT_DB_OK) {
_Tt_string_list_cursor objids_cursor(objids);
while (objids_cursor.next() && (dbResults == TT_DB_OK)) {
dbResults = removeObject(*objids_cursor, access);
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::setFileFile (const _Tt_string &file,
const _Tt_string &new_file,
const _Tt_db_access_ptr &access)
{
if (file == new_file) {
return TT_DB_ERR_SAME_FILE;
}
_Tt_string file_key;
// Use the "getFileKey" to position the current record of the
// file table on the record to update.
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
// Re-read the current file-object map record
_Tt_isam_record_ptr record_ptr;
record_ptr = fileTable->readRecord(ISCURR);
int results = fileTable->getErrorStatus();
if (!results) {
// Get a clean record
_Tt_isam_record_ptr new_record = fileTable->getEmptyRecord();
// Put the file key into the new record
record_ptr->setKeyPartValue(0, 0, file_key);
// Put the new file into the record
record_ptr->setBytes(TT_DB_FILE_PATH_OFFSET, new_file);
// Update the current file table record with the new info
results = fileTable->updateCurrentRecord(record_ptr);
}
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::getFileChildren (const _Tt_string &file,
_Tt_string_list_ptr &children)
{
int results;
// Construct the root path for finding children files
_Tt_string root_path = file;
root_path = root_path.cat("/");
children = new _Tt_string_list;
// Use the "getFileKey" to position the the file table on the first
// record that matches our file and to see if the file exists
// in the database.
_Tt_string file_key;
dbResults = getFileKey(file, file_key);
if (dbResults == TT_DB_OK) {
children->append(file);
}
else if (dbResults == TT_DB_ERR_NO_SUCH_FILE) {
dbResults = TT_DB_OK;
// Position the file at the first record that has the file name
// as the root of its path
_Tt_isam_record_ptr record_ptr = fileTable->getEmptyRecord();
record_ptr->setKeyPartValue(1, 0, root_path);
results =
fileTable->findStartRecord(fileTableFilePathKey,
((root_path.len() < TT_DB_MAX_KEY_LENGTH) ?
root_path.len() : TT_DB_MAX_KEY_LENGTH),
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileTable->getName();
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_SUCH_FILE;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
if (dbResults == TT_DB_OK) {
_Tt_isam_record_ptr record_ptr;
// Loop through the children files
results = 0;
while (!results) {
record_ptr = fileTable->readRecord(ISNEXT);
results = fileTable->getErrorStatus();
if (!results) {
_Tt_string child = record_ptr->getBytes(TT_DB_FILE_PATH_OFFSET, 0);
// Make sure the record just read contains a child of the root path
if (!strncmp((char *)root_path, (char *)child, root_path.len())) {
children->append(_Tt_string((char *)child));
}
// Else, no more children left...
else {
results = ENOREC;
}
}
}
if ((results == ENOREC) || (results == EENDFILE)) {
dbResults = TT_DB_OK;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::setFileAccess (const _Tt_string &file,
const _Tt_db_access_ptr &new_access,
const _Tt_db_access_ptr &access)
{
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
(void)verifyAccess(file_key, access, TRUE, TRUE);
if ((dbResults != TT_DB_OK) && (dbResults != TT_DB_ERR_NO_ACCESS_INFO)) {
return dbResults;
}
return setAccess(file_key, new_access);
}
_Tt_db_results
_Tt_db_server_db::getFileAccess (const _Tt_string &file,
const _Tt_db_access_ptr &access,
_Tt_db_access_ptr &current_access)
{
current_access = (_Tt_db_access *)NULL;
_Tt_string file_key;
if (getFileKey(file, file_key) != TT_DB_OK) {
return dbResults;
}
if (verifyAccess(file_key, access) != TT_DB_OK) {
return dbResults;
}
return getAccess(file_key, current_access);
}
_Tt_db_results
_Tt_db_server_db::setObjectProperty (const _Tt_string &objid,
const _Tt_db_property_ptr &property,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return setProperty(object_key, property);
}
_Tt_db_results _Tt_db_server_db
::setObjectProperties (const _Tt_string &objid,
const _Tt_db_property_list_ptr &properties,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return setProperties(object_key, properties);
}
_Tt_db_results
_Tt_db_server_db::addObjectProperty (const _Tt_string &objid,
const _Tt_db_property_ptr &property,
bool_t unique,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return addProperty(object_key, property, unique);
}
_Tt_db_results
_Tt_db_server_db::deleteObjectProperty (const _Tt_string &objid,
const _Tt_db_property_ptr &property,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return deleteProperty(object_key, property);
}
_Tt_db_results
_Tt_db_server_db::deleteObjectProperties (const _Tt_string &objid,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access, TRUE) != TT_DB_OK) {
return dbResults;
}
return deleteProperties(object_key);
}
_Tt_db_results
_Tt_db_server_db::getObjectProperty (const _Tt_string &objid,
const _Tt_string &name,
const _Tt_db_access_ptr &access,
_Tt_db_property_ptr &property)
{
property = (_Tt_db_property *)NULL;
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access) != TT_DB_OK) {
return dbResults;
}
return getProperty(object_key, name, property);
}
_Tt_db_results _Tt_db_server_db
::getObjectProperties (const _Tt_string &objid,
const _Tt_db_access_ptr &access,
_Tt_db_property_list_ptr &properties)
{
properties = (_Tt_db_property_list *)NULL;
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access) != TT_DB_OK) {
return dbResults;
}
return getProperties(object_key, properties);
}
_Tt_db_results
_Tt_db_server_db::setObjectFile (const _Tt_string &objid,
const _Tt_string &file,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access) != TT_DB_OK) {
return dbResults;
}
// Use "getFile" to position the current record of the file-object
// map on the record to update. Plus we need to get the old file
// name to make sure a move is really needed...
_Tt_string old_file;
dbResults = getFile(object_key, old_file);
if (dbResults == TT_DB_OK) {
// If the names are the same, then the move is not needed...
if (old_file == file) {
dbResults = TT_DB_ERR_SAME_OBJECT;
}
// Else, the move is needed...
else {
// Re-read the current file-object map record
_Tt_isam_record_ptr record_ptr;
record_ptr = fileObjectMap->readRecord(ISCURR);
int results = fileObjectMap->getErrorStatus();
if (!results) {
// See if the file exists by trying to obtain its key
_Tt_string file_key;
dbResults = getFileKey(file, file_key);
// If the file key was found...
if (dbResults == TT_DB_OK) {
// Put the new file key into the record and update the table
record_ptr->setKeyPartValue(1, 0, file_key);
results = fileObjectMap->updateCurrentRecord(record_ptr);
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
// Else, the file is not in the DB...
else if (dbResults == TT_DB_ERR_NO_SUCH_FILE) {
// Create a new file using the permissions of the object
_Tt_db_access_ptr object_access;
dbResults = getAccess(object_key, object_access);
if (dbResults == TT_DB_OK) {
dbResults = createFile (file, object_access);
}
if (dbResults == TT_DB_OK) {
// Get the new file key
if (getFileKey(file, file_key) == TT_DB_OK) {
// Put the new file key into the record and update the table
record_ptr->setKeyPartValue(1, 0, file_key);
results = fileObjectMap->updateCurrentRecord(record_ptr);
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
}
}
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::getObjectFile (const _Tt_string &objid,
const _Tt_db_access_ptr &access,
_Tt_string &file)
{
file = (char *)NULL;
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access) != TT_DB_OK) {
return dbResults;
}
return getFile(object_key, file);
}
_Tt_db_results
_Tt_db_server_db::setObjectAccess (const _Tt_string &objid,
const _Tt_db_access_ptr &new_access,
const _Tt_db_access_ptr &access)
{
_Tt_string object_key = getObjectKey(objid);
(void)verifyObjectAccess(object_key, access, TRUE, TRUE);
if ((dbResults != TT_DB_OK) && (dbResults != TT_DB_ERR_NO_ACCESS_INFO)) {
return dbResults;
}
return setAccess(object_key, new_access);
}
_Tt_db_results
_Tt_db_server_db::getObjectAccess (const _Tt_string &objid,
const _Tt_db_access_ptr &access,
_Tt_db_access_ptr &current_access)
{
current_access = (_Tt_db_access *)NULL;
_Tt_string object_key = getObjectKey(objid);
if (verifyObjectAccess(object_key, access) != TT_DB_OK) {
return dbResults;
}
return getAccess(object_key, current_access);
}
_Tt_db_results
_Tt_db_server_db::verifyObjectAccess (const _Tt_string &object_key,
const _Tt_db_access_ptr &access,
bool_t write,
bool_t user_only)
{
dbResults = verifyAccess(object_key, access, write, user_only);
if (dbResults == TT_DB_ERR_NO_ACCESS_INFO) {
_Tt_isam_record_ptr record_ptr = fileObjectMap->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, object_key);
// Position the file just before the object in the file-object map
int results = fileObjectMap->findStartRecord(fileObjectMapObjectKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileObjectMap->getName();
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_SUCH_OBJECT;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db
::verifyUserOnlyObjectAccess (const _Tt_string &object_key,
const _Tt_db_access_ptr &access)
{
if (verifyAccess(object_key, access, TRUE, TRUE) != TT_DB_OK) {
_Tt_string file;
if (getFile(object_key, file) == TT_DB_OK) {
_Tt_string file_key;
if (getFileKey(file, file_key) == TT_DB_OK) {
dbResults = verifyAccess(file_key, access, TRUE, TRUE);
}
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::verifyAccess (const _Tt_string &key,
const _Tt_db_access_ptr &access,
bool_t write,
bool_t user_only)
{
_Tt_isam_record_ptr record_ptr = accessTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the specified key in the access table
int results = accessTable->findStartRecord(accessTableKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = accessTable->getName();
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_ACCESS_INFO;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Read the access record
record_ptr = accessTable->readRecord(ISNEXT);
results = accessTable->getErrorStatus();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else if (!results) {
long n_user = *(long *)
((char *)record_ptr->getRecord()+TT_DB_ACCESS_USER_OFFSET);
uid_t user = (uid_t)ntohl(n_user);
long n_group = *(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_GROUP_OFFSET);
gid_t group = (gid_t)ntohl(n_group);
long n_mode = *(long *)
((char *)record_ptr->getRecord()+TT_DB_ACCESS_MODE_OFFSET);
mode_t mode = (mode_t)ntohl(n_mode);
// If the user in the DB is -1, all users match
bool_t user_flag = FALSE;
if (user == -1) {
user_flag = TRUE;
}
else {
if (user == access->user) {
user_flag = TRUE;
}
}
// If the group in the DB is -1, all groups match
bool_t group_flag = FALSE;
if (group == -1) {
group_flag = TRUE;
}
else {
if (group == access->group) {
group_flag = TRUE;
}
}
dbResults = TT_DB_ERR_ACCESS_DENIED;
// Root can do everything
if (access->user == 0) {
return (dbResults = TT_DB_OK);
}
// User of object can do anything
if (user_flag) {
return (dbResults = TT_DB_OK);
}
if (!user_only) {
if (mode == (mode_t)-1) {
return (dbResults = TT_DB_OK);
}
if (group_flag && (dbResults != TT_DB_OK)) {
if (write && (mode&S_IWGRP)) {
return (dbResults = TT_DB_OK);
}
else if (mode&S_IRGRP) {
return (dbResults = TT_DB_OK);
}
}
if (dbResults != TT_DB_OK) {
if (write && (mode&S_IWOTH)) {
return (dbResults = TT_DB_OK);
}
else if (mode&S_IROTH) {
return (dbResults = TT_DB_OK);
}
}
}
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::getFileKey (const _Tt_string &file,
_Tt_string &file_key)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = fileTable->getEmptyRecord();
record_ptr->setKeyPartValue(1, 0, file);
// Position file just before record with specified file path in the
// file table
int results =
fileTable->findStartRecord(fileTableFilePathKey,
((file.len() < TT_DB_MAX_KEY_LENGTH) ?
file.len() : TT_DB_MAX_KEY_LENGTH),
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileTable->getName();
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_SUCH_FILE;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
for (;;) {
// Read the next record
record_ptr = fileTable->readRecord(ISNEXT);
results = fileTable->getErrorStatus();
if (!results) {
// Extract the full file path from the record
_Tt_string temp_file = (char *)
record_ptr->getBytes(TT_DB_FILE_PATH_OFFSET, 0);
// If the record file path matchs the specified file, then
// we found our file, therefore break out of the loop...
if (file == temp_file) {
break;
}
}
// No more records left, our file doesn't exist...
else if ((results == ENOREC) || (results == EENDFILE)) {
dbResults = TT_DB_ERR_NO_SUCH_FILE;
break;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
if (dbResults == TT_DB_OK) {
// Extract the file key
file_key = record_ptr->getKeyPartValue(0, 0);
}
}
return dbResults;
}
_Tt_string _Tt_db_server_db::getObjectKey (const _Tt_string &objid)
{
// Create a key object from the specified object ID
_Tt_db_key_ptr object_key = new _Tt_db_key(objid);
// Write the binary key to a return buffer
_Tt_string object_key_bytes(TT_DB_KEY_LENGTH);
memcpy((char *)object_key_bytes,
(char *)object_key->binary(),
TT_DB_KEY_LENGTH);
return object_key_bytes;
}
_Tt_db_results _Tt_db_server_db::addPropertyValue(const _Tt_string &key,
const _Tt_string &name,
const _Tt_string &value)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
record_ptr->setKeyPartValue(0, 1, name);
record_ptr->setBytes(TT_DB_PROPERTY_VALUE_OFFSET, value);
record_ptr->setLength(TT_DB_PROPERTY_VALUE_OFFSET+value.len());
int results = propertyTable->writeRecord(record_ptr);
dbLastFileAccessed = propertyTable->getName();
if (results == ENOSPC) {
dbResults = TT_DB_ERR_DISK_FULL;
}
else if (results == ELOCKED) {
dbResults = TT_DB_ERR_DB_LOCKED;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::setProperty (const _Tt_string &key,
const _Tt_db_property_ptr &property)
{
_Tt_db_property_ptr temp_property = new _Tt_db_property;
temp_property->name = property->name;
(void)deleteProperty(key, temp_property);
return addProperty(key, property, FALSE);
}
_Tt_db_results
_Tt_db_server_db::setProperties (const _Tt_string &key,
const _Tt_db_property_list_ptr &properties)
{
dbResults = deleteProperties(key, TRUE);
_Tt_db_property_list_cursor properties_cursor(properties);
while (properties_cursor.next()) {
dbResults = setProperty(key, *properties_cursor);
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::addProperty (const _Tt_string &key,
const _Tt_db_property_ptr &property,
bool_t unique)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr;
_Tt_string temp_string;
_Tt_string_list_cursor values_cursor(property->values);
while (values_cursor.next() && (dbResults == TT_DB_OK)) {
// If unique... therefore add the value to the property only if
// the key, prop name and prop value combo does not already exist...
if (unique) {
record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
record_ptr->setKeyPartValue(0, 1, property->name);
// Position the file just before the first record with the specified key
// and property name value in the property table
int results = propertyTable->findStartRecord(propertyTablePropertyKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = propertyTable->getName();
// No such property, add the value
if (results == ENOREC) {
dbResults = addPropertyValue(key, property->name, *values_cursor);
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
// Property exists, let's check on its values...
else {
bool_t found = FALSE;
for (;;) {
// Read the next record
record_ptr = propertyTable->readRecord(ISNEXT);
results = propertyTable->getErrorStatus();
if (!results) {
// Extract the key from the record
temp_string = record_ptr->getKeyPartValue(0, 0);
// If the key doesn't match, we're done looking for values...
if (temp_string != key) {
break;
}
// Extract the property name from the record
temp_string = record_ptr->getKeyPartValue(0, 1);
// If the property name doesn't match, we're done looking
// for values.
if (strcmp((char *)temp_string, (char *)property->name)) {
break;
}
// Extract the property value from the record
temp_string = record_ptr->getBytes(TT_DB_PROPERTY_VALUE_OFFSET, 0);
// If the values are the same, the new property is not unique,
// so let's leave...
if (temp_string == *values_cursor) {
found = TRUE;
break;
}
}
// No more records, the new value is unique...
else if ((results == ENOREC) || (results == EENDFILE)) {
break;
}
else {
found = TRUE;
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
// If the same value wasn't found, the new value is unique,
// therefore add it...
if (!found) {
dbResults = addPropertyValue(key, property->name, *values_cursor);
}
}
}
// Else, who cares whether it's unique or not, just add it...
else {
dbResults = addPropertyValue(key, property->name, *values_cursor);
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::deleteProperty (const _Tt_string &key,
const _Tt_db_property_ptr &property)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
record_ptr->setKeyPartValue(0, 1, property->name);
// Position the file just before the first record with the specified key
// and property name value in the property table
int results = propertyTable->findStartRecord(propertyTablePropertyKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = propertyTable->getName();
bool_t found = FALSE;
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_SUCH_PROPERTY;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
_Tt_string_list_cursor values_cursor(property->values);
for (;;) {
// Read the next record
record_ptr = propertyTable->readRecord(ISNEXT);
results = propertyTable->getErrorStatus();
// No more records, let's get out of here...
if ((results == ENOREC) || (results == EENDFILE)) {
break;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
else {
// Extract the key from the record
_Tt_string temp_string = record_ptr->getKeyPartValue(0, 0);
// If the key doesn't match, we're done looking for values...
if (temp_string != key) {
break;
}
// Extract the property name from the record
temp_string = record_ptr->getKeyPartValue(0, 1);
// If the property name doesn't match, we're done looking
// for values.
if (strcmp((char *)property->name, (char *)temp_string)) {
break;
}
// If no specific values to delete were specified, delete all of
// the values we find...
if (property->is_empty()) {
found = TRUE;
results = propertyTable->deleteCurrentRecord();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
// Else specific values to delete have been specified...
else {
// Extract the property value from the record
_Tt_string property_value =
record_ptr->getBytes(TT_DB_PROPERTY_VALUE_OFFSET, 0);
// Loop through the specified values and see if any match
// the value in the record. If one matches, delete the
// record...
values_cursor.reset();
while (values_cursor.next()) {
if (property_value == *values_cursor) {
found = TRUE;
results = propertyTable->deleteCurrentRecord();
break;
}
}
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
}
}
}
if ((dbResults == TT_DB_OK) && (!found)) {
dbResults = TT_DB_ERR_NO_SUCH_PROPERTY;
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db
::deleteProperties (const _Tt_string &key,
bool_t preserve_special_properties)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the record with the specified key in
// the property table
int results = propertyTable->findStartRecord(propertyTablePropertyKey,
TT_DB_KEY_LENGTH,
record_ptr,
ISEQUAL);
dbLastFileAccessed = propertyTable->getName();
_Tt_string temp_string;
for (;;) {
if (!results) {
// Read the property record
record_ptr = propertyTable->readRecord(ISNEXT);
results = propertyTable->getErrorStatus();
if (!results) {
// Extract the key from the record
temp_string = record_ptr->getKeyPartValue(0, 0);
// If the key doesn't match, we're done looking for properties...
if (temp_string != key) {
break;
}
// If we need to preserve special properties, i.e. object type
// and cache level properties
if (preserve_special_properties) {
temp_string = record_ptr->getKeyPartValue(0, 1);
if (strcmp((char *)temp_string, TT_DB_PROPS_CACHE_LEVEL_PROPERTY) &&
strcmp((char *)temp_string, TT_DB_OBJECT_TYPE_PROPERTY)) {
results = propertyTable->deleteCurrentRecord();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
}
else {
results = propertyTable->deleteCurrentRecord();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
}
}
else if ((results == EENDFILE) || (results == ENOREC)) {
break;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::getProperty (const _Tt_string &key,
const _Tt_string &name,
_Tt_db_property_ptr &property)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
record_ptr->setKeyPartValue(0, 1, name);
// Position the file just before the first record with the specified key
// and property name value in the property table
int results = propertyTable->findStartRecord(propertyTablePropertyKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = (char *)propertyTable->getName();
if (results == ENOREC) {
dbResults = TT_DB_ERR_NO_SUCH_PROPERTY;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Create the object to return the property in
property = new _Tt_db_property;
property->name = name;
_Tt_string temp_string;
for (;;) {
// Read the next record
record_ptr = propertyTable->readRecord(ISNEXT);
results = propertyTable->getErrorStatus();
if (!results) {
// Extract the key from the record
temp_string = record_ptr->getKeyPartValue(0, 0);
// If the key does not match, we're done looking for values...
if (temp_string != key) {
break;
}
// Extract the property name from the record
temp_string = record_ptr->getKeyPartValue(0, 1);
// If the property name doesn't match, we're done looking
// for values.
if (strcmp((char *)name, (char *)temp_string)) {
break;
}
// Extract the property value from the record and append the
// value to the object being returned
temp_string = record_ptr->getBytes(TT_DB_PROPERTY_VALUE_OFFSET, 0);
property->values->append(temp_string);
}
// No more records, we're done getting the property...
else if ((results == ENOREC) || (results == EENDFILE)) {
break;
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
}
}
return dbResults;
}
_Tt_db_results
_Tt_db_server_db::getProperties (const _Tt_string &key,
_Tt_db_property_list_ptr &properties)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = propertyTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the first record with the specified key
// in the property table
int results = propertyTable->findStartRecord(propertyTablePropertyKey,
TT_DB_KEY_LENGTH,
record_ptr,
ISEQUAL);
dbLastFileAccessed = propertyTable->getName();
if (results && (results != ENOREC)) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
_Tt_string name;
_Tt_string value;
_Tt_string temp_string;
for (;;) {
// Read the next record
record_ptr = propertyTable->readRecord(ISNEXT);
results = propertyTable->getErrorStatus();
if ((results == ENOREC) || (results == EENDFILE)) {
break;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
break;
}
else {
// Extract the key from the record
temp_string = record_ptr->getKeyPartValue(0, 0);
// If the key does not match, we're done looking for properties...
if (temp_string != key) {
break;
}
// Extract the property name and value from the reocrd
name = record_ptr->getKeyPartValue(0, 1);
value = record_ptr->getBytes(TT_DB_PROPERTY_VALUE_OFFSET, 0);
if (properties.is_null()) {
properties = new _Tt_db_property_list;
}
bool_t found = FALSE;
_Tt_db_property_ptr property;
// See if a property with same name is already in our return list...
_Tt_db_property_list_cursor properties_cursor(properties);
while (properties_cursor.next()) {
// If the property exists, get the pointer to it...
if (properties_cursor->name == name) {
property = *properties_cursor;
found = TRUE;
break;
}
}
// If there is no property with the same name in the list,
// create a new property and it to the list...
if (!found) {
property = new _Tt_db_property;
properties->append(property);
}
// Append the value to the property
property->name = name;
property->values->append(value);
}
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::setAccess (const _Tt_string &key,
const _Tt_db_access_ptr &access)
{
dbResults = TT_DB_OK;
_Tt_isam_record_ptr record_ptr = accessTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the access info record for the key
int results = accessTable->findStartRecord(accessTableKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = accessTable->getName();
if (results == ENOREC) {
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_USER_OFFSET) = htonl(access->user);
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_GROUP_OFFSET) = htonl(access->group);
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_MODE_OFFSET) = htonl(access->mode);
int results = accessTable->writeRecord(record_ptr);
if (results == ENOSPC) {
dbResults = TT_DB_ERR_DISK_FULL;
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
else if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Read the access record
record_ptr = accessTable->readRecord(ISNEXT);
results = accessTable->getErrorStatus();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else if (!results) {
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_USER_OFFSET) = htonl(access->user);
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_GROUP_OFFSET) = htonl(access->group);
*(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_MODE_OFFSET) = htonl(access->mode);
// Update the record record that was read
results = accessTable->updateCurrentRecord(record_ptr);
dbResults = (results ? TT_DB_ERR_CORRUPT_DB : TT_DB_OK);
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::getAccess (const _Tt_string &key,
_Tt_db_access_ptr &access)
{
_Tt_isam_record_ptr record_ptr = accessTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the access info record for the key
int results = accessTable->findStartRecord(accessTableKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = accessTable->getName();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Read the access record
record_ptr = accessTable->readRecord(ISNEXT);
results = accessTable->getErrorStatus();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else if (!results) {
access = new _Tt_db_access;
long n_user = *(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_USER_OFFSET);
access->user = (uid_t)ntohl(n_user);
long n_group = *(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_GROUP_OFFSET);
access->group = (gid_t)ntohl(n_group);
long n_mode = *(long *)
((char *)record_ptr->getRecord()+
TT_DB_ACCESS_MODE_OFFSET);
access->mode = (mode_t)ntohl(n_mode);
dbResults = TT_DB_OK;
}
}
return dbResults;
}
_Tt_db_results _Tt_db_server_db::getFile (const _Tt_string &key,
_Tt_string &file)
{
_Tt_isam_record_ptr record_ptr = fileObjectMap->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, key);
// Position the file just before the object in the file-object map
int results = fileObjectMap->findStartRecord(fileObjectMapObjectKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileObjectMap->getName();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Read the object record
record_ptr = fileObjectMap->readRecord(ISNEXT);
results = fileObjectMap->getErrorStatus();
if (!results) {
// Extract the file key from the record
_Tt_string file_key = record_ptr->getKeyPartValue(1, 0);
record_ptr = fileTable->getEmptyRecord();
record_ptr->setKeyPartValue(0, 0, file_key);
// Position the file just before the file in the file table
int results = fileTable->findStartRecord(fileTableFileKey,
0,
record_ptr,
ISEQUAL);
dbLastFileAccessed = fileTable->getName();
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Read the file record
record_ptr = fileTable->readRecord(ISNEXT);
if (results) {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
else {
// Extract the file path from the record
file = record_ptr->getBytes(TT_DB_FILE_PATH_OFFSET, 0);
dbResults = TT_DB_OK;
}
}
}
else {
dbResults = TT_DB_ERR_CORRUPT_DB;
}
}
return dbResults;
}