Files
cdesktop/cde/lib/DtSvc/DtUtil1/DtsDb.c
2018-06-28 03:58:49 +01:00

559 lines
11 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. *
*/
/*
*+SNOTICE
*
* $TOG: DtsDb.c /main/10 1998/10/23 13:48:04 mgreess $
*
* RESTRICTED CONFIDENTIAL INFORMATION:
*
* The information in this document is subject to special
* restrictions in a confidential disclosure agreement bertween
* HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
* document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
* Sun's specific written approval. This documment and all copies
* and derivative works thereof must be returned or destroyed at
* Sun's request.
*
* Copyright 1993 Sun Microsystems, Inc. All rights reserved.
*
*+ENOTICE
*/
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifdef SUN_DB
#include <sys/mman.h>
#endif
#include <string.h>
#include <Dt/DbReader.h>
#include "Dt/DtsDb.h"
#include <Dt/UserMsg.h>
#include "DtSvcLock.h"
extern char *strdup(const char *);
#define PADMEM 10
typedef int (*genfunc)(const void *, const void *);
static DtDtsDbDatabase **db_list;
static int num_db = 0;
void
_DtDtsDbPrintFields(DtDtsDbRecord *rec_ptr, FILE *fd)
{
int fld;
DtDtsDbField *fld_ptr;
for(fld = 0; fld < rec_ptr->fieldCount; fld++)
{
fld_ptr = rec_ptr->fieldList[fld];
fprintf(fd, "\t\t[%d]\t%s\t%s\n", fld,
XrmQuarkToString(fld_ptr->fieldName),
fld_ptr->fieldValue?
fld_ptr->fieldValue:"(NULL)");
}
}
void
_DtDtsDbPrintRecords(DtDtsDbDatabase *db_ptr, FILE *fd)
{
int rec;
DtDtsDbRecord *rec_ptr;
_DtSvcProcessLock();
fprintf(fd, "%d Records\n", db_ptr->recordCount);
for(rec = 0; rec < db_ptr->recordCount; rec++)
{
rec_ptr = db_ptr->recordList[rec];
fprintf(fd, "\tRec[%d] name = %s\n\t%d Fields\n", rec,
XrmQuarkToString(rec_ptr->recordName),
rec_ptr->fieldCount);
_DtDtsDbPrintFields(rec_ptr, fd);
}
_DtSvcProcessUnlock();
}
void
_DtDtsDbPrint(FILE *org_fd)
{
int db;
int rec;
DtDtsDbDatabase *db_ptr;
DtDtsDbRecord *rec_ptr;
FILE *fd = org_fd;
_DtSvcProcessLock();
for(db = 0; db < num_db; db++)
{
if(!db_list[db])
{
continue;
}
db_ptr = db_list[db];
if(fd == 0)
{
chdir("/tmp");
if((fd = fopen(db_ptr->databaseName, "w")) == NULL)
{
_DtSimpleError(
DtProgName, DtError, NULL,
db_ptr->databaseName, NULL);
continue;
}
}
fprintf(fd, "DB[%d] ", db);
fprintf(fd, "name = %s\n", db_ptr->databaseName);
_DtDtsDbPrintRecords(db_ptr, fd);
if(org_fd == 0)
{
fclose(fd);
fd = 0;
}
}
_DtSvcProcessUnlock();
}
int
_DtDtsDbCompareRecordNames(DtDtsDbRecord **a, DtDtsDbRecord **b)
{
return ((*a)->recordName - (*b)->recordName);
}
int
_DtDtsDbCompareFieldNames(DtDtsDbField **a, DtDtsDbField **b)
{
return ((*a)->fieldName - (*b)->fieldName);
}
#include <Dt/Dts.h>
DtDtsDbDatabase **
_DtDtsDbInit(void)
{
DtDtsDbDatabase **db;
_DtSvcProcessLock();
num_db = 0;
db = db_list = (DtDtsDbDatabase **)calloc(num_db+3, sizeof(DtDtsDbDatabase *));
db_list[0] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
db_list[0]->databaseName = (char *)strdup(DtDTS_DC_NAME);
db_list[0]->ActionSequenceNumber = 0;
num_db++;
db_list[1] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
db_list[1]->databaseName = (char *)strdup(DtDTS_DA_NAME);
db_list[1]->ActionSequenceNumber = 0;
num_db++;
_DtSvcProcessUnlock();
return(db);
}
char **
_DtsDbListDb(void)
{
int i;
char **list = 0;
_DtSvcProcessLock();
for ( i = 0; db_list[i]; i++ );
if(i > 0)
{
list = (char **)calloc(i+1, sizeof(char *));
for ( i = 0; db_list[i]; i++ )
{
list[i] = (char *)strdup(db_list[i]->databaseName);
}
}
_DtSvcProcessUnlock();
return(list);
}
DtDtsDbDatabase *
_DtDtsDbAddDatabase( char *db_name )
{
int i = 0;
DtDtsDbDatabase **new_db_list;
DtDtsDbDatabase *ret_db;
_DtSvcProcessLock();
if ( !db_list )
{
_DtDtsDbInit();
}
for ( i = 0; db_list[i]; i++ )
{
if ( !strcmp(db_list[i]->databaseName,db_name) )
{
/*
* A database with the given name already exists.
* return a pointer to the existing database.
*/
ret_db = db_list[i];
_DtSvcProcessUnlock();
return ret_db;
}
}
/*
* We now have a count of the existing databases.
* allocate enough space for the existing databases + the new one
* + a NULL pointer to terminate the vector.
*/
new_db_list = (DtDtsDbDatabase **)calloc(i+2,sizeof(DtDtsDbDatabase *));
memmove(new_db_list,db_list,sizeof(DtDtsDbDatabase *) * i );
new_db_list[i] = (DtDtsDbDatabase *)calloc(1, sizeof(DtDtsDbDatabase));
new_db_list[i]->databaseName = strdup(db_name);
new_db_list[i]->ActionSequenceNumber = 0;
free(db_list);
db_list = new_db_list;
num_db++;
ret_db = db_list[i];
_DtSvcProcessUnlock();
return ret_db;
}
int
_DtDtsDbDeleteDb(DtDtsDbDatabase *db)
{
int i;
int flag = 0;
_DtSvcProcessLock();
_DtDtsDbDeleteRecords(db);
free(db->databaseName);
free(db);
for(i = 0; db_list[i]; i++)
{
if(db_list[i] == db)
{
flag = 1;
db_list[i] = 0;
}
if(flag)
{
db_list[i] = db_list[i+1];
}
}
if(db_list[0] == 0)
{
free(db_list);
db_list = 0;
}
_DtSvcProcessUnlock();
return(0);
}
DtDtsDbDatabase *
_DtDtsDbGet(char *name)
{
DtDtsDbDatabase *ret_db;
int i;
_DtSvcProcessLock();
if(!db_list)
{
_DtDtsDbInit();
}
for(i = 0; db_list && db_list[i] && db_list[i]->databaseName; i++)
{
if(strcmp(db_list[i]->databaseName, name) == 0)
{
ret_db = db_list[i];
_DtSvcProcessUnlock();
return(ret_db);
}
}
_DtSvcProcessUnlock();
return(NULL);
}
void
_DtDtsDbFieldSort(DtDtsDbRecord *rec, _DtDtsDbFieldCompare compare)
{
if(compare == NULL)
{
compare = _DtDtsDbCompareFieldNames;
}
qsort(rec->fieldList,
rec->fieldCount,
sizeof(DtDtsDbField *),
(genfunc)compare);
rec->compare = compare;
}
void
_DtDtsDbRecordSort(DtDtsDbDatabase *db, _DtDtsDbRecordCompare compare)
{
if(compare == NULL)
{
compare = _DtDtsDbCompareRecordNames;
}
qsort(db->recordList,
db->recordCount,
sizeof(DtDtsDbRecord *),
(genfunc)compare);
db->compare = compare;
}
DtDtsDbField *
_DtDtsDbGetField(DtDtsDbRecord *rec, char *name)
{
register int i;
/*
* Field names have been quarked so quark 'name' and
* do a linear search for the quark'ed field name.
*/
XrmQuark tmp = XrmStringToQuark (name);
for (i = 0; i < rec->fieldCount; i++)
{
if (rec->fieldList[i]->fieldName == tmp)
{
return (rec->fieldList[i]);
}
}
return(NULL);
}
char *
_DtDtsDbGetFieldByName(DtDtsDbRecord *rec, char *name)
{
DtDtsDbField *result;
result = _DtDtsDbGetField(rec, name);
if(result)
{
return(result->fieldValue);
}
else
{
return(NULL);
}
}
DtDtsDbRecord *
_DtDtsDbGetRecordByName(DtDtsDbDatabase *db, char *name)
{
DtDtsDbRecord srch;
DtDtsDbRecord **result;
DtDtsDbRecord *s = &srch;
register int i;
XrmQuark name_quark = XrmStringToQuark(name);
/*
* If the fields are not sorted in alphanumeric order
* by name a binary search will fail. So do the slow but
* sure linear search.
*/
if(db->compare != _DtDtsDbCompareRecordNames)
{
for (i = 0; i < db->recordCount; i++)
{
if (db->recordList[i]->recordName == name_quark)
{
return (db->recordList[i]);
}
}
return NULL;
}
srch.recordName = name_quark;
if(db->recordCount == 0 || db->recordList == NULL)
{
result = NULL;
}
else
{
result = (DtDtsDbRecord **)bsearch(&s,
db->recordList,
db->recordCount,
sizeof(DtDtsDbRecord *),
(genfunc)_DtDtsDbCompareRecordNames);
}
if(result)
{
return(*result);
}
else
{
return(NULL);
}
}
DtDtsDbRecord *
_DtDtsDbAddRecord(DtDtsDbDatabase *db)
{
DtDtsDbRecord **newlist;
int rec = db->recordCount;
db->compare = (_DtDtsDbRecordCompare)NULL;
if(rec%PADMEM == 0)
{
newlist = (DtDtsDbRecord **)calloc(rec+PADMEM,
sizeof(DtDtsDbRecord *));
if(db->recordList)
{
memmove(newlist, db->recordList,
rec*sizeof(DtDtsDbRecord *));
free(db->recordList);
}
db->recordList = newlist;
}
db->recordList[rec] = (DtDtsDbRecord *)calloc(1, sizeof(DtDtsDbRecord));
db->recordCount++;
return(db->recordList[rec]);
}
int
_DtDtsDbDeleteRecord(DtDtsDbRecord *rec, DtDtsDbDatabase *db)
{
int i;
_DtDtsDbDeleteFields(rec);
free(rec);
for(i = 0; i < db->recordCount; i++)
{
if(db->recordList[i] == rec)
{
memmove( &(db->recordList[i]),
&(db->recordList[i+1]),
(db->recordCount - i - 1)*
sizeof(DtDtsDbRecord *));
db->recordCount--;
return(1);
}
}
return(0);
}
int
_DtDtsDbDeleteRecords(DtDtsDbDatabase *db)
{
int i;
for(i = 0; i < db->recordCount; i++)
{
_DtDtsDbDeleteFields(db->recordList[i]);
free(db->recordList[i]);
}
free(db->recordList);
db->recordList = 0;
return(0);
}
DtDtsDbField *
_DtDtsDbAddField(DtDtsDbRecord *rec)
{
DtDtsDbField **newlist;
int flds = rec->fieldCount;
if(flds%PADMEM == 0)
{
newlist = (DtDtsDbField **)calloc(flds+PADMEM,
sizeof(DtDtsDbField *));
if(rec->fieldList)
{
memmove(newlist, rec->fieldList,
flds*sizeof(DtDtsDbField *));
free(rec->fieldList);
}
rec->fieldList = newlist;
}
rec->fieldList[flds] = (DtDtsDbField *)calloc(1, sizeof(DtDtsDbField));
rec->fieldCount++;
return(rec->fieldList[flds]);
}
int
_DtDtsDbDeleteField(DtDtsDbField *fld, DtDtsDbRecord *rec)
{
int i;
free(fld);
for(i = 0; i < rec->fieldCount; i++)
{
if(rec->fieldList[i] == fld)
{
memmove( &(rec->fieldList[i]),
&(rec->fieldList[i+1]),
(rec->fieldCount - i - 1)*
sizeof(DtDtsDbField *));
rec->fieldCount--;
return(1);
}
}
return(0);
}
int
_DtDtsDbDeleteFields(DtDtsDbRecord *rec)
{
int i;
for(i = 0; i < rec->fieldCount; i++)
{
free(rec->fieldList[i]->fieldValue);
free(rec->fieldList[i]);
}
free(rec->fieldList);
rec->fieldList = 0;
return(0);
}
int
_DtDtsMMCreateFile(DtDirPaths *dirs, const char *CacheFile)
{
return _MMWriteDb(dirs, num_db, db_list, CacheFile);
}