MIDAS
Loading...
Searching...
No Matches
odbedit.cxx
Go to the documentation of this file.
1/********************************************************************\
2
3 Name: odbedit.cxx
4 Created by: Stefan Ritt
5
6 Contents: Command-line interface to the MIDAS online data base.
7
8 $Id$
9
10\********************************************************************/
11
12#include "midas.h"
13#include "mstrlcpy.h"
14#include "msystem.h"
15#include <stdio.h>
16
17#include <assert.h>
18#include <string>
19
20extern INT cmd_edit(const char *prompt, char *cmd, INT (*dir)(char *, INT *), INT (*idle)());
21
24char pwd[256];
26
27typedef struct {
28 int flags;
29 char pattern[32];
30 int index;
32
33#define PI_LONG (1 << 0)
34#define PI_RECURSIVE (1 << 1)
35#define PI_VALUE (1 << 2)
36#define PI_HEX (1 << 3)
37#define PI_PAUSE (1 << 4)
38
40
41/*------------------------------------------------------------------*/
42
43INT thread(void *p) {
44 char str[32];
45 HNDLE hDB;
47 do {
48 sprintf(str, "%s", ss_tid_to_string(ss_gettid()).c_str());
49 db_set_value(hDB, 0, "/Experiment/Name", str, sizeof(str), 1, TID_STRING);
50 } while (1);
51
52 return 0;
53}
54
55/*------------------------------------------------------------------*/
56
58
59void key_update(HNDLE hDB, HNDLE hkey, void *info) {
61}
62
63/*------------------------------------------------------------------*/
64
65void print_help(char *command) {
66#ifndef OS_MSDOS /* save some DGROUP memory under MS-DOS */
67 if (!command[0]) {
68 printf("Database commands ([] are options, <> are placeholders):\n\n");
69 printf("alarm - reset all alarms\n");
70 printf("cd <dir> - change current directory\n");
71 printf("chat - enter chat mode\n");
72 printf("chmod <mode> <key> - change access mode of a key\n");
73 printf(" 1=read | 2=write | 4=delete\n");
74 printf("cleanup [client] [-f] - delete hanging clients [force]\n");
75 printf("copy <src> <dest> - copy a subtree to a new location\n");
76 printf("create <type> <key> - create a key of a certain type\n");
77 printf("create <type> <key>[n] - create an array of size [n]\n");
78 printf("create string <key>[n][m] - create an array of [n] strings of [m] characters\n");
79 printf("del/rm [-f] <key> - delete a key and its subkeys\n");
80 printf(" -f force deletion without asking\n");
81 printf("exec <key>/<cmd> - execute shell command (stored in key) on server\n");
82 printf("exp <key> <filename> - import key into ASCII file\n");
83 printf("find <pattern> - find a key with wildcard pattern\n");
84 printf("help/? [command] - print this help [for a specific command]\n");
85 printf("hi [analyzer] [id] - tell analyzer to clear histos\n");
86 printf("imp <filename> [key] - import ASCII file into string key\n");
87 printf("json <odb path> - print \"ODB save\" encoding of current directory or given odb path\n");
88 printf("jsls - print \"ls\" encoding of current directory\n");
89 printf("jsvalues - print \"get_values\" encoding of current directory\n");
90 printf("ln <source> <linkname> - create a link to <source> key\n");
91 printf("load <file> - load database from .ODB file at current position\n");
92 printf("-- hit return for more --\r");
93 getchar();
94 printf("ls/dir [-lhvrp] [<pat>] - show database entries which match pattern\n");
95 printf(" -l detailed info\n");
96 printf(" -h hex format\n");
97 printf(" -v only value\n");
98 printf(" -r show database entries recursively\n");
99 printf(" -p pause between screens\n");
100 printf("make [analyzer name] - create experim.h\n");
101 printf("mem [-v] - show memeory usage [verbose]\n");
102 printf("mkdir <subdir> - make new <subdir>\n");
103 printf("move <key> [top/bottom/[n]] - move key to position in keylist\n");
104 printf("msg [user] <msg> - send chat message (from interactive odbedit)\n");
105 printf("msg <facility> <type> <name> <msg> - send message to [facility] log\n");
106 printf("old [n] - display old n messages\n");
107 printf("passwd - change MIDAS password\n");
108 printf("pause - pause current run\n");
109 printf("pwd - show current directory\n");
110 printf("resume - resume current run\n");
111 printf("rename <old> <new> - rename key\n");
112 printf("-- hit return for more --\r");
113 getchar();
114 printf("save [-c -s -x -j -cs] <file> - save database at current position\n");
115 printf(" in ASCII format\n");
116 printf(" -c as a C structure\n");
117 printf(" -s as a #define'd string\n");
118 printf(" -x as an XML file, or use file.xml\n");
119 printf(" -j as a JSON file, or use file.json\n");
120 printf(" -z as value-only JSON file\n");
121 printf("set <key> <value> - set the value of a key\n");
122 printf("set <key>[i] <value> - set the value of index i\n");
123 printf("set <key>[*] <value> - set the value of all indices of a key\n");
124 printf("set <key>[i..j] <value> - set the value of all indices i..j\n");
125 printf("scl [-w] - show all active clients [with watchdog info]\n");
126 printf("shutdown <client>/all - shutdown individual or all clients\n");
127 printf("sor - show open records in current subtree\n");
128 printf("start [number][now][-v] - start a run [with a specific number],\n");
129 printf(" [now] w/o asking parameters, [-v] debug output\n");
130 printf("stop [-v] - stop current run, [-v] debug output\n");
131 printf("test_rpc - test mserver RPC connection and parameter encoding and decoding\n");
132 printf("trunc <key> <index> - truncate key to [index] values\n");
133 printf("ver - show MIDAS library version\n");
134 printf("webpasswd - change WWW password for mhttpd\n");
135 printf("wait <key> - wait for key to get modified\n");
136 printf("watch <key> - watch key or ODB tree to be modified\n");
137
138 printf("\nquit/exit - exit\n");
139 return;
140 }
141
142 if (equal_ustring(command, "cd")) {
143 printf("cd <dir> - change current directory. Use \"cd /\" to change to the root\n");
144 printf(" of the ODB, \"cd ..\" to change to the parent directory.\n");
145 } else if (equal_ustring(command, "chat")) {
146 printf("chat - enter chat mode. In this mode, users can \"talk\" to each other.\n");
147 printf(" Each user running ODBEdit connected to the same experiment can see\n");
148 printf(" the other messages and each user running ODBEdit in chat mode can\n");
149 printf(" produce messages. All messages are logged in the MIDAS logging file.\n");
150 } else
151 printf("No specific help available for command \"%s\".\n", command);
152
153#endif
154}
155
156/*------------------------------------------------------------------*/
157
159 time_t tm;
160 char str[80];
161
162 /* prepare time */
163 time(&tm);
164 assert(sizeof(str) >= 32);
165 ctime_r(&tm, str);
166 str[19] = 0;
167
168 /* print message text which comes after event header */
169 if (in_cmd_edit)
170 printf("\r%s %s\n", str + 11, (char *) message);
171 else
172 printf("\n%s %s\n", str + 11, (char *) message);
173
175}
176
177int print_message(const char *msg) {
178 if (in_cmd_edit)
179 printf("\r%s\n", msg);
180 else
181 printf("%s\n", msg);
182
184 return 0;
185}
186
187/*------------------------------------------------------------------*/
188
189BOOL match(char *pat, char *str)
190/* process a wildcard match */
191{
192 if (!*str)
193 return *pat == '*' ? match(pat + 1, str) : !*pat;
194
195 switch (*pat) {
196 case '\0':
197 return 0;
198 case '*':
199 return match(pat + 1, str) || match(pat, str + 1);
200 case '?':
201 return match(pat + 1, str + 1);
202 default:
203 return (toupper(*pat) == toupper(*str)) && match(pat + 1, str + 1);
204 }
205}
206
207/*------------------------------------------------------------------*/
208
210
211BOOL check_abort(int flags, int l) {
212 int c;
213
214 if ((flags & PI_PAUSE) && (l % 24) == 23) {
215 printf("Press any key to continue or q to quit ");
216 fflush(stdout);
217 do {
218 c = ss_getchar(0);
219 if (c == 'q') {
220 printf("\n");
221 ls_abort = TRUE;
222 return TRUE;
223 } else if (c > 0) {
224 printf("\r \r");
225 return FALSE;
226 }
227
228 int status = cm_yield(100);
229 if (status == SS_ABORT || status == RPC_SHUTDOWN)
230 break;
231
232 } while (!cm_is_ctrlc_pressed());
233 }
234
235 if (cm_is_ctrlc_pressed()) {
236 ls_abort = TRUE;
237 return TRUE;
238 }
239
240 return FALSE;
241}
242
243static void pad_to_pos(std::string *s, size_t pos) {
244 while (s->length() < pos)
245 (*s) += " ";
246}
247
248INT print_key(HNDLE hDB, HNDLE hKey, KEY *pkey, INT level, void *info) {
249 INT i, status;
250 DWORD delta;
251 PRINT_INFO *pi;
252 KEY key;
253
254 if (ls_abort)
255 return 0;
256
257 pi = (PRINT_INFO *) info;
258 memcpy(&key, pkey, sizeof(KEY));
259
260 /* if pattern set, check if match */
261 if (pi->pattern[0] && !match(pi->pattern, pkey->name))
262 return SUCCESS;
263
264 if (pi->flags & PI_VALUE) {
265 /* only print value */
266 if (key.type != TID_KEY) {
267 assert(key.total_size > 0);
268 char *buf = (char *) malloc(key.total_size);
269 int size = key.total_size;
270 status = db_get_link_data(hDB, hKey, buf, &size, key.type);
271
272 std::string xdata_str;
273
274 /* resolve links */
275 if (key.type == TID_LINK) {
276 if (strlen(buf) > 0 && buf[strlen(buf) - 1] == ']')
278 else
279 status = db_find_key(hDB, 0, buf, &hKey);
280 if (status == DB_SUCCESS) {
282 if (status == DB_SUCCESS) {
283 assert(key.total_size > 0);
284 buf = (char *) realloc(buf, key.total_size);
285 size = key.total_size;
286 if (key.type != TID_KEY)
287 status = db_get_data(hDB, hKey, buf, &size, key.type);
288 else
290 }
291 }
292 }
293
294 if (status == DB_NO_KEY)
295 xdata_str = "<cannot resolve link>";
296 else if (status == DB_NO_ACCESS)
297 xdata_str = "<no read access>";
298 else
299 for (i = 0; i < key.num_values; i++) {
300 if (pi->flags & PI_HEX)
301 xdata_str = db_sprintfh(buf, key.item_size, i, key.type);
302 else
303 xdata_str = db_sprintf(buf, key.item_size, i, key.type);
304
305 if ((pi->index != -1 && i == pi->index) || pi->index == -1)
306 printf("%s\n", xdata_str.c_str());
307 if (check_abort(pi->flags, ls_line++))
308 return 0;
309 }
310 free(buf);
311 }
312 } else {
313 /* print key name with value */
314 //memset(line, ' ', sizeof(line));
315 //line[sizeof(line)-1] = 0;
316 //sprintf(line + level * 4, "%s", key.name);
317 std::string xline;
318 pad_to_pos(&xline, level * 4);
319 xline += key.name;
320 if (key.type == TID_LINK) {
321 if (key.total_size > 0) {
322 char *buf = (char *) malloc(key.total_size);
323 int size = key.total_size;
324 db_get_link_data(hDB, hKey, buf, &size, key.type);
325 //sprintf(line + strlen(line), " -> %s", buf);
326 xline += " -> ";
327 xline += buf;
328 free(buf);
329 } else {
330 //sprintf(line + strlen(line), " -> (empty)");
331 xline += " -> (empty)";
332 }
333 if (pi->index != -1) {
334 //sprintf(line + strlen(line), "[%d]", pi->index);
335 xline += "[";
336 xline += std::to_string(pi->index);
337 xline += "]";
338 }
339 if (xline.length() >= 32) {
340 printf("%s\n", xline.c_str());
341 xline = "";
342 } else {
343 //line[strlen(line)] = ' ';
344 xline += " ";
345 }
346 } else {
347 if (pi->index != -1) {
348 //sprintf(line + strlen(line), "[%d]", pi->index);
349 }
350 //line[strlen(line)] = ' ';
351 xline += " ";
352 }
353
354 if (key.type == TID_KEY) {
355 if (pi->flags & PI_LONG) {
356 //sprintf(line + 32, "DIR");
357 pad_to_pos(&xline, 32);
358 xline += "DIR";
359 }
360 printf("%s\n", xline.c_str());
361 if (check_abort(pi->flags, ls_line++))
362 return 0;
363 } else {
364 char *data_buf = NULL;
365
366 if (key.total_size > 0) {
367 data_buf = (char *) malloc(key.total_size);
368 int size = key.total_size;
369 status = db_get_link_data(hDB, hKey, data_buf, &size, key.type);
370 } else {
372 }
373
374 std::string xdata_str;
375
376 /* resolve links */
377 if (key.type == TID_LINK && data_buf) {
378 if (strlen(data_buf) > 0 && data_buf[strlen(data_buf) - 1] == ']')
380 else
381 status = db_find_key(hDB, 0, data_buf, &hKey);
382 if (status == DB_SUCCESS) {
384 if (status == DB_SUCCESS) {
385 if (key.total_size > 0) {
386 data_buf = (char *) realloc(data_buf, key.total_size);
387 int size = key.total_size;
388 if (key.type != TID_KEY)
389 status = db_get_data(hDB, hKey, data_buf, &size, key.type);
390 else
392 } else {
393 if (data_buf)
394 free(data_buf);
395 data_buf = NULL;
396 }
397 }
398 }
399 }
400
402 xdata_str = "<subdirectory>";
403 else if (status == DB_NO_KEY || status == DB_INVALID_LINK)
404 xdata_str = "<cannot resolve link>";
405 else if (status == DB_NO_ACCESS)
406 xdata_str = "<no read access>";
407 else if (!data_buf)
408 xdata_str = "<empty>";
409 else {
410 if (pi->flags & PI_HEX)
411 xdata_str += db_sprintfh(data_buf, key.item_size, 0, key.type);
412 else
413 xdata_str += db_sprintf(data_buf, key.item_size, 0, key.type);
414 }
415
416 if (pi->flags & PI_LONG) {
417 //sprintf(line + 32, "%s", rpc_tid_name(key.type));
418 //line[strlen(line)] = ' ';
419 //sprintf(line + 40, "%d", key.num_values);
420 //line[strlen(line)] = ' ';
421 //sprintf(line + 46, "%d", key.item_size);
422 //line[strlen(line)] = ' ';
423 pad_to_pos(&xline, 32);
424 xline += rpc_tid_name(key.type);
425 pad_to_pos(&xline, 40);
426 xline += std::to_string(key.num_values);
427 pad_to_pos(&xline, 46);
428 xline += std::to_string(key.item_size);
429
430 db_get_key_time(hDB, hKey, &delta);
431
432 //if (delta < 60)
433 // sprintf(line + 52, "%ds", delta);
434 //else if (delta < 3600)
435 // sprintf(line + 52, "%1.0lfm", delta / 60.0);
436 //else if (delta < 86400)
437 // sprintf(line + 52, "%1.0lfh", delta / 3600.0);
438 //else if (delta < 86400 * 99)
439 // sprintf(line + 52, "%1.0lfh", delta / 86400.0);
440 //else
441 // sprintf(line + 52, ">99d");
442 //line[strlen(line)] = ' ';
443
444 pad_to_pos(&xline, 52);
445 if (delta < 60)
446 xline += msprintf("%ds", delta);
447 else if (delta < 3600)
448 xline += msprintf("%1.0lfm", delta / 60.0);
449 else if (delta < 86400)
450 xline += msprintf("%1.0lfh", delta / 3600.0);
451 else if (delta < 86400 * 99)
452 xline += msprintf("%1.0lfh", delta / 86400.0);
453 else
454 xline += ">99d";
455
456 //sprintf(line + 57, "%d", key.notify_count);
457 //line[strlen(line)] = ' ';
458 pad_to_pos(&xline, 57);
459 xline += std::to_string(key.notify_count);
460
461 pad_to_pos(&xline, 60);
463 xline += 'R';
464 else
465 xline += ' ';
466
468 xline += 'W';
469 else
470 xline += ' ';
471
473 xline += 'D';
474 else
475 xline += ' ';
476
478 xline += 'E';
479 else
480 xline += ' ';
481
482 pad_to_pos(&xline, 66);
483 if (key.type == TID_STRING && strchr(xdata_str.c_str(), '\n'))
484 xline += "<multi-line>";
485 else if (key.num_values == 1)
486 xline += xdata_str;
487 } else if (key.num_values == 1) {
488 pad_to_pos(&xline, 32);
489 if (key.type == TID_STRING && strchr(xdata_str.c_str(), '\n'))
490 xline += "<multi-line>";
491 else
492 xline += xdata_str;
493 }
494
495 if (!xline.empty())
496 printf("%s\n", xline.c_str());
497
498 if (key.type == TID_STRING && strchr(xdata_str.c_str(), '\n'))
499 puts(xdata_str.c_str());
500
501 if (check_abort(pi->flags, ls_line++))
502 return 0;
503
504 if (key.num_values > 1) {
505 for (i = 0; i < key.num_values; i++) {
506 if (data_buf) {
507 if (pi->flags & PI_HEX)
508 xdata_str = db_sprintfh(data_buf, key.item_size, i, key.type);
509 else
510 xdata_str = db_sprintf(data_buf, key.item_size, i, key.type);
511 } else {
512 xdata_str = "<empty>";
513 }
514
515 std::string yline;
516
517 if (pi->flags & PI_LONG) {
518 //sprintf(line + 40, "[%d]", i);
519 pad_to_pos(&yline, 40);
520 yline += "[";
521 yline += std::to_string(i);
522 yline += "]";
523
524 pad_to_pos(&yline, 56);
525 yline += xdata_str;
526 } else {
527 pad_to_pos(&yline, 32);
528 yline += xdata_str;
529 }
530
531 if ((pi->index != -1 && i == pi->index) || pi->index == -1)
532 printf("%s\n", yline.c_str());
533
534 if (check_abort(pi->flags, ls_line++))
535 return 0;
536 }
537 }
538 if (data_buf)
539 free(data_buf);
540 }
541 }
542
543 return SUCCESS;
544}
545
546/*------------------------------------------------------------------*/
547
548void set_key(HNDLE hDB, HNDLE hKey, int index1, int index2, char *value) {
549 KEY key;
550 char data[1000];
551 int i, size, status = 0;
552
554
555 memset(data, 0, sizeof(data));
556 db_sscanf(value, data, &size, 0, key.type);
557
558 /* extend data size for single string if necessary */
559 if ((key.type == TID_STRING || key.type == TID_LINK)
560 && (int) strlen(data) + 1 > key.item_size && key.num_values == 1)
561 key.item_size = strlen(data) + 1;
562
563 if (key.item_size == 0)
565
566 if (key.num_values > 1 && index1 == -1) {
567 for (i = 0; i < key.num_values; i++)
569 } else if (key.num_values > 1 && index2 > index1) {
570 for (i = index1; i < key.num_values && i <= index2; i++)
572 } else if (key.num_values > 1 || index1 > 0)
574 else
576
577 if (status == DB_NO_ACCESS)
578 printf("Write access not allowed\n");
579}
580
581/*------------------------------------------------------------------*/
582
583#if 0
584// scan_tree() is not used anywhere, best I can tell. K.O. Aug2024
585void scan_tree(HNDLE hDB, HNDLE hKey, INT * total_size_key, INT * total_size_data,
586 INT level, INT flags)
587{
588 INT i, j;
589 //INT size;
590 INT status;
591 KEY key;
593 static char data_str[256], line[256];
594 DWORD delta;
595
596 if (cm_is_ctrlc_pressed()) {
597 if (level == 0)
599 return;
600 }
601
603
604 *total_size_key += ALIGN8(sizeof(KEY));
605 if (key.type == TID_KEY)
606 *total_size_key += ALIGN8(sizeof(KEYLIST));
607 else
608 *total_size_data += ALIGN8(key.total_size);
609
610 if (flags & 0x4) {
611 /* only print value */
612 if (key.type != TID_KEY) {
613 assert(key.total_size > 0);
614 char* buf = (char*)malloc(key.total_size);
615 int size = key.total_size;
616 status = db_get_data(hDB, hKey, buf, &size, key.type);
617 if (status == DB_NO_ACCESS)
618 strcpy(data_str, "<no read access>");
619 else
620 for (j = 0; j < key.num_values; j++) {
621 std::string data_str;
622 if (flags & 0x8)
623 data_str = db_sprintfh(buf, key.item_size, j, key.type);
624 else
625 data_str = db_sprintf(buf, key.item_size, j, key.type);
626 printf("%s\n", data_str.c_str());
627 }
628 free(buf);
629 }
630 } else {
631 printf("XXX here!\n");
632 /* print key name with value */
633 memset(line, ' ', 80);
634 line[80] = 0;
635 sprintf(line + level * 4, "%s", key.name);
636 line[strlen(line)] = ' ';
637
638 if (key.type == TID_KEY) {
639 line[32] = 0;
640 printf("%s\n", line);
641 } else {
642 assert(key.total_size > 0);
643 char* buf = (char*)malloc(key.total_size);
644 int size = key.total_size;
645 status = db_get_data(hDB, hKey, buf, &size, key.type);
646 if (status == DB_NO_ACCESS)
647 strcpy(data_str, "<no read access>");
648 else {
649 if (flags & 0x8)
650 db_sprintfh(data_str, buf, key.item_size, 0, key.type);
651 else
652 db_sprintf(data_str, buf, key.item_size, 0, key.type);
653 }
654
655 if (flags & 0x1) {
656 sprintf(line + 32, "%s", rpc_tid_name(key.type));
657 line[strlen(line)] = ' ';
658 sprintf(line + 40, "%d", key.num_values);
659 line[strlen(line)] = ' ';
660 sprintf(line + 46, "%d", key.item_size);
661 line[strlen(line)] = ' ';
662
663 db_get_key_time(hDB, hKey, &delta);
664 if (delta < 60)
665 sprintf(line + 52, "%ds", delta);
666 else if (delta < 3600)
667 sprintf(line + 52, "%1.0lfm", delta / 60.0);
668 else if (delta < 86400)
669 sprintf(line + 52, "%1.0lfh", delta / 3600.0);
670 else if (delta < 86400 * 99)
671 sprintf(line + 52, "%1.0lfh", delta / 86400.0);
672 else
673 sprintf(line + 52, ">99d");
674 line[strlen(line)] = ' ';
675
676 sprintf(line + 57, "%d", key.notify_count);
677 line[strlen(line)] = ' ';
678
680 line[61] = 'R';
682 line[62] = 'W';
684 line[63] = 'D';
686 line[64] = 'E';
687
688 if (key.num_values == 1)
689 strcpy(line + 66, data_str);
690 else
691 line[66] = 0;
692 } else if (key.num_values == 1)
693 strcpy(line + 32, data_str);
694 else
695 line[32] = 0;
696
697 printf("%s\n", line);
698
699 if (key.num_values > 1) {
700 for (j = 0; j < key.num_values; j++) {
701 std::string data_str;
702
703 if (flags & 0x8)
704 data_str = db_sprintfh(buf, key.item_size, j, key.type);
705 else
706 data_str = db_sprintf(buf, key.item_size, j, key.type);
707
708 memset(line, ' ', 80);
709 line[80] = 0;
710
711 if (flags & 0x1) {
712 sprintf(line + 40, "[%d]", j);
713 line[strlen(line)] = ' ';
714
715 strcpy(line + 56, data_str);
716 } else
717 strcpy(line + 32, data_str);
718
719 printf("%s\n", line);
720 }
721 }
722
723 free(buf);
724 }
725 }
726
727 /* recurse subtree */
728 if (key.type == TID_KEY && (flags & 0x2)) {
729 for (i = 0;; i++) {
731
732 if (!hSubkey)
733 break;
734
735 scan_tree(hDB, hSubkey, total_size_key, total_size_data, level + 1, flags);
736
737 if (cm_is_ctrlc_pressed()) {
738 if (level == 0)
740 return;
741 }
742 }
743 }
744}
745#endif
746
747/*------------------------------------------------------------------*/
748
749/* complete partial key name, gets called from cmd_edit */
750INT cmd_dir(char *line, INT *cursor) {
751 KEY key;
753 INT i, j, match, size;
754 char *pc, partial[256], last_match[256];
755 char head[256], tail[256], key_name[256], c;
756 char test_key[256];
757 BOOL blanks, mismatch;
758
760
761 /* remember tail for later */
762 strcpy(head, line);
763 strcpy(tail, line + *cursor);
764 line[*cursor] = 0;
765
766 /* search beginning of key */
767 pc = head;
768 do {
769 while (*pc && *pc != ' ')
770 pc++;
771 while (*pc && *pc == ' ')
772 pc++;
773 } while (*pc == '-'); /* skip flags */
774
775 if (*pc) {
776 strcpy(key_name, pc);
777 *pc = 0; /* end of head */
778 } else
779 key_name[0] = 0;
780
781 /* check if key exists (for "set <key>" completion) */
782 if (strncmp(head, "set", 3) == 0 && strlen(key_name) > 0) {
783 std::string ystr;
784 if (key_name[0] == '"')
785 ystr = (key_name + 1);
786 else
787 ystr = key_name;
788 if (key_name[0] != '/') {
789 strcpy(test_key, pwd);
790 if (test_key[strlen(test_key) - 1] != '/')
791 strcat(test_key, "/");
792 strcat(test_key, ystr.c_str());// FIXME: buffer overflow. KO aug2024
793 } else {
794 strcpy(test_key, ystr.c_str());// FIXME: buffer overflow. KO aug2024
795 }
796
797 pc = test_key + strlen(test_key) - 1;
798 while (pc > test_key && (*pc == ' ' || *pc == '"'))
799 *pc-- = 0;
800 int status = db_find_key(hDB, 0, test_key, &hSubkey);
801 if (status == DB_SUCCESS) {
802 /* retrieve key data */
804
805 if (key.type != TID_KEY) {
806 if (strlen(key_name) > 0 && key_name[strlen(key_name) - 1] != ' ')
807 strcat(key_name, " ");
808
809 assert(key.total_size > 0);
810 char *buf = (char *) malloc(key.total_size);
811 size = key.total_size;
812 status = db_get_link_data(hDB, hSubkey, buf, &size, key.type);
813
814 std::string xstr;
815
816 if (key.type == TID_STRING || key.type == TID_LINK) {
817 xstr += "\"";
818 xstr += buf;
819 xstr += "\"";
820 } else {
821 xstr = db_sprintf(buf, size, 0, key.type);
822 }
823
824 free(buf);
825
826 strcpy(line, head);
827 strcat(line, key_name);
828 strcat(line, xstr.c_str());// FIXME: buffer overflow. KO Aug2024
829 *cursor = strlen(line);
830 strcat(line, tail);
831 return TRUE;
832 }
833 }
834 }
835
836 /* combine pwd and key_name */
837 pc = key_name;
838 if (*pc == '"')
839 pc++;
840
841 char str[256];// FIXME: buffer overflows. K.O> Aug2024
842 str[0] = 0;
843
844 if (*pc != '/') {
845 strcpy(str, pwd);
846 if (str[strlen(str) - 1] != '/')
847 strcat(str, "/");
848 strcat(str, pc);
849 } else
850 strcpy(str, pc);
851
852 /* split key_name into known and new directory */
853 for (pc = str + strlen(str) - 1; pc > str && *pc != '/'; pc--)
854 ;
855
856 if (*pc == '/') {
857 *pc = 0;
858 strcpy(partial, pc + 1);
859 } else
860 strcpy(partial, str);
861
862 db_find_link(hDB, 0, str, &hKey);
863 for (i = 0, match = 0;; i++) {
865
866 if (!hSubkey)
867 break;
868
870 strcpy(str, key.name);
871
872 str[strlen(partial)] = 0;
873
874 if (equal_ustring(str, partial))
875 match++;
876 }
877
878 if (match != 1)
879 printf("\r\n");
880
881 for (i = 0;; i++) {
883
884 if (!hSubkey)
885 break;
886
888 strcpy(str, key.name);
889
890 str[strlen(partial)] = 0;
891
892 if (equal_ustring(str, partial)) {
893 if (match == 1) {
894 /* search split point */
895 pc = key_name;
896 if (strlen(key_name) > 0)
897 for (pc = key_name + strlen(key_name) - 1; pc > key_name && *pc != '/';
898 pc--)
899 ;
900 if (*pc == '/')
901 pc++;
902
903 strcpy(pc, key.name);
904 if (key.type == TID_KEY)
905 strcat(pc, "/");
906
907 /* insert '"' if blanks in name */
908 if (strchr(key.name, ' ')) {
909 if (key_name[0] != '"') {
910 for (i = strlen(key_name); i >= 0; i--)
911 key_name[i + 1] = key_name[i];
912
913 key_name[0] = '"';
914 }
915 if (key.type != TID_KEY)
916 strcat(key_name, "\"");
917 }
918
919 if (key.type != TID_KEY) {
920 if (key_name[0] == '"' && key_name[strlen(key_name) - 1] != '"')
921 strcat(pc, "\" ");
922 else
923 strcat(pc, " ");
924 }
925
926 strcpy(line, head);
927 strcat(line, key_name);
928 *cursor = strlen(line);
929 strcat(line, tail);
930 return TRUE;
931 }
932 }
933 if (match == 0 || (match > 1 && equal_ustring(str, partial)))
934 printf("%s\r\n", key.name);
935 }
936
937 if (match > 1 && key_name[0]) {
938 blanks = FALSE;
939
940 for (j = strlen(partial);; j++) {
941 for (i = 0, c = 1, mismatch = FALSE;; i++) {
943
944 if (!hSubkey)
945 break;
946
948 strcpy(str, key.name);
949
950 str[strlen(partial)] = 0;
951
952 if (strchr(key.name, ' '))
953 blanks = TRUE;
954
955 if (equal_ustring(str, partial)) {
956 strcpy(last_match, key.name);
957 if (c == 1)
958 c = toupper(key.name[j]);
959 else if (c != toupper(key.name[j])) {
960 mismatch = TRUE;
961 break;
962 }
963 }
964 }
965
966 if (mismatch || last_match[j] == 0)
967 break;
968 }
969
970 /* search split point */
971 for (pc = key_name + strlen(key_name) - 1; pc > key_name && *pc != '/'; pc--)
972 ;
973 if (*pc == '/')
974 pc++;
975
976 for (i = 0; i < j; i++)
977 pc[i] = last_match[i];
978 pc[i] = 0;
979
980 /* insert '"' if blanks in name */
981 if (blanks) {
982 if (key_name[0] != '"') {
983 for (i = strlen(key_name); i >= 0; i--)
984 key_name[i + 1] = key_name[i];
985
986 key_name[0] = '"';
987 }
988 }
989
990 strcpy(line, head);
991 strcat(line, key_name);
992 *cursor = strlen(line);
993 strcat(line, tail);
994 return TRUE;
995 }
996
997 /* beep if not found */
998 printf("\007");
999
1000 strcpy(line, head);
1001 strcat(line, key_name);
1002 *cursor = strlen(line);
1003 strcat(line, tail);
1004 return FALSE;
1005}
1006
1007/*------------------------------------------------------------------*/
1008
1010 char *pattern = (char *) info;
1011
1012 if (match(pattern, key->name)) {
1013 std::string path = db_get_path(hDB, hKey);
1014 std::string line = path + " : ";
1015
1016 if (key->type != TID_KEY) {
1017 assert(key->total_size > 0);
1018 char *data = (char *) malloc(key->total_size);
1019 int size = key->total_size;
1020 int status = db_get_data(hDB, hKey, data, &size, key->type);
1021
1022 std::string data_str;
1023
1024 if (status == DB_NO_ACCESS)
1025 data_str = "<no read access>";
1026 else
1027 data_str = db_sprintf(data, key->item_size, 0, key->type);
1028
1029 if (key->num_values == 1)
1030 line += data_str;
1031
1032 printf("%s\n", line.c_str());
1033
1034 if (key->num_values > 1)
1035 for (int i = 0; i < key->num_values; i++) {
1036 data_str = db_sprintf(data, key->item_size, i, key->type);
1037
1038 printf(" [%d] : %s\n", i, data_str.c_str());
1039 }
1040 free(data);
1041 } else {
1042 printf("%s\n", line.c_str());
1043 }
1044 }
1045
1046 return SUCCESS;
1047}
1048
1049/*------------------------------------------------------------------*/
1050
1052 INT i;
1053 KEY key;
1054 HNDLE hSubkey;
1055
1056 for (i = 0;; i++) {
1058
1059 if (!hSubkey)
1060 break;
1061
1063 if (key.type == TID_KEY)
1064 del_tree(hDB, hSubkey, level + 1);
1065
1066 if (rand() < RAND_MAX / 10)
1068 }
1069}
1070
1071/*------------------------------------------------------------------*/
1072
1073static void xwrite(const char *filename, int fd, const void *data, int size) {
1074 int wr = write(fd, data, size);
1075 if (wr != size) {
1076 cm_msg(MERROR, "xwrite", "cannot write to \'%s\', write(%d) returned %d, errno %d (%s)", filename, size, wr, errno, strerror(errno));
1077 }
1078}
1079
1081 INT i, index, subindex, hfile, status, size;
1082 HNDLE hKey, hKeyRoot, hKeyEq, hDefKey, hKeyBank, hKeyPar;
1083 char str[100 + 80], eq_name[80], subeq_name[80];
1084 KEY key;
1085 time_t now;
1086
1087 char experim_h_comment1[] =
1088 "/********************************************************************\\\n\
1089\n\
1090 Name: experim.h\n\
1091 Created by: ODBedit program\n\
1092\n\
1093 Contents: This file contains C structures for the \"Experiment\"\n\
1094 tree in the ODB and the \"/Analyzer/Parameters\" tree.\n\
1095\n\
1096 Additionally, it contains the \"Settings\" subtree for\n\
1097 all items listed under \"/Equipment\" as well as their\n\
1098 event definition.\n\
1099\n\
1100 It can be used by the frontend and analyzer to work\n\
1101 with these information.\n\
1102\n\
1103 All C structures are accompanied with a string represen-\n\
1104 tation which can be used in the db_create_record function\n\
1105 to setup an ODB structure which matches the C structure.\n\
1106\n";
1107 char experim_h_comment2[] =
1108 "\\********************************************************************/\n\n";
1109
1110 const char *file_name = "experim.h";
1111
1112 /* create file */
1113 hfile = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0644);
1114 if (hfile == -1)
1115 cm_msg(MERROR, "create_experim_h", "cannot open experim.h file.");
1116
1117 /* write comment to file */
1118 xwrite(file_name, hfile, experim_h_comment1, strlen(experim_h_comment1));
1119 time(&now);
1120 char ctimebuf[32];
1121 ctime_r(&now, ctimebuf);
1122 sprintf(str, " Created on: %s\n", ctimebuf);
1123 xwrite(file_name, hfile, str, strlen(str));
1124 xwrite(file_name, hfile, experim_h_comment2, strlen(experim_h_comment2));
1125
1126 /* write /experiment/run parameters */
1127 db_find_key(hDB, 0, "/Experiment/Run Parameters", &hKey);
1128 if (hKey) {
1129 sprintf(str, "#define EXP_PARAM_DEFINED\n\n");
1130 xwrite(file_name, hfile, str, strlen(str));
1131 db_save_struct(hDB, hKey, file_name, "EXP_PARAM", TRUE);
1132 db_save_string(hDB, hKey, file_name, "EXP_PARAM_STR", TRUE);
1133 lseek(hfile, 0, SEEK_END);
1134 }
1135
1136 /* write /experiment/edit on start */
1137 db_find_key(hDB, 0, "/Experiment/Edit on start", &hKey);
1138 if (hKey) {
1139 sprintf(str, "#define EXP_EDIT_DEFINED\n\n");
1140 xwrite(file_name, hfile, str, strlen(str));
1141 db_save_struct(hDB, hKey, file_name, "EXP_EDIT", TRUE);
1142 db_save_string(hDB, hKey, file_name, "EXP_EDIT_STR", TRUE);
1143 lseek(hfile, 0, SEEK_END);
1144 }
1145
1146 /* write /<Analyzer>/parameters tree */
1147 sprintf(str, "/%s/Parameters", analyzer_name);
1148 status = db_find_key(hDB, 0, str, &hKeyRoot);
1149 if (status != DB_SUCCESS) {
1150 printf("Analyzer \"%s\" not found in ODB, skipping analyzer parameters.\n",
1152 } else {
1153 for (index = 0;; index++) {
1154 status = db_enum_key(hDB, hKeyRoot, index, &hKeyPar);
1156 break;
1157
1158 db_get_key(hDB, hKeyPar, &key);
1159 mstrlcpy(eq_name, key.name, sizeof(eq_name));
1160 name2c(eq_name);
1161 for (i = 0; i < (int) strlen(eq_name); i++)
1162 eq_name[i] = toupper(eq_name[i]);
1163
1164 lseek(hfile, 0, SEEK_END);
1165 sprintf(str, "#ifndef EXCL_%s\n\n", eq_name);
1166 xwrite(file_name, hfile, str, strlen(str));
1167
1168 sprintf(str, "#define %s_PARAM_DEFINED\n\n", eq_name);
1169 xwrite(file_name, hfile, str, strlen(str));
1170 sprintf(str, "%s_PARAM", eq_name);
1171 db_save_struct(hDB, hKeyPar, file_name, str, TRUE);
1172 sprintf(str, "%s_PARAM_STR", eq_name);
1173 db_save_string(hDB, hKeyPar, file_name, str, TRUE);
1174
1175 lseek(hfile, 0, SEEK_END);
1176 sprintf(str, "#endif\n\n");
1177 xwrite(file_name, hfile, str, strlen(str));
1178 }
1179 }
1180
1181 /* loop through equipment list */
1182 status = db_find_key(hDB, 0, "/Equipment", &hKeyRoot);
1183 if (status == DB_SUCCESS)
1184 for (index = 0;; index++) {
1185 status = db_enum_key(hDB, hKeyRoot, index, &hKeyEq);
1187 break;
1188
1189 db_get_key(hDB, hKeyEq, &key);
1190 strcpy(eq_name, key.name);
1191 name2c(eq_name);
1192 for (i = 0; i < (int) strlen(eq_name); i++)
1193 eq_name[i] = toupper(eq_name[i]);
1194
1195 lseek(hfile, 0, SEEK_END);
1196 sprintf(str, "#ifndef EXCL_%s\n\n", eq_name);
1197 xwrite(file_name, hfile, str, strlen(str));
1198
1199 size = sizeof(str);
1200 str[0] = 0;
1201 db_get_value(hDB, hKeyEq, "Common/Format", str, &size, TID_STRING, TRUE);
1202
1203 /* if event is in fixed format, extract header file */
1204 if (equal_ustring(str, "Fixed")) {
1205 db_find_key(hDB, hKeyEq, "Variables", &hDefKey);
1206 if (hDefKey) {
1207 lseek(hfile, 0, SEEK_END);
1208 sprintf(str, "#define %s_EVENT_DEFINED\n\n", eq_name);
1209 xwrite(file_name, hfile, str, strlen(str));
1210
1211 sprintf(str, "%s_EVENT", eq_name);
1212 db_save_struct(hDB, hDefKey, file_name, str, TRUE);
1213 sprintf(str, "%s_EVENT_STR", eq_name);
1214 db_save_string(hDB, hDefKey, file_name, str, TRUE);
1215 }
1216 }
1217
1218 /* if event is in MIDAS format, extract bank definition */
1219 else if (equal_ustring(str, "MIDAS")) {
1220 db_find_key(hDB, hKeyEq, "Variables", &hDefKey);
1221 if (hDefKey) {
1222 for (i = 0;; i++) {
1223 status = db_enum_key(hDB, hDefKey, i, &hKeyBank);
1225 break;
1226
1227 db_get_key(hDB, hKeyBank, &key);
1228
1229 if (key.type == TID_KEY) {
1230 lseek(hfile, 0, SEEK_END);
1231 sprintf(str, "#define %s_BANK_DEFINED\n\n", key.name);
1232 xwrite(file_name, hfile, str, strlen(str));
1233
1234 sprintf(str, "%s_BANK", key.name);
1235 db_save_struct(hDB, hKeyBank, file_name, str, TRUE);
1236 sprintf(str, "%s_BANK_STR", key.name);
1237 db_save_string(hDB, hKeyBank, file_name, str, TRUE);
1238 }
1239 }
1240 }
1241 }
1242
1243 /* Scan sub tree for that equipment */
1244 for (subindex = 0;; subindex++) {
1245 status = db_enum_key(hDB, hKeyEq, subindex, &hDefKey);
1247 break;
1248
1249 db_get_key(hDB, hDefKey, &key);
1250 strcpy(subeq_name, key.name);
1251 name2c(subeq_name);
1252
1253 for (i = 0; i < (int) strlen(subeq_name); i++)
1254 subeq_name[i] = toupper(subeq_name[i]);
1255
1256 /* Skip only the statistics */
1257 if (!equal_ustring(subeq_name, "statistics") && !equal_ustring(subeq_name, "variables")) {
1258 lseek(hfile, 0, SEEK_END);
1259 sprintf(str, "#define %s_%s_DEFINED\n\n", eq_name, subeq_name);
1260 xwrite(file_name, hfile, str, strlen(str));
1261
1262 sprintf(str, "%s_%s", eq_name, subeq_name);
1263 db_save_struct(hDB, hDefKey, file_name, str, TRUE);
1264 sprintf(str, "%s_%s_STR", eq_name, subeq_name);
1265 db_save_string(hDB, hDefKey, file_name, str, TRUE);
1266 }
1267 }
1268
1269 lseek(hfile, 0, SEEK_END);
1270 sprintf(str, "#endif\n\n");
1271 xwrite(file_name, hfile, str, strlen(str));
1272 }
1273
1274 close(hfile);
1275
1276 std::string cwd = ss_getcwd();
1277 printf("\"experim.h\" has been written to %s/%s\n", cwd.c_str(), file_name);
1278}
1279
1280/*------------------------------------------------------------------*/
1281
1283 INT status;
1284
1286
1287 status = cm_yield(100);
1288
1289 /* abort if server connection is broken */
1290 if (status == SS_ABORT || status == RPC_SHUTDOWN) {
1291 if (status == SS_ABORT)
1292 printf("Server connection broken.\n");
1293
1294 ss_getchar(1);
1296 exit(0);
1297 }
1298
1299 /* check for broken client connections */
1301
1302 return need_redraw;
1303}
1304
1305/*------------------------------------------------------------------*/
1306
1307void compose_name(char *pwd, char *name, char *full_name) {
1308 if (name[0] != '/') {
1309 strcpy(full_name, pwd);
1310 if (full_name[strlen(full_name) - 1] != '/')
1311 strcat(full_name, "/");
1312 strcat(full_name, name);
1313 } else
1314 strcpy(full_name, name);
1315}
1316
1317/*------------------------------------------------------------------*/
1318
1319void assemble_prompt(char *prompt, int psize, char *host_name, char *exp_name, char *pwd) {
1320 HNDLE hDB;
1321 char mask[256], str[32];
1322 int state, size;
1323 char *pp, *pm, *pc;
1324 time_t now;
1325
1326 const char *state_char[] = {"U", "S", "P", "R"};
1327 const char *state_str[] = {"Unknown", "Stopped", "Paused", "Running"};
1328
1330
1331 size = sizeof(mask);
1332 strcpy(mask, "[%h:%e:%s]%p>");
1333 db_get_value(hDB, 0, "/System/Prompt", mask, &size, TID_STRING, TRUE);
1334
1336 size = sizeof(state);
1337 db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
1338 if (state > STATE_RUNNING)
1339 state = 0;
1340
1341 pm = mask;
1342 pp = prompt;
1343 memset(prompt, 0, psize);
1344 do {
1345 if (*pm != '%') {
1346 *pp++ = *pm++;
1347 } else {
1348 switch (*++pm) {
1349 case 't':
1350 time(&now);
1351 assert(sizeof(str) >= 32);
1352 ctime_r(&now, str);
1353 str[19] = 0;
1354 strcpy(pp, str + 11);
1355 break;
1356 case 'h':
1357 if (host_name[0])
1358 strcat(pp, host_name);
1359 else
1360 strcat(pp, "local");
1361 break;
1362 case 'e':
1363 if (exp_name[0])
1364 strcat(pp, exp_name);
1365 else
1366 strcat(pp, "Default");
1367 break;
1368 case 's':
1369 strcat(pp, state_char[state]);
1370 break;
1371 case 'S':
1372 strcat(pp, state_str[state]);
1373 break;
1374 case 'P':
1375 strcat(pp, pwd);
1376 break;
1377 case 'p':
1378 pc = pwd + strlen(pwd) - 1;
1379 while (*pc != '/' && pc != pwd)
1380 pc--;
1381 if (pc == pwd)
1382 strcat(pp, pwd);
1383 else
1384 strcat(pp, pc + 1);
1385 break;
1386 }
1387 pm++;
1388 pp += strlen(pp);
1389 }
1390 } while (*pm);
1391}
1392
1393/*------------------------------------------------------------------*/
1394
1396 KEY key;
1397 int status;
1398
1399 std::string path = db_get_path(hDB, hKey);
1400
1402 if (status != DB_SUCCESS) {
1403 printf("callback for invalid or deleted hkey %d odb path %s\n", hKey, path.c_str());
1404 return;
1405 }
1406
1407 if (key.type == TID_KEY)
1408 printf("%s modified\n", path.c_str());
1409 else {
1410 if (key.num_values == 1) {
1411 if (key.type == TID_STRING) {
1412 std::string data;
1413 db_get_value_string(hDB, 0, path.c_str(), 0, &data);
1414 printf("%s = \"%s\"\n", path.c_str(), data.c_str());
1415 } else {
1416 char data[10000];
1417 int size = sizeof(data);
1418 db_get_data(hDB, hKey, data, &size, key.type);
1419 std::string str = db_sprintf(data, size, 0, key.type);
1420 printf("%s = %s\n", path.c_str(), str.c_str());
1421 }
1422 } else {
1423 if (index == -1) {
1424 printf("%s[*] modified\n", path.c_str());
1425 } else {
1426 if (key.type == TID_STRING) {
1427 std::string data;
1428 db_get_value_string(hDB, 0, path.c_str(), index, &data);
1429 printf("%s[%d] = \"%s\"\n", path.c_str(), index, data.c_str());
1430 } else {
1431 char data[10000];
1432 int size = sizeof(data);
1434 std::string str = db_sprintf(data, size, 0, key.type);
1435 printf("%s[%d] = %s\n", path.c_str(), index, str.c_str());
1436 }
1437 }
1438 }
1439 }
1440}
1441
1442/*------------------------------------------------------------------*/
1443
1444int command_loop(char *host_name, char *exp_name, char *cmd, char *start_dir) {
1445 INT status = 0, i, k, state, size, old_run_number, new_run_number;
1446 char line[2000], prompt[256];
1447 char param[10][2000];
1448 char str[2000], str2[80], name[256], *pc;
1449 char old_password[32], new_password[32];
1450 INT nparam, flags, index1, index2, debug_flag, mthread_flag;
1451 WORD mode;
1452 HNDLE hDB, hKey, hKeyClient, hSubkey, hRootKey;
1453 KEY key;
1454 char user_name[80] = "";
1455 FILE *cmd_file = NULL;
1456 DWORD last_msg_time = 0;
1457 char message[2000], client_name[256], *p;
1458 INT n1, n2;
1459 PRINT_INFO print_info;
1460
1461 cm_get_experiment_database(&hDB, &hKeyClient);
1462
1463 /* command loop */
1464 if (start_dir[0])
1465 strcpy(pwd, start_dir);
1466 else
1467 strcpy(pwd, "/");
1468
1469 /* check if dir exists */
1470 if (db_find_key(hDB, 0, pwd, &hKey) != DB_SUCCESS) {
1471 printf("Directory \"%s\" not found.\n", pwd);
1472 return -1;
1473 }
1474
1475 /* open command file */
1476 if (cmd[0] == '@') {
1477 cmd_file = fopen(cmd + 1, "r");
1478 if (cmd_file == NULL) {
1479 printf("Command file %s not found.\n", cmd + 1);
1480 return -1;
1481 }
1482 }
1483
1484 do {
1485 /* print prompt */
1486 if (!cmd_mode) {
1487 assemble_prompt(prompt, sizeof(prompt), host_name, exp_name, pwd);
1488
1489 in_cmd_edit = TRUE;
1490 line[0] = 0;
1491 cmd_edit(prompt, line, cmd_dir, cmd_idle);
1493 } else if (cmd[0] != '@')
1494 mstrlcpy(line, cmd, sizeof(line));
1495 else {
1496 memset(line, 0, sizeof(line));
1497 char *s = fgets(line, sizeof(line), cmd_file);
1498
1499 if (s == NULL || line[0] == 0)
1500 break;
1501
1502 /* cut off CR */
1503 while (strlen(line) > 0 && line[strlen(line) - 1] == '\n')
1504 line[strlen(line) - 1] = 0;
1505
1506 if (line[0] == 0)
1507 continue;
1508 }
1509
1510 /* analyze line */
1511 nparam = 0;
1512 pc = line;
1513 while (*pc == ' ')
1514 pc++;
1515
1516 memset(param, 0, sizeof(param));
1517 do {
1518 if (*pc == '"') {
1519 pc++;
1520 for (i = 0; *pc && *pc != '"' && i < (int) sizeof(param[0]) - 1; i++)
1521 param[nparam][i] = *pc++;
1522 if (*pc)
1523 pc++;
1524 } else if (*pc == '\'') {
1525 pc++;
1526 for (i = 0; *pc && *pc != '\'' && i < (int) sizeof(param[0]) - 1; i++)
1527 param[nparam][i] = *pc++;
1528 if (*pc)
1529 pc++;
1530 } else if (*pc == '`') {
1531 pc++;
1532 for (i = 0; *pc && *pc != '`' && i < (int) sizeof(param[0]) - 1; i++)
1533 param[nparam][i] = *pc++;
1534 if (*pc)
1535 pc++;
1536 } else
1537 for (i = 0; *pc && *pc != ' ' && i < (int) sizeof(param[0]) - 1; i++)
1538 param[nparam][i] = *pc++;
1539 param[nparam][i] = 0;
1540 while (*pc == ' ')
1541 pc++;
1542 nparam++;
1543 } while (*pc);
1544
1545 /* help */
1546 if ((param[0][0] == 'h' && param[0][1] == 'e') || param[0][0] == '?')
1547 print_help(param[1]);
1548
1549 /* ls */
1550 else if ((param[0][0] == 'l' && param[0][1] == 's') || (param[0][0] == 'd' && param[0][1] == 'i')) {
1551 db_find_key(hDB, 0, pwd, &hKey);
1552 print_info.flags = 0;
1553 print_info.pattern[0] = 0;
1554 ls_line = 0;
1555 ls_abort = FALSE;
1556
1557 /* parse options */
1558 for (i = 1; i < 4; i++)
1559 if (param[i][0] == '-') {
1560 for (int j = 1; param[i][j] != ' ' && param[i][j]; j++) {
1561 if (param[i][j] == 'l')
1562 print_info.flags |= PI_LONG;
1563 if (param[i][j] == 'r')
1564 print_info.flags |= PI_RECURSIVE;
1565 if (param[i][j] == 'v')
1566 print_info.flags |= PI_VALUE;
1567 if (param[i][j] == 'h')
1568 print_info.flags |= PI_HEX;
1569 if (param[i][j] == 'p')
1570 print_info.flags |= PI_PAUSE;
1571 }
1572 }
1573
1574 for (i = 1; param[i][0] == '-'; i++)
1575 ;
1576
1577 /* check if parameter contains array index */
1578 print_info.index = -1;
1579 if (strchr(param[i], '[') && strchr(param[i], ']')) {
1580 for (p = strchr(param[i], '[') + 1; *p && *p != ']'; p++)
1581 if (!isdigit(*p))
1582 break;
1583
1584 if (*p && *p == ']') {
1585 print_info.index = atoi(strchr(param[i], '[') + 1);
1586 *strchr(param[i], '[') = 0;
1587 }
1588 }
1589
1590 if (param[i][0]) {
1591 if (strpbrk(param[i], "*?") != NULL) {
1592 /* if parameter contains wildcards, set pattern */
1593 strcpy(print_info.pattern, param[i]);
1594 } else {
1595 if (param[i][0] == '/')
1596 status = db_find_link(hDB, 0, param[i], &hKey);
1597 else
1599
1600 if (status == DB_NO_KEY)
1601 printf("key %s not found\n", param[i]);
1602
1603 if (status == DB_INVALID_LINK)
1604 printf("link %s points to invalid location\n", param[i]);
1605 }
1606 }
1607
1608 if (hKey) {
1609 if ((print_info.flags & PI_LONG) && (print_info.flags & PI_VALUE) == 0) {
1610 printf("Key name Type #Val Size Last Opn Mode Value\n");
1611 printf("---------------------------------------------------------------------------\n");
1612 }
1613
1614 if (print_info.flags & PI_RECURSIVE) {
1615 db_scan_tree(hDB, hKey, 0, print_key, &print_info);
1616 if (cm_is_ctrlc_pressed())
1618 } else {
1619 db_get_link(hDB, hKey, &key);
1620 if (key.type != TID_KEY)
1621 print_key(hDB, hKey, &key, 0, &print_info);
1622 else
1623 for (i = 0;; i++) {
1624 if (cm_is_ctrlc_pressed()) {
1626 break;
1627 }
1628
1630
1631 if (!hSubkey)
1632 break;
1633
1635 status = print_key(hDB, hSubkey, &key, 0, &print_info);
1636 if (status == 0)
1637 break;
1638 }
1639 }
1640 }
1641 }
1642
1643 /* cd */
1644 else if (param[0][0] == 'c' && param[0][1] == 'd') {
1645 if (strlen(param[1]) == 0)
1646 strcpy(str, "/");
1647 else
1648 compose_name(pwd, param[1], str);
1649
1650 status = db_find_key(hDB, 0, str, &hKey);
1651
1652 if (strcmp(str, "/") == 0)
1653 strcpy(pwd, str);
1654 else if (status == DB_SUCCESS) {
1655 db_get_key(hDB, hKey, &key);
1656 if (key.type != TID_KEY)
1657 printf("key has no subkeys\n");
1658 else {
1659 std::string path = db_get_path(hDB, hKey);
1660 mstrlcpy(pwd, path.c_str(), sizeof(pwd));
1661 }
1662 } else
1663 printf("key not found\n");
1664 }
1665
1666 /* pwd */
1667 else if (param[0][0] == 'p' && param[0][1] == 'w') {
1668 printf("%s\n", pwd);
1669 }
1670
1671 /* create */
1672 else if (param[0][0] == 'c' && param[0][1] == 'r') {
1673 compose_name(pwd, param[2], str);
1674
1675 /* check if array */
1676
1677 k = -1;
1678 int j = 0;
1679 if (str[strlen(str) - 1] == ']') {
1680 if (strchr(str, '[')) {
1681 j = atoi(strchr(str, '[') + 1);
1682 mstrlcpy(str2, strchr(str, '[') + 1, sizeof(str2));
1683 *strchr(str, '[') = 0;
1684 if (strchr(str2, '['))
1685 k = atoi(strchr(str2, '[') + 1);
1686 }
1687 } else
1688 j = 1;
1689
1690 /* get TID */
1691 for (i = 0; i < TID_LAST; i++) {
1693 break;
1694 }
1695
1696 if (i == TID_LAST) {
1697 printf("Unknown type. Must be one of:\n");
1698 printf("{ UINT8,INT8,UINT16,INT16,UINT32,INT32,UINT64,INT64,BOOL,FLOAT,DOUBLE,STRING }\n");
1699 } else {
1700 db_create_key(hDB, 0, str, i);
1701 db_find_key(hDB, 0, str, &hKey);
1702 db_get_key(hDB, hKey, &key);
1703
1704 if (i == TID_STRING) {
1705 if (!cmd_mode && k == -1) {
1706 printf("String length [%d]: ", NAME_LENGTH);
1707 ss_gets(str, 256);
1708 if (str[0])
1709 key.item_size = atoi(str);
1710 else
1712 } else if (k == -1)
1714 else
1715 key.item_size = k;
1716
1717 char *buf = (char *) malloc(key.item_size);
1718 memset(buf, 0, sizeof(key.item_size));
1720 free(buf);
1721 }
1722
1723 if (j > 1) {
1724 if (key.type == TID_LINK)
1726 char *buf = (char *) malloc(key.item_size);
1727 memset(buf, 0, sizeof(key.item_size));
1729 free(buf);
1730 }
1731 }
1732 }
1733
1734 /* mkdir */
1735 else if (param[0][0] == 'm' && param[0][1] == 'k') {
1736 compose_name(pwd, param[1], str);
1738 }
1739
1740 /* link */
1741 else if (param[0][0] == 'l' && param[0][1] == 'n') {
1742 compose_name(pwd, param[2], str);
1743 db_create_link(hDB, 0, str, param[1]);
1744 }
1745
1746 /* copy */
1747 else if (param[0][0] == 'c' && (param[0][1] == 'o' || param[0][1] == 'p')) {
1748 /* test if destination exists */
1749 compose_name(pwd, param[2], str);
1750 status = db_find_link(hDB, 0, str, &hKey);
1751 if (status == DB_SUCCESS) {
1752 if (cmd_mode)
1753 str[0] = 'y';
1754 else {
1755 printf("Overwrite existing key\n\"%s\"\n(y/[n]) ", str);
1756 ss_gets(str, 256);
1757 }
1758 if (str[0] == 'y')
1760 }
1761
1762 if (status == DB_NO_KEY || str[0] == 'y') {
1763 compose_name(pwd, param[1], str);
1764
1765 status = db_find_link(hDB, 0, str, &hKey);
1766 if (status == DB_SUCCESS) {
1767 compose_name(pwd, param[2], str);
1768
1769 db_get_key(hDB, hKey, &key);
1771
1772 if (key.type != TID_KEY) {
1773 assert(key.total_size > 0);
1774 char *buf = (char *) malloc(key.total_size);
1775 size = key.total_size;
1776 db_get_data(hDB, hKey, buf, &size, key.type);
1777 db_find_key(hDB, 0, str, &hKey);
1779 free(buf);
1780 } else {
1781 char data[50000];
1782 size = sizeof(data);
1783 status = db_copy(hDB, hKey, data, &size, "");
1784 if (status == DB_TRUNCATED) {
1785 printf("error: db_copy() status %d, odbedit internal buffer is too small, size %d\n", status, size);
1786 } else if (status != DB_SUCCESS) {
1787 printf("error: db_copy() status %d\n", status);
1788 } else {
1789 db_find_key(hDB, 0, str, &hKey);
1790 db_paste(hDB, hKey, data);
1791 }
1792 }
1793 } else {
1794 printf("key not found\n");
1795 }
1796 }
1797 }
1798
1799 /* delete */
1800 else if ((param[0][0] == 'd' && param[0][1] == 'e') || (param[0][0] == 'r' && param[0][1] == 'm')) {
1801 flags = 0;
1802 if ((param[1][0] == '-' && param[1][1] == 'f') || (param[2][0] == '-' && param[2][1] == 'f'))
1803 flags |= (1 << 0);
1804
1805 for (i = 1; param[i][0] == '-'; i++)
1806 ;
1807
1809
1810 status = db_find_link(hDB, 0, str, &hKey);
1811 db_get_key(hDB, hKey, &key);
1812
1813 if (status == DB_SUCCESS) {
1814 if (flags & (1 << 0) || cmd_mode)
1815 str[0] = 'y';
1816 else {
1817 if (key.type == TID_KEY)
1818 printf("Are you sure to delete the key\n\"%s\"\nand all its subkeys? (y/[n]) ",
1819 str);
1820 else
1821 printf("Are you sure to delete the key\n\"%s\"\n(y/[n]) ", str);
1822
1823 ss_gets(str, 256);
1824 }
1825
1826 if (str[0] == 'y') {
1828 if (status == DB_NO_ACCESS) {
1829 printf("deletion of key not allowed\n");
1830 } else if (status == DB_OPEN_RECORD) {
1831 printf("key is open by other client\n");
1832 } else if (status != DB_SUCCESS) {
1833 printf("Error, db_delete_key() status %d\n", status);
1834 }
1835 }
1836 } else
1837 printf("key not found\n");
1838 }
1839
1840 /* set */
1841 else if (param[0][0] == 's' && param[0][1] == 'e') {
1842 /* check if index is supplied */
1843 index1 = index2 = 0;
1844 strcpy(str, param[1]);
1845 strarrayindex(str, &index1, &index2);
1847
1848 std::vector<HNDLE> keys;
1849 status = db_find_keys(hDB, 0, name, keys);
1850
1851 if (status != DB_SUCCESS) {
1852 printf("Error: Key \"%s\" not found\n", name);
1853 if (cmd_mode)
1854 return -1;
1855 } else {
1856 for (HNDLE hMatchedKey : keys) {
1857 set_key(hDB, hMatchedKey, index1, index2, param[2]);
1858 }
1859 }
1860 }
1861
1862 /* set mode */
1863 else if (param[0][0] == 'c' && param[0][1] == 'h' && param[0][2] == 'm') {
1864 if (param[1][0] == 0 && param[2][0] == 0) {
1865 printf("Please specify mode and key\n");
1866 } else {
1867 compose_name(pwd, param[2], str);
1868
1869 mode = atoi(param[1]);
1870
1871 if (strcmp(str, "/") != 0) {
1872 status = db_find_key(hDB, 0, str, &hKey);
1873 } else {
1875 hKey = 0;
1876 }
1877
1878 if (status == DB_SUCCESS) {
1879 if (cmd_mode)
1880 str[0] = 'y';
1881 else {
1882 printf("Are you sure to change the mode of key\n %s\nand all its subkeys\n",
1883 str);
1884 printf("to mode [%c%c%c%c]? (y/[n]) ", mode & MODE_READ ? 'R' : 0,
1885 mode & MODE_WRITE ? 'W' : 0, mode & MODE_DELETE ? 'D' : 0,
1886 mode & MODE_EXCLUSIVE ? 'E' : 0);
1887 ss_gets(str, 256);
1888 }
1889 if (str[0] == 'y')
1890 db_set_mode(hDB, hKey, mode, TRUE);
1891 } else {
1892 printf("Error: Key \"%s\" not found\n", str);
1893 if (cmd_mode)
1894 return -1;
1895 }
1896 }
1897 }
1898
1899 /* test_rpc */
1900 else if (strcmp(param[0], "test_rpc") == 0) {
1901 status = rpc_test_rpc();
1902 if (status == RPC_SUCCESS)
1903 printf("RPC test passed!\n");
1904 else
1905 printf("RPC test failed!\n");
1906 }
1907
1908 /* truncate */
1909 else if (param[0][0] == 't' && param[0][1] == 'r') {
1910 if (param[1][0] == 0) {
1911 printf("Please specify key\n");
1912 } else {
1913 compose_name(pwd, param[1], str);
1914
1915 status = db_find_key(hDB, 0, str, &hKey);
1916
1917 i = atoi(param[2]);
1918 if (i == 0)
1919 i = 1;
1920
1921 if (status == DB_SUCCESS)
1923 else {
1924 printf("Error: Key \"%s\" not found\n", str);
1925 if (cmd_mode)
1926 return -1;
1927 }
1928 }
1929 }
1930
1931 /* rename */
1932 else if (param[0][0] == 'r' && param[0][1] == 'e' && param[0][2] == 'n') {
1933 if (param[1][0] == 0) {
1934 printf("Please specify key\n");
1935 } else {
1936 compose_name(pwd, param[1], str);
1937
1938 if (strcmp(str, "/") != 0)
1939 status = db_find_link(hDB, 0, str, &hKey);
1940 else
1941 hKey = 0;
1942
1943 if (status == DB_SUCCESS || !hKey)
1945 else {
1946 printf("Error: Key \"%s\" not found\n", str);
1947 if (cmd_mode)
1948 return -1;
1949 }
1950 }
1951 }
1952
1953 /* move */
1954 else if (param[0][0] == 'm' && param[0][1] == 'o') {
1955 if (param[1][0] == 0) {
1956 printf("Please specify key\n");
1957 } else {
1958 compose_name(pwd, param[1], str);
1959
1960 if (strcmp(str, "/") != 0)
1961 status = db_find_link(hDB, 0, str, &hKey);
1962 else
1963 hKey = 0;
1964
1965 if (status == DB_SUCCESS || !hKey) {
1966 if (param[2][0] == 't')
1967 i = 0;
1968 else if (param[2][0] == 'b')
1969 i = -1;
1970 else
1971 i = atoi(param[2]);
1972
1974 if (status == DB_NO_ACCESS)
1975 printf("no write access to key\n");
1976 if (status == DB_OPEN_RECORD)
1977 printf("key is open by other client\n");
1978 } else {
1979 printf("Error: Key \"%s\" not found\n", str);
1980 if (cmd_mode)
1981 return -1;
1982 }
1983 }
1984 }
1985
1986 /* find key */
1987 else if (param[0][0] == 'f' && param[0][1] == 'i') {
1988 status = db_find_key(hDB, 0, pwd, &hKey);
1989
1990 if (status == DB_SUCCESS)
1991 db_scan_tree(hDB, hKey, 0, search_key, (void *) param[1]);
1992 else
1993 printf("current key is invalid / no read access\n");
1994 }
1995
1996 /* load */
1997 else if (param[0][0] == 'l' && param[0][1] == 'o') {
1998 db_find_key(hDB, 0, pwd, &hKey);
1999
2000 db_load(hDB, hKey, param[1], FALSE);
2001 }
2002
2003 /* save */
2004 else if (param[0][0] == 's' && param[0][1] == 'a') {
2005 db_find_key(hDB, 0, pwd, &hKey);
2006
2007 if (strstr(param[1], ".xml") || strstr(param[1], ".XML"))
2008 db_save_xml(hDB, hKey, param[1]);
2009 else if (strstr(param[1], ".json") || strstr(param[1], ".js"))
2010 db_save_json(hDB, hKey, param[1]);
2011 else if (param[1][0] == '-') {
2012 if (param[1][1] == 'c' && param[1][2] == 's') {
2013 db_save_struct(hDB, hKey, param[2], NULL, FALSE);
2014 db_save_string(hDB, hKey, param[2], NULL, TRUE);
2015 } else if (param[1][1] == 'c')
2016 db_save_struct(hDB, hKey, param[2], NULL, FALSE);
2017 else if (param[1][1] == 's')
2018 db_save_string(hDB, hKey, param[2], NULL, FALSE);
2019 else if (param[1][1] == 'x')
2020 db_save_xml(hDB, hKey, param[2]);
2021 else if (param[1][1] == 'j')
2022 db_save_json(hDB, hKey, param[2]);
2023 else if (param[1][1] == 'z')
2026 } else
2027 db_save(hDB, hKey, param[1], FALSE);
2028 }
2029
2030 /* json */
2031 else if (strncmp(param[0], "json", 8) == 0) {
2032
2033 if (param[1][0] == '/') {
2034 db_find_key(hDB, 0, param[1], &hKey);
2035 } else if (strlen(param[1]) > 0) {
2036 db_find_key(hDB, 0, pwd, &hKey);
2037 db_find_key(hDB, hKey, param[1], &hKey);
2038 } else {
2039 db_find_key(hDB, 0, pwd, &hKey);
2040 }
2041
2042 char *buffer = NULL;
2043 int buffer_size = 0;
2044 int buffer_end = 0;
2045
2046 status = db_copy_json_save(hDB, hKey, &buffer, &buffer_size, &buffer_end);
2047
2048 printf("status: %d, json: %s\n", status, buffer);
2049
2050 if (buffer)
2051 free(buffer);
2052 }
2053
2054 /* jsvalues */
2055 else if (strncmp(param[0], "jsvalues", 8) == 0) {
2056 db_find_key(hDB, 0, pwd, &hKey);
2057
2058 char *buffer = NULL;
2059 int buffer_size = 0;
2060 int buffer_end = 0;
2061
2062 int omit_names = 0;
2063 int omit_last_written = 0;
2064 time_t omit_old_timestamp = 0;
2065 int preserve_case = 0;
2066
2067 status = db_copy_json_values(hDB, hKey, &buffer, &buffer_size, &buffer_end, omit_names, omit_last_written, omit_old_timestamp, preserve_case);
2068
2069 printf("status: %d, json: %s\n", status, buffer);
2070
2071 if (buffer)
2072 free(buffer);
2073 }
2074
2075 /* jsls */
2076 else if (strncmp(param[0], "jsls", 4) == 0) {
2077
2078 if (param[1][0] == '/') {
2079 db_find_key(hDB, 0, param[1], &hKey);
2080 } else if (strlen(param[1]) > 0) {
2081 db_find_key(hDB, 0, pwd, &hKey);
2082 db_find_key(hDB, hKey, param[1], &hKey);
2083 } else {
2084 db_find_key(hDB, 0, pwd, &hKey);
2085 }
2086
2087 char *buffer = NULL;
2088 int buffer_size = 0;
2089 int buffer_end = 0;
2090
2091 status = db_copy_json_ls(hDB, hKey, &buffer, &buffer_size, &buffer_end);
2092
2093 printf("jsls \"%s\", status: %d, json: %s\n", pwd, status, buffer);
2094
2095 if (buffer)
2096 free(buffer);
2097 }
2098
2099 /* make */
2100 else if (param[0][0] == 'm' && param[0][1] == 'a') {
2101 if (param[1][0])
2103 else
2104 create_experim_h(hDB, "Analyzer");
2105 }
2106
2107 /* passwd */
2108 else if (param[0][0] == 'p' && param[0][1] == 'a' && param[0][2] == 's') {
2109 /*
2110 strcpy(str, ss_crypt("foob", "ar"));
2111 if(strcmp(str, "arlEKn0OzVJn.") != 0)
2112 printf("Warning: ss_crypt() works incorrect");
2113 */
2114
2115 if (db_find_key(hDB, 0, "/Experiment/Security/Password", &hKey) == DB_SUCCESS) {
2116 size = sizeof(old_password);
2117 db_get_data(hDB, hKey, old_password, &size, TID_STRING);
2118
2119 strcpy(str, ss_getpass("Old password: "));
2120 strcpy(str, ss_crypt(str, "mi"));
2121
2122 if (strcmp(str, old_password) == 0 || strcmp(str, "mid7qBxsNMHux") == 0) {
2123 strcpy(str, ss_getpass("New password: "));
2124 strcpy(new_password, ss_crypt(str, "mi"));
2125
2126 strcpy(str, ss_getpass("Retype new password: "));
2127 if (strcmp(new_password, ss_crypt(str, "mi")) != 0)
2128 printf("Mismatch - password unchanged\n");
2129 else
2130 db_set_data(hDB, hKey, new_password, 32, 1, TID_STRING);
2131 } else
2132 printf("Wrong password\n");
2133 } else {
2134 strcpy(str, ss_getpass("Password: "));
2135 strcpy(new_password, ss_crypt(str, "mi"));
2136
2137 strcpy(str, ss_getpass("Retype password: "));
2138 if (strcmp(new_password, ss_crypt(str, "mi")) != 0)
2139 printf("Mismatch - password not set\n");
2140 else {
2141 /* set password */
2142 db_set_value(hDB, 0, "/Experiment/Security/Password", new_password, 32, 1,
2143 TID_STRING);
2144
2145 /* create empty allowed hosts and allowd programs entries */
2146 db_create_key(hDB, 0,
2147 "/Experiment/Security/Allowed hosts/host.sample.domain",
2148 TID_INT);
2149 db_create_key(hDB, 0, "/Experiment/Security/Allowed programs/mstat",
2150 TID_INT);
2151 }
2152 }
2153
2154 }
2155
2156 /* webpasswd */
2157 else if (param[0][0] == 'w' && param[0][1] == 'e' && param[0][2] == 'b') {
2158 if (db_find_key(hDB, 0, "/Experiment/Security/Web Password", &hKey) == DB_SUCCESS) {
2159 size = sizeof(old_password);
2160 db_get_data(hDB, hKey, old_password, &size, TID_STRING);
2161
2162 strcpy(str, ss_getpass("Old password: "));
2163 strcpy(str, ss_crypt(str, "mi"));
2164
2165 if (strcmp(str, old_password) == 0 || strcmp(str, "mid7qBxsNMHux") == 0) {
2166 strcpy(str, ss_getpass("New password: "));
2167 strcpy(new_password, ss_crypt(str, "mi"));
2168
2169 strcpy(str, ss_getpass("Retype new password: "));
2170 if (strcmp(new_password, ss_crypt(str, "mi")) != 0)
2171 printf("Mismatch - password unchanged\n");
2172 else
2173 db_set_data(hDB, hKey, new_password, 32, 1, TID_STRING);
2174 } else
2175 printf("Wrong password\n");
2176 } else {
2177 strcpy(str, ss_getpass("Password: "));
2178 strcpy(new_password, ss_crypt(str, "mi"));
2179
2180 strcpy(str, ss_getpass("Retype password: "));
2181 if (strcmp(new_password, ss_crypt(str, "mi")) != 0)
2182 printf("Mismatch - password not set\n");
2183 else
2184 /* set password */
2185 db_set_value(hDB, 0, "/Experiment/Security/Web Password", new_password, 32,
2186 1, TID_STRING);
2187 }
2188 }
2189
2190 /* hi */
2191 else if (param[0][0] == 'h' && param[0][1] == 'i') {
2192 HNDLE hConn;
2193
2194 client_name[0] = 0;
2195
2196 if (!isalpha(param[1][0])) {
2197 /* find client which exports RPC_ANA_CLEAR_HISTOS */
2198 status = db_find_key(hDB, 0, "System/Clients", &hRootKey);
2199 if (status == DB_SUCCESS) {
2200 for (i = 0;; i++) {
2201 status = db_enum_key(hDB, hRootKey, i, &hSubkey);
2202 if (status == DB_NO_MORE_SUBKEYS) {
2203 printf("No client currently exports the CLEAR HISTO functionality.\n");
2204 break;
2205 }
2206
2207 sprintf(str, "RPC/%d", RPC_ANA_CLEAR_HISTOS);
2209 if (status == DB_SUCCESS) {
2210 size = sizeof(client_name);
2211 db_get_value(hDB, hSubkey, "Name", client_name, &size, TID_STRING,
2212 TRUE);
2213 break;
2214 }
2215 }
2216 }
2217
2218 if (isdigit(param[1][0]))
2219 n1 = atoi(param[1]);
2220 else
2221 n1 = 0; /* all histos by default */
2222
2223 if (isdigit(param[2][0]))
2224 n2 = atoi(param[2]);
2225 else
2226 n2 = n1; /* single histo by default */
2227 } else {
2228 strcpy(client_name, param[1]);
2229
2230 if (isdigit(param[2][0]))
2231 n1 = atoi(param[2]);
2232 else
2233 n1 = 0; /* all histos by default */
2234
2235 if (isdigit(param[3][0]))
2236 n2 = atoi(param[3]);
2237 else
2238 n2 = n1; /* single histo by default */
2239 }
2240
2241 if (client_name[0]) {
2242 if (cm_connect_client(client_name, &hConn) == CM_SUCCESS) {
2243 rpc_client_call(hConn, RPC_ANA_CLEAR_HISTOS, n1, n2);
2244 //cm_disconnect_client(hConn, FALSE);
2245 } else
2246 printf("Cannot connect to client %s\n", client_name);
2247 }
2248 }
2249
2250 /* import */
2251 else if (param[0][0] == 'i' && param[0][1] == 'm') {
2252 int fh = open(param[1], O_RDONLY | O_TEXT);
2253 if (fh < 0) {
2254 printf("Could not open file \"%s\", errno %d (%s)\n", param[1], errno, strerror(errno));
2255 } else {
2256 off_t off = lseek(fh, 0, SEEK_END);
2257 if (off < 0) {
2258 printf("Could not get size of file \"%s\", lseek(SEEK_END) errno %d (%s)\n", param[1], errno, strerror(errno));
2259 close(fh);
2260 } else {
2261 lseek(fh, 0, SEEK_SET);
2262 size_t size = off;
2263 char *buf = (char *) malloc(size + 1);
2264 ssize_t rd = read(fh, buf, size);
2265 if (rd < 0) {
2266 printf("Could not read file \"%s\", read(%zu) errno %d (%s)\n", param[1], size, errno, strerror(errno));
2267 close(fh);
2268 free(buf);
2269 } else {
2270 close(fh);
2271 size = rd;
2272 if (size == 0) {
2273 buf[size] = 0;
2274 size++;
2275 } else if (buf[size - 1] != 0) {
2276 buf[size] = 0;
2277 size++;
2278 }
2279
2280 if (param[2][0] == 0) {
2281 printf("Key name: ");
2282 ss_gets(name, 256);
2283 } else {
2284 strcpy(name, param[2]);
2285 }
2286
2288
2290 db_find_key(hDB, 0, str, &hKey);
2291 db_set_data(hDB, hKey, buf, size, 1, TID_STRING);
2292 free(buf);
2293 }
2294 }
2295 }
2296
2297 }
2298
2299 /* export */
2300 else if (param[0][0] == 'e' && param[0][1] == 'x' && param[0][2] == 'p') {
2301 FILE *f;
2302
2303 if (param[1][0] == 0)
2304 printf("please specify key\n");
2305 else {
2306 compose_name(pwd, param[1], str);
2307
2308 db_find_key(hDB, 0, str, &hKey);
2309 if (hKey == 0)
2310 printf("Error: Key \"%s\" not found\n", param[1]);
2311 else {
2312 if (param[2][0] == 0) {
2313 printf("File name: ");
2314 ss_gets(name, 256);
2315 } else
2316 strcpy(name, param[2]);
2317
2318 f = fopen(name, "w");
2319 if (f == NULL)
2320 printf("Cannot open file \"%s\"\n", name);
2321 else {
2322 db_get_key(hDB, hKey, &key);
2323 if (key.type != TID_STRING)
2324 printf("Only export of STRING key possible\n");
2325 else {
2326 char *buf = (char *) malloc(key.total_size);
2327 size = key.total_size;
2328 memset(buf, 0, size);
2329 db_get_data(hDB, hKey, buf, &size, key.type);
2330 fprintf(f, "%s", buf);
2331 fclose(f);
2332 free(buf);
2333 }
2334 }
2335 }
2336 }
2337 }
2338
2339 /* alarm reset */
2340 else if (param[0][0] == 'a' && param[0][1] == 'l') {
2341 /* go through all alarms */
2342 db_find_key(hDB, 0, "/Alarms/Alarms", &hKey);
2343 if (hKey) {
2344 for (i = 0;; i++) {
2346
2347 if (!hSubkey)
2348 break;
2349
2352 if (status == AL_RESET)
2353 printf("Alarm of class \"%s\" reset sucessfully\n", key.name);
2354 }
2355 }
2356 }
2357
2358 /* mem */
2359 else if (param[0][0] == 'm' && param[0][1] == 'e') {
2360 if (rpc_is_remote())
2361 printf("This function works only locally\n");
2362 else {
2363#ifdef LOCAL_ROUTINES
2364 std::string buf = db_show_mem(hDB, param[1][0]);
2365 puts(buf.c_str());
2366#else
2367 printf("This MIDAS only works remotely\n");
2368#endif// LOCAL_ROUTINES
2369 }
2370 }
2371
2372 /* sor (show open records) */
2373 else if (param[0][0] == 's' && param[0][1] == 'o') {
2374 db_find_key(hDB, 0, pwd, &hKey);
2375 char data[50000];
2377 printf("%s", data);
2378 }
2379
2380 /* scl (show clients ) */
2381 else if (param[0][0] == 's' && param[0][1] == 'c') {
2382 status = db_find_key(hDB, 0, "System/Clients", &hKey);
2383 if (status != DB_SUCCESS)
2384 cm_msg(MERROR, "command_loop",
2385 "cannot find System/Clients entry in database");
2386 else {
2387 if (param[1][1] == 'w')
2388 printf("Name Host Timeout Last called\n");
2389 else
2390 printf("Name Host\n");
2391
2392 /* search database for clients with transition mask set */
2393 for (i = 0, status = 0;; i++) {
2396 break;
2397
2398 if (status == DB_SUCCESS) {
2399 size = sizeof(name);
2400 db_get_value(hDB, hSubkey, "Name", name, &size, TID_STRING, TRUE);
2401 printf("%s", name);
2402 for (int j = 0; j < 20 - (int) strlen(name); j++)
2403 printf(" ");
2404
2405 size = sizeof(str);
2406 db_get_value(hDB, hSubkey, "Host", str, &size, TID_STRING, TRUE);
2407 printf("%s", str);
2408 for (int j = 0; j < 20 - (int) strlen(str); j++)
2409 printf(" ");
2410
2411 /* display optional watchdog info */
2412 if (param[1][1] == 'w') {
2413 DWORD timeout, last;
2414
2415 status = cm_get_watchdog_info(hDB, name, &timeout, &last);
2416 printf("%-10d %-10d", timeout, last);
2417 }
2418
2419 printf("\n");
2420 }
2421 }
2422 }
2423 }
2424
2425 /* start */
2426 else if (param[0][0] == 's' && param[0][1] == 't' && param[0][2] == 'a') {
2427 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v') || (param[3][0] == '-' && param[3][1] == 'v'));
2428 mthread_flag = ((param[1][0] == '-' && param[1][1] == 'm') || (param[2][0] == '-' && param[2][1] == 'm') || (param[3][0] == '-' && param[3][1] == 'm'));
2429
2430 /* check if run is already started */
2431 size = sizeof(i);
2432 i = STATE_STOPPED;
2433 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2434 if (i == STATE_RUNNING) {
2435 printf("Run is already started\n");
2436 } else if (i == STATE_PAUSED) {
2437 printf("Run is paused, please use \"resume\"\n");
2438 } else {
2439 /* get present run number */
2440 old_run_number = 0;
2441 status = db_get_value(hDB, 0, "/Runinfo/Run number", &old_run_number, &size, TID_INT, TRUE);
2442 assert(status == SUCCESS);
2443 assert(old_run_number >= 0);
2444
2445 /* edit run parameter if command is not "start now" */
2446 if ((param[1][0] == 'n' && param[1][1] == 'o' && param[1][2] == 'w') || cmd_mode) {
2447 new_run_number = old_run_number + 1;
2448 line[0] = 'y';
2449 } else {
2450 db_find_key(hDB, 0, "/Experiment/Edit on start", &hKey);
2451 do {
2452 if (hKey) {
2453 for (i = 0;; i++) {
2455
2456 if (!hSubkey)
2457 break;
2458
2460 std::string str = key.name;
2461
2462 if (equal_ustring(str.c_str(), "Edit run number"))
2463 continue;
2464
2465 if (str.find("Options ") == 0)
2466 continue;
2467
2470
2471 assert(key.total_size > 0);
2472 char *buf = (char *) malloc(key.total_size);
2473
2474 size = key.total_size;
2475 status = db_get_data(hDB, hSubkey, buf, &size, key.type);
2476 if (status != DB_SUCCESS) {
2477 free(buf);
2478 continue;
2479 }
2480
2481 for (int j = 0; j < key.num_values; j++) {
2482 std::string xdata_str = db_sprintf(buf, key.item_size, j, key.type);
2483 std::string xprompt;
2484 xprompt += str;
2485 if (key.num_values == 1) {
2486 xprompt += " : ";
2487 } else {
2488 xprompt += msprintf("[%d] : ", j);
2489 }
2490
2491 strcpy(line, xdata_str.c_str());// FIXME: buffer overflow. K.O. aug2024
2492 in_cmd_edit = TRUE;
2493 cmd_edit(xprompt.c_str(), line, NULL, cmd_idle);
2495
2496 if (line[0]) {
2497 db_sscanf(line, buf, &size, j, key.type);
2499 }
2500 }
2501
2502 free(buf);
2503 }
2504 }
2505
2506 /* increment run number */
2507 new_run_number = old_run_number + 1;
2508
2509 if (db_find_key(hDB, 0, "/Experiment/Edit on start/Edit Run number", &hKey) == DB_SUCCESS && db_get_data(hDB, hKey, &i, &size, TID_BOOL) && i == 0) {
2510 printf("Run number: %d\n", new_run_number);
2511 } else {
2512
2513 printf("Run number [%d]: ", new_run_number);
2514 ss_gets(line, 256);
2515 if (line[0] && atoi(line) > 0)
2516 new_run_number = atoi(line);
2517 }
2518
2519 printf("Are the above parameters correct? ([y]/n/q): ");
2520 ss_gets(line, 256);
2521
2522 } while (line[0] == 'n' || line[0] == 'N');
2523 }
2524
2525 if (line[0] != 'q' && line[0] != 'Q') {
2526 /* start run */
2527 printf("Starting run #%d\n", new_run_number);
2528
2529 assert(new_run_number > 0);
2530
2531 status = cm_transition(TR_START, new_run_number, str,
2532 sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2533 if (status != CM_SUCCESS) {
2534 /* in case of error, reset run number */
2535 status =
2536 db_set_value(hDB, 0, "/Runinfo/Run number", &old_run_number,
2537 sizeof(old_run_number), 1, TID_INT);
2538 assert(status == SUCCESS);
2539
2540 printf("Error: %s\n", str);
2541 }
2542 }
2543 }
2544 }
2545
2546 /* stop */
2547 else if (param[0][0] == 's' && param[0][1] == 't' && param[0][2] == 'o') {
2548 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v') || (param[3][0] == '-' && param[3][1] == 'v'));
2549 mthread_flag = ((param[1][0] == '-' && param[1][1] == 'm') || (param[2][0] == '-' && param[2][1] == 'm') || (param[3][0] == '-' && param[3][1] == 'm'));
2550
2551 /* check if run is stopped */
2553 size = sizeof(i);
2554 db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
2555 str[0] = 0;
2556 if (state == STATE_STOPPED && !cmd_mode) {
2557 printf("Run is already stopped. Stop again? (y/[n]) ");
2558 ss_gets(str, 256);
2559 }
2560 if (str[0] == 'y' || state != STATE_STOPPED || cmd_mode) {
2561 if (param[1][0] == 'n')
2562 status =
2563 cm_transition(TR_STOP | TR_DEFERRED, 0, str, sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2564 else
2565 status = cm_transition(TR_STOP, 0, str, sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2566
2568 printf("%s\n", str);
2570 printf("Deferred stop already in progress, enter \"stop now\" to force stop\n");
2571 else if (status != CM_SUCCESS)
2572 printf("Error: %s\n", str);
2573 }
2574 }
2575
2576 /* pause */
2577 else if (param[0][0] == 'p' && param[0][1] == 'a' && param[0][2] == 'u') {
2578 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v'));
2579
2580 /* check if run is started */
2581 i = STATE_STOPPED;
2582 size = sizeof(i);
2583 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2584 if (i != STATE_RUNNING) {
2585 printf("Run is not started\n");
2586 } else {
2587 if (param[1][0] == 'n')
2588 status = cm_transition(TR_PAUSE | TR_DEFERRED, 0, str, sizeof(str), TR_SYNC, debug_flag);
2589 else
2590 status = cm_transition(TR_PAUSE, 0, str, sizeof(str), TR_SYNC, debug_flag);
2591
2593 printf("%s\n", str);
2595 printf("Deferred pause already in progress, enter \"pause now\" to force pause\n");
2596 else if (status != CM_SUCCESS)
2597 printf("Error: %s\n", str);
2598 }
2599 }
2600
2601 /* resume */
2602 else if (param[0][0] == 'r' && param[0][1] == 'e' && param[0][2] == 's') {
2603 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v'));
2604
2605 /* check if run is paused */
2606 i = STATE_STOPPED;
2607 size = sizeof(i);
2608 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2609 if (i != STATE_PAUSED) {
2610 printf("Run is not paused\n");
2611 } else {
2612 status = cm_transition(TR_RESUME, 0, str, sizeof(str), TR_SYNC, debug_flag);
2613 if (status != CM_SUCCESS)
2614 printf("Error: %s\n", str);
2615 }
2616 }
2617
2618 /* msg */
2619 else if (param[0][0] == 'm' && param[0][1] == 's') {
2620 // param[1]: facility, param[2]: type, param[3]: name param[4]: message
2621 if (!param[4][0]) {
2622 printf("Error: Not enough parameters. Please use\n\n");
2623 printf(" msg <facility> <type> <name> <message>\n\n");
2624 printf("where <facility> can be \"midas\", \"chat\", ...\n");
2625 printf("and <type> must be \"error\", \"info\", \"debug\", \"user\", \"log\", \"talk\" or \"call\".\n");
2626 } else {
2627 int type = 0;
2629 type = MT_ERROR;
2631 type = MT_INFO;
2633 type = MT_DEBUG;
2635 type = MT_USER;
2637 type = MT_LOG;
2639 type = MT_TALK;
2641 type = MT_CALL;
2642 if (type == 0) {
2643 printf("Error: inavlid type \"%s\".\n", param[2]);
2644 printf("<type> must be one of \"error\", \"info\", \"debug\", \"user\", \"log\", \"talk\", \"call\".\n");
2645 } else {
2646
2647 cm_msg1(type, __FILE__, __LINE__, param[1], param[3], "%s", param[4]);
2648 last_msg_time = ss_time();
2649 }
2650 }
2651 }
2652
2653 /* chat */
2654 else if (param[0][0] == 'c' && param[0][1] == 'h' && param[0][2] == 'a') {
2655 message[0] = 0;
2656
2657 if (ss_time() - last_msg_time > 300) {
2658 printf("Your name> ");
2659 ss_gets(user_name, 80);
2660 }
2661
2662 printf("Exit chat mode with empty line.\n");
2663 do {
2664 in_cmd_edit = TRUE;
2665 message[0] = 0;
2666 cmd_edit("> ", message, NULL, cmd_idle);
2668
2669 if (message[0])
2670 cm_msg1(MUSER, "chat", user_name, "%s", message);
2671
2672 } while (message[0]);
2673
2674 last_msg_time = ss_time();
2675 }
2676
2677 /* old */
2678 else if (param[0][0] == 'o' && param[0][1] == 'l') {
2679 i = 20;
2680 if (param[1][0])
2681 i = atoi(param[1]);
2682
2683 char data[50000];
2684 cm_msg_retrieve(i, data, sizeof(data));
2685 printf("%s\n\n", data);
2686 }
2687
2688 /* cleanup */
2689 else if (param[0][0] == 'c' && param[0][1] == 'l') {
2690 HNDLE hBuf;
2691 BOOL force;
2692
2693 force = FALSE;
2694 if (param[1][0] == '-' && param[1][1] == 'f')
2695 force = TRUE;
2696 if (param[2][0] == '-' && param[2][1] == 'f')
2697 force = TRUE;
2698
2700
2701 if (param[1][0] && param[1][0] != '-')
2702 cm_cleanup(param[1], force);
2703 else
2704 cm_cleanup("", force);
2706 }
2707
2708 /* shutdown */
2709 else if (param[0][0] == 's' && param[0][1] == 'h') {
2710 if (param[1][0] == 0)
2711 printf("Please enter client name or \"all\" to shutdown all clients.\n");
2712 else {
2714 if (status != CM_SUCCESS) {
2715 if (strcmp(param[1], "all") == 0)
2716 printf("No clients found\n");
2717 else
2718 printf("Client \"%s\" not active\n", param[1]);
2719 }
2720 }
2721 }
2722
2723 /* ver */
2724 else if (param[0][0] == 'v' && param[0][1] == 'e') {
2725 printf("MIDAS version: %s\n", cm_get_version());
2726 printf("GIT revision: %s\n", cm_get_revision());
2727 printf("ODB version: %d\n", DATABASE_VERSION);
2728 }
2729
2730 /* exec */
2731 else if (param[0][0] == 'e' && param[0][1] == 'x' && param[0][2] == 'e') {
2732 compose_name(pwd, param[1], str);
2733 char data[50000];
2734 status = db_find_key(hDB, 0, str, &hKey);
2735 if (status == DB_SUCCESS) {
2736 db_get_key(hDB, hKey, &key);
2737 if (key.type != TID_STRING) {
2738 printf("Key contains no command\n");
2739 continue;
2740 }
2741 size = sizeof(str);
2742 db_get_data(hDB, hKey, str, &size, key.type);
2743
2744 cm_execute(str, data, sizeof(data));
2745 } else {
2746 cm_execute(param[1], data, sizeof(data));
2747 }
2748 puts(data);
2749 }
2750
2751 /* wait */
2752 else if (param[0][0] == 'w' && param[0][1] == 'a' && param[0][2] == 'i') {
2753 if (param[1][0] == 0) {
2754 printf("Please specify key\n");
2755 } else {
2756 compose_name(pwd, param[1], str);
2757
2758 if (equal_ustring(str, "/")) {
2760 status = db_find_link(hDB, 0, "/", &hKey);
2761 } else
2762 status = db_find_link(hDB, 0, str, &hKey);
2763
2764 if (status == DB_SUCCESS) {
2765 db_get_key(hDB, hKey, &key);
2766 printf("Waiting for key \"%s\" to be modified, abort with any key\n", key.name);
2767 db_get_record_size(hDB, hKey, 0, &size);
2768 char *buf = (char *) malloc(size);
2770 db_open_record(hDB, hKey, buf, size, MODE_READ, key_update, NULL);
2771
2772 do {
2773 status = cm_yield(1000);
2774 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2775 break;
2776 } while (!key_modified && !ss_kbhit());
2777
2778 while (ss_kbhit())
2779 ss_getchar(0);
2780
2782 if (buf) {
2783 free(buf);
2784 buf = NULL;
2785 }
2786
2787 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2788 break;
2789
2790 if (i == '!')
2791 printf("Wait aborted.\n");
2792 else
2793 printf("Key has been modified.\n");
2794 } else
2795 printf("key \"%s\" not found\n", str);
2796 }
2797 }
2798
2799 /* watch */
2800 else if (param[0][0] == 'w' && param[0][1] == 'a' && param[0][2] == 't') {
2801 if (param[1][0] == 0) {
2802 printf("Please specify key\n");
2803 } else {
2804 compose_name(pwd, param[1], str);
2805
2806 status = db_find_link(hDB, 0, str, &hKey);
2807 if (status == DB_SUCCESS) {
2808 db_get_key(hDB, hKey, &key);
2809 if (key.type != TID_KEY)
2810 printf("Watch key \"%s\" to be modified, abort with any key\n", str);
2811 else
2812 printf("Watch ODB tree \"%s\" to be modified, abort with any key\n", str);
2814
2815 do {
2816 status = cm_yield(1000);
2817 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2818 break;
2819 } while (!ss_kbhit());
2820
2821 while (ss_kbhit())
2822 ss_getchar(0);
2823
2825
2826 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2827 break;
2828 } else
2829 printf("key \"%s\" not found\n", str);
2830 }
2831 }
2832
2833 /* test 1 */
2834 else if (param[0][0] == 't' && param[0][1] == '1') {
2835 DWORD start_time;
2836 INT i, size, rn;
2837 HNDLE hKey;
2838
2839 start_time = ss_millitime();
2840 status = db_find_key(hDB, 0, "/runinfo/run number", &hKey);
2841 assert(status == SUCCESS);
2842 size = sizeof(rn);
2843
2844 i = 0;
2845 do {
2846 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2847 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2848 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2849 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2850 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2851 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2852 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2853 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2854 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2855 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2856 i += 10;
2857 } while (ss_millitime() - start_time < 5000);
2858
2859 printf("%d accesses per second\n", i / 5);
2860 }
2861
2862 /* test 2 */
2863 else if (param[0][0] == 't' && param[0][1] == '2') {
2864 do {
2865 do {
2866 i = ss_getchar(0);
2867 printf("%d\n", i);
2868 } while (i > 0 && i != 4);
2869
2870 ss_sleep(1000);
2871 } while (i != 4);
2872
2873 ss_getchar(1);
2874 }
2875
2876 /* test 3 */
2877 else if (param[0][0] == 't' && param[0][1] == '3') {
2878#ifdef USE_ADDRESS_SANITIZER
2879 // test address sanitizer
2880 int *a = (int *) malloc(sizeof(int) * 10);
2881 i = a[11];
2882 free(a);
2883#else
2884 printf("test address sanitizer is disabled!\n");
2885#endif
2886 }
2887
2888 /* exit/quit */
2889 else if ((param[0][0] == 'e' && param[0][1] == 'x' && param[0][2] == 'i') || (param[0][0] == 'q'))
2890 break;
2891
2892 else if (param[0][0] == 0)
2893 ;
2894
2895 else
2896 printf("Unknown command %s %s %s\n", param[0], param[1], param[2]);
2897
2898 /* exit after single command */
2899 if (cmd_mode && cmd[0] != '@')
2900 break;
2901
2902 /* check if client connections are broken */
2903 status = cm_yield(0);
2904 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2905 break;
2906
2907 } while (TRUE);
2908
2909 /* check if client connections are broken */
2910 status = cm_yield(0);
2911
2912 return 1; /* indicate success */
2913}
2914
2915/*------------------------------------------------------------------*/
2916
2918 /* reset terminal */
2919 ss_getchar(1);
2920
2921 /* no shutdown message */
2922 cm_set_msg_print(MT_ERROR, 0, NULL);
2923
2925
2926 printf("\n");
2927 exit(EXIT_SUCCESS);
2928}
2929
2930/*------------------------------------------------------------------*/
2931
2932#ifdef OS_VXWORKS
2933int odbedit(char *ahost_name, char *aexp_name)
2934#else
2935int main(int argc, char *argv[])
2936#endif
2937{
2938 INT status, i, odb_size, size;
2940 char cmd[2000], dir[256];
2941 BOOL debug;
2942 BOOL quiet;
2943 BOOL corrupted;
2944 BOOL reload_from_file = FALSE;
2945 HNDLE hDB;
2946
2947 cmd[0] = dir[0] = 0;
2949 debug = corrupted = cmd_mode = quiet = FALSE;
2950
2951#ifdef OS_VXWORKS
2952 strcpy(host_name, ahost_name);
2953 strcpy(exp_name, aexp_name);
2954#else
2955
2956 /* get default from environment */
2958
2959 /* check for MIDASSYS */
2960 if (!getenv("MIDASSYS")) {
2961 puts("Please define environment variable 'MIDASSYS'");
2962 puts("pointing to the midas source installation directory.");
2963 }
2964
2965 /* parse command line parameters */
2966 for (i = 1; i < argc; i++) {
2967 if (argv[i][0] == '-' && argv[i][1] == 'g')
2968 debug = TRUE;
2969 else if (argv[i][0] == '-' && argv[i][1] == 'q')
2970 quiet = TRUE;
2971 else if (argv[i][0] == '-' && argv[i][1] == 'R')
2972 reload_from_file = TRUE;
2973 else if (argv[i][0] == '-' && argv[i][1] == 'C')
2974 corrupted = TRUE;
2975 else if (argv[i][0] == '-') {
2976 if (i + 1 >= argc || argv[i + 1][0] == '-')
2977 goto usage;
2978 if (argv[i][1] == 'e')
2979 strcpy(exp_name, argv[++i]);
2980 else if (argv[i][1] == 'h')
2981 strcpy(host_name, argv[++i]);
2982 else if (argv[i][1] == 'c') {
2983 if (strlen(argv[i + 1]) >= sizeof(cmd)) {
2984 printf("error: command line too long (>%d bytes)\n", (int) sizeof(cmd));
2985 return 0;
2986 }
2987 mstrlcpy(cmd, argv[++i], sizeof(cmd));
2988 cmd_mode = TRUE;
2989 } else if (argv[i][1] == 'd')
2990 mstrlcpy(dir, argv[++i], sizeof(dir));
2991 else if (argv[i][1] == 's')
2992 odb_size = atoi(argv[++i]);
2993 else {
2994 usage:
2995 printf("usage: odbedit [-h Hostname] [-e Experiment] [-d ODB Subtree]\n");
2996 printf(" [-q] [-c Command] [-c @CommandFile] [-s size]\n");
2997 printf(" [-g (debug)] [-C (connect to corrupted ODB)]\n");
2998 printf(" [-R (reload ODB from .ODB.SHM)]\n\n");
2999 printf("For a list of valid commands start odbedit interactively\n");
3000 printf("and type \"help\".\n");
3001 return 0;
3002 }
3003 } else
3004 mstrlcpy(host_name, argv[i], sizeof(host_name));
3005 }
3006#endif
3007
3008 if (reload_from_file) {
3009#ifdef LOCAL_ROUTINES
3011 if (status != CM_SUCCESS) {
3012 printf("Cannot setup experiment name and path.\n");
3013 return 1;
3014 }
3015 status = ss_shm_delete("ODB");
3016 printf("MIDAS ODB shared memory was deleted, ss_shm_delete(ODB) status %d\n", status);
3017 printf("Please run odbedit again without \'-R\' and ODB will be reloaded from .ODB.SHM\n");
3018 return 1;
3019#else
3020 printf("This odbedit only works remotely, -R is not supported\n");
3021 return 1;
3022#endif
3023 }
3024
3025 /* no startup message if called with command */
3026 if (cmd[0])
3027 cm_set_msg_print(MT_ERROR, 0, NULL);
3028
3029 status = cm_connect_experiment1(host_name, exp_name, "ODBEdit", NULL,
3031
3032 if (host_name[0])
3033 printf("Connected to MIDAS server \"%s\" experiment \"%s\"\n", host_name, exp_name);
3034
3036 return 1;
3037
3039
3040 if ((status == DB_INVALID_HANDLE) && corrupted) {
3041 std::string s = cm_get_error(status);
3042 puts(s.c_str());
3043 printf("ODB is corrupted, connecting anyway...\n");
3044 } else if (status != CM_SUCCESS) {
3045 std::string s = cm_get_error(status);
3046 puts(s.c_str());
3047 return 1;
3048 }
3049
3050 /* place a request for system messages */
3052
3053 /* route local messages through print_message */
3055
3056 /* turn off watchdog if in debug mode */
3057 if (debug)
3059
3060 /* get experiment name */
3061 if (!exp_name[0]) {
3063 size = NAME_LENGTH;
3064 db_get_value(hDB, 0, "/Experiment/Name", exp_name, &size, TID_STRING, TRUE);
3065 }
3066
3067 /* register Ctrl-C handler */
3069
3070 /* for use with the mac os profiler */
3071 //cmd_mode = TRUE;
3072 //status = command_loop(host_name, exp_name, "save xxx3.json", dir);
3073
3074 /* log all commands passed via -c on command line */
3075 if (cmd_mode && !quiet)
3076 cm_msg(MINFO, "odbedit", "Execute command from command line: \"%s\"", cmd);
3077
3078 /* command loop */
3079 status = command_loop(host_name, exp_name, cmd, dir);
3080
3081 /* no shutdown message if called with command */
3082 if (cmd_mode)
3083 cm_set_msg_print(MT_ERROR, 0, NULL);
3084
3086
3087 if (status != 1)
3088 return EXIT_FAILURE;
3089
3090 return EXIT_SUCCESS;
3091}
3092
3093/* emacs
3094 * Local Variables:
3095 * tab-width: 8
3096 * c-basic-offset: 3
3097 * indent-tabs-mode: nil
3098 * End:
3099 */
#define FALSE
Definition cfortran.h:309
static void usage()
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:525
INT bm_open_buffer(const char *buffer_name, INT buffer_size, INT *buffer_handle)
Definition midas.cxx:6727
INT bm_close_buffer(INT buffer_handle)
Definition midas.cxx:7106
INT cm_shutdown(const char *name, BOOL bUnique)
Definition midas.cxx:7410
INT cm_yield(INT millisec)
Definition midas.cxx:5659
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3026
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2781
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5303
INT cm_connect_experiment1(const char *host_name, const char *default_exp_name, const char *client_name, void(*func)(char *), INT odb_size, DWORD watchdog_timeout)
Definition midas.cxx:2312
void cm_ack_ctrlc_pressed()
Definition midas.cxx:5473
INT cm_execute(const char *command, char *result, INT bufsize)
Definition midas.cxx:5740
INT cm_get_watchdog_info(HNDLE hDB, const char *client_name, DWORD *timeout, DWORD *last)
Definition midas.cxx:3359
INT cm_cleanup(const char *client_name, BOOL ignore_timeout)
Definition midas.cxx:7620
INT cm_disconnect_experiment(void)
Definition midas.cxx:2861
int cm_set_experiment_local(const char *exp_name)
Definition midas.cxx:2181
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2149
const char * cm_get_version()
Definition midas.cxx:1491
const char * cm_get_revision()
Definition midas.cxx:1499
BOOL cm_is_ctrlc_pressed()
Definition midas.cxx:5469
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3298
#define CM_SUCCESS
Definition midas.h:582
#define CM_DEFERRED_TRANSITION
Definition midas.h:591
#define CM_TRANSITION_IN_PROGRESS
Definition midas.h:592
#define CM_WRONG_PASSWORD
Definition midas.h:589
#define DB_INVALID_HANDLE
Definition midas.h:636
#define DB_NO_ACCESS
Definition midas.h:649
#define DB_SUCCESS
Definition midas.h:632
#define DB_NO_KEY
Definition midas.h:643
#define DB_TYPE_MISMATCH
Definition midas.h:646
#define DB_INVALID_LINK
Definition midas.h:653
#define DB_OPEN_RECORD
Definition midas.h:651
#define DB_NO_MORE_SUBKEYS
Definition midas.h:647
#define DB_TRUNCATED
Definition midas.h:645
#define SS_ABORT
Definition midas.h:678
#define RPC_SHUTDOWN
Definition midas.h:708
#define RPC_SUCCESS
Definition midas.h:699
#define AL_RESET
Definition midas.h:758
unsigned short int WORD
Definition mcstd.h:49
unsigned int DWORD
Definition mcstd.h:51
#define SUCCESS
Definition mcstd.h:54
#define TR_RESUME
Definition midas.h:408
#define TR_PAUSE
Definition midas.h:407
#define MT_LOG_STR
Definition midas.h:555
#define TID_KEY
Definition midas.h:349
#define TID_BOOL
Definition midas.h:340
#define TR_START
Definition midas.h:405
#define TR_SYNC
Definition midas.h:358
#define MODE_EXCLUSIVE
Definition midas.h:373
#define MT_ALL
Definition midas.h:549
#define MUSER
Definition midas.h:562
#define MT_CALL_STR
Definition midas.h:557
#define MT_INFO_STR
Definition midas.h:552
#define TR_MTHREAD
Definition midas.h:361
#define MT_INFO
Definition midas.h:543
#define STATE_STOPPED
Definition midas.h:305
#define MINFO
Definition midas.h:560
#define MODE_DELETE
Definition midas.h:372
#define MT_DEBUG_STR
Definition midas.h:553
#define MT_TALK
Definition midas.h:547
#define MT_USER
Definition midas.h:545
#define MT_USER_STR
Definition midas.h:554
#define MT_LOG
Definition midas.h:546
#define TID_LINK
Definition midas.h:350
#define STATE_PAUSED
Definition midas.h:306
#define MT_TALK_STR
Definition midas.h:556
#define TID_STRING
Definition midas.h:346
#define MODE_WRITE
Definition midas.h:371
#define TR_DEFERRED
Definition midas.h:410
#define MERROR
Definition midas.h:559
#define STATE_RUNNING
Definition midas.h:307
#define MODE_READ
Definition midas.h:370
#define MT_DEBUG
Definition midas.h:544
#define TID_INT
Definition midas.h:338
#define MT_CALL
Definition midas.h:548
#define TR_STOP
Definition midas.h:406
#define TID_LAST
Definition midas.h:354
#define MT_ERROR
Definition midas.h:542
#define MT_ERROR_STR
Definition midas.h:551
#define ALIGN8(x)
Definition midas.h:522
#define O_TEXT
Definition msystem.h:227
BOOL ss_kbhit()
Definition system.cxx:3736
DWORD ss_millitime()
Definition system.cxx:3465
INT ss_shm_delete(const char *name)
Definition system.cxx:911
INT ss_getchar(BOOL reset)
Definition system.cxx:7581
std::string ss_getcwd()
Definition system.cxx:5848
char * ss_getpass(const char *prompt)
Definition system.cxx:7518
std::string ss_tid_to_string(midas_thread_t thread_id)
Definition system.cxx:1643
DWORD ss_time()
Definition system.cxx:3534
midas_thread_t ss_gettid(void)
Definition system.cxx:1591
INT ss_sleep(INT millisec)
Definition system.cxx:3700
char * ss_crypt(const char *buf, const char *salt)
Definition system.cxx:7969
char * ss_gets(char *string, int size)
Definition system.cxx:7848
void * ss_ctrlc_handler(void(*func)(int))
Definition system.cxx:3971
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:988
INT cm_msg_register(EVENT_HANDLER *func)
Definition midas.cxx:1066
INT cm_msg_flush_buffer()
Definition midas.cxx:880
std::string cm_get_error(INT code)
Definition midas.cxx:468
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:930
INT cm_msg_retrieve(INT n_message, char *message, INT buf_size)
Definition midas.cxx:1349
INT cm_set_msg_print(INT system_mask, INT user_mask, int(*func)(const char *))
Definition midas.cxx:660
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3285
INT db_sprintfh(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10752
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:6664
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:3933
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4293
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5185
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6132
INT db_save_json(HNDLE hDB, HNDLE hKey, const char *filename, int flags)
Definition odb.cxx:10295
INT db_open_record(HNDLE hDB, HNDLE hKey, void *ptr, INT rec_size, WORD access_mode, void(*dispatcher)(INT, INT, void *), void *info)
Definition odb.cxx:13069
INT db_get_open_records(HNDLE hDB, HNDLE hKey, char *str, INT buf_size, BOOL fix)
Definition odb.cxx:4955
INT db_save_xml(HNDLE hDB, HNDLE hKey, const char *filename)
Definition odb.cxx:9250
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7196
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:4775
INT db_copy(HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, const char *path)
Definition odb.cxx:7977
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7520
std::string db_show_mem(HNDLE hDB, BOOL verbose)
Definition odb.cxx:704
INT db_get_record_size(HNDLE hDB, HNDLE hKey, INT align, INT *buf_size)
Definition odb.cxx:11387
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6310
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3392
INT db_copy_json_save(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10243
INT db_save_struct(HNDLE hDB, HNDLE hKey, const char *file_name, const char *struct_name, BOOL append)
Definition odb.cxx:10395
INT db_unwatch(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:13667
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:7787
INT db_save(HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote)
Definition odb.cxx:9010
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
Definition odb.cxx:4544
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:5790
INT db_get_link(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:5843
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
Definition odb.cxx:7886
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)
Definition odb.cxx:13714
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:7415
INT db_save_string(HNDLE hDB, HNDLE hKey, const char *file_name, const char *string_name, BOOL append)
Definition odb.cxx:10456
INT db_paste(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
Definition odb.cxx:8252
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:13592
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:6986
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5496
INT db_copy_json_ls(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:10189
void name2c(char *str)
Definition odb.cxx:8862
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:10612
void strarrayindex(char *odbpath, int *index1, int *index2)
Definition odb.cxx:3357
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)
Definition odb.cxx:10211
INT db_set_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, const void *data, INT data_size, INT num_values, DWORD type)
Definition odb.cxx:5028
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4256
INT db_get_link_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:6427
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6032
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition odb.cxx:5903
INT db_find_keys(HNDLE hDB, HNDLE hKeyRoot, const char *odbpath, std::vector< HNDLE > &hKeyVector)
Definition odb.cxx:4352
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5357
INT db_close_record(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:13252
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
Definition odb.cxx:11083
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:7270
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:3688
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13497
bool rpc_is_remote(void)
Definition midas.cxx:12786
int rpc_test_rpc()
Definition midas.cxx:15071
void rpc_client_check()
Definition midas.cxx:12295
const char * rpc_tid_name(INT id)
Definition midas.cxx:11789
#define RPC_ANA_CLEAR_HISTOS
Definition mrpc.h:118
INT rpc_tid_size(INT id)
Definition midas.cxx:11782
int main()
Definition hwtest.cxx:23
void ** info
Definition fesimdaq.cxx:41
HNDLE hKey
char exp_name[NAME_LENGTH]
Definition mana.cxx:243
INT index
Definition mana.cxx:271
BOOL quiet
Definition mana.cxx:256
const char * analyzer_name
Definition analyzer.c:25
char param[10][256]
Definition mana.cxx:250
void * data
Definition mana.cxx:268
INT odb_size
Definition analyzer.cxx:46
BOOL debug
debug printouts
Definition mana.cxx:254
INT type
Definition mana.cxx:269
HNDLE hDB
main ODB handle
Definition mana.cxx:207
char host_name[HOST_NAME_LENGTH]
Definition mana.cxx:242
KEY key
Definition mdump.cxx:34
INT i
Definition mdump.cxx:32
HNDLE hSubkey
Definition mdump.cxx:35
std::string msprintf(const char *format,...)
Definition midas.cxx:419
#define JSFLAG_RECURSE
Definition midas.h:1723
INT HNDLE
Definition midas.h:132
#define HOST_NAME_LENGTH
Definition midas.h:273
DWORD BOOL
Definition midas.h:105
#define DEFAULT_WATCHDOG_TIMEOUT
Definition midas.h:290
int INT
Definition midas.h:129
#define JSFLAG_FOLLOW_LINKS
Definition midas.h:1722
#define JSFLAG_OMIT_LAST_WRITTEN
Definition midas.h:1726
#define DATABASE_VERSION
Definition midas.h:34
#define DEFAULT_BUFFER_SIZE
Definition midas.h:255
#define TRUE
Definition midas.h:182
#define EVENT_BUFFER_NAME
Definition midas.h:269
#define DEFAULT_ODB_SIZE
Definition midas.h:270
INT MUTEX_T
Definition midas.h:237
#define NAME_LENGTH
Definition midas.h:272
#define message(type, str)
#define read(n, a, f)
#define write(n, a, f, d)
#define mask(slot)
Definition midas_macro.h:54
#define name(x)
Definition midas_macro.h:24
HNDLE hBuf
Definition minife.c:23
INT rn
Definition mstat.cxx:30
int ls_abort
Definition odbedit.cxx:209
INT cmd_edit(const char *prompt, char *cmd, INT(*dir)(char *, INT *), INT(*idle)())
Definition cmdedit.cxx:38
void watch_callback(HNDLE hDB, HNDLE hKey, INT index, void *info)
Definition odbedit.cxx:1395
INT thread(void *p)
Definition odbedit.cxx:43
void ctrlc_odbedit(INT i)
Definition odbedit.cxx:2917
void compose_name(char *pwd, char *name, char *full_name)
Definition odbedit.cxx:1307
int print_message(const char *msg)
Definition odbedit.cxx:177
#define PI_HEX
Definition odbedit.cxx:36
BOOL check_abort(int flags, int l)
Definition odbedit.cxx:211
void set_key(HNDLE hDB, HNDLE hKey, int index1, int index2, char *value)
Definition odbedit.cxx:548
int ls_line
Definition odbedit.cxx:209
void print_help(char *command)
Definition odbedit.cxx:65
MUTEX_T * tm
Definition odbedit.cxx:39
#define PI_VALUE
Definition odbedit.cxx:35
BOOL in_cmd_edit
Definition odbedit.cxx:23
static void xwrite(const char *filename, int fd, const void *data, int size)
Definition odbedit.cxx:1073
void del_tree(HNDLE hDB, HNDLE hKey, INT level)
Definition odbedit.cxx:1051
INT cmd_dir(char *line, INT *cursor)
Definition odbedit.cxx:750
#define PI_RECURSIVE
Definition odbedit.cxx:34
void assemble_prompt(char *prompt, int psize, char *host_name, char *exp_name, char *pwd)
Definition odbedit.cxx:1319
char pwd[256]
Definition odbedit.cxx:24
INT cmd_idle()
Definition odbedit.cxx:1282
INT search_key(HNDLE hDB, HNDLE hKey, KEY *key, INT level, void *info)
Definition odbedit.cxx:1009
static void pad_to_pos(std::string *s, size_t pos)
Definition odbedit.cxx:243
void process_message(HNDLE hBuf, HNDLE id, EVENT_HEADER *pheader, void *message)
Definition odbedit.cxx:158
BOOL match(char *pat, char *str)
Definition odbedit.cxx:189
BOOL cmd_mode
Definition odbedit.cxx:25
BOOL need_redraw
Definition odbedit.cxx:22
#define PI_LONG
Definition odbedit.cxx:33
#define PI_PAUSE
Definition odbedit.cxx:37
void create_experim_h(HNDLE hDB, const char *analyzer_name)
Definition odbedit.cxx:1080
int command_loop(char *host_name, char *exp_name, char *cmd, char *start_dir)
Definition odbedit.cxx:1444
BOOL key_modified
Definition odbedit.cxx:57
void key_update(HNDLE hDB, HNDLE hkey, void *info)
Definition odbedit.cxx:59
INT print_key(HNDLE hDB, HNDLE hKey, KEY *pkey, INT level, void *info)
Definition odbedit.cxx:248
INT j
Definition odbhist.cxx:40
double value[100]
Definition odbhist.cxx:42
INT k
Definition odbhist.cxx:40
char str[256]
Definition odbhist.cxx:33
char file_name[256]
Definition odbhist.cxx:41
DWORD status
Definition odbhist.cxx:39
Definition midas.h:1027
INT num_values
Definition midas.h:1029
DWORD type
Definition midas.h:1028
WORD notify_count
Definition midas.h:1035
INT total_size
Definition midas.h:1032
WORD access_mode
Definition midas.h:1034
char name[NAME_LENGTH]
Definition midas.h:1030
INT item_size
Definition midas.h:1033
char pattern[32]
Definition odbedit.cxx:29
char c
Definition system.cxx:1312
static double pi(void)
Definition tinyexpr.c:135