28#ifndef DOXYGEN_SHOULD_SKIP_THIS
33#include "git-revision.h"
41#define CHECK_OPEN_RECORD 1
115 while (msg !=
NULL) {
116 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());
139 msg->filename = filename;
141 msg->routine = routine;
173 printf(
"db_flush_msg: %p\n", msg);
177 while (msg !=
NULL) {
223 while (
pfree->size < size &&
pfree->next_free) {
235 if (
pfree->size < size)
269 assert((
void*)
pfound != (
void*)pheader);
284 assert(address != pheader);
305 if (
pprev->next_free <= 0) {
306 cm_msg(
MERROR,
"free_key",
"database is corrupted: pprev=%p, pprev->next_free=%d",
pprev,
pprev->next_free);
385 if (
pfree->size >= size) {
391 if (!
pfree->next_free) {
439 assert((
void*)
pfound != (
void*)pheader);
453 assert(address != pheader);
471 pfree->next_free = 0;
487 if (
pprev->next_free == 0) {
493 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);
603 for (
int i = 0;
list[
i];
i++) {
685 sprintf(
str,
"Database header size is 0x%04X, all following values are offset by this!\n", (
int)
sizeof(
DATABASE_HEADER));
697 add_to_buf(&
buf,
"ODB is corrupted: pheader->first_free_key is invalid\n");
711 sprintf(
str,
"Free block at 0x%08X, size 0x%08X, next 0x%08X\n",
730 add_to_buf(&
buf,
"ODB is corrupted: pheader->first_free_data is invalid\n");
744 sprintf(
str,
"Free block at 0x%08X, size 0x%08X, next 0x%08X\n",
758 sprintf(
str,
"\nFree: %1d (%1.1lf%%) keylist, %1d (%1.1lf%%) data\n",
771 sprintf(
str,
"\nTotal ODB size: %d (0x%08X) Bytes, %lg MiB\n",
801 *key_size +=
pfree->size;
809 *data_size +=
pfree->size;
845 db_msg(msg,
MERROR,
"db_validate_name",
"Invalid name passed to %s: should not be an empty string",
caller_name);
854 if (
name[0] ==
' ') {
859 if (
name[len-1] ==
' ') {
958 db_msg(msg,
MERROR,
caller,
"db_get_pkey: root_key hkey %d invalid key type %d, database root directory is corrupted",
hKey, tid);
964 db_msg(msg,
MERROR,
caller,
"db_get_pkey: hkey %d path \"%s\" invalid key type %d",
hKey, path.c_str(), tid);
971 if (
pkey->name[0] == 0) {
986 db_msg(msg,
MERROR,
caller,
"db_get_pkeylist: hkey %d path \"%s\" unexpected call to db_get_pkeylist(), not a subdirectory, pkey->type %d",
hKey, path.c_str(),
pkey->type);
1018 db_msg(msg,
MERROR,
caller,
"hkey %d path \"%s\" repaired invalid num_keys %d when pkeylist->first_key is zero",
hKey, path.c_str(),
pkeylist->num_keys);
1032 if (
pkey->parent_keylist == 0) {
1062 db_msg(msg,
MERROR,
"db_enum_first_locked",
"hkey %d path \"%s\" tid %d is not a directory",
hKey, path.c_str(),
pkey->type);
1088 if (
pkey->next_key == 0)
1101 if (*((
char *) pheader +
pkey->data) ==
'/') {
1159 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid hkey",
hkey, path);
1165 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", name \"%s\", invalid key type %d",
hkey, path,
pkey->name,
pkey->type);
1174 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\": invalid name \"%s\" replaced with \"%s\"",
hkey, path,
pkey->name,
newname);
1182 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);
1193 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->total_size %d",
hkey, path,
pkey->total_size);
1198 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->item_size: %d",
hkey, path,
pkey->item_size);
1203 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->num_values: %d",
hkey, path,
pkey->num_values);
1208 if (
pkey->total_size !=
pkey->item_size *
pkey->num_values) {
1209 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);
1215 if (
pkey->data == 0 &&
pkey->total_size != 0) {
1216 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);
1217 pkey->num_values = 0;
1218 pkey->total_size = 0;
1223 const char* s = (
char*)pheader +
pkey->data;
1225 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", string value is not valid UTF-8",
hkey, path);
1236 if (
pkey->total_size <= 2) {
1237 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK is an empty link",
hkey, path);
1254 const char*
link = (
char*)pheader +
pkey->data;
1260 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK to \"%s\" is a link to itself",
hkey, path,
link);
1270 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_LINK to \"%s\" is a loop",
hkey, path,
link);
1279 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->access_mode %d",
hkey, path,
pkey->access_mode);
1286 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->last_written time %d",
hkey, path,
pkey->last_written);
1297 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", invalid pkey->data %d",
hkey, path,
pkey->data);
1301 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);
1307 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid pkeylist->num_keys %d",
hkey, path,
pkeylist->num_keys);
1315 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid pkeylist->first_key %d",
hkey, path,
pkeylist->first_key);
1329 db_msg(msg,
MERROR,
"db_validate_key",
"hkey %d, path \"%s\", TID_KEY invalid subhkey %d",
hkey, path,
subhkey);
1351 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);
1368 assert(
pdb->database_header);
1372 int idx =
pdb->client_index;
1375 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);
1383 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);
1391 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);
1416#define S(x) printf("assert(sizeof(%-20s) == %6d);\n", #x, (int)sizeof(x))
1464 printf(
"EQUIPMENT_INFO offset of event_id: %d\n", (
int)((
char*)&
eq.event_id - (
char*)&
eq));
1465 printf(
"EQUIPMENT_INFO offset of eq_type: %d\n", (
int)((
char*)&
eq.eq_type - (
char*)&
eq));
1466 printf(
"EQUIPMENT_INFO offset of event_limit: %d\n", (
int)((
char*)&
eq.event_limit - (
char*)&
eq));
1467 printf(
"EQUIPMENT_INFO offset of num_subevents: %d\n", (
int)((
char*)&
eq.num_subevents - (
char*)&
eq));
1468 printf(
"EQUIPMENT_INFO offset of status: %d\n", (
int)((
char*)&
eq.status - (
char*)&
eq));
1469 printf(
"EQUIPMENT_INFO offset of hidden: %d\n", (
int)((
char*)&
eq.hidden - (
char*)&
eq));
1472 assert(
sizeof(
UINT8) == 1);
1473 assert(
sizeof(
INT8) == 1);
1474 assert(
sizeof(
UINT16) == 2);
1475 assert(
sizeof(
INT16) == 2);
1476 assert(
sizeof(
UINT32) == 4);
1477 assert(
sizeof(
INT32) == 4);
1478 assert(
sizeof(
UINT64) == 8);
1479 assert(
sizeof(
INT64) == 8);
1488 assert(
sizeof(
TAG) == 40);
1489 assert(
sizeof(
KEY) == 68);
1490 assert(
sizeof(
KEYLIST) == 12);
1498 assert(
sizeof(
BANK) == 8);
1499 assert(
sizeof(
BANK32) == 12);
1502 assert(
sizeof(
ALARM) == 460);
1531 for (
k=0;
k<
uorp->num_keys;
k++)
1560 printf(
"%s, notify_count %d, found %d, our count %d\n", path,
pkey->notify_count,
found,
count);
1564 db_msg(msg,
MINFO,
"db_update_open_record",
"Added missing open record flag to \"%s\"", path.c_str());
1566 uorp->num_modified++;
1571 db_msg(msg,
MINFO,
"db_update_open_record",
"Removed open record flag from \"%s\"", path.c_str());
1572 pkey->notify_count = 0;
1573 uorp->num_modified++;
1578 db_msg(msg,
MERROR,
"db_update_open_record",
"Cannot remove exclusive access mode from \"%s\", db_set_mode() status %d", path.c_str(),
status);
1581 db_msg(msg,
MINFO,
"db_update_open_record",
"Removed exclusive access mode from \"%s\"", path.c_str());
1586 if (
pkey->notify_count !=
uorp->counts[
k]) {
1587 db_msg(msg,
MINFO,
"db_update_open_record",
"Updated notify_count of \"%s\" from %d to %d", path.c_str(),
pkey->notify_count,
count);
1589 uorp->num_modified++;
1607 uor.num_modified = 0;
1613 uor.pheader = pheader;
1618 if (
pclient->open_record[
j].handle) {
1620 for (
k=0;
k<
uor.num_keys;
k++) {
1629 uor.counts[
uor.num_keys] = 1;
1637 for (
i=0;
i<
uor.num_keys;
i++)
1638 printf(
"index %d, handle %d, count %d, access mode %d\n",
i,
uor.hkeys[
i],
uor.counts[
i],
uor.modes[
i]);
1647 if (
uor.num_modified) {
1648 db_msg(msg,
MINFO,
"db_validate_open_records",
"Corrected %d ODB entries",
uor.num_modified);
1692 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));
1693 pfree->next_free = 0;
1704 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database key area is %.0f%% full",
ratio * 100.0);
1725 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database corruption, invalid data area next_free 0x%08X",
pfree->next_free - (
int)
sizeof(
DATABASE_HEADER));
1735 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));
1736 pfree->next_free = 0;
1747 db_msg(msg,
MERROR,
"db_validate_db",
"Warning: database data area is %.0f%% full",
ratio * 100.0);
1765 db_msg(msg,
MERROR,
"db_validate_db",
"Error: ODB corruption detected, see previous messages");
1792#ifdef LOCAL_ROUTINES
1816 cm_msg(
MERROR,
"db_open_database",
"client name \'%s\' is longer than %d characters", client_name,
NAME_LENGTH-1);
1821 cm_msg(
MERROR,
"db_open_database",
"client name \'%s\' should not contain the slash \'/\' character", client_name);
1867 void* shm_adr =
NULL;
1868 size_t shm_size = 0;
1910 pfree->next_free = 0;
1914 pfree->next_free = 0;
1922 pkey->num_values = 1;
1924 strcpy(
pkey->name,
"root");
1925 pkey->parent_keylist = 0;
1950 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);
1956 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key offset %d is invalid", pheader->
root_key);
1962 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key type %d is not TID_KEY",
pkey->type);
1967 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key name \"%s\" is not \"root\"",
pkey->name);
1982 cm_msg(
MERROR,
"db_open_database",
"Invalid, incompatible or corrupted database: root key is invalid");
2025 int num_clients = 0;
2026 int max_client_index = 0;
2031 max_client_index =
i + 1;
2069 cm_msg(
MERROR,
"db_open_database",
"maximum number of clients exceeded");
2090 pclient->num_open_records = 0;
2097 pclient->watchdog_timeout = timeout;
2122 *
hDB = (handle + 1);
2129 cm_msg(
MERROR,
"db_open_database",
"Error: db_validate_open_records() status %d",
status);
2157#ifdef LOCAL_ROUTINES
2163 cm_msg(
MERROR,
"db_close_database",
"invalid database handle %d",
hDB);
2175 if (!
pdb->attached) {
2177 cm_msg(
MERROR,
"db_close_database",
"database not attached");
2188 if (
pclient->open_record[
i].handle)
2265#ifndef DOXYGEN_SHOULD_SKIP_THIS
2292#ifdef LOCAL_ROUTINES
2299 cm_msg(
MERROR,
"db_flush_database",
"invalid database handle");
2312 cm_msg(
MERROR,
"db_flush_database",
"Cannot obtain key /System/Flush/Last flush");
2322 cm_msg(
MERROR,
"db_flush_database",
"invalid database handle");
2389#ifdef LOCAL_ROUTINES
2425#ifdef LOCAL_ROUTINES
2428 cm_msg(
MERROR,
"db_set_client_name",
"invalid database handle %d",
hDB);
2457#ifdef LOCAL_ROUTINES
2461 cm_msg(
MERROR,
"db_lock_database",
"invalid database handle %d, aborting...",
hDB);
2475 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");
2501 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB semaphore, timeout %d ms, aborting...",
_database[
hDB - 1].timeout);
2506 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB semaphore, timeout %d ms, ss_semaphore_wait_for() status %d, aborting...",
_database[
hDB - 1].timeout,
status);
2513#ifdef CHECK_LOCK_COUNT
2529 cm_msg(
MERROR,
"db_lock_database",
"cannot lock ODB, ss_shm_unprotect(TRUE,FALSE) failed with status %d, aborting...",
status);
2547#ifdef LOCAL_ROUTINES
2558 cm_msg(
MERROR,
"db_allow_write_locked",
"cannot write to ODB, ss_shm_unprotect(TRUE,TRUE) failed with status %d, aborting...",
status);
2579#ifdef LOCAL_ROUTINES
2582 cm_msg(
MERROR,
"db_unlock_database",
"invalid database handle %d",
hDB);
2585#ifdef CHECK_LOCK_COUNT
2596 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");
2619 cm_msg(
MERROR,
"db_unlock_database",
"cannot unlock ODB, ss_shm_protect() failed with status %d, aborting...",
status);
2644#ifdef LOCAL_ROUTINES
2651 cm_msg(
MERROR,
"db_get_lock_cnt",
"invalid database handle %d, aborting...",
hDB);
2652 fprintf(
stderr,
"db_get_lock_cnt: invalid database handle %d, aborting...\n",
hDB);
2666#ifdef LOCAL_ROUTINES
2673 cm_msg(
MERROR,
"db_set_lock_timeout",
"invalid database handle %d",
hDB);
2687#ifdef LOCAL_ROUTINES
2715 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...");
2724#ifdef LOCAL_ROUTINES
2734 if (
pkey->notify_count > 0)
2759#ifdef LOCAL_ROUTINES
2793#ifdef LOCAL_ROUTINES
2795 cm_msg(
MERROR,
"db_delete_client_info",
"invalid database handle");
2800 cm_msg(
MERROR,
"db_delete_client_info",
"invalid database handle");
2829#ifdef LOCAL_ROUTINES
2863 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);
2877 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)",
2895#ifdef LOCAL_ROUTINES
2923 if (
j ==
pdb->client_index)
2927 if ((client_name ==
NULL || client_name[0] == 0
2932 db_msg(&msg,
MINFO,
"db_cleanup2",
"Client \'%s\' on database \'%s\' pid %d does not exist and db_cleanup2 called by %s removed it",
2954 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)",
2985 if (!
pdb->attached) {
2995 pclient->watchdog_timeout = timeout;
3017 cm_msg(
MERROR,
"db_get_watchdog_info",
"invalid database handle");
3022 cm_msg(
MERROR,
"db_get_watchdog_info",
"invalid database handle");
3043 *timeout = *
last = 0;
3062 cm_msg(
MERROR,
"db_check_client",
"invalid database handle");
3067 cm_msg(
MERROR,
"db_check_client",
"invalid database handle");
3102 int size =
sizeof(
name);
3143 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);
3145 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);
3172#ifdef LOCAL_ROUTINES
3174 cm_msg(
MERROR,
"db_protect_database",
"invalid database handle %d",
hDB);
3247 if(pattern[1] == 0)
return true;
3285 while (*
pc !=
'.' && *
pc !=
'-')
3287 while (*
pc ==
'.' || *
pc ==
'-')
3314#ifdef LOCAL_ROUTINES
3319 cm_msg(
MERROR,
"db_create_key",
"invalid database handle");
3324 cm_msg(
MERROR,
"db_create_key",
"invalid database handle");
3362#ifdef LOCAL_ROUTINES
3480 pkey->num_values = 1;
3523 pkey->num_values = 1;
3530 if (
pkey->item_size > 0) {
3533 pkey->total_size = 0;
3538 pkey->total_size =
pkey->item_size;
3542 pkey->item_size = 0;
3543 pkey->total_size = 0;
3562 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_locked(pheader,
pitem).
c_str(), key_name,
type,
db_get_path_locked(pheader,
parentKey).
c_str());
3574 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_locked(pheader,
pitem).
c_str(), key_name,
db_get_path_locked(pheader,
parentKey).
c_str());
3610 cm_msg(
MERROR,
"db_create_link",
"link destination name is NULL");
3615 cm_msg(
MERROR,
"db_create_link",
"link destination name \'%s\' should start with \'/\', relative links are forbidden",
destination);
3625 cm_msg(
MERROR,
"db_create_link",
"links to \"/\" are forbidden");
3671#ifdef LOCAL_ROUTINES
3682 cm_msg(
MERROR,
"db_delete_key1",
"invalid database handle");
3687 cm_msg(
MERROR,
"db_delete_key1",
"invalid database handle");
3692 cm_msg(
MERROR,
"db_delete_key1",
"invalid key handle");
3716#ifdef CHECK_OPEN_RECORD
3717 if (
pkey->notify_count) {
3723 if (
pkey->parent_keylist == 0)
3762 cm_msg(
MERROR,
"db_delete_key1",
"try to delete cyclic link");
3775 if (
pkey->parent_keylist == 0) {
3788#ifdef CHECK_OPEN_RECORD
3789 if (
pkey->notify_count) {
3801 free_data(pheader, (
char *) pheader +
pkey->data,
pkey->total_size,
"db_delete_key1");
3864#ifdef LOCAL_ROUTINES
3879 db_msg(msg,
MERROR,
"db_find_key",
"hkey %d path \"%s\" tid %d is not a directory, looking for \"%s\"",
hKey, path.c_str(), tid, key_name);
3885 if (key_name[0] == 0 ||
strcmp(key_name,
"/") == 0) {
3918 if (
pkey->parent_keylist) {
3945 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);
3951 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);
3960 if (
pkey->next_key == 0) {
4084#ifdef LOCAL_ROUTINES
4092 cm_msg(
MERROR,
"db_find_key",
"invalid database handle");
4097 cm_msg(
MERROR,
"db_find_key",
"invalid database handle");
4122#ifndef DOXYGEN_SHOULD_SKIP_THIS
4151#ifdef LOCAL_ROUTINES
4162 cm_msg(
MERROR,
"db_find_key",
"invalid database handle");
4167 cm_msg(
MERROR,
"db_find_key",
"invalid database handle");
4189 if (key_name[0] == 0 ||
strcmp(key_name,
"/") == 0) {
4209 if (
pkey->parent_keylist) {
4228 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
4239 strcpy(
str, (
char *) pheader +
pkey->data);
4304#ifdef LOCAL_ROUTINES
4315 cm_msg(
MERROR,
"db_find_link",
"Invalid database handle");
4320 cm_msg(
MERROR,
"db_find_link",
"invalid database handle");
4345 if (key_name[0] == 0 ||
strcmp(key_name,
"/") == 0) {
4367 if (
pkey->parent_keylist) {
4393 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
4405 strcpy(
str, (
char *) pheader +
pkey->data);
4465#ifdef LOCAL_ROUTINES
4476 cm_msg(
MERROR,
"db_find_link",
"Invalid database handle");
4481 cm_msg(
MERROR,
"db_find_link",
"invalid database handle");
4502 if (key_name[0] == 0 ||
strcmp(key_name,
"/") == 0) {
4521 if (
pkey->parent_keylist) {
4537 cm_msg(
MERROR,
"db_find_link1",
"Warning: database corruption, key \"%s\", next_key 0x%08X is invalid", key_name,
pkey->next_key - (
int)
sizeof(
DATABASE_HEADER));
4545 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
4556 strcpy(
str, (
char *) pheader +
pkey->data);
4613 char *pattern =
NULL;
4662 for (
int i=0 ; ;
i++)
4721#ifdef LOCAL_ROUTINES
4728 cm_msg(
MERROR,
"db_get_parent",
"invalid database handle");
4733 cm_msg(
MERROR,
"db_get_parent",
"invalid database handle");
4821#ifdef LOCAL_ROUTINES
4899#ifdef LOCAL_ROUTINES
4903 std::string path =
"";
4910 sprintf(buf,
"(INVALID_KEY_TYPE_%d)",
pkey->type);
4913 if (path.length() > 0) {
4921 std::string
str = path;
4923 if (
pkey->name[0] == 0) {
4924 path +=
"(EMPTY_NAME)";
4928 if (
str.length() > 0)
4932 if (!
pkey->parent_keylist) {
4937 return "(INVALID_PARENT_KEYLIST)/" + path;
4948 return "(NULL_PARENT)/" + path;
4952 return "(INVALID_PARENT)/" + path;
4975 return "(ZERO_HKEY)";
4980 return "(INVALID_HKEY)";
5017#ifdef LOCAL_ROUTINES
5022 cm_msg(
MERROR,
"db_get_path",
"invalid database handle");
5027 cm_msg(
MERROR,
"db_get_path",
"invalid database handle");
5073#ifdef LOCAL_ROUTINES
5078 cm_msg(
MERROR,
"db_get_path",
"invalid database handle");
5079 return "(DB_INVALID_HANDLE)";
5083 cm_msg(
MERROR,
"db_get_path",
"invalid database handle");
5084 return "(DB_INVALID_HANDLE)";
5099 return "(no LOCAL_ROUTINES)";
5102#ifdef LOCAL_ROUTINES
5133 line +=
" a deleted client";
5138 std::string *result = (std::string*)
xresult;
5148 std::string *result = (std::string*)
xresult;
5179 *result +=
" fixed\n";
5218#ifdef LOCAL_ROUTINES
5267#ifdef LOCAL_ROUTINES
5271 if (num_values == 0)
5299#ifdef LOCAL_ROUTINES
5304 if (num_values == 0)
5315 if (data_size == 0) {
5316 db_msg(msg,
MERROR,
"db_set_value",
"zero data size not allowed");
5321 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);
5420#ifdef LOCAL_ROUTINES
5444 if (*p && *p ==
']') {
5505#ifdef LOCAL_ROUTINES
5527 if ((
idx == -1 &&
pkey->num_values *
pkey->item_size > *buf_size) || (
idx != -1 &&
pkey->item_size > *buf_size)) {
5529 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_locked(pheader,
pkey).
c_str(),
pkey->num_values *
pkey->item_size,
pkey->num_values,
pkey->item_size, *buf_size);
5542 *buf_size =
pkey->num_values *
pkey->item_size;
5545 *buf_size =
pkey->item_size;
5591#ifdef LOCAL_ROUTINES
5599 cm_msg(
MERROR,
"db_enum_key",
"invalid database handle");
5604 cm_msg(
MERROR,
"db_enum_key",
"invalid database handle");
5664 for (
i = 0;
i <
idx;
i++) {
5665 if (
pkey->next_key == 0) {
5668 cm_msg(
MERROR,
"db_enum_key",
"hkey %d path \"%s\" unexpected end of key list at index %d",
hKey, path.c_str(),
i);
5678 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);
5685 strcpy(
str, (
char *) pheader +
pkey->data);
5700 if (
pkey->parent_keylist) {
5721#ifndef DOXYGEN_SHOULD_SKIP_THIS
5755#ifdef LOCAL_ROUTINES
5763 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5768 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5802 for (
i = 0;
i <
idx;
i++) {
5804 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
5842#ifdef LOCAL_ROUTINES
5850 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5855 cm_msg(
MERROR,
"db_enum_link",
"invalid database handle");
5879 if (
pkey->next_key) {
5882 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
5893 if (
pkey->parent_keylist == 0) {
5940#ifdef LOCAL_ROUTINES
6024#ifdef LOCAL_ROUTINES
6030 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6035 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6077#ifdef LOCAL_ROUTINES
6082 cm_msg(
MERROR,
"db_get_link",
"invalid database handle");
6087 cm_msg(
MERROR,
"db_get_link",
"invalid database handle");
6137#ifdef LOCAL_ROUTINES
6143 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6148 cm_msg(
MERROR,
"db_get_key",
"invalid database handle");
6196#ifdef LOCAL_ROUTINES
6203 cm_msg(
MERROR,
"db_get_key_info",
"invalid database handle");
6208 cm_msg(
MERROR,
"db_get_key_info",
"invalid database handle");
6213 cm_msg(
MERROR,
"db_get_key_info",
"invalid key handle");
6241 *num_values =
pkey->num_values;
6242 *item_size =
pkey->item_size;
6257#ifndef DOXYGEN_SHOULD_SKIP_THIS
6286#ifdef LOCAL_ROUTINES
6293 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6298 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6320 cm_msg(
MERROR,
"db_rename_key",
"key name is too short");
6325 cm_msg(
MERROR,
"db_rename_key",
"key name may not contain \"/\"");
6388#ifdef LOCAL_ROUTINES
6396 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6401 cm_msg(
MERROR,
"db_rename_key",
"invalid database handle");
6436#ifdef CHECK_OPEN_RECORD
6437 if (
pkey->notify_count) {
6442 if (
pkey->parent_keylist == 0)
6493 for (
i = 0;
i <
idx - 1;
i++) {
6544#ifdef LOCAL_ROUTINES
6549 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6554 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6590 if (pos == std::string::npos) {
6661#ifdef LOCAL_ROUTINES
6667 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6672 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6718 cm_msg(
MERROR,
"db_get_data",
"Key cannot contain data");
6723 if (
pkey->data == 0) {
6731 if (
pkey->num_values *
pkey->item_size > *buf_size) {
6736 cm_msg(
MERROR,
"db_get_data",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(),
pkey_size, *buf_size);
6742 *buf_size =
pkey->num_values *
pkey->item_size;
6753#ifndef DOXYGEN_SHOULD_SKIP_THIS
6785#ifdef LOCAL_ROUTINES
6791 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6796 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6842 cm_msg(
MERROR,
"db_get_data",
"Key cannot contain data");
6847 if (
pkey->data == 0) {
6855 if (
pkey->num_values *
pkey->item_size > *buf_size) {
6860 cm_msg(
MERROR,
"db_get_data",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(),
pkey_size, *buf_size);
6866 *buf_size =
pkey->num_values *
pkey->item_size;
6867 *num_values =
pkey->num_values;
6898#ifdef LOCAL_ROUTINES
6904 cm_msg(
MERROR,
"db_get_data",
"Invalid database handle");
6909 cm_msg(
MERROR,
"db_get_data",
"invalid database handle");
6955 cm_msg(
MERROR,
"db_get_data_index",
"Key cannot contain data");
6960 if (
pkey->data == 0) {
6979 if (
pkey->item_size > *buf_size) {
6985 cm_msg(
MERROR,
"db_get_data_index",
"data for key \"%s\" truncated from %d to %d bytes", path.c_str(),
pkey_size, *buf_size);
6991 *buf_size =
pkey->item_size;
7001#ifdef LOCAL_ROUTINES
7018 data_size =
pkey->item_size * num_values;
7021 if (
pkey->total_size != data_size) {
7025 if (
pkey->data == 0) {
7026 pkey->total_size = 0;
7032 pkey->total_size = data_size;
7036 pkey->num_values = num_values;
7039 pkey->item_size = data_size / num_values;
7060 if (
idx >=
pkey->num_values ||
pkey->item_size == 0) {
7064 if (
pkey->data == 0) {
7065 pkey->total_size = 0;
7066 pkey->num_values = 0;
7072 if (!
pkey->item_size)
7073 pkey->item_size = data_size;
7074 pkey->total_size = data_size * (
idx + 1);
7081 *((
char *)
data +
pkey->item_size - 1) = 0;
7120 if (num_values > 1) {
7121 int item_size =
pkey->item_size;
7122 if (data_size > 0 && num_values > 0)
7123 item_size = data_size/num_values;
7125 for (
int i=0;
i<num_values;
i++) {
7126 const char*
value = ((
const char*)
data) +
i * item_size;
7185 if (
pkey->item_size != 0 && data_size !=
pkey->item_size) {
7220#ifdef LOCAL_ROUTINES
7230 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7235 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7244 if (num_values == 0)
7323#ifdef LOCAL_ROUTINES
7333 cm_msg(
MERROR,
"db_set_data1",
"invalid database handle");
7338 cm_msg(
MERROR,
"db_set_data1",
"invalid database handle");
7347 if (num_values == 0)
7430#ifdef LOCAL_ROUTINES
7437 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7442 cm_msg(
MERROR,
"db_set_data",
"invalid database handle");
7451 if (num_values == 0)
7499#ifndef DOXYGEN_SHOULD_SKIP_THIS
7526#ifdef LOCAL_ROUTINES
7533 cm_msg(
MERROR,
"db_set_num_values",
"invalid database handle");
7538 cm_msg(
MERROR,
"db_set_num_values",
"invalid database handle");
7543 cm_msg(
MERROR,
"db_set_num_values",
"invalid key handle");
7547 if (num_values <= 0) {
7548 cm_msg(
MERROR,
"db_set_num_values",
"invalid num_values %d", num_values);
7552 if (num_values == 0)
7577 cm_msg(
MERROR,
"db_set_num_values",
"Key cannot contain data");
7581 if (
pkey->total_size !=
pkey->item_size *
pkey->num_values) {
7587 if (
pkey->item_size == 0) {
7589 cm_msg(
MERROR,
"db_set_num_values",
"Cannot resize array with item_size equal to zero");
7596 if (
pkey->num_values != num_values) {
7601 if (
pkey->data == 0) {
7602 pkey->total_size = 0;
7603 pkey->num_values = 0;
7613 pkey->num_values = num_values;
7653#ifdef LOCAL_ROUTINES
7663 cm_msg(
MERROR,
"db_set_data_index",
"invalid database handle");
7668 cm_msg(
MERROR,
"db_set_data_index",
"invalid database handle");
7673 cm_msg(
MERROR,
"db_set_data_index",
"invalid key handle");
7759#ifdef LOCAL_ROUTINES
7766 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid database handle");
7771 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid database handle");
7776 cm_msg(
MERROR,
"db_set_link_data_index",
"invalid key handle");
7825#ifndef DOXYGEN_SHOULD_SKIP_THIS
7859#ifdef LOCAL_ROUTINES
7866 cm_msg(
MERROR,
"db_set_data_index1",
"invalid database handle");
7871 cm_msg(
MERROR,
"db_set_data_index1",
"invalid database handle");
7876 cm_msg(
MERROR,
"db_set_data_index1",
"invalid key handle");
7957 if (num_values == 0)
7976#ifdef LOCAL_ROUTINES
8056#ifdef LOCAL_ROUTINES
8062 cm_msg(
MERROR,
"db_set_mode",
"invalid database handle");
8067 cm_msg(
MERROR,
"db_set_mode",
"invalid database handle");
8138 cm_msg(
MERROR,
"db_load",
"file \"%s\" not found", filename);
8145 buffer = (
char *)
malloc(size + 1);
8147 if (buffer ==
NULL) {
8148 cm_msg(
MERROR,
"db_load",
"cannot allocate ODB load buffer");
8164 if (
strncmp(buffer,
"<?xml version=\"1.0\"", 19) == 0) {
8167 printf(
"Error in file \"%s\"\n", filename);
8168 }
else if( buffer[0] ==
'{'){
8243 cm_msg(
MERROR,
"db_copy",
"cannot allocate data buffer");
8260 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8265 strcpy(buffer, line);
8267 *buffer_size -=
strlen(line);
8275 strcpy(buffer,
data);
8279 strcpy(line,
"\n====#$@$#====\n");
8301 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8306 strcpy(buffer, line);
8308 *buffer_size -=
strlen(line);
8315 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8320 strcpy(buffer, line);
8322 *buffer_size -=
strlen(line);
8340 cm_msg(
MERROR,
"db_copy",
"cannot allocate data buffer");
8351 if (*buffer_size < 2) {
8356 strcpy(buffer,
"\n");
8373 buffer +=
strlen(buffer);
8384 sprintf(line,
"[%s]\n", path);
8399 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8404 strcpy(buffer, line);
8406 *buffer_size -=
strlen(line);
8414 strcpy(buffer,
data);
8418 strcpy(line,
"\n====#$@$#====\n");
8440 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8445 strcpy(buffer, line);
8447 *buffer_size -=
strlen(line);
8453 if ((
INT) (
strlen(line) + 1) > *buffer_size) {
8458 strcpy(buffer, line);
8460 *buffer_size -=
strlen(line);
8468 if (*buffer_size < 2)
8471 strcpy(buffer,
"\n");
8508 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8519 line[
i] = *buffer++;
8523 cm_msg(
MERROR,
"db_paste",
"line too long: %s...", line);
8529 if (*buffer ==
'\n')
8533 if (line[0] ==
'[') {
8535 mstrlcpy(title, line + 1,
sizeof(title));
8538 if (title[0] && title[
strlen(title) - 1] !=
'/')
8539 mstrlcat(title,
"/",
sizeof(title));
8542 if (
strchr(line,
'=') && line[0] !=
';') {
8555 while (*
pline ==
' ')
8565 while (*
pline ==
' ')
8569 if (title[0] !=
'.')
8570 mstrlcpy(key_name, title,
sizeof(key_name));
8572 mstrlcat(key_name, line,
sizeof(key_name));
8585 for (tid = 0; tid <
TID_LAST; tid++)
8589 for (tid = 0; tid <
TID_LAST; tid++)
8597 cm_msg(
MERROR,
"db_paste",
"found unknown data type \"%s\" in ODB file", line);
8601 while (*
pc !=
' ' && *
pc)
8603 while ((*
pc ==
' ' || *
pc ==
':') && *
pc)
8615 for (
j = 0; *buffer !=
'\n' && *buffer;
j++)
8618 if (*buffer ==
'\n')
8622 for (
i = 0;
i < n_data;
i++) {
8625 while (*
pc ==
'\n' || *
pc ==
'\r')
8636 cm_msg(
MERROR,
"db_paste",
"found string exceeding MAX_STRING_LENGTH, odb path \"%s\"", key_name);
8640 cm_msg(
MERROR,
"db_paste",
"found string length of zero, set to 32, odb path \"%s\"", key_name);
8646 if (
strstr(buffer,
"\n====#$@$#====\n") !=
NULL) {
8653 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8661 buffer =
strstr(buffer,
"\n====#$@$#====\n") +
strlen(
"\n====#$@$#====\n");
8663 cm_msg(
MERROR,
"db_paste",
"found multi-line string without termination sequence");
8666 while (*
pc && *
pc !=
' ')
8681 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8691 if (n_data > 1 &&
data_str[0] ==
'[') {
8694 while (*
pc && *
pc ==
' ')
8704 cm_msg(
MERROR,
"db_paste",
"cannot allocate data buffer");
8712 if (
i < n_data - 1) {
8719 for (
j = 0; *buffer !=
'\n' && *buffer;
j++)
8722 if (*buffer ==
'\n')
8744 if (key_name[0] ==
'/') {
8804 cm_msg(
MINFO,
"db_paste_node",
"cannot load key \"%s\": write protected",
name);
8851 cm_msg(
MERROR,
"db_paste_node",
"found unknown data type \"%s\" in XML data",
type);
8860 cm_msg(
MINFO,
"db_paste_node",
"cannot load key \"%s\": write protected",
name);
8895 buf = (
char *)
malloc(size);
9016 puts(
"Cannot find element \"odb\" in XML data");
9043#ifdef LOCAL_ROUTINES
9051 if (writer ==
NULL) {
9052 cm_msg(
MERROR,
"db_copy_xml",
"Cannot allocate buffer");
9078 if (len > *buffer_size) {
9094#ifndef DOXYGEN_SHOULD_SKIP_THIS
9106 if (*
str >=
'0' && *
str <=
'9')
9110 if (!(*
str >=
'a' && *
str <=
'z') && !(*
str >=
'A' && *
str <=
'Z') && !(*
str >=
'0' && *
str <=
'9'))
9160 strcpy(line,
"char");
9163 strcpy(line,
"short");
9166 strcpy(line,
"float");
9169 strcpy(line,
"double");
9172 strcpy(line,
"unsigned char");
9175 strcpy(line,
"char");
9178 strcpy(line,
"char");
9195 mstrlcat(line,
";\n",
sizeof(line));
9250#ifdef LOCAL_ROUTINES
9258 cm_msg(
MERROR,
"db_save",
"Cannot open file \"%s\"", filename);
9264 buffer_size = 10000;
9266 buffer = (
char *)
malloc(buffer_size);
9267 if (buffer ==
NULL) {
9268 cm_msg(
MERROR,
"db_save",
"cannot allocate ODB dump buffer");
9279 if (
n != buffer_size - size) {
9308 dst = (
char *)
malloc(size);
9331 if ((
int)
strlen(dst) >= size) {
9409 cm_msg(
MERROR,
"db_save_xml_key",
"cannot allocate data buffer");
9423 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());
9450 cm_msg(
MERROR,
"db_save_xml_key",
"Long odb string array probably truncated, odb path \"%s\"[%d]", path.c_str(),
i);
9482#ifdef LOCAL_ROUTINES
9489 if (writer ==
NULL) {
9490 cm_msg(
MERROR,
"db_save_xml",
"Cannot open file \"%s\"", filename);
9554 (*buffer)[(*buffer_end)++] =
' ';
9637 if (
comma !=
nullptr) {
9691 float flt = (*(
float*)p);
9699 }
else if (
flt == 0)
9701 else if (
flt == (
int)
flt) {
9713 double dbl = (*(
double*)p);
9721 }
else if (
dbl == 0)
9723 else if (
dbl == (
int)
dbl) {
9864 else if (
level > 0) {
9877 cm_msg(
MERROR,
"db_save_json_key",
"max nesting level exceeded at \"%s\", check for symlink loops in this subtree", path.c_str());
9992 cm_msg(
MERROR,
"db_save_json_key",
"cannot allocate data buffer for %d bytes", size);
10057 float flt = (*(
float*)p);
10065 }
else if (
flt == 0)
10067 else if (
flt == (
int)
flt) {
10077 double dbl = (*(
double*)p);
10085 }
else if (
dbl == 0)
10087 else if (
dbl == (
int)
dbl) {
10176 cm_msg(
MERROR,
"db_save_json_key_data",
"cannot allocate data buffer for %d bytes",
asize);
10312 mstrlcat(buf,
"/name",
sizeof(buf));
10322 mstrlcat(buf,
"/key",
sizeof(buf));
10330 mstrlcat(buf,
"/last_written",
sizeof(buf));
10357 cm_msg(
MERROR,
"json_write_bare_subdir",
"Max ODB subdirectory nesting level exceeded %d",
level);
10361 for (
int i=0; ;
i++) {
10424 bool unlock =
false;
10456 bool unlock =
false;
10478 bool unlock =
false;
10538 bool unlock =
false;
10556 char* buffer =
NULL;
10557 int buffer_size = 0;
10629 char str[100], line[10+100];
10647 sprintf(line,
"typedef struct {\n");
10684#ifndef DOXYGEN_SHOULD_SKIP_THIS
10712 char str[256], line[50+256];
10714 char *buffer =
NULL, *
pc;
10741 sprintf(line,
"#define %s(_name) const char *_name[] = {\\\n",
str);
10752 buffer_size = 10000;
10754 buffer = (
char *)
malloc(buffer_size);
10755 if (buffer ==
NULL) {
10756 cm_msg(
MERROR,
"db_save",
"cannot allocate ODB dump buffer");
10760 size = buffer_size;
10777 while (*
pc !=
'\n' && *
pc != 0) {
10778 if (*
pc ==
'\"' || *
pc ==
'\'')
10782 strcpy(&line[
i],
"\",\\\n");
10845 if (data_size == 0)
10899 sprintf(
string,
"<unknown>");
10921 if (data_size == 0)
10975 sprintf(
string,
"<unknown>");
11005 if (data_size == 0)
11059 sprintf(
string,
"<unknown>");
11089 if (data_size == 0) {
11143 return (((
char *)
data) + data_size *
idx);
11145 return "<unknown>";
11165 if (data_size == 0) {
11219 return (((
char *)
data) + data_size *
idx);
11221 return "<unknown>";
11227#ifndef DOXYGEN_SHOULD_SKIP_THIS
11252 if (data_size == 0) {
11306 return (((
char *)
data) + data_size *
idx);
11308 return "<unknown>";
11437#ifdef LOCAL_ROUTINES
11486 corr =
VALIGN(*total_size, align) - *total_size;
11487 *total_size +=
corr;
11489 *
data = (
void *) ((
char *) (*data) +
corr);
11492 size =
pkey->item_size *
pkey->num_values;
11502 if (convert_flags) {
11503 if (
pkey->num_values > 1)
11522 if (convert_flags) {
11523 if (
pkey->num_values > 1)
11526 pkey->item_size *
pkey->num_values, convert_flags);
11536 *total_size += size;
11548 corr =
VALIGN(*total_size, align) - *total_size;
11549 *total_size +=
corr;
11551 *
data = (
void *) ((
char *) (*data) +
corr);
11556 corr =
VALIGN(*total_size, align) - *total_size;
11557 *total_size +=
corr;
11559 *
data = (
void *) ((
char *) (*data) +
corr);
11567 if (!
pkey->next_key)
11571 pkey = (
KEY *) ((
char *) pheader +
pkey->next_key);
11621#ifdef LOCAL_ROUTINES
11715#ifdef LOCAL_ROUTINES
11722 if (
data && buf_size) {
11751 if (convert_flags) {
11763 if (total_size != *buf_size) {
11807 int size = *buf_size;
11822 cm_msg(
MINFO,
"db_get_record1",
"Fixing ODB \"%s\" struct size mismatch (expected %d, odb size %d)", path.c_str(), size,
odb_size);
11852 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());
11858 cm_msg(
MERROR,
"db_get_record1",
"repaired struct size mismatch of \"%s\"", path.c_str());
11898 char* p =
strchr(title,
']');
11902 int len =
strlen(title);
11904 if (title[len - 1] !=
'/')
11939 cm_msg(
MERROR,
"db_parse_record",
"do not see \'=\'");
11972 if (s ==
' ')
break;
11973 if (s ==
'\n')
break;
11974 if (s ==
'[')
break;
11991 cm_msg(
MERROR,
"db_parse_record",
"do not see \':\'");
12006 cm_msg(
MERROR,
"db_parse_record",
"do not see closing bracket \']\'");
12017 cm_msg(
MERROR,
"db_parse_record",
"do not see \':\'");
12052 assert(n_data > 0);
12059 *(*buf_ptr) = 0xFF;
12065 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);
12076 cm_msg(
MERROR,
"db_get_record2",
"cannot read \"%s\", db_get_value() status %d", key_name,
status);
12087 for (
i=0;
i<n_data;
i++) {
12090 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);
12100 cm_msg(
MERROR,
"db_get_record2",
"string key \"%s\" index %d, string value was truncated", key_name,
i);
12102 cm_msg(
MERROR,
"db_get_record2",
"cannot read string \"%s\"[%d], db_get_value() status %d", key_name,
i,
status);
12113 cm_msg(
MERROR,
"db_get_record2",
"cannot read key \"%s\" of unsupported type %d", key_name, tid);
12173 printf(
"db_get_record2!\n");
12218 if (key_name[0] == 0) {
12225 cm_msg(
MERROR,
"db_get_record2",
"error: cannot continue reading odb record because of previous fatal error, status %d",
status);
12237 for (
i=0;
i<
rs;
i++) {
12246 printf(
"db_get_record2: check ok\n");
12297#ifdef LOCAL_ROUTINES
12324 if (convert_flags) {
12337 if (total_size != buf_size) {
12360#ifndef DOXYGEN_SHOULD_SKIP_THIS
12375#ifdef LOCAL_ROUTINES
12381 cm_msg(
MERROR,
"db_add_open_record",
"invalid database handle");
12407 if (
pclient->open_record[
i].handle == 0)
12432 pclient->open_record[
i].access_mode = access_mode;
12435 pkey->notify_count++;
12450#ifdef LOCAL_ROUTINES
12475 if (
pkey->notify_count > 0)
12488 for (
i =
pclient->max_index - 1;
i >= 0;
i--)
12489 if (
pclient->open_record[
i].handle != 0)
12512#ifdef LOCAL_ROUTINES
12515 cm_msg(
MERROR,
"db_remove_open_record",
"invalid database handle %d",
hDB);
12537#ifdef LOCAL_ROUTINES
12565 if (
pkey->notify_count)
12576 if (
pkey->parent_keylist == 0 || !
bWalk)
12603 cm_msg(
MERROR,
"db_notify_clients",
"db_notify_clients() does not work in remotely connected MIDAS clients");
12607#ifdef LOCAL_ROUTINES
12639#ifdef LOCAL_ROUTINES
12736 if (
pkey->notify_count)
12802 char str[256], key_name[256], *buffer;
12814 if (
strlen(key_name) > 1 && key_name[
strlen(key_name) - 1] ==
'/')
12815 key_name[
strlen(key_name) - 1] = 0;
12821#ifdef CHECK_OPEN_RECORD
12861 buffer_size = 10000;
12862 buffer = (
char *)
malloc(buffer_size);
12864 size = buffer_size;
12867 buffer_size += 10000;
12868 buffer = (
char *)
realloc(buffer, buffer_size);
12904 size = buffer_size;
12907 buffer_size += 10000;
12908 buffer = (
char *)
realloc(buffer, buffer_size);
12947 cm_msg(
MERROR,
"db_create_record",
"aborting on unexpected failure of db_find_key(%s), status %d", key_name,
status);
13036 if (line[0] ==
'[') {
13038 strcpy(title, line + 1);
13040 *
strchr(title,
']') = 0;
13041 if (title[0] && title[
strlen(title) - 1] !=
'/')
13045 if (
strchr(line,
'=') && line[0] !=
';') {
13059 mstrlcpy(key_name, line,
sizeof(key_name));
13067 if (
strchr(line,
'[')) {
13072 for (tid = 0; tid <
TID_LAST; tid++)
13076 for (tid = 0; tid <
TID_LAST; tid++)
13084 cm_msg(
MERROR,
"db_check_record",
"found unknown data type \"%s\" in ODB file", line);
13088 while (*
pc !=
' ' && *
pc)
13090 while ((*
pc ==
' ' || *
pc ==
':') && *
pc)
13105 for (
i = 0;
i < n_data;
i++) {
13108 while (*
pc ==
'\n' || *
pc ==
'\r')
13124 cm_msg(
MERROR,
"db_check_record",
"found string exceeding MAX_STRING_LENGTH");
13135 cm_msg(
MERROR,
"db_check_record",
"found multi-line string without termination sequence");
13141 while (*
pc && *
pc !=
' ')
13143 while (*
pc && *
pc ==
' ')
13152 if (n_data > 1 &&
info_str[0] ==
'[') {
13154 while (*
pc && *
pc ==
' ')
13159 if (
i < n_data - 1) {
13292 WORD access_mode,
void (*dispatcher) (
INT,
INT,
void *),
void *
info)
13303 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13319 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13335 cm_msg(
MERROR,
"db_open_record",
"cannot get record size, db_get_record_size() status %d",
status);
13342 cm_msg(
MERROR,
"db_open_record",
"struct size mismatch for \"%s\" (expected size: %d, size in ODB: %d)", path.c_str(),
rec_size, size);
13359 cm_msg(
MERROR,
"db_open_record",
"not enough memory, malloc(%d) returned NULL", size);
13365 *((
void **) ptr) =
data;
13375 cm_msg(
MERROR,
"db_open_record",
"cannot get record, db_get_record() status %d",
status);
13387 cm_msg(
MERROR,
"db_open_record",
"cannot set record, db_set_record() status %d",
status);
13395 cm_msg(
MERROR,
"db_open_record",
"not enough memory");
13442 WORD access_mode,
void (*dispatcher) (
INT,
INT,
void *),
void *
info,
13475#ifdef LOCAL_ROUTINES
13614 if (convert_flags) {
13857 cm_msg(
MERROR,
"db_watch",
"cannot get key \"%s\"", path.c_str());
13865 cm_msg(
MERROR,
"db_watch",
"cannot get key \"%s\"", path.c_str());
13889#ifdef LOCAL_ROUTINES
13942 cm_msg(
MERROR,
"db_get_value_string",
"cannot resize odb string arrays, please use db_resize_string() instead");
13961 char* buf = (
char*)
malloc(size);
13962 assert(buf !=
NULL);
13986 int size = s->length() + 1;
14008 int size = s->length() + 1;
14078 if (num_values < 1)
14081 int new_size = num_values * item_size;
14089 if (
num > num_values)
14094 for (
int i=0;
i<
num;
i++) {
14113#ifdef LOCAL_ROUTINES
14114 MJsonNode*
scl = MJsonNode::MakeObject();
14115 MJsonNode* clients = MJsonNode::MakeArray();
14118 scl->AddToObject(
"clients", clients);
14132 MJsonNode*
c = MJsonNode::MakeObject();
14133 c->AddToObject(
"slot", MJsonNode::MakeNumber(
i));
14134 c->AddToObject(
"pid", MJsonNode::MakeNumber(
pclient->pid));
14135 c->AddToObject(
"name", MJsonNode::MakeString(
pclient->name));
14136 std::string path =
msprintf(
"/System/Clients/%d/Host",
pclient->pid);
14141 assert(host !=
NULL);
14143 c->AddToObject(
"host", MJsonNode::MakeString(host));
14146 c->AddToObject(
"watchdog_timeout_millisec", MJsonNode::MakeNumber(
pclient->watchdog_timeout));
14148 c->AddToObject(
"last_activity_millisec", MJsonNode::MakeNumber(
now -
pclient->last_activity));
14149 clients->AddToArray(
c);
14157 return MJsonNode::MakeNull();
14165#ifdef LOCAL_ROUTINES
14167 MJsonNode*
sor = MJsonNode::MakeArray();
14179 for (
int j = 0;
j <
pclient->max_index;
j++) {
14185 MJsonNode*
c = MJsonNode::MakeObject();
14186 c->AddToObject(
"name", MJsonNode::MakeString(
pclient->name));
14188 c->AddToObject(
"access_mode", MJsonNode::MakeNumber(
pclient->open_record[
j].access_mode));
14189 c->AddToObject(
"flags", MJsonNode::MakeNumber(
pclient->open_record[
j].flags));
14190 c->AddToObject(
"path", MJsonNode::MakeString(path.c_str()));
14191 sor->AddToArray(
c);
14200 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_find_key1(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
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)
static int db_delete_client_info_wlocked(HNDLE hDB, DATABASE_HEADER *pheader, int pid, db_err_msg **msg)
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)
INT db_show_mem(HNDLE hDB, char **result, BOOL verbose)
static const KEY * db_resolve_link_locked(const DATABASE_HEADER *, const KEY *, int *pstatus, db_err_msg **)
INT db_lock_database(HNDLE hDB)
static bool db_validate_hkey(const DATABASE_HEADER *pheader, HNDLE hKey)
std::string strcomb1(const char **list)
INT db_delete_key1(HNDLE hDB, HNDLE hKey, INT level, BOOL follow_links)
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)
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
static INT db_find_key_locked(const DATABASE_HEADER *pheader, HNDLE hKey, const char *key_name, HNDLE *subhKey, 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 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)
INT db_unlock_database(HNDLE hDB)
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)
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 const KEYLIST * db_get_pkeylist(const DATABASE_HEADER *pheader, HNDLE hKey, const KEY *pkey, const char *caller, db_err_msg **msg, bool kludge_repair=false)
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)
static void add_to_buf(struct print_key_info_buf *buf, const char *s)
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 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)
INT db_find_keys(HNDLE hDB, HNDLE hKeyRoot, char *odbpath, std::vector< HNDLE > &hKeyVector)
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)
INT db_close_all_records()
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 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_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)
static int db_set_value_wlocked(DATABASE_HEADER *pheader, HNDLE hDB, 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(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 int db_notify_clients_locked(const DATABASE_HEADER *pheader, HNDLE hDB, HNDLE hKeyMod, int index, BOOL bWalk, db_err_msg **msg)
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
static const KEY * db_find_pkey_locked(const DATABASE_HEADER *pheader, const KEY *pkey, const char *key_name, int *pstatus, db_err_msg **msg)
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
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_find_link1(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
static void db_recurse_record_tree_locked(HNDLE hDB, const DATABASE_HEADER *pheader, const KEY *pkey, void **data, INT *total_size, INT base_align, INT *max_align, BOOL bSet, INT convert_flags, db_err_msg **msg)
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_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)
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)
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)
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)
static INT print_key_info(HNDLE hDB, HNDLE hKey, KEY *pkey, INT level, void *info)
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
TH1X EXPRT * h1_book(const char *name, const char *title, int bins, double min, double max)
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)