28#ifndef DOXYGEN_SHOULD_SKIP_THIS
33#include "git-revision.h"
41#define CHECK_OPEN_RECORD 1
136 while (msg != NULL) {
137 printf(
"db_err_msg: %p, next %p, type %d, file \'%s:%d\', function \'%s\': %s\n", msg, msg->
next, msg->
message_type, msg->
filename.c_str(), msg->
line, msg->
routine.c_str(), msg->
text.c_str());
142void db_msg(
db_err_msg** msgp,
INT message_type,
const char *filename,
INT line,
const char *routine,
const char *format, ...)
151 va_start(argptr, format);
157 const char* s =
"!db_msg too long!";
182 while (m->
next != NULL) {
185 assert(m->
next == NULL);
199 printf(
"db_flush_msg: %p\n", msg);
203 while (msg != NULL) {
239 assert(size ==
sizeof(
KEY) || size ==
sizeof(
KEYLIST));
252 bool have_good_block =
false;
260 if (pfree->
size >= size) {
261 have_good_block =
true;
265 int remaining = pfree->
size - size;
266 if ((remaining == 0) || (remaining >= (int)
ALIGN8(
sizeof(
KEYLIST))))
277 if (pass == 1 && have_good_block) {
297 assert(pfree->
size >= size);
303 if (size < pfree->size) {
337 assert((
void*)pfound != (
void*)pheader);
339 memset(pfound, 0, size);
352 assert(address != pheader);
361 memset(address, 0, size);
374 cm_msg(
MERROR,
"free_key",
"database is corrupted: pprev=%p, pprev->next_free=%d", pprev, pprev->
next_free);
392 memset(pnext, 0, pnext->
size);
400 memset(pfree, 0, pfree->
size);
453 if (pfree->
size >= size) {
475 assert(pfound != NULL);
476 assert(size <= pfound->size);
480 if (size < pfree->size) {
507 assert((
void*)pfound != (
void*)pheader);
510 memset(pfound, 0, size);
521 assert(address != pheader);
534 memset(address, 0, size);
554 while (pprev->
next_free < pfree_offset) {
561 cm_msg(
MERROR,
"free_data",
"database is corrupted: pprev=%p, pprev->next_free=%d in free_data(%p,%p,%d) from %s", pprev, pprev->
next_free, pheader, address, size, caller);
581 memset(pnext, 0, pnext->
size);
590 memset(pfree, 0, pfree->
size);
603 tmp = malloc(old_size);
605 cm_msg(
MERROR,
"realloc_data",
"cannot malloc(%d), called from %s", old_size, caller);
609 memcpy(tmp, address, old_size);
614 cm_msg(
MERROR,
"realloc_data",
"cannot free_data(%p, %d), called from %s", address, old_size, caller);
624 cm_msg(
MERROR,
"realloc_data",
"cannot malloc_data(%d), called from %s", new_size, caller);
629 memcpy(pnew, tmp, old_size < new_size ? old_size : new_size);
643 static char *
str = NULL;
651 str = (
char *) malloc(
j);
653 str = (
char *) realloc(
str,
j);
673 for (
int i = 0;
list[
i];
i++) {
687 std::string* pbuf = (std::string*)
info;
695 for (
int i = 0;
i < level;
i++)
713 return "(Cannot lock ODB)";
726 int total_size_key = 0;
730 buf +=
"ODB is corrupted: pheader->first_free_key is invalid\n";
737 total_size_key += pfree->
size;
738 buf +=
msprintf(
"Free block at %9d, size %9d, next %9d\n",
742 buf +=
"ODB is corrupted: next_free is invalid!";
749 buf +=
msprintf(
"Free Key area: %d bytes out of %d bytes\n", total_size_key, pheader->
key_size);
754 int total_size_data = 0;
758 buf +=
"ODB is corrupted: pheader->first_free_data is invalid\n";
765 total_size_data += pfree->
size;
766 buf +=
msprintf(
"Free block at %9d, size %9d, next %9d\n",
770 buf +=
"ODB is corrupted: next_free is invalid!";
777 buf +=
msprintf(
"Free Data area: %d bytes out of %d bytes\n", total_size_data, pheader->
data_size);
779 buf +=
msprintf(
"Free: %1d (%1.1lf%%) keylist, %1d (%1.1lf%%) data\n",
781 100 * (
double) total_size_key / pheader->
key_size,
782 total_size_data, 100 * (
double) total_size_data / pheader->
data_size);
785 const KEY* proot =
db_get_pkey(pheader, 0, 0,
"db_show_mem", &msg);
790 buf +=
" Key Data Size\n";
791 buf +=
"-----------------------------\n";
793 buf +=
"-----------------------------\n";
794 buf +=
" Key Data Size\n";
799 buf +=
msprintf(
"Total ODB size: %d (0x%08X) Bytes, %lg MBytes\n",
828 *key_size += pfree->
size;
837 *data_size += pfree->
size;
867 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name passed to %s: should not be NULL", caller_name);
871 size_t len = strlen(
name);
874 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name passed to %s: should not be an empty string", caller_name);
878 if (strchr(
name,
'[')) {
879 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: should not contain \"[\"",
name, caller_name);
883 if (
name[0] ==
' ') {
884 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: should not start with a space",
name, caller_name);
888 if (
name[len-1] ==
' ') {
889 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: should not end with a space",
name, caller_name);
893 if (strchr(
name,
']')) {
894 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: should not contain \"[\"",
name, caller_name);
899 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: invalid unicode UTF-8 encoding",
name, caller_name);
904 if (strchr(
name,
'/')) {
905 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: should not contain \"/\"",
name, caller_name);
910 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name \"%s\" passed to %s: length %d should be less than %d bytes",
name, caller_name, (
int)strlen(
name),
NAME_LENGTH);
964 hKey_is_root_key =
TRUE;
982 const KEY* pkey = (
const KEY *) ((
char *) pheader +
hKey);
986 if (hKey_is_root_key) {
987 db_msg(msg,
MERROR, caller,
"db_get_pkey: root_key hkey %d invalid key type %d, database root directory is corrupted",
hKey, tid);
993 db_msg(msg,
MERROR, caller,
"db_get_pkey: hkey %d path \"%s\" invalid key type %d",
hKey, path.c_str(), tid);
1000 if (pkey->
name[0] == 0) {
1002 db_msg(msg,
MERROR, caller,
"db_get_pkey: hkey %d path \"%s\" invalid name \"%s\" is empty",
hKey, path.c_str(), pkey->
name);
1015 db_msg(msg,
MERROR, caller,
"db_get_pkeylist: path \"%s\" unexpected call to db_get_pkeylist(), not a subdirectory, pkey->type %d", path.c_str(), pkey->
type);
1021 db_msg(msg,
MERROR, caller,
"Invalid pkey->data %d at path \"%s\"", pkey->
data, path.c_str());
1034 if (!kludge_repair) {
1036 db_msg(msg,
MERROR, caller,
"Invalid pkeylist->first_key %d should be non zero for num_keys %d at \"%s\"", pkeylist->
first_key, pkeylist->
num_keys, path.c_str());
1045 db_msg(msg,
MERROR, caller,
"Repaired invalid num_keys %d when pkeylist->first_key is zero at \"%s\"", pkeylist->
num_keys, path.c_str());
1046 ((
KEYLIST*)pkeylist)->num_keys = 0;
1087 db_msg(msg,
MERROR,
"db_enum_first_locked",
"path \"%s\" tid %d is not a directory", path.c_str(), pkey->
type);
1131 if (*((
char *) pheader + pkey->
data) ==
'/') {
1145 path = xpath.c_str();
1148 printf(
"path \"%s\", parenthkey %d, hkey %d, name \"%s\", type %d, parent %d, data %d, total_size %d", path, parenthkeylist, hkey, pkey->
name, pkey->
type, pkey->
parent_keylist, pkey->
data, pkey->
total_size);
1156 printf(
", pkeylist parent %d, num_keys %d, first_key %d", pkeylist->
parent, pkeylist->
num_keys, pkeylist->
first_key);
1164 const KEY *pkey =
db_get_pkey(pheader, hkey, NULL,
"db_print_key", NULL);
1170 db_print_pkey(pheader, pkey, recurse, path, parenthkeylist);
1179 db_msg(msg,
MERROR,
"db_validate_and_repair_key_wlocked",
"Max ODB depth level %d exceeded at \"%s\"",
MAX_ODB_PATH, path);
1192 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid hkey", hkey, path);
1198 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", name \"%s\", invalid key type %d", hkey, path, pkey->
name, pkey->
type);
1206 sprintf(newname,
"%p", pkey);
1207 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\": invalid name \"%s\" replaced with \"%s\"", hkey, path, pkey->
name, newname);
1208 mstrlcpy(pkey->
name, newname,
sizeof(pkey->
name));
1215 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", name \"%s\", invalid parent_keylist %d should be %d", hkey, path, pkey->
name, pkey->
parent_keylist, parenthkeylist);
1220 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid data offset 0x%08X is invalid", hkey, path, pkey->
data - (
int)
sizeof(
DATABASE_HEADER));
1226 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->total_size %d", hkey, path, pkey->
total_size);
1231 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->item_size: %d", hkey, path, pkey->
item_size);
1236 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->num_values: %d", hkey, path, pkey->
num_values);
1242 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", corrected pkey->total_size from %d to %d*%d=%d", hkey, path, pkey->
total_size, pkey->
item_size, pkey->
num_values, pkey->
item_size * pkey->
num_values);
1249 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", pkey->data is zero, corrected pkey->num_values %d and pkey->total_size %d to be zero, should be zero", hkey, path, pkey->
num_values, pkey->
total_size);
1256 const char* s = (
char*)pheader + pkey->
data;
1258 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", string value is not valid UTF-8", hkey, path);
1270 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK is an empty link", hkey, path);
1287 const char* link = (
char*)pheader + pkey->
data;
1288 int link_len = strlen(link);
1289 int path_len = strlen(path);
1290 if (link_len == path_len) {
1293 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK to \"%s\" is a link to itself", hkey, path, link);
1297 }
else if (link_len < path_len) {
1300 memcpy(tmp, path, link_len);
1303 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK to \"%s\" is a loop", hkey, path, link);
1312 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->access_mode %d", hkey, path, pkey->
access_mode);
1319 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->last_written time %d", hkey, path, pkey->
last_written);
1325 bool pkeylist_ok =
true;
1330 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->data %d", hkey, path, pkey->
data);
1333 if (pkeylist->
parent != hkey) {
1334 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid pkeylist->parent %d is not hkey %d", hkey, path, pkeylist->
parent, hkey);
1336 pkeylist_ok =
false;
1340 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid pkeylist->num_keys %d", hkey, path, pkeylist->
num_keys);
1342 pkeylist_ok =
false;
1348 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid pkeylist->first_key %d", hkey, path, pkeylist->
first_key);
1350 pkeylist_ok =
false;
1359 while (subhkey != 0) {
1360 KEY* subpkey = (
KEY*)
db_get_pkey(pheader, subhkey, NULL,
"db_validate_key", msg);
1362 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid subhkey %d", hkey, path, subhkey);
1363 pkeylist_ok =
false;
1371 buf += subpkey->
name;
1384 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", repaired TID_KEY mismatch of pkeylist->num_keys %d against key chain length %d", hkey, path, pkeylist->
num_keys,
count);
1387 pkeylist_ok =
false;
1408 cm_msg(
MERROR,
"db_get_my_client_locked",
"My client index %d in ODB is invalid: out of range 0..%d. Maybe this client was removed by a timeout, see midas.log. Cannot continue, aborting...", idx, pheader->
max_client_index-1);
1415 if (pclient->
name[0] == 0) {
1416 cm_msg(
MERROR,
"db_get_my_client_locked",
"My client index %d in ODB is invalid: client name is blank. Maybe this client was removed by a timeout, see midas.log. Cannot continue, aborting...", idx);
1423 if (pclient->
pid != pid) {
1424 cm_msg(
MERROR,
"db_get_my_client_locked",
"My client index %d in ODB is invalid: pid mismatch, my pid is %d, but ODB has %d. Maybe this client was removed by a timeout, see midas.log. Cannot continue, aborting...", idx, pid, pclient->
pid);
1449#define S(x) printf("assert(sizeof(%-20s) == %6d);\n", #x, (int)sizeof(x))
1497 printf(
"EQUIPMENT_INFO offset of event_id: %d\n", (
int)((
char*)&
eq.event_id - (
char*)&
eq));
1498 printf(
"EQUIPMENT_INFO offset of eq_type: %d\n", (
int)((
char*)&
eq.eq_type - (
char*)&
eq));
1499 printf(
"EQUIPMENT_INFO offset of event_limit: %d\n", (
int)((
char*)&
eq.event_limit - (
char*)&
eq));
1500 printf(
"EQUIPMENT_INFO offset of num_subevents: %d\n", (
int)((
char*)&
eq.num_subevents - (
char*)&
eq));
1501 printf(
"EQUIPMENT_INFO offset of status: %d\n", (
int)((
char*)&
eq.status - (
char*)&
eq));
1502 printf(
"EQUIPMENT_INFO offset of hidden: %d\n", (
int)((
char*)&
eq.hidden - (
char*)&
eq));
1505 assert(
sizeof(
UINT8) == 1);
1506 assert(
sizeof(
INT8) == 1);
1507 assert(
sizeof(
UINT16) == 2);
1508 assert(
sizeof(
INT16) == 2);
1509 assert(
sizeof(
UINT32) == 4);
1510 assert(
sizeof(
INT32) == 4);
1511 assert(
sizeof(
UINT64) == 8);
1512 assert(
sizeof(
INT64) == 8);
1521 assert(
sizeof(
TAG) == 40);
1522 assert(
sizeof(
KEY) == 68);
1523 assert(
sizeof(
KEYLIST) == 12);
1531 assert(
sizeof(
BANK) == 8);
1532 assert(
sizeof(
BANK32) == 12);
1535 assert(
sizeof(
ALARM) == 460);
1593 printf(
"%s, notify_count %d, found %d, our count %d\n", path, pkey->
notify_count, found,
count);
1597 db_msg(msg,
MINFO,
"db_update_open_record",
"Added missing open record flag to \"%s\"", path.c_str());
1604 db_msg(msg,
MINFO,
"db_update_open_record",
"Removed open record flag from \"%s\"", path.c_str());
1611 db_msg(msg,
MERROR,
"db_update_open_record",
"Cannot remove exclusive access mode from \"%s\", db_set_mode() status %d", path.c_str(),
status);
1614 db_msg(msg,
MINFO,
"db_update_open_record",
"Removed exclusive access mode from \"%s\"", path.c_str());
1642 assert(uor.
hkeys != NULL);
1643 assert(uor.
counts != NULL);
1644 assert(uor.
modes != NULL);
1671 printf(
"index %d, handle %d, count %d, access mode %d\n",
i, uor.
hkeys[
i], uor.
counts[
i], uor.
modes[
i]);
1694 int total_size_key = 0;
1695 int total_size_data = 0;
1721 total_size_key += pfree->
size;
1724 if (pfree->
next_free != 0 && nextpfree == pfree) {
1725 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database corruption, key area next_free 0x%08X is same as current free %p, truncating the free list", pfree->
next_free, pfree - (
int)
sizeof(
DATABASE_HEADER));
1735 ratio = ((double) (pheader->
key_size - total_size_key)) / ((
double) pheader->
key_size);
1737 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database key area is %.0f%% full", ratio * 100.0);
1739 if (total_size_key > pheader->
key_size) {
1740 db_msg(msg,
MERROR,
"db_validate_db",
"Error: database corruption, total_key_size 0x%08X bigger than pheader->key_size 0x%08X", total_size_key, pheader->
key_size);
1764 total_size_data += pfree->
size;
1767 if (pfree->
next_free != 0 && nextpfree == pfree) {
1768 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database corruption, data area next_free 0x%08X is same as current free %p, truncating the free list", pfree->
next_free, pfree - (
int)
sizeof(
DATABASE_HEADER));
1778 ratio = ((double) (pheader->
data_size - total_size_data)) / ((
double) pheader->
data_size);
1780 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database data area is %.0f%% full", ratio * 100.0);
1782 if (total_size_data > pheader->
data_size) {
1783 db_msg(msg,
MERROR,
"db_validate_db",
"Error: database corruption, total_size_data 0x%08X bigger than pheader->data_size 0x%08X", total_size_key, pheader->
data_size);
1798 db_msg(msg,
MERROR,
"db_validate_db",
"Error: ODB corruption detected, see previous messages");
1825#ifdef LOCAL_ROUTINES
1840 mstrlcpy(database_name, xdatabase_name,
NAME_LENGTH);
1842 int odb_size_limit = 100*1000*1000;
1843 if (database_size < 0 || database_size > odb_size_limit) {
1844 cm_msg(
MERROR,
"db_open_database",
"invalid database size: %d bytes. ODB size limit is %d bytes", database_size, odb_size_limit);
1849 cm_msg(
MERROR,
"db_open_database",
"client name \'%s\' is longer than %d characters", client_name,
NAME_LENGTH-1);
1853 if (strchr(client_name,
'/') != NULL) {
1854 cm_msg(
MERROR,
"db_open_database",
"client name \'%s\' should not contain the slash \'/\' character", client_name);
1905 void* shm_adr = NULL;
1906 size_t shm_size = 0;
1933 if (shm_created && pheader->
name[0] == 0) {
1937 strcpy(pheader->
name, database_name);
1962 strcpy(pkey->
name,
"root");
1988 cm_msg(
MERROR,
"db_open_database",
"Invalid database, shared memory size %d is smaller than database size %d (header: %d, key area: %d, data area: %d). Delete this shared memory (odbedit -R), create a new odb (odbinit) and reload it from the last odb save file.",
_database[handle].shm_size, (
int)
sizeof(
DATABASE_HEADER) + pheader->
key_size + pheader->
data_size, (
int)
sizeof(
DATABASE_HEADER), pheader->
key_size, pheader->
data_size);
1994 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key offset %d is invalid", pheader->
root_key);
1997 pkey = (
KEY*)((
char*)pheader + pheader->
root_key);
2000 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key type %d is not TID_KEY", pkey->
type);
2004 if (strcmp(pkey->
name,
"root") != 0) {
2005 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key name \"%s\" is not \"root\"", pkey->
name);
2020 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key is invalid");
2063 int num_clients = 0;
2064 int max_client_index = 0;
2069 max_client_index =
i + 1;
2084 mstrlcpy(client_name_tmp, pheader->
client[
i].
name,
sizeof(client_name_tmp));
2093 cm_msg(
MERROR,
"db_open_database",
"Removed ODB client \'%s\', index %d because process pid %d does not exists", client_name_tmp,
i, client_pid);
2107 cm_msg(
MERROR,
"db_open_database",
"maximum number of clients exceeded");
2123 pclient = &pheader->
client[
i];
2126 mstrlcpy(pclient->
name, client_name,
sizeof(pclient->
name));
2160 *
hDB = (handle + 1);
2167 cm_msg(
MERROR,
"db_open_database",
"Error: db_validate_open_records() status %d",
status);
2195#ifdef LOCAL_ROUTINES
2197 INT destroy_flag,
i,
j;
2201 cm_msg(
MERROR,
"db_close_database",
"invalid database handle %d",
hDB);
2215 cm_msg(
MERROR,
"db_close_database",
"database not attached");
2253 mstrlcpy(xname, pheader->
name,
sizeof(xname));
2303#ifndef DOXYGEN_SHOULD_SKIP_THIS
2330#ifdef LOCAL_ROUTINES
2333 uint32_t flush_period = 60;
2334 uint32_t last_flush = 0;
2337 cm_msg(
MERROR,
"db_flush_database",
"invalid database handle");
2342 size =
sizeof(flush_period);
2344 size =
sizeof(last_flush);
2350 cm_msg(
MERROR,
"db_flush_database",
"Cannot obtain key /System/Flush/Last flush");
2360 cm_msg(
MERROR,
"db_flush_database",
"invalid database handle");
2375 size =
sizeof(last_flush);
2379 if (
ss_time() > last_flush + flush_period) {
2427#ifdef LOCAL_ROUTINES
2463#ifdef LOCAL_ROUTINES
2466 cm_msg(
MERROR,
"db_set_client_name",
"invalid database handle %d",
hDB);
2474 mstrlcpy(pclient->
name, client_name,
sizeof(pclient->
name));
2495#ifdef LOCAL_ROUTINES
2506#ifdef LOCAL_ROUTINES
2511 cm_msg(
MERROR, caller,
"invalid database handle %d, aborting...",
hDB);
2521 if (check_attached && !pdb->
attached) {
2522 cm_msg(
MERROR, caller,
"invalid database handle %d, aborting...",
hDB);
2531 cm_msg(
MERROR,
"db_lock_database",
"database handle mismatch %d vs %d, aborting...",
hDB, pdb->
hDB);
2542 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB mutex, timeout %d ms, status %d, aborting...", pdb->
timeout,
status);
2549 fprintf(stderr,
"db_lock_database: Detected recursive call to db_{lock,unlock}_database() while already inside db_{lock,unlock}_database(). Maybe this is a call from a signal handler. Cannot continue, aborting...\n");
2575 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB semaphore, timeout %d ms, aborting...", pdb->
timeout);
2581 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB semaphore, timeout %d ms, ss_semaphore_wait_for() status %d, aborting...", pdb->
timeout,
status);
2589#ifdef CHECK_LOCK_COUNT
2603 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB, ss_shm_unprotect(TRUE,FALSE) failed with status %d, aborting...",
status);
2629 cm_msg(
MERROR,
"db_allow_write_locked",
"cannot write to ODB, ss_shm_unprotect(TRUE,TRUE) failed with status %d, aborting...",
status);
2650#ifdef LOCAL_ROUTINES
2653 cm_msg(
MERROR,
"db_unlock_database",
"invalid database handle %d",
hDB);
2668#ifdef LOCAL_ROUTINES
2672#ifdef CHECK_LOCK_COUNT
2681 fprintf(stderr,
"db_unlock_database: Detected recursive call to db_{lock,unlock}_database() while already inside db_{lock,unlock}_database(). Maybe this is a call from a signal handler. Cannot continue, aborting...\n");
2704 cm_msg(
MERROR,
"db_unlock_database",
"cannot unlock ODB, ss_shm_protect() failed with status %d, aborting...",
status);
2728#ifdef LOCAL_ROUTINES
2735 cm_msg(
MERROR,
"db_get_lock_cnt",
"invalid database handle %d, aborting...",
hDB);
2736 fprintf(stderr,
"db_get_lock_cnt: invalid database handle %d, aborting...\n",
hDB);
2750#ifdef LOCAL_ROUTINES
2757 cm_msg(
MERROR,
"db_set_lock_timeout",
"invalid database handle %d",
hDB);
2761 if (timeout_millisec > 0) {
2771#ifdef LOCAL_ROUTINES
2789 if (pdbclient->
pid == pid) {
2799 cm_msg(
MERROR,
"db_update_last_activity",
"Did not find this client in any database. Maybe this client was removed by a timeout, see midas.log. Cannot continue, aborting...");
2808#ifdef LOCAL_ROUTINES
2843#ifdef LOCAL_ROUTINES
2851 std::string
str =
msprintf(
"System/Clients/%0d", pid);
2878#ifdef LOCAL_ROUTINES
2880 cm_msg(
MERROR,
"db_delete_client_info",
"invalid database handle");
2885 cm_msg(
MERROR,
"db_delete_client_info",
"invalid database handle");
2913#ifdef LOCAL_ROUTINES
2931 if (wrong_interval) {
2942 int client_pid = pdbclient->
pid;
2943 if (client_pid == 0)
2947 db_msg(&msg,
MINFO,
"db_cleanup",
"Client \'%s\' on database \'%s\' pid %d does not exist and db_cleanup called by %s removed it", pdbclient->
name, pheader->
name, client_pid, who);
2961 db_msg(&msg,
MINFO,
"db_cleanup",
"Client \'%s\' on database \'%s\' pid %d timed out and db_cleanup called by %s removed it (idle %1.1lfs,TO %1.0lfs)",
2962 pdbclient->
name, pheader->
name, client_pid,
2979#ifdef LOCAL_ROUTINES
3009 if (!pdbclient->
pid)
3011 if ((client_name == NULL || client_name[0] == 0
3012 || strncmp(pdbclient->
name, client_name, strlen(client_name)) == 0)) {
3013 int client_pid = pdbclient->
pid;
3016 db_msg(&msg,
MINFO,
"db_cleanup2",
"Client \'%s\' on database \'%s\' pid %d does not exist and db_cleanup2 called by %s removed it",
3037 if ((interval > 0 && now - pdbclient->
last_activity > interval)) {
3038 db_msg(&msg,
MINFO,
"db_cleanup2",
"Client \'%s\' on database \'%s\' timed out and db_cleanup2 called by %s removed it (idle %1.1lfs,TO %1.0lfs)",
3041 (now - pdbclient->
last_activity) / 1000.0, interval / 1000.0);
3101 cm_msg(
MERROR,
"db_get_watchdog_info",
"invalid database handle");
3106 cm_msg(
MERROR,
"db_get_watchdog_info",
"invalid database handle");
3127 *timeout = *last = 0;
3146 cm_msg(
MERROR,
"db_check_client",
"invalid database handle");
3151 cm_msg(
MERROR,
"db_check_client",
"invalid database handle");
3173 int client_pid = atoi(pkey->
name);
3186 int size =
sizeof(
name);
3204 if (pclient->
pid == client_pid) {
3219 if (!found || dead) {
3227 db_msg(&msg,
MERROR,
"db_check_client",
"Cannot delete client info for client \'%s\', pid %d, db_delete_client_info() status %d",
name, client_pid,
status);
3229 db_msg(&msg,
MINFO,
"db_check_client",
"Deleted entry \'/System/Clients/%d\' for client \'%s\' because it is not connected to ODB", client_pid,
name);
3231 db_msg(&msg,
MINFO,
"db_check_client",
"Deleted entry \'/System/Clients/%d\' for client \'%s\' because process pid %d does not exists", client_pid,
name, client_pid);
3256#ifdef LOCAL_ROUTINES
3258 cm_msg(
MERROR,
"db_protect_database",
"invalid database handle %d",
hDB);
3271const char *
extract_key(
const char *key_list,
char *key_name,
int key_name_length)
3275 if (*key_list ==
'/')
3278 while (*key_list && *key_list !=
'/' && ++
i < key_name_length)
3279 *key_name++ = *key_list++;
3287 if (str1 == NULL && str2 != NULL)
3289 if (str1 != NULL && str2 == NULL)
3291 if (str1 == NULL && str2 == NULL)
3293 if (strlen(str1) != strlen(str2))
3297 if (toupper(*str1++) != toupper(*str2++))
3308 int len_str = strlen(
str);
3309 int len_suffix = strlen(suffix);
3312 if (len_suffix > len_str)
3331 if(pattern[1] == 0)
return true;
3347 }
else if(toupper(*
str) == toupper(*pattern)){
3360 *index1 = *index2 = 0;
3361 if (odbpath[strlen(odbpath) - 1] ==
']') {
3362 if (strchr(odbpath,
'[')) {
3363 if (*(strchr(odbpath,
'[') + 1) ==
'*')
3365 else if (strchr((strchr(odbpath,
'[') + 1),
'.') ||
3366 strchr((strchr(odbpath,
'[') + 1),
'-')) {
3367 *index1 = atoi(strchr(odbpath,
'[') + 1);
3368 pc = strchr(odbpath,
'[') + 1;
3369 while (*pc !=
'.' && *pc !=
'-')
3371 while (*pc ==
'.' || *pc ==
'-')
3375 *index1 = atoi(strchr(odbpath,
'[') + 1);
3379 *strchr(odbpath,
'[') = 0;
3398#ifdef LOCAL_ROUTINES
3403 cm_msg(
MERROR,
"db_create_key",
"invalid database handle");
3408 cm_msg(
MERROR,
"db_create_key",
"invalid database handle");
3431 KEY* newpkey = NULL;
3447#ifdef LOCAL_ROUTINES
3456 if (parentKey== NULL) {
3471 if (type <= 0 || type >=
TID_LAST) {
3476 const KEY* pdir = parentKey;
3479 db_msg(msg,
MERROR,
"db_create_key",
"cannot create \'%s\' in \'%s\' tid is %d, not a directory", key_name,
db_get_path_pkey(pheader, pdir).c_str(), pdir->
type);
3483 KEY* pcreated = NULL;
3485 const char* pkey_name = key_name;
3505 if (strcmp(
name,
"..") == 0) {
3512 if (strcmp(
name,
".") == 0)
3522 pprev = (
KEY*)pitem;
3555 db_msg(msg,
MERROR,
"db_create_key",
"online database full while creating \'%s\' in \'%s\'", key_name,
db_get_path_pkey(pheader, parentKey).c_str());
3575 if (pkeylist == NULL) {
3576 db_msg(msg,
MERROR,
"db_create_key",
"online database full while creating \'%s\' in \'%s'", key_name,
db_get_path_pkey(pheader, parentKey).c_str());
3599 db_msg(msg,
MERROR,
"db_create_key",
"online database full while creating \'%s\' in \'%s\'", key_name,
db_get_path_pkey(pheader, parentKey).c_str());
3621 db_msg(msg,
MERROR,
"db_create_key",
"online database full while creating \'%s\' in \'%s\'", key_name,
db_get_path_pkey(pheader, parentKey).c_str());
3647 if (!(*pkey_name ==
'/')) {
3649 db_msg(msg,
MERROR,
"db_create_key",
"object of type %d already exists at \"%s\" while creating \'%s\' of type %d in \'%s\'", pitem->
type,
db_get_path_pkey(pheader, pitem).c_str(), key_name,
type,
db_get_path_pkey(pheader, parentKey).c_str());
3655 *pnewkey = (
KEY*)pitem;
3661 db_msg(msg,
MERROR,
"db_create_key",
"path element \"%s\" in \"%s\" is not a subdirectory at \"%s\" while creating \'%s\' in \'%s\'",
name, key_name,
db_get_path_pkey(pheader, pitem).c_str(), key_name,
db_get_path_pkey(pheader, parentKey).c_str());
3667 }
while (*pkey_name ==
'/');
3669 assert(pcreated != NULL);
3672 *pnewkey = pcreated;
3696 if (destination == NULL) {
3697 cm_msg(
MERROR,
"db_create_link",
"link destination name is NULL");
3701 if (destination[0] !=
'/') {
3702 cm_msg(
MERROR,
"db_create_link",
"link destination name \'%s\' should start with \'/\', relative links are forbidden", destination);
3706 if (strlen(destination) < 1) {
3707 cm_msg(
MERROR,
"db_create_link",
"link destination name \'%s\' is too short", destination);
3711 if ((destination[0] ==
'/') && (destination[1] == 0)) {
3712 cm_msg(
MERROR,
"db_create_link",
"links to \"/\" are forbidden");
3719 cm_msg(
MERROR,
"db_create_link",
"Link destination \"%s\" does not exist", destination);
3735 cm_msg(
MERROR,
"db_create_link",
"Existing key \"%s\" is not a link", link_name);
3757#ifdef LOCAL_ROUTINES
3763#ifdef CHECK_OPEN_RECORD
3798 bool deny_delete =
false;
3838#ifdef CHECK_OPEN_RECORD
3882 ((
KEYLIST*)pkeylist)->num_keys--;
3938#ifdef LOCAL_ROUTINES
3971#ifdef LOCAL_ROUTINES
4009#ifdef LOCAL_ROUTINES
4041#ifdef LOCAL_ROUTINES
4054 db_msg(msg,
MERROR,
"db_find_key",
"Path \"%s\" tid %d is not a directory, looking for \"%s\"", path.c_str(), tid, key_name);
4060 if (key_name[0] == 0 || strcmp(key_name,
"/") == 0) {
4080 const char *pkey_name = key_name;
4082 assert(pkeylist!=NULL);
4090 if (strchr(
str,
'[') &&
str[strlen(
str) - 1] ==
']')
4091 *strchr(
str,
'[') = 0;
4094 if (strcmp(
str,
"..") == 0) {
4098 pkey = (
KEY *) ((
char *) pheader + pkeylist->
parent);
4102 if (strcmp(
str,
".") == 0)
4105 last_good_hkey =
hKey;
4122 db_msg(msg,
MERROR,
"db_find_key",
"hkey %d path \"%s\" invalid subdirectory entry hkey %d, looking for \"%s\"", last_good_hkey, path.c_str(),
hKey, key_name);
4128 db_msg(msg,
MERROR,
"db_find_key",
"hkey %d path \"%s\" invalid next_key %d, looking for \"%s\"",
hKey, path.c_str(), pkey->
next_key, key_name);
4155 mstrlcpy(
str, (
char *) pheader + pkey->
data,
sizeof(
str));
4156 if (
str[strlen(
str) - 1] ==
'/')
4157 str[strlen(
str) - 1] = 0;
4160 if (
str[strlen(
str) - 1] ==
']')
4165 mstrlcat(
str, pkey_name,
sizeof(
str));
4182 if (*pkey_name ==
'/') {
4203 }
while (*pkey_name ==
'/' && *(pkey_name + 1));
4261#ifdef LOCAL_ROUTINES
4290#ifndef DOXYGEN_SHOULD_SKIP_THIS
4323#ifdef LOCAL_ROUTINES
4378 char *pattern = NULL;
4379 char *subkeypath = NULL;
4380 char *parentkeypath = NULL;
4384 mstrlcpy(localpath, odbpath,
sizeof(localpath));
4385 parentkeypath = localpath;
4389 char *wildcard = strpbrk(localpath,
"*?");
4392 subkeypath = strchr(wildcard,
'/');
4398 parentkeypath = strrchr(localpath,
'/');
4399 if (parentkeypath) {
4402 pattern = parentkeypath+1;
4403 if((parentkeypath-1) == localpath){
4405 parentkeypath = NULL;
4407 parentkeypath = localpath;
4411 pattern = localpath;
4412 parentkeypath = NULL;
4421 if (parentkeypath) {
4433 hKeyVector.push_back(
hKey);
4439 for (
int i=0 ; ;
i++) {
4461 hKeyVector.push_back(hSubKey);
4469 if (hKeyVector.empty())
4498#ifdef LOCAL_ROUTINES
4505 cm_msg(
MERROR,
"db_get_parent",
"invalid database handle");
4510 cm_msg(
MERROR,
"db_get_parent",
"invalid database handle");
4522 pkey = (
const KEY *) ((
char *) pheader +
hKey);
4532 pkey = (
const KEY *) ((
char *) pheader + pkeylist->
parent);
4598#ifdef LOCAL_ROUTINES
4602 assert(pkey != NULL);
4615 while (subkey != NULL) {
4680#ifdef LOCAL_ROUTINES
4684 std::string path =
"";
4691 std::string xpath =
msprintf(
"(INVALID_KEY_TYPE_%d)", pkey->
type);;
4692 if (path.length() > 0) {
4700 std::string
str = path;
4702 if (pkey->
name[0] == 0) {
4703 path +=
"(EMPTY_NAME)";
4707 if (
str.length() > 0)
4716 return "(INVALID_PARENT_KEYLIST)/" + path;
4726 if (pkeylist->
parent == 0) {
4727 return "(NULL_PARENT)/" + path;
4731 return "(INVALID_PARENT)/" + path;
4734 pkey = (
const KEY *) ((
char *) pheader + pkeylist->
parent);
4739 return "(TRUNCATED)/" + path;
4760 return "(ZERO_HKEY)";
4765 return "(INVALID_HKEY)";
4768 const KEY* pkey = (
const KEY *) ((
char *) pheader +
hKey);
4802#ifdef LOCAL_ROUTINES
4815 mstrlcpy(path, xpath.c_str(), buf_size);
4849#ifdef LOCAL_ROUTINES
4856 return "(CANNOT LOCK ODB)";
4866 return "(no LOCAL_ROUTINES)";
4869#ifdef LOCAL_ROUTINES
4893 line += pclient->
name;
4900 line +=
" a deleted client";
4905 std::string *result = (std::string*)xresult;
4915 std::string *result = (std::string*)xresult;
4930 if (j < pclient->max_index)
4941 KEY *pkey = (
KEY *) ((
char *) pheader +
hKey);
4946 *result +=
" fixed\n";
4985#ifdef LOCAL_ROUTINES
4994 mstrlcpy(
str, result.c_str(), buf_size);
5034#ifdef LOCAL_ROUTINES
5038 if (num_values == 0)
5067#ifdef LOCAL_ROUTINES
5072 if (num_values == 0)
5085 if (data_size == 0) {
5086 db_msg(msg,
MERROR,
"db_set_value",
"zero data size not allowed");
5091 db_msg(msg,
MERROR,
"db_set_value",
"\"%s\" data_size %d does not match tid %d size %d times num_values %d", key_name, data_size,
type,
rpc_tid_size(
type), num_values);
5190#ifdef LOCAL_ROUTINES
5206 mstrlcpy(keyname, key_name,
sizeof(keyname));
5208 if (strchr(keyname,
'[') && strchr(keyname,
']')) {
5210 for (p = strchr(keyname,
'[') + 1; *p && *p !=
']'; p++)
5214 if (*p && *p ==
']') {
5215 idx = atoi(strchr(keyname,
'[') + 1);
5216 *strchr(keyname,
'[') = 0;
5276#ifdef LOCAL_ROUTINES
5299 memcpy(
data, (
char *) pheader + pkey->
data, *buf_size);
5300 db_msg(msg,
MERROR,
"db_get_data_locked",
"odb entry \"%s\" data truncated, size is %d (%d*%d), buffer size is only %d",
db_get_path_pkey(pheader, pkey).c_str(), pkey->
num_values * pkey->
item_size, pkey->
num_values, pkey->
item_size, *buf_size);
5362#ifdef LOCAL_ROUTINES
5369 cm_msg(
MERROR,
"db_enum_key",
"invalid database handle");
5374 cm_msg(
MERROR,
"db_enum_key",
"invalid database handle");
5430 cm_msg(
MERROR,
"db_enum_key",
"hkey %d path \"%s\" invalid first_key %d",
hKey, path.c_str(), xfirst_key);
5434 for (
i = 0;
i < idx;
i++) {
5438 cm_msg(
MERROR,
"db_enum_key",
"hkey %d path \"%s\" unexpected end of key list at index %d",
hKey, path.c_str(),
i);
5448 cm_msg(
MERROR,
"db_enum_key",
"hkey %d path \"%s\" invalid key list at index %d, next_key %d",
hKey, path.c_str(),
i, pkey->
next_key);
5455 const char*
str = (
char *) pheader + pkey->
data;
5458 if (strlen(
str) > 0 &&
str[strlen(
str) - 1] ==
']') {
5472 parent = pkeylist->
parent;
5491#ifndef DOXYGEN_SHOULD_SKIP_THIS
5525#ifdef LOCAL_ROUTINES
5533 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5538 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5557 pkey = (
KEY *) ((
char *) pheader +
hKey);
5563 pkeylist = (
KEYLIST *) ((
char *) pheader + pkey->
data);
5571 pkey = (
KEY *) ((
char *) pheader + pkeylist->
first_key);
5572 for (
i = 0;
i < idx;
i++) {
5574 pkey = (
KEY *) ((
char *) pheader + pkey->
next_key);
5612#ifdef LOCAL_ROUTINES
5620 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5625 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5644 pkey = (
KEY *) ((
char *) pheader +
hKey);
5652 pkey = (
KEY *) ((
char *) pheader + pkey->
next_key);
5673 pkey = (
KEY *) ((
char *) pheader + pkeylist->
parent);
5679 pkeylist = (
KEYLIST *) ((
char *) pheader + pkey->
data);
5687 pkey = (
KEY *) ((
char *) pheader + pkeylist->
first_key);
5705#ifdef LOCAL_ROUTINES
5710 sub_handles->clear();
5740 sub_handles->push_back(hlink);
5742 sub_keys->push_back(*plink);
5747 sub_handles->push_back(hsubkey);
5749 sub_keys->push_back(*psubkey);
5753 sub_handles->push_back(hsubkey);
5755 sub_keys->push_back(*psubkey);
5791 sub_handles->clear();
5796 for (
int i=0 ; ;
i++) {
5813 sub_handles->push_back(
hSubkey);
5815 sub_keys->push_back(subkey);
5822#ifdef LOCAL_ROUTINES
5825 sub_handles->clear();
5881 sub_handles->clear();
5896 for (
int i=0 ; ;
i++) {
5913 sub_handles->push_back(
hSubkey);
5915 sub_keys->push_back(subkey);
5922#ifdef LOCAL_ROUTINES
5925 sub_handles->clear();
5964#ifdef LOCAL_ROUTINES
5976 const KEY* pkey = (
const KEY *) ((
char *) pheader +
hKey);
5979 int pkey_type = pkey->
type;
5980 db_msg(msg,
MERROR,
"db_get_key",
"hkey %d invalid key type %d",
hKey, pkey_type);
5987 mstrlcpy(link_name, (
char *) pheader + pkey->
data,
sizeof(link_name));
5988 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] ==
']') {
5989 if (strchr(link_name,
'[') == NULL)
6001 memcpy(
key, pkey,
sizeof(
KEY));
6048#ifdef LOCAL_ROUTINES
6054 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6059 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6101#ifdef LOCAL_ROUTINES
6106 cm_msg(
MERROR,
"db_get_link",
"invalid database handle");
6111 cm_msg(
MERROR,
"db_get_link",
"invalid database handle");
6130 memcpy(
key, pkey,
sizeof(
KEY));
6132 memset(
key, 0,
sizeof(
KEY));
6161#ifdef LOCAL_ROUTINES
6167 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6172 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6191 pkey = (
KEY *) ((
char *) pheader +
hKey);
6220#ifdef LOCAL_ROUTINES
6227 cm_msg(
MERROR,
"db_get_key_info",
"invalid database handle");
6232 cm_msg(
MERROR,
"db_get_key_info",
"invalid database handle");
6237 cm_msg(
MERROR,
"db_get_key_info",
"invalid key handle");
6251 pkey = (
KEY *) ((
char *) pheader +
hKey);
6253 if ((
INT) strlen(pkey->
name) + 1 > name_size) {
6255 memcpy(
name, pkey->
name, name_size - 1);
6256 name[name_size] = 0;
6261 if (strcmp(
name,
"root") == 0)
6269 pkeylist = (
KEYLIST *) ((
char *) pheader + pkey->
data);
6281#ifndef DOXYGEN_SHOULD_SKIP_THIS
6310#ifdef LOCAL_ROUTINES
6317 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6322 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6343 if (strlen(
name) < 1) {
6344 cm_msg(
MERROR,
"db_rename_key",
"key name is too short");
6348 if (strchr(
name,
'/')) {
6349 cm_msg(
MERROR,
"db_rename_key",
"key name may not contain \"/\"");
6363 pkey = (
KEY *) ((
char *) pheader +
hKey);
6366 int pkey_type = pkey->
type;
6368 cm_msg(
MERROR,
"db_rename_key",
"hkey %d invalid key type %d",
hKey, pkey_type);
6412#ifdef LOCAL_ROUTINES
6415 KEY *pkey, *pnext_key, *pkey_tmp;
6420 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6425 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6444 pkey = (
KEY *) ((
char *) pheader +
hKey);
6447 int pkey_type = pkey->
type;
6449 cm_msg(
MERROR,
"db_reorder_key",
"hkey %d invalid key type %d",
hKey, pkey_type);
6460#ifdef CHECK_OPEN_RECORD
6471 pkey = (
KEY *) ((
char *) pheader + pkeylist->
parent);
6476 pkey = (
KEY *) ((
char *) pheader +
hKey);
6482 if ((
KEY *) ((
char *) pheader + pkeylist->
first_key) == pkey) {
6488 pkey_tmp = (
KEY *) ((
char *) pheader + pkeylist->
first_key);
6489 while ((
KEY *) ((
char *) pheader + pkey_tmp->
next_key) != pkey) {
6491 pkey_tmp = (
KEY *) ((
char *) pheader + pkey_tmp->
next_key);
6498 pkey_tmp = (
KEY *) ((
char *) pheader + pkeylist->
first_key);
6499 if (idx < 0 || idx >= pkeylist->
num_keys - 1) {
6505 pkey_tmp = (
KEY *) ((
char *) pheader + pkey_tmp->
next_key);
6517 for (
i = 0;
i < idx - 1;
i++) {
6519 pkey_tmp = (
KEY *) ((
char *) pheader + pkey_tmp->
next_key);
6568#ifdef LOCAL_ROUTINES
6573 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6578 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6611 std::string link_name = (
char *) pheader + pkey->
data;
6612 if (link_name.length() > 0 && link_name.back() ==
']') {
6613 size_t pos = link_name.rfind(
"[");
6614 if (pos == std::string::npos) {
6615 db_msg(&msg,
MERROR,
"db_get_data",
"missing \"[\" in symlink to array element \"%s\" in \"%s\"", link_name.c_str(),
db_get_path_pkey(pheader, pkey).c_str());
6621 int idx = atoi(link_name.c_str()+pos+1);
6622 link_name.resize(pos);
6626 if (link_name[0] !=
'/') {
6627 db_msg(&msg,
MERROR,
"db_get_data",
"symlink \"%s\" should start with \"/\" in \"%s\"", link_name.c_str(),
db_get_path_pkey(pheader, pkey).c_str());
6685#ifdef LOCAL_ROUTINES
6691 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6696 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6715 pkey = (
KEY *) ((
char *) pheader +
hKey);
6724 int pkey_type = pkey->
type;
6726 cm_msg(
MERROR,
"db_get_data",
"hkey %d invalid key type %d",
hKey, pkey_type);
6731 int pkey_type = pkey->
type;
6733 mstrlcpy(pkey_name, pkey->
name,
sizeof(pkey_name));
6742 cm_msg(
MERROR,
"db_get_data",
"Key cannot contain data");
6747 if (pkey->
data == 0) {
6748 memset(
data, 0, *buf_size);
6757 memcpy(
data, (
char *) pheader + pkey->
data, *buf_size);
6760 cm_msg(
MERROR,
"db_get_data",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(), pkey_size, *buf_size);
6777#ifndef DOXYGEN_SHOULD_SKIP_THIS
6809#ifdef LOCAL_ROUTINES
6815 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6820 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6839 pkey = (
KEY *) ((
char *) pheader +
hKey);
6848 int pkey_type = pkey->
type;
6850 cm_msg(
MERROR,
"db_get_data",
"hkey %d invalid key type %d",
hKey, pkey_type);
6855 int pkey_type = pkey->
type;
6857 mstrlcpy(pkey_name, pkey->
name,
sizeof(pkey_name));
6866 cm_msg(
MERROR,
"db_get_data",
"Key cannot contain data");
6871 if (pkey->
data == 0) {
6872 memset(
data, 0, *buf_size);
6881 memcpy(
data, (
char *) pheader + pkey->
data, *buf_size);
6884 cm_msg(
MERROR,
"db_get_data",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(), pkey_size, *buf_size);
6922#ifdef LOCAL_ROUTINES
6928 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6933 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6952 pkey = (
KEY *) ((
char *) pheader +
hKey);
6961 int pkey_type = pkey->
type;
6963 cm_msg(
MERROR,
"db_get_data_index",
"hkey %d invalid key type %d",
hKey, pkey_type);
6968 int pkey_type = pkey->
type;
6970 mstrlcpy(pkey_name, pkey->
name,
sizeof(pkey_name));
6979 cm_msg(
MERROR,
"db_get_data_index",
"Key cannot contain data");
6984 if (pkey->
data == 0) {
6985 memset(
data, 0, *buf_size);
6994 memset(
data, 0, *buf_size);
6998 cm_msg(
MERROR,
"db_get_data_index",
"index (%d) exceeds array length (%d) for key \"%s\"", idx, pkey_num_values, path.c_str());
7009 cm_msg(
MERROR,
"db_get_data_index",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(), pkey_size, *buf_size);
7025#ifdef LOCAL_ROUTINES
7042 data_size = pkey->
item_size * num_values;
7049 if (pkey->
data == 0) {
7051 db_msg(msg,
MERROR, caller,
"Cannot reallocate \"%s\" with new size %d bytes, online database full",
db_get_path_pkey(pheader, pkey).c_str(), data_size);
7063 pkey->
item_size = data_size / num_values;
7069 mstrlcpy((
char *) pheader + pkey->
data, (
const char*)
data, data_size);
7072 memcpy((
char *) pheader + pkey->
data,
data, data_size);
7088 if (pkey->
data == 0) {
7091 db_msg(msg,
MERROR, caller,
"Cannot reallocate \"%s\" with new num_values %d and new size %d bytes, online database full",
db_get_path_pkey(pheader, pkey).c_str(), idx + 1, data_size * (idx + 1));
7144 if (num_values > 1) {
7146 if (data_size > 0 && num_values > 0)
7147 item_size = data_size/num_values;
7149 for (
int i=0;
i<num_values;
i++) {
7150 const char*
value = ((
const char*)
data) +
i * item_size;
7195 db_msg(msg,
MERROR,
"db_set_data_index",
"\"%s\" index %d set to invalid UTF-8 Unicode string value \"%s\"",
db_get_path_pkey(pheader, pkey).c_str(), idx,
value);
7244#ifdef LOCAL_ROUTINES
7251 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7256 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7265 if (num_values == 0)
7281 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7291 char link_name[256];
7292 mstrlcpy(link_name, (
char *) pheader + pkey->
data,
sizeof(link_name));
7293 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] ==
']') {
7295 if (strchr(link_name,
'[') == NULL)
7297 link_idx = atoi(strchr(link_name,
'[') + 1);
7298 *strchr(link_name,
'[') = 0;
7347#ifdef LOCAL_ROUTINES
7353 char link_name[256];
7357 cm_msg(
MERROR,
"db_set_data1",
"invalid database handle");
7362 cm_msg(
MERROR,
"db_set_data1",
"invalid database handle");
7371 if (num_values == 0)
7385 pkey = (
KEY *) ((
char *) pheader +
hKey);
7395 mstrlcpy(link_name, (
char *) pheader + pkey->
data,
sizeof(link_name));
7396 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] ==
']') {
7398 if (strchr(link_name,
'[') == NULL)
7400 link_idx = atoi(strchr(link_name,
'[') + 1);
7401 *strchr(link_name,
'[') = 0;
7454#ifdef LOCAL_ROUTINES
7457 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7462 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7471 if (num_values == 0)
7486 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7520#ifndef DOXYGEN_SHOULD_SKIP_THIS
7547#ifdef LOCAL_ROUTINES
7552 cm_msg(
MERROR,
"db_set_num_values",
"invalid database handle");
7557 cm_msg(
MERROR,
"db_set_num_values",
"invalid database handle");
7562 cm_msg(
MERROR,
"db_set_num_values",
"invalid key handle");
7566 if (num_values <= 0) {
7567 cm_msg(
MERROR,
"db_set_num_values",
"invalid num_values %d", num_values);
7571 if (num_values == 0)
7586 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7597 cm_msg(
MERROR,
"db_set_num_values",
"Key cannot contain data");
7609 cm_msg(
MERROR,
"db_set_num_values",
"Cannot resize array with item_size equal to zero");
7617 new_size = pkey->
item_size * num_values;
7621 if (pkey->
data == 0) {
7624 db_msg(&msg,
MERROR,
"db_set_num_values",
"Cannot resize \"%s\" with num_values %d and new size %d bytes, online database full",
db_get_path_pkey(pheader, pkey).c_str(), num_values, new_size);
7673#ifdef LOCAL_ROUTINES
7680 cm_msg(
MERROR,
"db_set_data_index",
"invalid database handle");
7685 cm_msg(
MERROR,
"db_set_data_index",
"invalid database handle");
7690 cm_msg(
MERROR,
"db_set_data_index",
"invalid key handle");
7706 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7716 char link_name[256];
7717 mstrlcpy(link_name, (
char *) pheader + pkey->
data,
sizeof(link_name));
7718 if (strlen(link_name) > 0 && link_name[strlen(link_name) - 1] ==
']') {
7720 if (strchr(link_name,
'[') == NULL)
7722 link_idx = atoi(strchr(link_name,
'[') + 1);
7723 *strchr(link_name,
'[') = 0;
7778#ifdef LOCAL_ROUTINES
7781 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid database handle");
7786 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid database handle");
7791 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid key handle");
7807 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7841#ifndef DOXYGEN_SHOULD_SKIP_THIS
7875#ifdef LOCAL_ROUTINES
7878 cm_msg(
MERROR,
"db_set_data_index1",
"invalid database handle");
7883 cm_msg(
MERROR,
"db_set_data_index1",
"invalid database handle");
7888 cm_msg(
MERROR,
"db_set_data_index1",
"invalid key handle");
7904 KEY* pkey = (
KEY *) ((
char *) pheader +
hKey);
7970 if (num_values == 0)
7981 old_size = data_size;
7989#ifdef LOCAL_ROUTINES
8069#ifdef LOCAL_ROUTINES
8075 cm_msg(
MERROR,
"db_set_mode",
"invalid database handle");
8080 cm_msg(
MERROR,
"db_set_mode",
"invalid database handle");
8141 struct stat stat_buf;
8149 hfile = open(filename, O_RDONLY |
O_TEXT, 0644);
8151 cm_msg(
MERROR,
"db_load",
"file \"%s\" not found", filename);
8156 fstat(hfile, &stat_buf);
8157 size = stat_buf.st_size;
8158 buffer = (
char *) malloc(size + 1);
8160 if (buffer == NULL) {
8161 cm_msg(
MERROR,
"db_load",
"cannot allocate ODB load buffer");
8169 i =
read(hfile, buffer +
n, size -
n);
8177 if (strncmp(buffer,
"<?xml version=\"1.0\"", 19) == 0) {
8180 printf(
"Error in file \"%s\"\n", filename);
8181 }
else if( buffer[0] ==
'{'){
8182 if(strrchr(buffer,
'}')){
8239 std::string full_path = path;
8242 cm_msg(
MERROR,
"db_copy",
"ODB path too long at \"%s\"", path);
8260 data = (
char *) malloc(size);
8262 cm_msg(
MERROR,
"db_copy",
"cannot allocate data buffer");
8275 line +=
"[====#$@$#====]\n";
8278 if ((
INT) (line.length() + 1) > *buffer_size) {
8283 strcpy(buffer, line.c_str());
8284 buffer += line.length();
8285 *buffer_size -= line.length();
8293 strcpy(buffer,
data);
8294 buffer += strlen(
data);
8295 *buffer_size -= strlen(
data);
8297 line =
"\n====#$@$#====\n";
8319 if ((
INT) (line.length() + 1) > *buffer_size) {
8324 strcpy(buffer, line.c_str());
8325 buffer += line.length();
8326 *buffer_size -= line.length();
8333 if ((
INT) (line.length() + 1) > *buffer_size) {
8338 strcpy(buffer, line.c_str());
8339 buffer += line.length();
8340 *buffer_size -= line.length();
8353 if (strcmp(
key.
name,
"arr2") == 0)
8356 data = (
char *) malloc(size);
8358 cm_msg(
MERROR,
"db_copy",
"cannot allocate data buffer");
8367 if (*buffer_size < 2) {
8372 strcpy(buffer,
"\n");
8377 strcpy(
str, full_path.c_str());
8378 if (
str[0] &&
str[strlen(
str) - 1] !=
'/')
8389 buffer += strlen(buffer);
8411 line +=
"[====#$@$#====]\n";
8417 if ((
INT) (line.length() + 1) > *buffer_size) {
8422 strcpy(buffer, line.c_str());
8423 buffer += line.length();
8424 *buffer_size -= line.length();
8432 strcpy(buffer,
data);
8433 buffer += strlen(
data);
8434 *buffer_size -= strlen(
data);
8436 line =
"\n====#$@$#====\n";
8458 if ((
INT) (line.length() + 1) > *buffer_size) {
8463 strcpy(buffer, line.c_str());
8464 buffer += line.length();
8465 *buffer_size -= line.length();
8471 if ((
INT) (line.length() + 1) > *buffer_size) {
8476 strcpy(buffer, line.c_str());
8477 buffer += line.length();
8478 *buffer_size -= line.length();
8486 if (*buffer_size < 2)
8489 strcpy(buffer,
"\n");
8511 INT tid,
i,
j, n_data, string_length,
status, size;
8524 data = (
char *) malloc(data_size);
8526 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8537 line[
i] = *buffer++;
8541 cm_msg(
MERROR,
"db_paste",
"line too long: %s...", line);
8547 if (*buffer ==
'\n')
8551 if (line[0] ==
'[') {
8553 mstrlcpy(title, line + 1,
sizeof(title));
8554 if (strchr(title,
']'))
8555 *strchr(title,
']') = 0;
8556 if (title[0] && title[strlen(title) - 1] !=
'/')
8557 mstrlcat(title,
"/",
sizeof(title));
8560 if (strchr(line,
'=') && line[0] !=
';') {
8566 char* pline = strrchr(line,
'=') + 1;
8567 while (strstr(line,
": [") != NULL && strstr(line,
": [") < pline) {
8569 while (*pline !=
'=' && pline > line)
8573 while (*pline ==
' ')
8575 mstrlcpy(data_str, pline,
sizeof(data_str));
8578 *strrchr(line,
'=') = 0;
8579 while (strstr(line,
": [") && strchr(line,
'='))
8580 *strrchr(line,
'=') = 0;
8582 pline = &line[strlen(line) - 1];
8583 while (*pline ==
' ')
8587 if (title[0] !=
'.')
8588 mstrlcpy(key_name, title,
sizeof(key_name));
8590 mstrlcat(key_name, line,
sizeof(key_name));
8593 mstrlcpy(line, data_str,
sizeof(line));
8594 if (strchr(line,
' '))
8595 *strchr(line,
' ') = 0;
8598 if (strchr(line,
'[')) {
8599 n_data = atol(strchr(line,
'[') + 1);
8600 *strchr(line,
'[') = 0;
8603 for (tid = 0; tid <
TID_LAST; tid++)
8607 for (tid = 0; tid <
TID_LAST; tid++)
8615 cm_msg(
MERROR,
"db_paste",
"found unknown data type \"%s\" in ODB file", line);
8618 char* pc = data_str;
8619 while (*pc !=
' ' && *pc)
8621 while ((*pc ==
' ' || *pc ==
':') && *pc)
8625 assert(strlen(pc) <
sizeof(data_str));
8626 memmove(data_str, pc, strlen(pc)+1);
8633 for (
j = 0; *buffer !=
'\n' && *buffer;
j++)
8634 data_str[
j] = *buffer++;
8636 if (*buffer ==
'\n')
8640 for (
i = 0;
i < n_data;
i++) {
8642 char* pc = &data_str[strlen(data_str) - 1];
8643 while (*pc ==
'\n' || *pc ==
'\r')
8647 if (!string_length) {
8648 if (data_str[1] ==
'=')
8651 string_length = atoi(data_str + 1);
8654 cm_msg(
MERROR,
"db_paste",
"found string exceeding MAX_STRING_LENGTH, odb path \"%s\"", key_name);
8656 if (string_length == 0) {
8658 cm_msg(
MERROR,
"db_paste",
"found string length of zero, set to 32, odb path \"%s\"", key_name);
8662 if (string_length == -1) {
8664 if (strstr(buffer,
"\n====#$@$#====\n") != NULL) {
8665 string_length = (
POINTER_T) strstr(buffer,
"\n====#$@$#====\n") - (
POINTER_T) buffer + 1;
8667 if (string_length >= data_size) {
8668 data_size += string_length + 100;
8669 data = (
char *) realloc(
data, data_size);
8671 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8676 memset(
data, 0, data_size);
8677 strncpy(
data, buffer, string_length);
8678 data[string_length - 1] = 0;
8679 buffer = strstr(buffer,
"\n====#$@$#====\n") + strlen(
"\n====#$@$#====\n");
8681 cm_msg(
MERROR,
"db_paste",
"found multi-line string without termination sequence");
8683 char* pc = data_str + 2;
8684 while (*pc && *pc !=
' ')
8692 *(pc + string_length - 1) = 0;
8695 if (string_length * (
i + 1) >= data_size) {
8697 data = (
char *) realloc(
data, data_size);
8699 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8704 mstrlcpy(
data + string_length *
i, pc, string_length);
8707 char* pc = data_str;
8709 if (n_data > 1 && data_str[0] ==
'[') {
8710 index = atoi(data_str+1);
8711 pc = strchr(data_str,
']') + 1;
8712 while (*pc && *pc ==
' ')
8720 data = (
char *) realloc(
data, data_size);
8722 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8730 if (
i < n_data - 1) {
8737 for (
j = 0; *buffer !=
'\n' && *buffer;
j++)
8738 data_str[
j] = *buffer++;
8740 if (*buffer ==
'\n')
8745 if (data_str[0] == 0 || (strchr(data_str,
'=')
8746 && strchr(data_str,
':')))
8753 mstrlcpy(test_str, key_name,
sizeof(test_str));
8762 if (key_name[0] ==
'/') {
8802 if (strcmp(mxml_get_name(node),
"odb") == 0) {
8803 for (
int i = 0;
i < mxml_get_number_of_children(node);
i++) {
8808 }
else if (strcmp(mxml_get_name(node),
"dir") == 0) {
8809 const char*
name = mxml_get_attribute(node,
"name");
8812 cm_msg(
MERROR,
"db_paste_node",
"found key \"%s\" with no name in XML data", mxml_get_name(node));
8822 cm_msg(
MINFO,
"db_paste_node",
"cannot load key \"%s\": write protected",
name);
8839 for (
int i = 0;
i < mxml_get_number_of_children(node);
i++) {
8845 }
else if (strcmp(mxml_get_name(node),
"key") == 0 || strcmp(mxml_get_name(node),
"keyarray") == 0) {
8847 const char*
name = mxml_get_attribute(node,
"name");
8850 cm_msg(
MERROR,
"db_paste_node",
"found key \"%s\" with no name in XML data", mxml_get_name(node));
8855 if (strcmp(mxml_get_name(node),
"keyarray") == 0)
8856 num_values = atoi(mxml_get_attribute(node,
"num_values"));
8860 const char*
type = mxml_get_attribute(node,
"type");
8863 cm_msg(
MERROR,
"db_paste_node",
"found key \"%s\" with no type in XML data", mxml_get_name(node));
8869 cm_msg(
MERROR,
"db_paste_node",
"found unknown data type \"%s\" in XML data",
type);
8878 cm_msg(
MINFO,
"db_paste_node",
"cannot load key \"%s\": write protected",
name);
8912 size = atoi(mxml_get_attribute(node,
"size"));
8913 buf = (
char *)malloc(size);
8920 for (
int i = 0;
i < mxml_get_number_of_children(node);
i++) {
8921 PMXML_NODE child = mxml_subnode(node,
i);
8923 if (mxml_get_attribute(child,
"index"))
8924 idx = atoi(mxml_get_attribute(child,
"index"));
8928 if (mxml_get_value(child) == NULL) {
8931 cm_msg(
MINFO,
"db_paste_node",
"cannot load string or link \"%s\": write protected", mxml_get_attribute(node,
"name"));
8934 cm_msg(
MERROR,
"db_paste_node",
"cannot load string or link \"%s\": db_set_data_index() status %d", mxml_get_attribute(node,
"name"),
status);
8938 mstrlcpy(buf, mxml_get_value(child), size);
8941 cm_msg(
MINFO,
"db_paste_node",
"cannot load array element \"%s\": write protected", mxml_get_attribute(node,
"name"));
8944 cm_msg(
MERROR,
"db_paste_node",
"cannot load array element \"%s\": db_set_data_index() status %d", mxml_get_attribute(node,
"name"),
status);
8953 cm_msg(
MINFO,
"db_paste_node",
"cannot load array element \"%s\": write protected", mxml_get_attribute(node,
"name"));
8956 cm_msg(
MERROR,
"db_paste_node",
"cannot load array element \"%s\": db_set_data_index() status %d", mxml_get_attribute(node,
"name"),
status);
8964 size = atoi(mxml_get_attribute(node,
"size"));
8965 if (mxml_get_value(node) == NULL) {
8968 cm_msg(
MINFO,
"db_paste_node",
"cannot load string or link \"%s\": write protected", mxml_get_attribute(node,
"name"));
8971 cm_msg(
MERROR,
"db_paste_node",
"cannot load string or link \"%s\": db_set_data() status %d", mxml_get_attribute(node,
"name"),
status);
8975 mstrlcpy(buf, mxml_get_value(node), size);
8978 cm_msg(
MINFO,
"db_paste_node",
"cannot load value \"%s\": write protected", mxml_get_attribute(node,
"name"));
8981 cm_msg(
MERROR,
"db_paste_node",
"cannot load value \"%s\": db_set_data() status %d", mxml_get_attribute(node,
"name"),
status);
8990 cm_msg(
MINFO,
"db_paste_node",
"cannot load value \"%s\": write protected", mxml_get_attribute(node,
"name"));
8993 cm_msg(
MERROR,
"db_paste_node",
"cannot load value \"%s\": db_set_data() status %d", mxml_get_attribute(node,
"name"),
status);
9020 PMXML_NODE tree, node;
9026 tree = mxml_parse_buffer(buffer, error,
sizeof(error), NULL);
9032 node = mxml_find_node(tree,
"odb");
9034 puts(
"Cannot find element \"odb\" in XML data");
9040 mxml_free_tree(tree);
9061#ifdef LOCAL_ROUTINES
9065 MXML_WRITER *writer;
9068 writer = mxml_open_buffer();
9069 if (writer == NULL) {
9070 cm_msg(
MERROR,
"db_copy_xml",
"Cannot allocate buffer");
9078 mxml_start_element(writer,
"odb");
9079 mxml_write_attribute(writer,
"root", path.c_str());
9080 mxml_write_attribute(writer,
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
9081 mxml_write_attribute(writer,
"xsi:noNamespaceSchemaLocation",
"http://midas.psi.ch/odb.xsd");
9084 mxml_end_element(writer);
9094 p = mxml_close_buffer(writer);
9095 len = strlen(p) + 1;
9096 if (len > *buffer_size) {
9102 mstrlcpy(buffer, p, len);
9112#ifndef DOXYGEN_SHOULD_SKIP_THIS
9124 if (*
str >=
'0' && *
str <=
'9')
9128 if (!(*
str >=
'a' && *
str <=
'z') && !(*
str >=
'A' && *
str <=
'Z') && !(*
str >=
'0' && *
str <=
'9'))
9130 *
str = (char) tolower(*
str);
9152 for (idx = 0;; idx++) {
9170 for (
i = 0;
i <= level;
i++) {
9171 wr =
write(hfile,
" ", 2);
9178 strcpy(line,
"char");
9181 strcpy(line,
"short");
9184 strcpy(line,
"float");
9187 strcpy(line,
"double");
9190 strcpy(line,
"unsigned char");
9193 strcpy(line,
"char");
9196 strcpy(line,
"char");
9203 mstrlcat(line,
" ",
sizeof(line));
9212 mstrlcpy(line + 10,
str,
sizeof(line) - 10);
9213 mstrlcat(line,
";\n",
sizeof(line));
9215 wr =
write(hfile, line, strlen(line));
9222 for (
i = 0;
i <= level;
i++) {
9223 wr =
write(hfile,
" ", 2);
9227 sprintf(line,
"struct {\n");
9228 wr =
write(hfile, line, strlen(line));
9232 for (
i = 0;
i <= level;
i++) {
9233 wr =
write(hfile,
" ", 2);
9240 sprintf(line,
"} %s;\n",
str);
9241 wr =
write(hfile, line, strlen(line));
9268#ifdef LOCAL_ROUTINES
9274 hfile = open(filename, O_WRONLY | O_CREAT | O_TRUNC |
O_TEXT, 0644);
9276 cm_msg(
MERROR,
"db_save",
"Cannot open file \"%s\"", filename);
9282 buffer_size = 10000;
9284 buffer = (
char *) malloc(buffer_size);
9285 if (buffer == NULL) {
9286 cm_msg(
MERROR,
"db_save",
"cannot allocate ODB dump buffer");
9293 n =
write(hfile, buffer, buffer_size - size);
9297 if (
n != buffer_size - size) {
9326 dst = (
char *) malloc(size);
9331 for (
i = 0;
i < (int) strlen(src);
i++) {
9334 mstrlcat(dst,
"<", size);
9337 mstrlcat(dst,
">", size);
9340 mstrlcat(dst,
"&", size);
9343 mstrlcat(dst,
""", size);
9346 mstrlcat(dst,
"'", size);
9349 if ((
int) strlen(dst) >= size) {
9353 p = dst + strlen(dst);
9359 mstrlcpy(src, dst, size);
9385 mxml_start_element(writer,
"dir");
9386 mxml_write_attribute(writer,
"name",
key.
name);
9387 mxml_write_attribute(writer,
"handle", std::to_string(
hKey).c_str());
9390 for (idx = 0;; idx++) {
9404 mxml_end_element(writer);
9410 mxml_start_element(writer,
"keyarray");
9412 mxml_start_element(writer,
"key");
9413 mxml_write_attribute(writer,
"name",
key.
name);
9415 mxml_write_attribute(writer,
"handle", std::to_string(
hKey).c_str());
9420 mxml_write_attribute(writer,
"size",
str);
9426 mxml_write_attribute(writer,
"num_values",
str);
9430 data = (
char *) malloc(size+1);
9432 cm_msg(
MERROR,
"db_save_xml_key",
"cannot allocate data buffer");
9441 mxml_write_value(writer,
data);
9446 cm_msg(
MERROR,
"db_save_xml_key",
"Long odb string probably truncated, odb path \"%s\", string length %d truncated to %d", path.c_str(), (
int)strlen(
data), (
int)
str.length());
9448 mxml_write_value(writer,
str.c_str());
9450 mxml_end_element(writer);
9456 mxml_start_element(writer,
"value");
9460 sprintf(
str,
"%d",
i);
9461 mxml_write_attribute(writer,
"index",
str);
9468 mxml_write_value(writer, p);
9473 cm_msg(
MERROR,
"db_save_xml_key",
"Long odb string array probably truncated, odb path \"%s\"[%d]", path.c_str(),
i);
9475 mxml_write_value(writer,
str.c_str());
9478 mxml_end_element(writer);
9481 mxml_end_element(writer);
9505#ifdef LOCAL_ROUTINES
9508 MXML_WRITER *writer;
9511 writer = mxml_open_file(filename);
9512 if (writer == NULL) {
9513 cm_msg(
MERROR,
"db_save_xml",
"Cannot open file \"%s\"", filename);
9520 mxml_start_element(writer,
"odb");
9521 mxml_write_attribute(writer,
"root", path.c_str());
9522 mxml_write_attribute(writer,
"filename", filename);
9523 mxml_write_attribute(writer,
"xmlns:xsi",
"http://www.w3.org/2001/XMLSchema-instance");
9525 std::string xsd_path;
9527 if (getenv(
"MIDASSYS"))
9528 xsd_path = getenv(
"MIDASSYS");
9533 xsd_path +=
"odb.xsd";
9534 mxml_write_attribute(writer,
"xsi:noNamespaceSchemaLocation", xsd_path.c_str());
9538 mxml_end_element(writer);
9539 mxml_close_file(writer);
9550void json_write(
char **buffer,
int* buffer_size,
int* buffer_end,
int level,
const char* s,
int quoted)
9552 int len, remain, xlevel;
9555 remain = *buffer_size - *buffer_end;
9556 assert(remain >= 0);
9560 while (10 + xlevel + 3*len > remain) {
9562 int new_buffer_size = 2*(*buffer_size);
9563 if (new_buffer_size < 4*1024)
9564 new_buffer_size = 4*1024;
9566 assert(new_buffer_size > *buffer_size);
9567 *buffer = (
char *)realloc(*buffer, new_buffer_size);
9569 *buffer_size = new_buffer_size;
9570 remain = *buffer_size - *buffer_end;
9571 assert(remain >= 0);
9576 for (
i=0;
i<xlevel;
i++)
9577 (*buffer)[(*buffer_end)++] =
' ';
9581 memcpy(*buffer + *buffer_end, s, len);
9583 (*buffer)[*buffer_end] = 0;
9587 char *bufptr = *buffer;
9588 int bufend = *buffer_end;
9590 bufptr[bufend++] =
'"';
9595 bufptr[bufend++] =
'\\';
9596 bufptr[bufend++] =
'\"';
9600 bufptr[bufend++] =
'\\';
9601 bufptr[bufend++] =
'\\';
9606 bufptr[bufend++] =
'\\';
9607 bufptr[bufend++] =
'/';
9612 bufptr[bufend++] =
'\\';
9613 bufptr[bufend++] =
'b';
9617 bufptr[bufend++] =
'\\';
9618 bufptr[bufend++] =
'f';
9622 bufptr[bufend++] =
'\\';
9623 bufptr[bufend++] =
'n';
9627 bufptr[bufend++] =
'\\';
9628 bufptr[bufend++] =
'r';
9632 bufptr[bufend++] =
'\\';
9633 bufptr[bufend++] =
't';
9637 bufptr[bufend++] = *s++;
9641 bufptr[bufend++] =
'"';
9644 *buffer_end = bufend;
9646 remain = *buffer_size - *buffer_end;
9660 if (
comma !=
nullptr) {
9670 sprintf(
str,
"%u", *(
unsigned char*)p);
9674 sprintf(
str,
"%d", *(
char*)p);
9678 sprintf(
str,
"%c", *(
char*)p);
9682 sprintf(
str,
"\"0x%04x\"", *(
WORD*)p);
9686 sprintf(
str,
"%d", *(
short*)p);
9690 sprintf(
str,
"\"0x%08x\"", *(
DWORD*)p);
9694 sprintf(
str,
"%d", *(
int*)p);
9699 sprintf(
str,
"\"0x%016llx\"", *(
UINT64*)p);
9704 sprintf(
str,
"\"%lld\"", *(
INT64*)p);
9709 json_write(buffer, buffer_size, buffer_end, 0,
"true", 0);
9711 json_write(buffer, buffer_size, buffer_end, 0,
"false", 0);
9714 float flt = (*(
float*)p);
9716 json_write(buffer, buffer_size, buffer_end, 0,
"\"NaN\"", 0);
9717 else if (isinf(flt)) {
9719 json_write(buffer, buffer_size, buffer_end, 0,
"\"Infinity\"", 0);
9721 json_write(buffer, buffer_size, buffer_end, 0,
"\"-Infinity\"", 0);
9722 }
else if (flt == 0)
9723 json_write(buffer, buffer_size, buffer_end, 0,
"0", 0);
9724 else if (flt == (
int)flt) {
9725 sprintf(
str,
"%.0f", flt);
9729 sprintf(
str,
"%.7e", flt);
9736 double dbl = (*(
double*)p);
9738 json_write(buffer, buffer_size, buffer_end, 0,
"\"NaN\"", 0);
9739 else if (isinf(dbl)) {
9741 json_write(buffer, buffer_size, buffer_end, 0,
"\"Infinity\"", 0);
9743 json_write(buffer, buffer_size, buffer_end, 0,
"\"-Infinity\"", 0);
9744 }
else if (dbl == 0)
9745 json_write(buffer, buffer_size, buffer_end, 0,
"0", 0);
9746 else if (dbl == (
int)dbl) {
9747 sprintf(
str,
"%.0f", dbl);
9751 sprintf(
str,
"%.16e", dbl);
9758 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_BITFIELD value)", 1);
9762 json_write(buffer, buffer_size, buffer_end, 0, p, 1);
9765 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_ARRAY value)", 1);
9768 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_STRUCT value)", 1);
9771 json_write(buffer, buffer_size, buffer_end, 0,
"{ }", 0);
9775 json_write(buffer, buffer_size, buffer_end, 0, p, 1);
9778 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_UNKNOWN value)", 1);
9786 json_write(buffer, buffer_size, buffer_end, 0,
"{ ", 0);
9792 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9793 json_write(buffer, buffer_size, buffer_end, 0,
"link", 1);
9794 json_write(buffer, buffer_size, buffer_end, 0,
": ", 0);
9795 json_write(buffer, buffer_size, buffer_end, 0, link_path, 1);
9799 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9806 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9813 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9819 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9824 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9829 json_write(buffer, buffer_size, buffer_end, 0,
" ", 0);
9831 json_write(buffer, buffer_size, buffer_end, 0,
"}", 0);
9841 int omit_top_level_braces = 0;
9847 omit_top_level_braces = 1;
9858 size =
sizeof(link_path);
9881 int do_close_curly_bracket = 0;
9883 if (level == 0 && !omit_top_level_braces) {
9884 json_write(buffer, buffer_size, buffer_end, 0,
"{\n", 0);
9885 do_close_curly_bracket = 1;
9887 else if (level > 0) {
9888 json_write(buffer, buffer_size, buffer_end, level, link_key.
name, 1);
9889 json_write(buffer, buffer_size, buffer_end, 0,
" : {\n", 0);
9890 do_close_curly_bracket = 1;
9896 json_write(buffer, buffer_size, buffer_end, 0,
"/error", 1);
9897 json_write(buffer, buffer_size, buffer_end, 0,
" : ", 0);
9898 json_write(buffer, buffer_size, buffer_end, 0,
"max nesting level exceed", 1);
9900 cm_msg(
MERROR,
"db_save_json_key",
"max nesting level exceeded at \"%s\", check for symlink loops in this subtree", path.c_str());
9912 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
9922 if (do_close_curly_bracket) {
9924 json_write(buffer, buffer_size, buffer_end, 0,
"\n", 0);
9925 json_write(buffer, buffer_size, buffer_end, level,
"}", 0);
9930 if (save_keys && level == 0) {
9931 json_write(buffer, buffer_size, buffer_end, 0,
"{\n", 0);
9936 if (save_keys == 1) {
9938 sprintf(
str,
"%s/key", link_key.
name);
9941 json_write(buffer, buffer_size, buffer_end, 0,
" : { ", 0);
9947 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9948 json_write(buffer, buffer_size, buffer_end, 0,
"link", 1);
9949 json_write(buffer, buffer_size, buffer_end, 0,
": ", 0);
9950 json_write(buffer, buffer_size, buffer_end, 0, link_path, 1);
9954 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9961 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9968 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9974 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9979 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
9984 json_write(buffer, buffer_size, buffer_end, 0,
" ", 0);
9986 json_write(buffer, buffer_size, buffer_end, 0,
"}", 0);
9988 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
9991 if (save_keys == 2) {
9993 sprintf(
str,
"%s/last_written", link_key.
name);
10000 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
10004 json_write(buffer, buffer_size, buffer_end, level, link_key.
name, 1);
10005 json_write(buffer, buffer_size, buffer_end, 0,
" : ", 0);
10009 json_write(buffer, buffer_size, buffer_end, 0,
"[ ", 0);
10013 data = (
char *) malloc(size);
10014 if (
data == NULL) {
10015 cm_msg(
MERROR,
"db_save_json_key",
"cannot allocate data buffer for %d bytes", size);
10034 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
10038 sprintf(
str,
"%u", *(
unsigned char*)p);
10042 sprintf(
str,
"%d", *(
char*)p);
10046 sprintf(
str,
"%c", *(
char*)p);
10050 sprintf(
str,
"\"0x%04x\"", *(
WORD*)p);
10054 sprintf(
str,
"%d", *(
short*)p);
10058 sprintf(
str,
"\"0x%08x\"", *(
DWORD*)p);
10062 sprintf(
str,
"%d", *(
int*)p);
10066 sprintf(
str,
"\"0x%08llx\"", *(
UINT64*)p);
10075 json_write(buffer, buffer_size, buffer_end, 0,
"true", 0);
10077 json_write(buffer, buffer_size, buffer_end, 0,
"false", 0);
10080 float flt = (*(
float*)p);
10082 json_write(buffer, buffer_size, buffer_end, 0,
"\"NaN\"", 0);
10083 else if (isinf(flt)) {
10085 json_write(buffer, buffer_size, buffer_end, 0,
"\"Infinity\"", 0);
10087 json_write(buffer, buffer_size, buffer_end, 0,
"\"-Infinity\"", 0);
10088 }
else if (flt == 0)
10089 json_write(buffer, buffer_size, buffer_end, 0,
"0", 0);
10090 else if (flt == (
int)flt) {
10091 sprintf(
str,
"%.0f", flt);
10094 sprintf(
str,
"%.7e", flt);
10100 double dbl = (*(
double*)p);
10102 json_write(buffer, buffer_size, buffer_end, 0,
"\"NaN\"", 0);
10103 else if (isinf(dbl)) {
10105 json_write(buffer, buffer_size, buffer_end, 0,
"\"Infinity\"", 0);
10107 json_write(buffer, buffer_size, buffer_end, 0,
"\"-Infinity\"", 0);
10108 }
else if (dbl == 0)
10109 json_write(buffer, buffer_size, buffer_end, 0,
"0", 0);
10110 else if (dbl == (
int)dbl) {
10111 sprintf(
str,
"%.0f", dbl);
10114 sprintf(
str,
"%.16e", dbl);
10120 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_BITFIELD value)", 1);
10124 json_write(buffer, buffer_size, buffer_end, 0, p, 1);
10127 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_ARRAY value)", 1);
10130 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_STRUCT value)", 1);
10133 json_write(buffer, buffer_size, buffer_end, 0,
"{ }", 0);
10137 json_write(buffer, buffer_size, buffer_end, 0, p, 1);
10140 json_write(buffer, buffer_size, buffer_end, 0,
"(TID_UNKNOWN value)", 1);
10146 json_write(buffer, buffer_size, buffer_end, 0,
" ]", 0);
10148 json_write(buffer, buffer_size, buffer_end, 0,
"", 0);
10154 if (save_keys && level == 0) {
10155 json_write(buffer, buffer_size, buffer_end, 0,
"\n}", 0);
10188 json_write(buffer, buffer_size, buffer_end, 0,
"[ ", 0);
10197 data = (
char *) malloc(asize);
10198 if (
data == NULL) {
10199 cm_msg(
MERROR,
"db_save_json_key_data",
"cannot allocate data buffer for %d bytes", asize);
10215 json_write(buffer, buffer_size, buffer_end, 0,
", ", 0);
10221 json_write(buffer, buffer_size, buffer_end, 0,
" ]", 0);
10253 char*
data = (
char*)malloc(size + 1);
10254 assert(
data != NULL);
10277 char* link_path = NULL;
10279 HNDLE hLinkTarget = hLink;
10282 int size =
sizeof(link_buf);
10289 if ((size > 0) && (strlen(link_buf) > 0)) {
10290 link_path = link_buf;
10297 hLinkTarget = hLink;
10318 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
10320 json_write(buffer, buffer_size, buffer_end, 0,
"\n", 0);
10325 mstrlcpy(link_name, link.
name,
sizeof(link_name));
10328 for (
int i=0; (
i<(int)
sizeof(link.
name)) && link.
name[
i];
i++)
10329 link_name[
i] = tolower(link.
name[
i]);
10334 mstrlcpy(buf, link_name,
sizeof(buf));
10335 mstrlcat(buf,
"/name",
sizeof(buf));
10336 json_write(buffer, buffer_size, buffer_end, level, buf, 1);
10337 json_write(buffer, buffer_size, buffer_end, 0,
" : " , 0);
10339 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
10344 mstrlcpy(buf, link_name,
sizeof(buf));
10345 mstrlcat(buf,
"/key",
sizeof(buf));
10346 json_write(buffer, buffer_size, buffer_end, level, buf, 1);
10347 json_write(buffer, buffer_size, buffer_end, 0,
" : " , 0);
10348 json_write_key(
hDB, hLink, &link_target, link_path, buffer, buffer_size, buffer_end);
10349 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
10352 mstrlcpy(buf, link_name,
sizeof(buf));
10353 mstrlcat(buf,
"/last_written",
sizeof(buf));
10354 json_write(buffer, buffer_size, buffer_end, level, buf, 1);
10355 json_write(buffer, buffer_size, buffer_end, 0,
" : " , 0);
10357 json_write(buffer, buffer_size, buffer_end, 0, buf, 0);
10358 json_write(buffer, buffer_size, buffer_end, 0,
",\n", 0);
10361 json_write(buffer, buffer_size, buffer_end, level, link_name, 1);
10362 json_write(buffer, buffer_size, buffer_end, 0,
" : " , 0);
10365 json_write(buffer, buffer_size, buffer_end, 0,
"{ }" , 0);
10382 for (
int i=0; ;
i++) {
10395 bool need_comma = (
i!=0);
10416 json_write(buffer, buffer_size, buffer_end, 0,
"{", 0);
10422 json_write(buffer, buffer_size, buffer_end, 0,
"\n", 0);
10423 json_write(buffer, buffer_size, buffer_end, level,
"}", 0);
10425 }
else if (must_be_subdir) {
10426 json_write(buffer, buffer_size, buffer_end, 0,
"{", 0);
10430 json_write(buffer, buffer_size, buffer_end, 0,
"\n", 0);
10431 json_write(buffer, buffer_size, buffer_end, level,
"}", 0);
10445 bool unlock =
false;
10470 if (omit_last_written)
10472 if (omit_old_timestamp)
10474 if (!preserve_case)
10477 bool unlock =
false;
10499 bool unlock =
false;
10532 json_write(buffer, buffer_size, buffer_end, 0,
"\n", 0);
10553 FILE *
fp = fopen(filename,
"w");
10555 cm_msg(
MERROR,
"db_save_json",
"Cannot open file \"%s\", fopen() errno %d (%s)", filename, errno, strerror(errno));
10559 bool unlock =
false;
10572 bool emptySubdir =
false;
10576 emptySubdir =
true;
10578 char* buffer = NULL;
10579 int buffer_size = 0;
10580 int buffer_end = 0;
10582 json_write(&buffer, &buffer_size, &buffer_end, 0,
"{\n", 0);
10584 json_write(&buffer, &buffer_size, &buffer_end, 1,
"/MIDAS version", 1);
10585 json_write(&buffer, &buffer_size, &buffer_end, 0,
" : ", 0);
10587 json_write(&buffer, &buffer_size, &buffer_end, 0,
",\n", 0);
10589 json_write(&buffer, &buffer_size, &buffer_end, 1,
"/MIDAS git revision", 1);
10590 json_write(&buffer, &buffer_size, &buffer_end, 0,
" : ", 0);
10591 json_write(&buffer, &buffer_size, &buffer_end, 0, GIT_REVISION, 1);
10592 json_write(&buffer, &buffer_size, &buffer_end, 0,
",\n", 0);
10594 json_write(&buffer, &buffer_size, &buffer_end, 1,
"/filename", 1);
10595 json_write(&buffer, &buffer_size, &buffer_end, 0,
" : ", 0);
10596 json_write(&buffer, &buffer_size, &buffer_end, 0, filename, 1);
10597 json_write(&buffer, &buffer_size, &buffer_end, 0,
",\n", 0);
10599 json_write(&buffer, &buffer_size, &buffer_end, 1,
"/ODB path", 1);
10600 json_write(&buffer, &buffer_size, &buffer_end, 0,
" : ", 0);
10601 json_write(&buffer, &buffer_size, &buffer_end, 0, path.c_str(), 1);
10604 json_write(&buffer, &buffer_size, &buffer_end, 0,
"", 0);
10606 json_write(&buffer, &buffer_size, &buffer_end, 0,
",\n", 0);
10611 json_write(&buffer, &buffer_size, &buffer_end, 0,
"\n}\n", 0);
10619 size_t wr = fwrite(buffer, 1, buffer_end,
fp);
10620 if (wr != (
size_t)buffer_end) {
10621 cm_msg(
MERROR,
"db_save_json",
"Cannot write to file \"%s\", fwrite() errno %d (%s)", filename, errno, strerror(errno));
10651 char str[100], line[10+100];
10656 fh = open(
file_name, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0644);
10669 sprintf(line,
"typedef struct {\n");
10671 size = strlen(line);
10672 wr =
write(fh, line, size);
10674 cm_msg(
MERROR,
"db_save_struct",
"file \"%s\" write error: write(%d) returned %d, errno %d (%s)",
file_name, size, wr, errno, strerror(errno));
10681 if (struct_name && struct_name[0])
10682 mstrlcpy(
str, struct_name,
sizeof(
str));
10687 for (
i = 0;
i < (int) strlen(
str);
i++)
10690 sprintf(line,
"} %s;\n\n",
str);
10692 size = strlen(line);
10693 wr =
write(fh, line, size);
10695 cm_msg(
MERROR,
"db_save_struct",
"file \"%s\" write error: write(%d) returned %d, errno %d (%s)",
file_name, size, wr, errno, strerror(errno));
10706#ifndef DOXYGEN_SHOULD_SKIP_THIS
10734 char str[256], line[50+256];
10736 char *buffer = NULL, *pc;
10741 fh = open(
file_name, O_WRONLY | O_CREAT | (append ? O_APPEND : O_TRUNC), 0644);
10754 if (string_name && string_name[0])
10755 strcpy(
str, string_name);
10760 for (
i = 0;
i < (int) strlen(
str);
i++)
10763 sprintf(line,
"#define %s(_name) const char *_name[] = {\\\n",
str);
10764 size = strlen(line);
10765 wr =
write(fh, line, size);
10767 cm_msg(
MERROR,
"db_save",
"file \"%s\" write error: write(%d) returned %d, errno %d (%s)",
file_name, size, wr, errno, strerror(errno));
10774 buffer_size = 10000;
10776 buffer = (
char *) malloc(buffer_size);
10777 if (buffer == NULL) {
10778 cm_msg(
MERROR,
"db_save",
"cannot allocate ODB dump buffer");
10782 size = buffer_size;
10799 while (*pc !=
'\n' && *pc != 0) {
10800 if (*pc ==
'\"' || *pc ==
'\'')
10804 strcpy(&line[
i],
"\",\\\n");
10806 size = strlen(line);
10807 wr =
write(fh, line, size);
10809 cm_msg(
MERROR,
"db_save",
"file \"%s\" write error: write(%d) returned %d, errno %d (%s)",
file_name, size, wr, errno, strerror(errno));
10822 sprintf(line,
"NULL }\n\n");
10823 size = strlen(line);
10824 wr =
write(fh, line, size);
10826 cm_msg(
MERROR,
"db_save",
"file \"%s\" write error: write(%d) returned %d, errno %d (%s)",
file_name, size, wr, errno, strerror(errno));
10867 if (data_size == 0)
10868 sprintf(
string,
"<NULL>");
10872 sprintf(
string,
"%d", *(((
BYTE *)
data) + idx));
10875 sprintf(
string,
"%d", *(((
char *)
data) + idx));
10878 sprintf(
string,
"%c", *(((
char *)
data) + idx));
10881 sprintf(
string,
"%u", *(((
WORD *)
data) + idx));
10884 sprintf(
string,
"%d", *(((
short *)
data) + idx));
10887 sprintf(
string,
"%u", *(((
DWORD *)
data) + idx));
10890 sprintf(
string,
"%d", *(((
INT *)
data) + idx));
10893 sprintf(
string,
"%llu", *(((
UINT64 *)
data) + idx));
10896 sprintf(
string,
"%lld", *(((
INT64 *)
data) + idx));
10899 sprintf(
string,
"%c", *(((
BOOL *)
data) + idx) ?
'y' :
'n');
10903 sprintf(
string,
"NAN");
10905 sprintf(
string,
"%.7g", *(((
float *)
data) + idx));
10909 sprintf(
string,
"NAN");
10911 sprintf(
string,
"%.16lg", *(((
double *)
data) + idx));
10914 sprintf(
string,
"%u", *(((
DWORD *)
data) + idx));
10921 sprintf(
string,
"<unknown>");
10943 if (data_size == 0)
10944 sprintf(
string,
"<NULL>");
10948 sprintf(
string, format, *(((
BYTE *)
data) + idx));
10951 sprintf(
string, format, *(((
char *)
data) + idx));
10954 sprintf(
string, format, *(((
char *)
data) + idx));
10957 sprintf(
string, format, *(((
WORD *)
data) + idx));
10960 sprintf(
string, format, *(((
short *)
data) + idx));
10963 sprintf(
string, format, *(((
DWORD *)
data) + idx));
10966 sprintf(
string, format, *(((
INT *)
data) + idx));
10969 sprintf(
string, format, *(((
UINT64 *)
data) + idx));
10972 sprintf(
string, format, *(((
INT64 *)
data) + idx));
10975 sprintf(
string, format, *(((
BOOL *)
data) + idx) ?
'y' :
'n');
10979 sprintf(
string,
"NAN");
10981 sprintf(
string, format, *(((
float *)
data) + idx));
10985 sprintf(
string,
"NAN");
10987 sprintf(
string, format, *(((
double *)
data) + idx));
10990 sprintf(
string, format, *(((
DWORD *)
data) + idx));
10997 sprintf(
string,
"<unknown>");
11027 if (data_size == 0)
11028 sprintf(
string,
"<NULL>");
11032 sprintf(
string,
"0x%X", *(((
BYTE *)
data) + idx));
11035 sprintf(
string,
"0x%X", *(((
char *)
data) + idx));
11038 sprintf(
string,
"%c", *(((
char *)
data) + idx));
11041 sprintf(
string,
"0x%X", *(((
WORD *)
data) + idx));
11044 sprintf(
string,
"0x%hX", *(((
short *)
data) + idx));
11047 sprintf(
string,
"0x%X", *(((
DWORD *)
data) + idx));
11050 sprintf(
string,
"0x%X", *(((
INT *)
data) + idx));
11053 sprintf(
string,
"0x%llX", *(((
UINT64 *)
data) + idx));
11056 sprintf(
string,
"0x%llX", *(((
INT64 *)
data) + idx));
11059 sprintf(
string,
"%c", *(((
BOOL *)
data) + idx) ?
'y' :
'n');
11063 sprintf(
string,
"NAN");
11065 sprintf(
string,
"%.7g", *(((
float *)
data) + idx));
11069 sprintf(
string,
"NAN");
11071 sprintf(
string,
"%.16lg", *(((
double *)
data) + idx));
11074 sprintf(
string,
"0x%X", *(((
DWORD *)
data) + idx));
11078 sprintf(
string,
"%s", ((
char *)
data) + data_size * idx);
11081 sprintf(
string,
"<unknown>");
11111 if (data_size == 0) {
11117 sprintf(buf,
"%d", *(((
BYTE *)
data) + idx));
11120 sprintf(buf,
"%d", *(((
char *)
data) + idx));
11123 sprintf(buf,
"%c", *(((
char *)
data) + idx));
11126 sprintf(buf,
"%u", *(((
WORD *)
data) + idx));
11129 sprintf(buf,
"%d", *(((
short *)
data) + idx));
11132 sprintf(buf,
"%u", *(((
DWORD *)
data) + idx));
11135 sprintf(buf,
"%d", *(((
INT *)
data) + idx));
11138 sprintf(buf,
"%llu", *(((
UINT64 *)
data) + idx));
11141 sprintf(buf,
"%lld", *(((
INT64 *)
data) + idx));
11144 sprintf(buf,
"%c", *(((
BOOL *)
data) + idx) ?
'y' :
'n');
11150 sprintf(buf,
"%.7g", *(((
float *)
data) + idx));
11157 sprintf(buf,
"%.16lg", *(((
double *)
data) + idx));
11161 sprintf(buf,
"%u", *(((
DWORD *)
data) + idx));
11165 return (((
char *)
data) + data_size * idx);
11167 return "<unknown>";
11187 if (data_size == 0) {
11193 sprintf(buf, format, *(((
BYTE *)
data) + idx));
11196 sprintf(buf, format, *(((
char *)
data) + idx));
11199 sprintf(buf, format, *(((
char *)
data) + idx));
11202 sprintf(buf, format, *(((
WORD *)
data) + idx));
11205 sprintf(buf, format, *(((
short *)
data) + idx));
11208 sprintf(buf, format, *(((
DWORD *)
data) + idx));
11211 sprintf(buf, format, *(((
INT *)
data) + idx));
11214 sprintf(buf, format, *(((
UINT64 *)
data) + idx));
11217 sprintf(buf, format, *(((
INT64 *)
data) + idx));
11220 sprintf(buf, format, *(((
BOOL *)
data) + idx) ?
'y' :
'n');
11226 sprintf(buf, format, *(((
float *)
data) + idx));
11233 sprintf(buf, format, *(((
double *)
data) + idx));
11237 sprintf(buf, format, *(((
DWORD *)
data) + idx));
11241 return (((
char *)
data) + data_size * idx);
11243 return "<unknown>";
11249#ifndef DOXYGEN_SHOULD_SKIP_THIS
11274 if (data_size == 0) {
11280 sprintf(buf,
"0x%X", *(((
BYTE *)
data) + idx));
11283 sprintf(buf,
"0x%X", *(((
char *)
data) + idx));
11286 sprintf(buf,
"%c", *(((
char *)
data) + idx));
11289 sprintf(buf,
"0x%X", *(((
WORD *)
data) + idx));
11292 sprintf(buf,
"0x%hX", *(((
short *)
data) + idx));
11295 sprintf(buf,
"0x%X", *(((
DWORD *)
data) + idx));
11298 sprintf(buf,
"0x%X", *(((
INT *)
data) + idx));
11301 sprintf(buf,
"0x%llX", *(((
UINT64 *)
data) + idx));
11304 sprintf(buf,
"0x%llX", *(((
INT64 *)
data) + idx));
11307 sprintf(buf,
"%c", *(((
BOOL *)
data) + idx) ?
'y' :
'n');
11313 sprintf(buf,
"%.7g", *(((
float *)
data) + idx));
11320 sprintf(buf,
"%.16lg", *(((
double *)
data) + idx));
11324 sprintf(buf,
"0x%X", *(((
DWORD *)
data) + idx));
11328 return (((
char *)
data) + data_size * idx);
11330 return "<unknown>";
11360 if (data_str == NULL)
11364 if (strncmp(data_str,
"0x", 2) == 0) {
11366 sscanf(data_str + 2,
"%x", &
value);
11375 *((
char *)
data +
i) = (char) atoi(data_str);
11378 *((
char *)
data +
i) = data_str[0];
11388 *((
short int *)
data +
i) = (
short int)
value;
11390 *((
short int *)
data +
i) = (
short int) atoi(data_str);
11394 value = strtoul(data_str,
nullptr, 16);
11396 value = strtoul(data_str,
nullptr, 10);
11402 value = strtol(data_str,
nullptr, 16);
11404 value = strtol(data_str,
nullptr, 10);
11410 *((
UINT64 *)
data +
i) = strtoull(data_str,
nullptr, 16);
11412 *((
UINT64 *)
data +
i) = strtoull(data_str,
nullptr, 10);
11416 *((
UINT64 *)
data +
i) = strtoll(data_str,
nullptr, 16);
11418 *((
UINT64 *)
data +
i) = strtoll(data_str,
nullptr, 10);
11421 if (data_str[0] ==
'y' || data_str[0] ==
'Y' ||
11422 data_str[0] ==
't' || data_str[0] ==
'T' || atoi(data_str) > 0)
11428 if (data_str[0] ==
'n' || data_str[0] ==
'N')
11431 *((
float *)
data +
i) = (float) atof(data_str);
11434 if (data_str[0] ==
'n' || data_str[0] ==
'N')
11437 *((
double *)
data +
i) = atof(data_str);
11441 value = strtoul(data_str,
nullptr, 16);
11443 value = strtoul(data_str,
nullptr, 10);
11449 strcpy((
char *)
data, data_str);
11450 *data_size = strlen(data_str) + 1;
11459#ifdef LOCAL_ROUTINES
11472 INT size, align, corr, total_size_tmp;
11482 pkey = (
const KEY *) ((
char *) pheader + pkeylist->
first_key);
11509 if (max_align && align > *max_align)
11510 *max_align = align;
11512 corr =
VALIGN(*total_size, align) - *total_size;
11513 *total_size += corr;
11515 *
data = (
void *) ((
char *) (*data) + corr);
11522 KEY* wpkey = (
KEY*)pkey;
11528 if (convert_flags) {
11548 if (convert_flags) {
11562 *total_size += size;
11568 total_size_tmp = *total_size;
11571 if (max_align && align > *max_align)
11572 *max_align = align;
11574 corr =
VALIGN(*total_size, align) - *total_size;
11575 *total_size += corr;
11577 *
data = (
void *) ((
char *) (*data) + corr);
11582 corr =
VALIGN(*total_size, align) - *total_size;
11583 *total_size += corr;
11585 *
data = (
void *) ((
char *) (*data) + corr);
11597 pkey = (
KEY *) ((
char *) pheader + pkey->
next_key);
11646#ifdef LOCAL_ROUTINES
11671 *buf_size = max_align = 0;
11676 *buf_size =
VALIGN(*buf_size, max_align);
11742#ifdef LOCAL_ROUTINES
11749 if (
data && buf_size) {
11750 memset(
data, 0x00, *buf_size);
11772 cm_msg(
MERROR,
"db_get_record",
"struct size mismatch for \"%s\" (expected size: %d, size in ODB: %d * %d = %d)",
11779 if (convert_flags) {
11791 if (total_size != *buf_size) {
11792 cm_msg(
MERROR,
"db_get_record",
"struct size mismatch for \"%s\" (expected size: %d, size in ODB: %d)",
db_get_path(
hDB,
hKey).c_str(), *buf_size, total_size);
11836 int size = *buf_size;
11851 cm_msg(
MINFO,
"db_get_record1",
"Fixing ODB \"%s\" struct size mismatch (expected %d, odb size %d)", path.c_str(), size,
odb_size);
11881 cm_msg(
MERROR,
"db_get_record1",
"after db_check_record() still struct size mismatch (expected %d, odb size %d) of \"%s\", calling db_create_record()", size,
odb_size, path.c_str());
11887 cm_msg(
MERROR,
"db_get_record1",
"repaired struct size mismatch of \"%s\"", path.c_str());
11895static int db_parse_record(
const char* rec_str,
const char** out_rec_str,
char* title,
int title_size,
char* key_name,
int key_name_size,
int* tid,
int* n_data,
int* string_length)
11901 *string_length = 0;
11902 *out_rec_str = NULL;
11916 while (*rec_str ==
'\n')
11920 if (rec_str[0] ==
'[') {
11926 mstrlcpy(title, rec_str, title_size);
11927 char* p = strchr(title,
']');
11931 int len = strlen(title);
11933 if (title[len - 1] !=
'/')
11934 mstrlcat(title,
"/", title_size);
11938 const char* pend = strchr(rec_str,
'\n');
11942 rec_str = rec_str+strlen(rec_str);
11944 while (*rec_str ==
'\n')
11947 *out_rec_str = rec_str;
11951 if (rec_str[0] ==
';') {
11953 const char* pend = strchr(rec_str,
'\n');
11957 rec_str = rec_str+strlen(rec_str);
11959 while (*rec_str ==
'\n')
11962 *out_rec_str = rec_str;
11966 const char* peq = strchr(rec_str,
'=');
11968 cm_msg(
MERROR,
"db_parse_record",
"do not see \'=\'");
11972 int key_name_len = peq - rec_str;
11975 while (key_name_len > 1) {
11976 if (rec_str[key_name_len-1] ==
'=') {
11980 if (rec_str[key_name_len-1] ==
' ') {
11987 memcpy(key_name, rec_str, key_name_len);
11988 key_name[key_name_len] = 0;
11992 while (*rec_str ==
' ')
11998 for (
i=0;
i<(int)
sizeof(stid)-1;
i++) {
12001 if (s ==
' ')
break;
12002 if (s ==
'\n')
break;
12003 if (s ==
'[')
break;
12010 for (xtid = 0; xtid <
TID_LAST; xtid++) {
12020 cm_msg(
MERROR,
"db_parse_record",
"do not see \':\'");
12024 while (*rec_str ==
' ')
12029 if (*rec_str ==
'[') {
12032 *n_data = atoi(rec_str);
12033 const char *pbr = strchr(rec_str,
']');
12035 cm_msg(
MERROR,
"db_parse_record",
"do not see closing bracket \']\'");
12041 while (*rec_str ==
' ')
12044 const char* pcol = strchr(rec_str,
':');
12046 cm_msg(
MERROR,
"db_parse_record",
"do not see \':\'");
12050 rec_str = pcol + 1;
12052 while (*rec_str ==
' ')
12055 *string_length = 0;
12058 const char* pbr = strchr(rec_str,
'[');
12060 *string_length = atoi(pbr+1);
12065 const char* pend = strchr(rec_str,
'\n');
12069 rec_str = rec_str+strlen(rec_str);
12071 while (*rec_str ==
'\n')
12074 *out_rec_str = rec_str;
12081 assert(n_data > 0);
12083 int offset = *buf_ptr - buf_start;
12085 if (tsize && (
offset%tsize != 0)) {
12086 while (
offset%tsize != 0) {
12088 *(*buf_ptr) = 0xFF;
12094 printf(
"read element [%s] tid %d, n_data %d, string_length %d, tid_size %d, align %d, offset %d, buf_remain %d\n", key_name, tid, n_data, string_length, tsize, align,
offset, *buf_remain);
12096 int xsize = tsize*n_data;
12097 if (xsize > *buf_remain) {
12098 cm_msg(
MERROR,
"db_get_record2",
"buffer overrun at key \"%s\", size %d, buffer remaining %d", key_name, xsize, *buf_remain);
12105 cm_msg(
MERROR,
"db_get_record2",
"cannot read \"%s\", db_get_value() status %d", key_name,
status);
12106 memset(*buf_ptr, 0, xsize);
12108 *buf_remain -= xsize;
12112 *buf_remain -= xsize;
12116 for (
i=0;
i<n_data;
i++) {
12117 int xsize = string_length;
12118 if (xsize > *buf_remain) {
12119 cm_msg(
MERROR,
"db_get_record2",
"string buffer overrun at key \"%s\" index %d, size %d, buffer remaining %d", key_name,
i, xsize, *buf_remain);
12122 std::string xkey_name =
msprintf(
"%s[%d]", key_name,
i);
12127 (*buf_ptr)[string_length-1] = 0;
12128 cm_msg(
MERROR,
"db_get_record2",
"string key \"%s\" index %d, string value was truncated", key_name,
i);
12130 cm_msg(
MERROR,
"db_get_record2",
"cannot read string \"%s\"[%d], db_get_value() status %d", key_name,
i,
status);
12131 memset(*buf_ptr, 0, string_length);
12134 *buf_ptr += string_length;
12135 *buf_remain -= string_length;
12137 if (xstatus != 0) {
12141 cm_msg(
MERROR,
"db_get_record2",
"cannot read key \"%s\" of unsupported type %d", key_name, tid);
12201 printf(
"db_get_record2!\n");
12203 assert(
data != NULL);
12204 assert(xbuf_size != NULL);
12205 assert(*xbuf_size > 0);
12206 assert(correct == 0);
12211 int rs = *xbuf_size;
12213 r1 = (
char*)malloc(rs);
12214 assert(r1 != NULL);
12215 memset(
data, 0xFF, *xbuf_size);
12216 memset(r1, 0xFF, rs);
12219 printf(
"db_get_record status %d\n",
status);
12223 char* buf_start = (
char*)
data;
12224 int buf_size = *xbuf_size;
12226 char* buf_ptr = buf_start;
12227 int buf_remain = buf_size;
12229 while (rec_str && *rec_str != 0) {
12234 int string_length = 0;
12235 const char* rec_str_next = NULL;
12237 status =
db_parse_record(rec_str, &rec_str_next, title,
sizeof(title), key_name,
sizeof(key_name), &tid, &n_data, &string_length);
12241 rec_str = rec_str_next;
12247 if (key_name[0] == 0) {
12254 cm_msg(
MERROR,
"db_get_record2",
"error: cannot continue reading odb record because of previous fatal error, status %d",
status);
12260 rec_str = rec_str_next;
12266 for (
i=0;
i<rs;
i++) {
12267 if (r1[
i] != buf_start[
i]) {
12272 if (ok>=0 || buf_remain>0) {
12273 printf(
"db_get_record2: miscompare at %d out of %d, buf_remain %d\n", ok, rs, buf_remain);
12275 printf(
"db_get_record2: check ok\n");
12279 if (buf_remain > 0) {
12326#ifdef LOCAL_ROUTINES
12353 if (convert_flags) {
12366 if (total_size != buf_size) {
12390#ifndef DOXYGEN_SHOULD_SKIP_THIS
12405#ifdef LOCAL_ROUTINES
12411 cm_msg(
MERROR,
"db_add_open_record",
"invalid database handle");
12430 if (i < pclient->max_index) {
12480#ifdef LOCAL_ROUTINES
12490 for (idx = 0; idx < pclient->
max_index; idx++)
12542#ifdef LOCAL_ROUTINES
12545 cm_msg(
MERROR,
"db_remove_open_record",
"invalid database handle %d",
hDB);
12567#ifdef LOCAL_ROUTINES
12634 cm_msg(
MERROR,
"db_notify_clients",
"db_notify_clients() does not work in remotely connected MIDAS clients");
12638#ifdef LOCAL_ROUTINES
12670#ifdef LOCAL_ROUTINES
12702 mstrlcpy(full_name, s.c_str(),
sizeof(full_name));
12703 *strchr(full_name,
'O') =
'I';
12710 cm_msg(
MERROR,
"merge_records",
"merge_record error at \'%s\', db_get_key() status %d", full_name,
status);
12715 cm_msg(
MERROR,
"merge_records",
"merge_record error at \'%s\', second db_get_key() status %d", full_name,
status);
12720 char* allocbuffer = NULL;
12721 char stackbuffer[10000];
12722 char* buffer = stackbuffer;
12723 size =
sizeof(stackbuffer);
12730 cm_msg(
MERROR,
"merge_records",
"merge_record error at \'%s\', db_set_data() status %d", full_name,
status);
12737 allocbuffer = (
char *)realloc(allocbuffer, size);
12738 assert(allocbuffer != NULL);
12739 buffer = allocbuffer;
12742 cm_msg(
MERROR,
"merge_records",
"aborting on unexpected failure of db_get_data(%s), status %d", full_name,
status);
12753 size =
sizeof(full_name);
12756 cm_msg(
MERROR,
"merge_records",
"Invalid link \"%s\"", full_name);
12758 cm_msg(
MERROR,
"merge_records",
"aborting on unexpected failure of db_find_key(%s), status %d", full_name,
status);
12833 char key_name[256], *buffer;
12844 mstrlcpy(key_name, orig_key_name,
sizeof(key_name));
12845 if (strlen(key_name) > 1 && key_name[strlen(key_name) - 1] ==
'/')
12846 key_name[strlen(key_name) - 1] = 0;
12851 assert(hKeyOrig != 0);
12852#ifdef CHECK_OPEN_RECORD
12888 buffer_size = 10000;
12889 buffer = (
char *) malloc(buffer_size);
12890 assert(buffer != NULL);
12893 size = buffer_size;
12896 buffer_size += 10000;
12897 buffer = (
char *) realloc(buffer, buffer_size);
12898 assert(buffer != NULL);
12935 size = buffer_size;
12938 buffer_size += 10000;
12939 buffer = (
char *) realloc(buffer, buffer_size);
12978 cm_msg(
MERROR,
"db_create_record",
"aborting on unexpected failure of db_find_key(%s), status %d", key_name,
status);
13010 const char *pold, *rec_str_orig;
13013 HNDLE hKeyRoot, hKeyTest;
13015 int bad_string_length;
13033 rec_str_orig = rec_str;
13041 hKeyTest = hKeyRoot;
13043 if (hKeyTest == 0 && *rec_str != 0) {
13055 line[
i] = *rec_str++;
13063 if (*rec_str ==
'\n')
13067 if (line[0] ==
'[') {
13069 strcpy(title, line + 1);
13070 if (strchr(title,
']'))
13071 *strchr(title,
']') = 0;
13072 if (title[0] && title[strlen(title) - 1] !=
'/')
13073 strcat(title,
"/");
13076 if (strchr(line,
'=') && line[0] !=
';') {
13078 pc = strchr(line,
'=') + 1;
13081 strcpy(info_str, pc);
13084 *strchr(line,
'=') = 0;
13086 pc = &line[strlen(line) - 1];
13090 mstrlcpy(key_name, line,
sizeof(key_name));
13093 strcpy(line, info_str);
13094 if (strchr(line,
' '))
13095 *strchr(line,
' ') = 0;
13098 if (strchr(line,
'[')) {
13099 n_data = atol(strchr(line,
'[') + 1);
13100 *strchr(line,
'[') = 0;
13103 for (tid = 0; tid <
TID_LAST; tid++)
13107 for (tid = 0; tid <
TID_LAST; tid++)
13115 cm_msg(
MERROR,
"db_check_record",
"found unknown data type \"%s\" in ODB file", line);
13119 while (*pc !=
' ' && *pc)
13121 while ((*pc ==
' ' || *pc ==
':') && *pc)
13129 for (
j = 0; *rec_str !=
'\n' && *rec_str;
j++)
13130 info_str[
j] = *rec_str++;
13132 if (*rec_str ==
'\n')
13136 for (
i = 0;
i < n_data;
i++) {
13138 pc = &info_str[strlen(info_str) - 1];
13139 while (*pc ==
'\n' || *pc ==
'\r')
13143 if (!string_length) {
13144 if (info_str[1] ==
'=')
13145 string_length = -1;
13147 pc = strchr(info_str,
'[');
13149 string_length = atoi(pc + 1);
13151 string_length = -1;
13155 cm_msg(
MERROR,
"db_check_record",
"found string exceeding MAX_STRING_LENGTH");
13159 if (string_length == -1) {
13161 if (strstr(rec_str,
"\n====#$@$#====\n") != NULL) {
13162 string_length = (
POINTER_T) strstr(rec_str,
"\n====#$@$#====\n") - (
POINTER_T) rec_str + 1;
13164 rec_str = strstr(rec_str,
"\n====#$@$#====\n") + strlen(
"\n====#$@$#====\n");
13166 cm_msg(
MERROR,
"db_check_record",
"found multi-line string without termination sequence");
13168 if (strchr(info_str,
']'))
13169 pc = strchr(info_str,
']') + 1;
13172 while (*pc && *pc !=
' ')
13174 while (*pc && *pc ==
' ')
13178 *(pc + string_length - 1) = 0;
13183 if (n_data > 1 && info_str[0] ==
'[') {
13184 pc = strchr(info_str,
']') + 1;
13185 while (*pc && *pc ==
' ')
13190 if (
i < n_data - 1) {
13197 for (
j = 0; *rec_str !=
'\n' && *rec_str;
j++)
13198 info_str[
j] = *rec_str++;
13200 if (*rec_str ==
'\n')
13205 if (info_str[0] == 0 || (strchr(info_str,
'=')
13206 && strchr(info_str,
':')))
13223 bad_string_length = 0;
13227 if (string_length > 0 && string_length !=
key.
item_size) {
13228 bad_string_length = 1;
13323 WORD access_mode,
void (*dispatcher) (
INT,
INT,
void *),
void *
info)
13335 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13351 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13367 cm_msg(
MERROR,
"db_open_record",
"cannot get record size, db_get_record_size() status %d",
status);
13371 if (size != rec_size && ptr != NULL) {
13374 cm_msg(
MERROR,
"db_open_record",
"struct size mismatch for \"%s\" (expected size: %d, size in ODB: %d)", path.c_str(), rec_size, size);
13387 data = malloc(size);
13389 if (
data == NULL) {
13391 cm_msg(
MERROR,
"db_open_record",
"not enough memory, malloc(%d) returned NULL", size);
13395 memset(
data, 0, size);
13397 *((
void **) ptr) =
data;
13407 cm_msg(
MERROR,
"db_open_record",
"cannot get record, db_get_record() status %d",
status);
13419 cm_msg(
MERROR,
"db_open_record",
"cannot set record, db_set_record() status %d",
status);
13427 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13474 WORD access_mode,
void (*dispatcher) (
INT,
INT,
void *),
void *
info,
13475 const char *rec_str)
13481 int size = rec_size;
13482 pbuf = (
char*)malloc(size);
13483 assert(pbuf != NULL);
13507#ifdef LOCAL_ROUTINES
13642 *((
INT *) nc->
param + 1) = hKeyRoot;
13646 if (convert_flags) {
13890 cm_msg(
MERROR,
"db_watch",
"cannot get key \"%s\"", path.c_str());
13898 cm_msg(
MERROR,
"db_watch",
"cannot get key \"%s\"", path.c_str());
13922#ifdef LOCAL_ROUTINES
13975 cm_msg(
MERROR,
"db_get_value_string",
"cannot resize odb string arrays, please use db_resize_string() instead");
13994 char* buf = (
char*)malloc(size);
13995 assert(buf != NULL);
14018 if (create_string_length == 0) {
14019 int size = s->length() + 1;
14022 char* buf = (
char*)malloc(create_string_length);
14024 mstrlcpy(buf, s->c_str(), create_string_length);
14041 int size = s->length() + 1;
14065 int old_num_values = 0;
14066 int old_item_size = 0;
14068 char* old_data = NULL;
14083 old_size = old_num_values * old_item_size;
14084 if (old_size > 0) {
14085 old_data = (
char*)malloc(old_size);
14086 assert(old_data != NULL);
14087 int size = old_size;
14093 assert(size == old_size);
14106 int item_size = max_string_length;
14109 item_size = old_item_size;
14111 if (num_values < 1)
14112 num_values = old_num_values;
14114 int new_size = num_values * item_size;
14115 char* new_data = (
char*)malloc(new_size);
14118 memset(new_data, 0, new_size);
14121 int num = old_num_values;
14122 if (num > num_values)
14127 for (
int i=0;
i<num;
i++) {
14128 const char* old_ptr = old_data +
i*old_item_size;
14129 char* new_ptr = new_data +
i*item_size;
14130 mstrlcpy(new_ptr, old_ptr, item_size);
14146#ifdef LOCAL_ROUTINES
14147 MJsonNode* scl = MJsonNode::MakeObject();
14148 MJsonNode* clients = MJsonNode::MakeArray();
14150 scl->AddToObject(
"now", MJsonNode::MakeNumber(
ss_time_sec()));
14151 scl->AddToObject(
"clients", clients);
14164 if (pclient->
pid) {
14165 MJsonNode*
c = MJsonNode::MakeObject();
14166 c->AddToObject(
"slot", MJsonNode::MakeNumber(
i));
14167 c->AddToObject(
"pid", MJsonNode::MakeNumber(pclient->
pid));
14168 c->AddToObject(
"name", MJsonNode::MakeString(pclient->
name));
14169 std::string path =
msprintf(
"/System/Clients/%d/Host", pclient->
pid);
14173 char* host = (
char*)malloc(host_size);
14174 assert(host != NULL);
14176 c->AddToObject(
"host", MJsonNode::MakeString(host));
14179 c->AddToObject(
"watchdog_timeout_millisec", MJsonNode::MakeNumber(pclient->
watchdog_timeout));
14181 c->AddToObject(
"last_activity_millisec", MJsonNode::MakeNumber(now - pclient->
last_activity));
14182 clients->AddToArray(
c);
14190 return MJsonNode::MakeNull();
14197 assert(root_path != NULL);
14198#ifdef LOCAL_ROUTINES
14199 size_t root_path_len = strlen(root_path);
14200 MJsonNode* sor = MJsonNode::MakeArray();
14211 if (pclient->
pid) {
14214 if (path.length() < root_path_len)
14216 if (strncmp(root_path, path.c_str(), root_path_len) != 0)
14218 MJsonNode*
c = MJsonNode::MakeObject();
14219 c->AddToObject(
"name", MJsonNode::MakeString(pclient->
name));
14223 c->AddToObject(
"path", MJsonNode::MakeString(path.c_str()));
14224 sor->AddToArray(
c);
14233 return MJsonNode::MakeNull();
INT cm_get_watchdog_params(BOOL *call_watchdog, DWORD *timeout)
#define DB_STRUCT_MISMATCH
#define DB_INVALID_HANDLE
#define DB_STRUCT_SIZE_MISMATCH
#define DB_NO_MORE_SUBKEYS
#define DB_VERSION_MISMATCH
#define VALIGN(adr, align)
#define MAX_STRING_LENGTH
INT ss_get_struct_align()
INT ss_suspend_get_odb_port(INT *port)
bool ss_is_valid_utf8(const char *string)
INT ss_mutex_release(MUTEX_T *mutex)
INT ss_shm_flush(const char *name, const void *adr, size_t size, HNDLE handle, bool wait_for_thread)
INT ss_semaphore_create(const char *name, HNDLE *semaphore_handle)
INT ss_mutex_delete(MUTEX_T *mutex)
INT ss_mutex_create(MUTEX_T **mutex, BOOL recursive)
INT ss_shm_open(const char *name, INT size, void **adr, size_t *shm_size, HNDLE *handle, BOOL get_size)
INT ss_semaphore_release(HNDLE semaphore_handle)
void ss_stack_history_entry(char *tag)
std::string ss_tid_to_string(midas_thread_t thread_id)
INT ss_resume(INT port, const char *message)
midas_thread_t ss_gettid(void)
INT ss_semaphore_delete(HNDLE semaphore_handle, INT destroy_flag)
INT ss_semaphore_wait_for(HNDLE semaphore_handle, DWORD timeout_millisec)
INT ss_shm_unprotect(HNDLE handle, void **adr, size_t shm_size, BOOL read, BOOL write, const char *caller_name)
INT ss_shm_close(const char *name, void *adr, size_t shm_size, HNDLE handle, INT destroy_flag)
INT send_tcp(int sock, char *buffer, DWORD buffer_size, INT flags)
BOOL ss_pid_exists(int pid)
INT ss_shm_protect(HNDLE handle, void *adr, size_t shm_size)
INT ss_mutex_wait_for(MUTEX_T *mutex, INT timeout)
INT cm_msg_flush_buffer()
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
BOOL equal_ustring(const char *str1, const char *str2)
static void free_key(DATABASE_HEADER *pheader, void *address, INT size)
INT db_sprintfh(char *string, const void *data, INT data_size, INT idx, DWORD type)
INT db_flush_database(HNDLE hDB)
static void json_write_key(HNDLE hDB, HNDLE hKey, const KEY *key, const char *link_path, char **buffer, int *buffer_size, int *buffer_end)
INT db_remove_open_record(HNDLE hDB, HNDLE hKey, BOOL lock)
static void check_open_keys(HNDLE hDB, HNDLE hKey, KEY *pkey, INT level, void *info)
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
INT db_send_changed_records()
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
INT db_check_client(HNDLE hDB, HNDLE hKeyClient)
static void * malloc_key(DATABASE_HEADER *pheader, INT size, const char *caller)
static INT db_set_data_index_wlocked(DATABASE_HEADER *pheader, KEY *pkey, int idx, const void *data, INT data_size, DWORD type, const char *caller, db_err_msg **msg)
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
static const KEY * db_get_parent(const DATABASE_HEADER *pheader, const KEY *pkey, int *pstatus, const char *caller, db_err_msg **msg)
static int db_scan_tree_locked(const DATABASE_HEADER *pheader, const KEY *pkey, int level, int(*callback)(const DATABASE_HEADER *, const KEY *, int, void *, db_err_msg **), void *info, db_err_msg **msg)
INT db_save_json(HNDLE hDB, HNDLE hKey, const char *filename, int flags)
static INT _record_list_entries
INT db_open_record(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info)
INT db_open_database(const char *xdatabase_name, INT database_size, HNDLE *hDB, const char *client_name)
static int db_paste_node(HNDLE hDB, HNDLE hKeyRoot, PMXML_NODE node)
INT db_get_open_records(HNDLE hDB, HNDLE hKey, char *str, INT buf_size, BOOL fix)
INT db_paste_xml(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
static INT db_check_set_data_locked(DATABASE_HEADER *pheader, const KEY *pkey, const void *data, INT data_size, INT num_values, DWORD type, const char *caller, db_err_msg **msg)
void db_cleanup(const char *who, DWORD actual_time, BOOL wrong_interval)
static const KEY * db_resolve_link_locked(const DATABASE_HEADER *, const KEY *, int *pstatus, db_err_msg **)
static bool db_validate_hkey(const DATABASE_HEADER *pheader, HNDLE hKey)
std::string strcomb1(const char **list)
static void db_print_hkey(const DATABASE_HEADER *pheader, HNDLE hkey, int recurse=0, const char *path=NULL, HNDLE parenthkeylist=0)
static void * malloc_data(DATABASE_HEADER *pheader, INT size)
static int db_save_json_key_obsolete(HNDLE hDB, HNDLE hKey, INT level, char **buffer, int *buffer_size, int *buffer_end, int save_keys, int follow_links, int recurse)
INT db_save_xml(HNDLE hDB, HNDLE hKey, const char *filename)
static int db_delete_key_locked(DATABASE *pdb, const KEY *pkey, int level, db_err_msg **msg)
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
static INT print_key_info_locked(const DATABASE_HEADER *pheader, const KEY *pkey, INT level, void *info, db_err_msg **msg)
static const KEY * db_find_pkey_locked(const DATABASE_HEADER *pheader, const KEY *pkey, const char *key_name, bool follow_links, int *pstatus, db_err_msg **msg)
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
int json_write_bare_subdir(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int level, int flags, time_t timestamp)
INT db_get_record1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align, const char *rec_str)
static int db_create_key_wlocked(DATABASE_HEADER *pheader, KEY *parentKey, const char *key_name, DWORD type, KEY **pnewkey, db_err_msg **msg)
INT db_copy(HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, const char *path)
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
BOOL strmatch(char *pattern, char *str)
INT EXPRT db_enum(HNDLE hDB, HNDLE hKeyRoot, std::vector< HNDLE > *sub_handles, std::vector< KEY > *sub_keys, bool follow_links)
std::string db_show_mem(HNDLE hDB, BOOL verbose)
INT db_get_record_size(HNDLE hDB, HNDLE hKey, INT align, INT *buf_size)
static INT db_check_set_data_index_locked(DATABASE_HEADER *pheader, const KEY *pkey, int idx, const void *data, INT data_size, DWORD type, const char *caller, db_err_msg **msg)
static INT db_get_data_locked(DATABASE_HEADER *pheader, const KEY *pkey, int idx, void *data, INT *buf_size, DWORD type, db_err_msg **msg)
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
INT db_check_record(HNDLE hDB, HNDLE hKey, const char *keyname, const char *rec_str, BOOL correct)
static int validate_free_data(DATABASE_HEADER *pheader, int free_data)
INT db_copy_json_save(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
INT db_copy_xml(HNDLE hDB, HNDLE hKey, char *buffer, int *buffer_size, bool header)
MJsonNode * db_scl(HNDLE hDB)
static RECORD_LIST * _record_list
INT db_save_struct(HNDLE hDB, HNDLE hKey, const char *file_name, const char *struct_name, BOOL append)
INT db_get_record(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT align)
static void * realloc_data(DATABASE_HEADER *pheader, void *address, INT old_size, INT new_size, const char *caller)
void xml_encode(char *src, int size)
INT db_unwatch(HNDLE hDB, HNDLE hKey)
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
INT db_get_next_link(HNDLE hDB, HNDLE hKey, HNDLE *subkey_handle)
static const KEYLIST * db_get_pkeylist(const DATABASE_HEADER *pheader, const KEY *pkey, const char *caller, db_err_msg **msg, bool kludge_repair=false)
INT db_scan_tree_link(HNDLE hDB, HNDLE hKey, INT level, void(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
INT db_save(HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote)
static bool db_validate_and_repair_db_wlocked(DATABASE_HEADER *pheader, db_err_msg **msg)
INT db_allow_write_locked(DATABASE *p, const char *caller_name)
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
static INT db_get_key_locked(const DATABASE_HEADER *pheader, HNDLE hKey, KEY *key, db_err_msg **msg)
static int _global_open_count
INT db_get_link(HNDLE hDB, HNDLE hKey, KEY *key)
static INT _database_entries
static bool db_validate_data_offset(const DATABASE_HEADER *pheader, int offset)
static int db_remove_open_record_wlocked(DATABASE *pdb, DATABASE_HEADER *pheader, HNDLE hKey)
static int json_write_bare_key(HNDLE hDB, HNDLE hLink, const KEY &link, char **buffer, int *buffer_size, int *buffer_end, int level, int flags, time_t timestamp, bool need_comma)
static int db_get_record2_read_element(HNDLE hDB, HNDLE hKey, const char *key_name, int tid, int n_data, int string_length, char *buf_start, char **buf_ptr, int *buf_remain, BOOL correct)
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
INT EXPRT db_get_value_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int index, std::string *s, BOOL create, int create_string_length)
INT db_sprintff(char *string, const char *format, const void *data, INT data_size, INT idx, DWORD type)
static void db_delete_client_wlocked(DATABASE_HEADER *pheader, int jclient, db_err_msg **msg)
INT db_get_watchdog_info(HNDLE hDB, const char *client_name, DWORD *timeout, DWORD *last)
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
static int db_notify_clients_locked(const DATABASE *pdb, HNDLE hKeyMod, int index, BOOL bWalk, db_err_msg **msg)
static HNDLE db_pkey_to_hkey(const DATABASE_HEADER *pheader, const KEY *pkey)
static bool db_validate_key_offset(const DATABASE_HEADER *pheader, int offset)
static int free_data(DATABASE_HEADER *pheader, void *address, INT size, const char *caller)
static void db_save_tree_struct(HNDLE hDB, HNDLE hKey, int hfile, INT level)
static void db_print_pkey(const DATABASE_HEADER *pheader, const KEY *pkey, int recurse=0, const char *path=NULL, HNDLE parenthkeylist=0)
INT db_save_string(HNDLE hDB, HNDLE hKey, const char *file_name, const char *string_name, BOOL append)
static int db_update_open_record_wlocked(const DATABASE_HEADER *xpheader, const KEY *xpkey, int level, void *voidp, db_err_msg **msg)
INT db_copy_json_index(HNDLE hDB, HNDLE hKey, int index, char **buffer, int *buffer_size, int *buffer_end)
static int db_check_open_record(const DATABASE_HEADER *pheader, const KEY *pkey, db_err_msg **msg)
INT db_close_all_records()
static int db_delete_client_info_wlocked(DATABASE *pdb, int pid, db_err_msg **msg)
static const KEY * db_enum_next_locked(const DATABASE_HEADER *pheader, const KEY *pdir, const KEY *pkey, db_err_msg **msg)
INT db_paste(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
INT db_save_xml_key(HNDLE hDB, HNDLE hKey, INT level, MXML_WRITER *writer)
static std::string db_get_path_pkey(const DATABASE_HEADER *pheader, const KEY *pkey)
static void static void db_print_msg(const db_err_msg *msg)
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
static std::string db_get_path_locked(const DATABASE_HEADER *pheader, HNDLE hKey)
INT db_get_key_info(HNDLE hDB, HNDLE hKey, char *name, INT name_size, INT *type, INT *num_values, INT *item_size)
INT db_close_all_databases(void)
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
static const KEY * db_get_pkey(const DATABASE_HEADER *pheader, HNDLE hKey, int *pstatus, const char *caller, db_err_msg **msg)
INT db_copy_json_ls(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
char * strcomb(const char **list)
static INT db_set_data_wlocked(DATABASE_HEADER *pheader, KEY *pkey, const void *data, INT data_size, INT num_values, DWORD type, const char *caller, db_err_msg **msg)
int EXPRT json_write_anything(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int level, int must_be_subdir, int flags, time_t timestamp)
static WATCH_LIST * _watch_list
static int db_fix_open_records(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *xresult)
INT db_delete(HNDLE hDB, HNDLE hKeyRoot, const char *odb_path)
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
INT db_update_last_activity(DWORD millitime)
INT db_copy_json_obsolete(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int save_keys, int follow_links, int recurse)
void strarrayindex(char *odbpath, int *index1, int *index2)
INT db_set_data1(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
DATABASE_CLIENT * db_get_my_client_locked(DATABASE *pdb)
static int db_set_mode_wlocked(DATABASE_HEADER *, KEY *, WORD mode, int recurse, db_err_msg **)
INT db_get_data1(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type, INT *num_values)
INT db_copy_json_values(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end, int omit_names, int omit_last_written, time_t omit_old_timestamp, int preserve_case)
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
static int db_find_open_records(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *xresult)
static void json_write_data(char **buffer, int *buffer_size, int *buffer_end, int level, const KEY *key, const char *p)
static INT _watch_list_entries
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
static void db_recurse_record_tree_locked(const DATABASE *pdb, const KEY *pkey, void **data, INT *total_size, INT base_align, INT *max_align, BOOL bSet, INT convert_flags, db_err_msg **msg)
static const KEY * db_enum_first_locked(const DATABASE_HEADER *pheader, const KEY *pkey, db_err_msg **msg)
INT db_update_record_local(INT hDB, INT hKeyRoot, INT hKey, int index)
INT db_copy_json_array(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
MJsonNode * db_sor(HNDLE hDB, const char *root_path)
INT db_get_link_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
void db_set_watchdog_params(DWORD timeout)
static void db_validate_sizes()
INT db_update_record_mserver(INT hDB, INT hKeyRoot, INT hKey, int index, int client_socket)
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
BOOL ends_with_ustring(const char *str, const char *suffix)
void db_cleanup2(const char *client_name, int ignore_timeout, DWORD actual_time, const char *who)
void json_write(char **buffer, int *buffer_size, int *buffer_end, int level, const char *s, int quoted)
INT EXPRT db_paste_json(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
static bool is_utf8(const char *string)
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
int db_delete_client_info(HNDLE hDB, int pid)
static bool db_validate_and_repair_key_wlocked(DATABASE_HEADER *pheader, int recurse, const char *path, HNDLE parenthkeylist, HNDLE hkey, KEY *pkey, db_err_msg **msg)
static void db_flush_msg(db_err_msg **msg)
static INT db_find_key_locked(const DATABASE_HEADER *pheader, HNDLE hKey, const char *key_name, bool follow_links, HNDLE *subhKey, db_err_msg **msg)
static DATABASE * db_lock_database(HNDLE hDB, int *pstatus, const char *caller, bool check_attached=true)
INT db_find_keys(HNDLE hDB, HNDLE hKeyRoot, const char *odbpath, std::vector< HNDLE > &hKeyVector)
static int db_validate_name(const char *name, int maybe_path, const char *caller_name, db_err_msg **msg)
INT db_set_client_name(HNDLE hDB, const char *client_name)
static int db_set_value_wlocked(DATABASE *pdb, KEY *pkey_root, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type, db_err_msg **msg)
INT db_set_value_index(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT idx, DWORD type, BOOL trunc)
INT db_notify_clients_array(HNDLE hDB, HNDLE hKeys[], INT size)
INT db_open_record1(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info, const char *rec_str)
INT db_merge_data(HNDLE hDB, HNDLE hKeyRoot, const char *name, void *data, INT data_size, INT num_values, INT type)
INT db_notify_clients(HNDLE hDB, HNDLE hKeyMod, int index, BOOL bWalk)
INT db_set_record(HNDLE hDB, HNDLE hKey, void *data, INT buf_size, INT align)
INT db_set_data_index1(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type, BOOL bNotify)
static int db_parse_record(const char *rec_str, const char **out_rec_str, char *title, int title_size, char *key_name, int key_name_size, int *tid, int *n_data, int *string_length)
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
INT EXPRT db_resize_string(HNDLE hdb, HNDLE hKeyRoot, const char *key_name, int num_values, int max_string_length)
static void db_unlock_database(DATABASE *pdb, const char *caller)
INT db_close_record(HNDLE hDB, HNDLE hKey)
static int db_validate_open_records_wlocked(DATABASE_HEADER *pheader, db_err_msg **msg)
INT db_create_record(HNDLE hDB, HNDLE hKey, const char *orig_key_name, const char *init_str)
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
static db_err_msg * _last_error_message
static void db_msg(db_err_msg **msg, INT message_type, const char *filename, INT line, const char *routine, const char *format,...) MATTRPRINTF(6
INT db_add_open_record(HNDLE hDB, HNDLE hKey, WORD access_mode)
INT EXPRT db_set_value_string(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const std::string *s)
INT db_set_lock_timeout(HNDLE hDB, int timeout_millisec)
static int db_enum_locked(const DATABASE_HEADER *pheader, const KEY *pkey, std::vector< HNDLE > *sub_handles, std::vector< KEY > *sub_keys, bool follow_links, db_err_msg **msg)
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
INT db_get_record2(HNDLE hDB, HNDLE hKey, void *data, INT *xbuf_size, INT align, const char *rec_str, BOOL correct)
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
static void merge_records(HNDLE hDB, HNDLE hKey, KEY *pkey, INT level, void *info)
INT db_close_database(HNDLE hDB)
INT db_protect_database(HNDLE hDB)
struct db_err_msg_struct db_err_msg
const char * extract_key(const char *key_list, char *key_name, int key_name_length)
INT db_get_free_mem(HNDLE hDB, INT *key_size, INT *data_size)
static DATABASE * _database
static void json_ensure_decimal_dot(char *str)
#define RPC_DB_ADD_OPEN_RECORD
#define RPC_DB_SET_DATA_INDEX
void rpc_convert_data(void *data, INT tid, INT flags, INT total_size, INT convert_flags)
#define RPC_DB_CLOSE_DATABASE
#define RPC_DB_CREATE_RECORD
#define RPC_DB_CREATE_LINK
#define RPC_DB_NOTIFY_CLIENTS_ARRAY
#define RPC_DB_DELETE_KEY
#define RPC_DB_SET_NUM_VALUES
const char * rpc_tid_name_old(INT id)
#define RPC_DB_SET_CLIENT_NAME
#define RPC_DB_REMOVE_OPEN_RECORD
#define RPC_DB_CLOSE_ALL_DATABASES
#define RPC_DB_SET_LINK_DATA_INDEX
#define RPC_DB_RENAME_KEY
#define RPC_DB_GET_NEXT_LINK
INT rpc_call(DWORD routine_id,...)
const char * rpc_tid_name(INT id)
#define RPC_DB_SET_LINK_DATA
#define RPC_DB_GET_LINK_DATA
#define RPC_DB_SET_DATA_INDEX1
#define RPC_DB_GET_PARENT
#define RPC_DB_REORDER_KEY
#define RPC_DB_OPEN_DATABASE
#define RPC_DB_CHECK_RECORD
#define RPC_DB_GET_DATA_INDEX
int rpc_name_tid(const char *name)
#define RPC_DB_GET_KEY_INFO
bool rpc_is_mserver(void)
#define RPC_DB_FLUSH_DATABASE
#define RPC_DB_GET_KEY_TIME
#define RPC_DB_SET_RECORD
#define RPC_DB_GET_RECORD_SIZE
#define RPC_DB_GET_OPEN_RECORDS
INT rpc_get_convert_flags(void)
void rpc_convert_single(void *data, INT tid, INT flags, INT convert_flags)
#define RPC_DB_CREATE_KEY
#define RPC_DB_GET_RECORD
std::string msprintf(const char *format,...)
#define DIR_SEPARATOR_STR
#define JSFLAG_FOLLOW_LINKS
#define MATTRPRINTF(a, b)
#define JSFLAG_OMIT_LAST_WRITTEN
unsigned long long UINT64
#define JSFLAG_OMIT_NAMES
#define WATCHDOG_INTERVAL
#define JS_MUST_BE_SUBDIR
#define message(type, str)
#define write(n, a, f, d)
struct callback_addr callback
BOOL match(char *pat, char *str)
OPEN_RECORD open_record[MAX_OPEN_RECORDS]
DATABASE_CLIENT client[MAX_CLIENTS]
DATABASE_HEADER * database_header
NET_COMMAND_HEADER header
void(* dispatcher)(INT, INT, void *)
DATABASE_HEADER * pheader
void(* dispatcher)(INT, INT, INT, void *info)
static double comma(double a, double b)
static te_expr * list(state *s)