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 size_t key_free, data_free, data_biggest;
2367 db_get_free_mem(hDB, &key_free, &data_free, &data_biggest);
2368 printf("ODB free keys: %zu, free data: %zu, biggest free data block: %zu\n", key_free, data_free, data_biggest);
2369#else
2370 printf("This MIDAS only works remotely\n");
2371#endif// LOCAL_ROUTINES
2372 }
2373 }
2374
2375 /* sor (show open records) */
2376 else if (param[0][0] == 's' && param[0][1] == 'o') {
2377 db_find_key(hDB, 0, pwd, &hKey);
2378 char data[50000];
2380 printf("%s", data);
2381 }
2382
2383 /* scl (show clients ) */
2384 else if (param[0][0] == 's' && param[0][1] == 'c') {
2385 status = db_find_key(hDB, 0, "System/Clients", &hKey);
2386 if (status != DB_SUCCESS)
2387 cm_msg(MERROR, "command_loop",
2388 "cannot find System/Clients entry in database");
2389 else {
2390 if (param[1][1] == 'w')
2391 printf("Name Host Timeout Last called\n");
2392 else
2393 printf("Name Host\n");
2394
2395 /* search database for clients with transition mask set */
2396 for (i = 0, status = 0;; i++) {
2399 break;
2400
2401 if (status == DB_SUCCESS) {
2402 size = sizeof(name);
2403 db_get_value(hDB, hSubkey, "Name", name, &size, TID_STRING, TRUE);
2404 printf("%s", name);
2405 for (int j = 0; j < 20 - (int) strlen(name); j++)
2406 printf(" ");
2407
2408 size = sizeof(str);
2409 db_get_value(hDB, hSubkey, "Host", str, &size, TID_STRING, TRUE);
2410 printf("%s", str);
2411 for (int j = 0; j < 20 - (int) strlen(str); j++)
2412 printf(" ");
2413
2414 /* display optional watchdog info */
2415 if (param[1][1] == 'w') {
2416 DWORD timeout, last;
2417
2418 status = cm_get_watchdog_info(hDB, name, &timeout, &last);
2419 printf("%-10d %-10d", timeout, last);
2420 }
2421
2422 printf("\n");
2423 }
2424 }
2425 }
2426 }
2427
2428 /* start */
2429 else if (param[0][0] == 's' && param[0][1] == 't' && param[0][2] == 'a') {
2430 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v') || (param[3][0] == '-' && param[3][1] == 'v'));
2431 mthread_flag = ((param[1][0] == '-' && param[1][1] == 'm') || (param[2][0] == '-' && param[2][1] == 'm') || (param[3][0] == '-' && param[3][1] == 'm'));
2432
2433 /* check if run is already started */
2434 size = sizeof(i);
2435 i = STATE_STOPPED;
2436 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2437 if (i == STATE_RUNNING) {
2438 printf("Run is already started\n");
2439 } else if (i == STATE_PAUSED) {
2440 printf("Run is paused, please use \"resume\"\n");
2441 } else {
2442 /* get present run number */
2443 old_run_number = 0;
2444 status = db_get_value(hDB, 0, "/Runinfo/Run number", &old_run_number, &size, TID_INT, TRUE);
2445 assert(status == SUCCESS);
2446 assert(old_run_number >= 0);
2447
2448 /* edit run parameter if command is not "start now" */
2449 if ((param[1][0] == 'n' && param[1][1] == 'o' && param[1][2] == 'w') || cmd_mode) {
2450 new_run_number = old_run_number + 1;
2451 line[0] = 'y';
2452 } else {
2453 db_find_key(hDB, 0, "/Experiment/Edit on start", &hKey);
2454 do {
2455 if (hKey) {
2456 for (i = 0;; i++) {
2458
2459 if (!hSubkey)
2460 break;
2461
2463 std::string str = key.name;
2464
2465 if (equal_ustring(str.c_str(), "Edit run number"))
2466 continue;
2467
2468 if (str.find("Options ") == 0)
2469 continue;
2470
2473
2474 assert(key.total_size > 0);
2475 char *buf = (char *) malloc(key.total_size);
2476
2477 size = key.total_size;
2478 status = db_get_data(hDB, hSubkey, buf, &size, key.type);
2479 if (status != DB_SUCCESS) {
2480 free(buf);
2481 continue;
2482 }
2483
2484 for (int j = 0; j < key.num_values; j++) {
2485 std::string xdata_str = db_sprintf(buf, key.item_size, j, key.type);
2486 std::string xprompt;
2487 xprompt += str;
2488 if (key.num_values == 1) {
2489 xprompt += " : ";
2490 } else {
2491 xprompt += msprintf("[%d] : ", j);
2492 }
2493
2494 strcpy(line, xdata_str.c_str());// FIXME: buffer overflow. K.O. aug2024
2495 in_cmd_edit = TRUE;
2496 cmd_edit(xprompt.c_str(), line, NULL, cmd_idle);
2498
2499 if (line[0]) {
2500 db_sscanf(line, buf, &size, j, key.type);
2502 }
2503 }
2504
2505 free(buf);
2506 }
2507 }
2508
2509 /* increment run number */
2510 new_run_number = old_run_number + 1;
2511
2512 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) {
2513 printf("Run number: %d\n", new_run_number);
2514 } else {
2515
2516 printf("Run number [%d]: ", new_run_number);
2517 ss_gets(line, 256);
2518 if (line[0] && atoi(line) > 0)
2519 new_run_number = atoi(line);
2520 }
2521
2522 printf("Are the above parameters correct? ([y]/n/q): ");
2523 ss_gets(line, 256);
2524
2525 } while (line[0] == 'n' || line[0] == 'N');
2526 }
2527
2528 if (line[0] != 'q' && line[0] != 'Q') {
2529 /* start run */
2530 printf("Starting run #%d\n", new_run_number);
2531
2532 assert(new_run_number > 0);
2533
2534 status = cm_transition(TR_START, new_run_number, str,
2535 sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2536 if (status != CM_SUCCESS) {
2537 /* in case of error, reset run number */
2538 status =
2539 db_set_value(hDB, 0, "/Runinfo/Run number", &old_run_number,
2540 sizeof(old_run_number), 1, TID_INT);
2541 assert(status == SUCCESS);
2542
2543 printf("Error: %s\n", str);
2544 }
2545 }
2546 }
2547 }
2548
2549 /* stop */
2550 else if (param[0][0] == 's' && param[0][1] == 't' && param[0][2] == 'o') {
2551 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v') || (param[3][0] == '-' && param[3][1] == 'v'));
2552 mthread_flag = ((param[1][0] == '-' && param[1][1] == 'm') || (param[2][0] == '-' && param[2][1] == 'm') || (param[3][0] == '-' && param[3][1] == 'm'));
2553
2554 /* check if run is stopped */
2556 size = sizeof(i);
2557 db_get_value(hDB, 0, "/Runinfo/State", &state, &size, TID_INT, TRUE);
2558 str[0] = 0;
2559 if (state == STATE_STOPPED && !cmd_mode) {
2560 printf("Run is already stopped. Stop again? (y/[n]) ");
2561 ss_gets(str, 256);
2562 }
2563 if (str[0] == 'y' || state != STATE_STOPPED || cmd_mode) {
2564 if (param[1][0] == 'n')
2565 status =
2566 cm_transition(TR_STOP | TR_DEFERRED, 0, str, sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2567 else
2568 status = cm_transition(TR_STOP, 0, str, sizeof(str), mthread_flag ? TR_MTHREAD | TR_SYNC : TR_SYNC, debug_flag);
2569
2571 printf("%s\n", str);
2573 printf("Deferred stop already in progress, enter \"stop now\" to force stop\n");
2574 else if (status != CM_SUCCESS)
2575 printf("Error: %s\n", str);
2576 }
2577 }
2578
2579 /* pause */
2580 else if (param[0][0] == 'p' && param[0][1] == 'a' && param[0][2] == 'u') {
2581 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v'));
2582
2583 /* check if run is started */
2584 i = STATE_STOPPED;
2585 size = sizeof(i);
2586 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2587 if (i != STATE_RUNNING) {
2588 printf("Run is not started\n");
2589 } else {
2590 if (param[1][0] == 'n')
2591 status = cm_transition(TR_PAUSE | TR_DEFERRED, 0, str, sizeof(str), TR_SYNC, debug_flag);
2592 else
2593 status = cm_transition(TR_PAUSE, 0, str, sizeof(str), TR_SYNC, debug_flag);
2594
2596 printf("%s\n", str);
2598 printf("Deferred pause already in progress, enter \"pause now\" to force pause\n");
2599 else if (status != CM_SUCCESS)
2600 printf("Error: %s\n", str);
2601 }
2602 }
2603
2604 /* resume */
2605 else if (param[0][0] == 'r' && param[0][1] == 'e' && param[0][2] == 's') {
2606 debug_flag = ((param[1][0] == '-' && param[1][1] == 'v') || (param[2][0] == '-' && param[2][1] == 'v'));
2607
2608 /* check if run is paused */
2609 i = STATE_STOPPED;
2610 size = sizeof(i);
2611 db_get_value(hDB, 0, "/Runinfo/State", &i, &size, TID_INT, TRUE);
2612 if (i != STATE_PAUSED) {
2613 printf("Run is not paused\n");
2614 } else {
2615 status = cm_transition(TR_RESUME, 0, str, sizeof(str), TR_SYNC, debug_flag);
2616 if (status != CM_SUCCESS)
2617 printf("Error: %s\n", str);
2618 }
2619 }
2620
2621 /* msg */
2622 else if (param[0][0] == 'm' && param[0][1] == 's') {
2623 // param[1]: facility, param[2]: type, param[3]: name param[4]: message
2624 if (!param[4][0]) {
2625 printf("Error: Not enough parameters. Please use\n\n");
2626 printf(" msg <facility> <type> <name> <message>\n\n");
2627 printf("where <facility> can be \"midas\", \"chat\", ...\n");
2628 printf("and <type> must be \"error\", \"info\", \"debug\", \"user\", \"log\", \"talk\" or \"call\".\n");
2629 } else {
2630 int type = 0;
2632 type = MT_ERROR;
2634 type = MT_INFO;
2636 type = MT_DEBUG;
2638 type = MT_USER;
2640 type = MT_LOG;
2642 type = MT_TALK;
2644 type = MT_CALL;
2645 if (type == 0) {
2646 printf("Error: inavlid type \"%s\".\n", param[2]);
2647 printf("<type> must be one of \"error\", \"info\", \"debug\", \"user\", \"log\", \"talk\", \"call\".\n");
2648 } else {
2649
2650 cm_msg1(type, __FILE__, __LINE__, param[1], param[3], "%s", param[4]);
2651 last_msg_time = ss_time();
2652 }
2653 }
2654 }
2655
2656 /* chat */
2657 else if (param[0][0] == 'c' && param[0][1] == 'h' && param[0][2] == 'a') {
2658 message[0] = 0;
2659
2660 if (ss_time() - last_msg_time > 300) {
2661 printf("Your name> ");
2662 ss_gets(user_name, 80);
2663 }
2664
2665 printf("Exit chat mode with empty line.\n");
2666 do {
2667 in_cmd_edit = TRUE;
2668 message[0] = 0;
2669 cmd_edit("> ", message, NULL, cmd_idle);
2671
2672 if (message[0])
2673 cm_msg1(MUSER, "chat", user_name, "%s", message);
2674
2675 } while (message[0]);
2676
2677 last_msg_time = ss_time();
2678 }
2679
2680 /* old */
2681 else if (param[0][0] == 'o' && param[0][1] == 'l') {
2682 i = 20;
2683 if (param[1][0])
2684 i = atoi(param[1]);
2685
2686 char data[50000];
2687 cm_msg_retrieve(i, data, sizeof(data));
2688 printf("%s\n\n", data);
2689 }
2690
2691 /* cleanup */
2692 else if (param[0][0] == 'c' && param[0][1] == 'l') {
2693 HNDLE hBuf;
2694 BOOL force;
2695
2696 force = FALSE;
2697 if (param[1][0] == '-' && param[1][1] == 'f')
2698 force = TRUE;
2699 if (param[2][0] == '-' && param[2][1] == 'f')
2700 force = TRUE;
2701
2703
2704 if (param[1][0] && param[1][0] != '-')
2705 cm_cleanup(param[1], force);
2706 else
2707 cm_cleanup("", force);
2709 }
2710
2711 /* shutdown */
2712 else if (param[0][0] == 's' && param[0][1] == 'h') {
2713 if (param[1][0] == 0)
2714 printf("Please enter client name or \"all\" to shutdown all clients.\n");
2715 else {
2717 if (status != CM_SUCCESS) {
2718 if (strcmp(param[1], "all") == 0)
2719 printf("No clients found\n");
2720 else
2721 printf("Client \"%s\" not active\n", param[1]);
2722 }
2723 }
2724 }
2725
2726 /* ver */
2727 else if (param[0][0] == 'v' && param[0][1] == 'e') {
2728 printf("MIDAS version: %s\n", cm_get_version());
2729 printf("GIT revision: %s\n", cm_get_revision());
2730 printf("ODB version: %d\n", DATABASE_VERSION);
2731 }
2732
2733 /* exec */
2734 else if (param[0][0] == 'e' && param[0][1] == 'x' && param[0][2] == 'e') {
2735 compose_name(pwd, param[1], str);
2736 char data[50000];
2737 status = db_find_key(hDB, 0, str, &hKey);
2738 if (status == DB_SUCCESS) {
2739 db_get_key(hDB, hKey, &key);
2740 if (key.type != TID_STRING) {
2741 printf("Key contains no command\n");
2742 continue;
2743 }
2744 size = sizeof(str);
2745 db_get_data(hDB, hKey, str, &size, key.type);
2746
2747 cm_execute(str, data, sizeof(data));
2748 } else {
2749 cm_execute(param[1], data, sizeof(data));
2750 }
2751 puts(data);
2752 }
2753
2754 /* wait */
2755 else if (param[0][0] == 'w' && param[0][1] == 'a' && param[0][2] == 'i') {
2756 if (param[1][0] == 0) {
2757 printf("Please specify key\n");
2758 } else {
2759 compose_name(pwd, param[1], str);
2760
2761 if (equal_ustring(str, "/")) {
2763 status = db_find_link(hDB, 0, "/", &hKey);
2764 } else
2765 status = db_find_link(hDB, 0, str, &hKey);
2766
2767 if (status == DB_SUCCESS) {
2768 db_get_key(hDB, hKey, &key);
2769 printf("Waiting for key \"%s\" to be modified, abort with any key\n", key.name);
2770 db_get_record_size(hDB, hKey, 0, &size);
2771 char *buf = (char *) malloc(size);
2773 db_open_record(hDB, hKey, buf, size, MODE_READ, key_update, NULL);
2774
2775 do {
2776 status = cm_yield(1000);
2777 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2778 break;
2779 } while (!key_modified && !ss_kbhit());
2780
2781 while (ss_kbhit())
2782 ss_getchar(0);
2783
2785 if (buf) {
2786 free(buf);
2787 buf = NULL;
2788 }
2789
2790 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2791 break;
2792
2793 if (i == '!')
2794 printf("Wait aborted.\n");
2795 else
2796 printf("Key has been modified.\n");
2797 } else
2798 printf("key \"%s\" not found\n", str);
2799 }
2800 }
2801
2802 /* watch */
2803 else if (param[0][0] == 'w' && param[0][1] == 'a' && param[0][2] == 't') {
2804 if (param[1][0] == 0) {
2805 printf("Please specify key\n");
2806 } else {
2807 compose_name(pwd, param[1], str);
2808
2809 status = db_find_link(hDB, 0, str, &hKey);
2810 if (status == DB_SUCCESS) {
2811 db_get_key(hDB, hKey, &key);
2812 if (key.type != TID_KEY)
2813 printf("Watch key \"%s\" to be modified, abort with any key\n", str);
2814 else
2815 printf("Watch ODB tree \"%s\" to be modified, abort with any key\n", str);
2817
2818 do {
2819 status = cm_yield(1000);
2820 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2821 break;
2822 } while (!ss_kbhit());
2823
2824 while (ss_kbhit())
2825 ss_getchar(0);
2826
2828
2829 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2830 break;
2831 } else
2832 printf("key \"%s\" not found\n", str);
2833 }
2834 }
2835
2836 /* test 1 */
2837 else if (param[0][0] == 't' && param[0][1] == '1') {
2838 DWORD start_time;
2839 INT i, size, rn;
2840 HNDLE hKey;
2841
2842 start_time = ss_millitime();
2843 status = db_find_key(hDB, 0, "/runinfo/run number", &hKey);
2844 assert(status == SUCCESS);
2845 size = sizeof(rn);
2846
2847 i = 0;
2848 do {
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 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2857 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2858 db_get_data(hDB, hKey, &rn, &size, TID_INT);
2859 i += 10;
2860 } while (ss_millitime() - start_time < 5000);
2861
2862 printf("%d accesses per second\n", i / 5);
2863 }
2864
2865 /* test 2 */
2866 else if (param[0][0] == 't' && param[0][1] == '2') {
2867 do {
2868 do {
2869 i = ss_getchar(0);
2870 printf("%d\n", i);
2871 } while (i > 0 && i != 4);
2872
2873 ss_sleep(1000);
2874 } while (i != 4);
2875
2876 ss_getchar(1);
2877 }
2878
2879 /* test 3 */
2880 else if (param[0][0] == 't' && param[0][1] == '3') {
2881#ifdef USE_ADDRESS_SANITIZER
2882 // test address sanitizer
2883 int *a = (int *) malloc(sizeof(int) * 10);
2884 i = a[11];
2885 free(a);
2886#else
2887 printf("test address sanitizer is disabled!\n");
2888#endif
2889 }
2890
2891 /* exit/quit */
2892 else if ((param[0][0] == 'e' && param[0][1] == 'x' && param[0][2] == 'i') || (param[0][0] == 'q'))
2893 break;
2894
2895 else if (param[0][0] == 0)
2896 ;
2897
2898 else
2899 printf("Unknown command %s %s %s\n", param[0], param[1], param[2]);
2900
2901 /* exit after single command */
2902 if (cmd_mode && cmd[0] != '@')
2903 break;
2904
2905 /* check if client connections are broken */
2906 status = cm_yield(0);
2907 if (status == SS_ABORT || status == RPC_SHUTDOWN)
2908 break;
2909
2910 } while (TRUE);
2911
2912 /* check if client connections are broken */
2913 status = cm_yield(0);
2914
2915 return 1; /* indicate success */
2916}
2917
2918/*------------------------------------------------------------------*/
2919
2921 /* reset terminal */
2922 ss_getchar(1);
2923
2924 /* no shutdown message */
2925 cm_set_msg_print(MT_ERROR, 0, NULL);
2926
2928
2929 printf("\n");
2930 exit(EXIT_SUCCESS);
2931}
2932
2933/*------------------------------------------------------------------*/
2934
2935#ifdef OS_VXWORKS
2936int odbedit(char *ahost_name, char *aexp_name)
2937#else
2938int main(int argc, char *argv[])
2939#endif
2940{
2941 INT status, i, odb_size, size;
2943 char cmd[2000], dir[256];
2944 BOOL debug;
2945 BOOL quiet;
2946 BOOL corrupted;
2947 BOOL reload_from_file = FALSE;
2948 HNDLE hDB;
2949
2950 cmd[0] = dir[0] = 0;
2952 debug = corrupted = cmd_mode = quiet = FALSE;
2953
2954#ifdef OS_VXWORKS
2955 strcpy(host_name, ahost_name);
2956 strcpy(exp_name, aexp_name);
2957#else
2958
2959 /* get default from environment */
2961
2962 /* check for MIDASSYS */
2963 if (!getenv("MIDASSYS")) {
2964 puts("Please define environment variable 'MIDASSYS'");
2965 puts("pointing to the midas source installation directory.");
2966 }
2967
2968 /* parse command line parameters */
2969 for (i = 1; i < argc; i++) {
2970 if (argv[i][0] == '-' && argv[i][1] == 'g')
2971 debug = TRUE;
2972 else if (argv[i][0] == '-' && argv[i][1] == 'q')
2973 quiet = TRUE;
2974 else if (argv[i][0] == '-' && argv[i][1] == 'R')
2975 reload_from_file = TRUE;
2976 else if (argv[i][0] == '-' && argv[i][1] == 'C')
2977 corrupted = TRUE;
2978 else if (argv[i][0] == '-') {
2979 if (i + 1 >= argc || argv[i + 1][0] == '-')
2980 goto usage;
2981 if (argv[i][1] == 'e')
2982 strcpy(exp_name, argv[++i]);
2983 else if (argv[i][1] == 'h')
2984 strcpy(host_name, argv[++i]);
2985 else if (argv[i][1] == 'c') {
2986 if (strlen(argv[i + 1]) >= sizeof(cmd)) {
2987 printf("error: command line too long (>%d bytes)\n", (int) sizeof(cmd));
2988 return 0;
2989 }
2990 mstrlcpy(cmd, argv[++i], sizeof(cmd));
2991 cmd_mode = TRUE;
2992 } else if (argv[i][1] == 'd')
2993 mstrlcpy(dir, argv[++i], sizeof(dir));
2994 else if (argv[i][1] == 's')
2995 odb_size = atoi(argv[++i]);
2996 else {
2997 usage:
2998 printf("usage: odbedit [-h Hostname] [-e Experiment] [-d ODB Subtree]\n");
2999 printf(" [-q] [-c Command] [-c @CommandFile] [-s size]\n");
3000 printf(" [-g (debug)] [-C (connect to corrupted ODB)]\n");
3001 printf(" [-R (reload ODB from .ODB.SHM)]\n\n");
3002 printf("For a list of valid commands start odbedit interactively\n");
3003 printf("and type \"help\".\n");
3004 return 0;
3005 }
3006 } else
3007 mstrlcpy(host_name, argv[i], sizeof(host_name));
3008 }
3009#endif
3010
3011 if (reload_from_file) {
3012#ifdef LOCAL_ROUTINES
3014 if (status != CM_SUCCESS) {
3015 printf("Cannot setup experiment name and path.\n");
3016 return 1;
3017 }
3018 status = ss_shm_delete("ODB");
3019 printf("MIDAS ODB shared memory was deleted, ss_shm_delete(ODB) status %d\n", status);
3020 printf("Please run odbedit again without \'-R\' and ODB will be reloaded from .ODB.SHM\n");
3021 return 1;
3022#else
3023 printf("This odbedit only works remotely, -R is not supported\n");
3024 return 1;
3025#endif
3026 }
3027
3028 /* no startup message if called with command */
3029 if (cmd[0])
3030 cm_set_msg_print(MT_ERROR, 0, NULL);
3031
3032 status = cm_connect_experiment1(host_name, exp_name, "ODBEdit", NULL,
3034
3035 if (host_name[0])
3036 printf("Connected to MIDAS server \"%s\" experiment \"%s\"\n", host_name, exp_name);
3037
3039 return 1;
3040
3042
3043 if ((status == DB_INVALID_HANDLE) && corrupted) {
3044 std::string s = cm_get_error(status);
3045 puts(s.c_str());
3046 printf("ODB is corrupted, connecting anyway...\n");
3047 } else if (status != CM_SUCCESS) {
3048 std::string s = cm_get_error(status);
3049 puts(s.c_str());
3050 return 1;
3051 }
3052
3053 /* place a request for system messages */
3055
3056 /* route local messages through print_message */
3058
3059 /* turn off watchdog if in debug mode */
3060 if (debug)
3062
3063 /* get experiment name */
3064 if (!exp_name[0]) {
3066 size = NAME_LENGTH;
3067 db_get_value(hDB, 0, "/Experiment/Name", exp_name, &size, TID_STRING, TRUE);
3068 }
3069
3070 /* register Ctrl-C handler */
3072
3073 /* for use with the mac os profiler */
3074 //cmd_mode = TRUE;
3075 //status = command_loop(host_name, exp_name, "save xxx3.json", dir);
3076
3077 /* log all commands passed via -c on command line */
3078 if (cmd_mode && !quiet)
3079 cm_msg(MINFO, "odbedit", "Execute command from command line: \"%s\"", cmd);
3080
3081 /* command loop */
3082 status = command_loop(host_name, exp_name, cmd, dir);
3083
3084 /* no shutdown message if called with command */
3085 if (cmd_mode)
3086 cm_set_msg_print(MT_ERROR, 0, NULL);
3087
3089
3090 if (status != 1)
3091 return EXIT_FAILURE;
3092
3093 return EXIT_SUCCESS;
3094}
3095
3096/* emacs
3097 * Local Variables:
3098 * tab-width: 8
3099 * c-basic-offset: 3
3100 * indent-tabs-mode: nil
3101 * End:
3102 */
#define FALSE
Definition cfortran.h:309
static void usage()
INT al_reset_alarm(const char *alarm_name)
Definition alarm.cxx:519
INT bm_open_buffer(const char *buffer_name, INT buffer_size, INT *buffer_handle)
Definition midas.cxx:6728
INT bm_close_buffer(INT buffer_handle)
Definition midas.cxx:7116
INT cm_shutdown(const char *name, BOOL bUnique)
Definition midas.cxx:7420
INT cm_yield(INT millisec)
Definition midas.cxx:5660
INT cm_get_experiment_database(HNDLE *hDB, HNDLE *hKeyClient)
Definition midas.cxx:3027
INT cm_connect_client(const char *client_name, HNDLE *hConn)
Definition midas.cxx:2782
INT cm_transition(INT transition, INT run_number, char *errstr, INT errstr_size, INT async_flag, INT debug_flag)
Definition midas.cxx:5304
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:2313
void cm_ack_ctrlc_pressed()
Definition midas.cxx:5474
INT cm_execute(const char *command, char *result, INT bufsize)
Definition midas.cxx:5741
INT cm_get_watchdog_info(HNDLE hDB, const char *client_name, DWORD *timeout, DWORD *last)
Definition midas.cxx:3360
INT cm_cleanup(const char *client_name, BOOL ignore_timeout)
Definition midas.cxx:7630
INT cm_disconnect_experiment(void)
Definition midas.cxx:2862
int cm_set_experiment_local(const char *exp_name)
Definition midas.cxx:2182
INT cm_get_environment(char *host_name, int host_name_size, char *exp_name, int exp_name_size)
Definition midas.cxx:2150
const char * cm_get_version()
Definition midas.cxx:1492
const char * cm_get_revision()
Definition midas.cxx:1500
BOOL cm_is_ctrlc_pressed()
Definition midas.cxx:5470
INT cm_set_watchdog_params(BOOL call_watchdog, DWORD timeout)
Definition midas.cxx:3299
#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:3743
DWORD ss_millitime()
Definition system.cxx:3472
INT ss_shm_delete(const char *name)
Definition system.cxx:911
INT ss_getchar(BOOL reset)
Definition system.cxx:7588
std::string ss_getcwd()
Definition system.cxx:5855
char * ss_getpass(const char *prompt)
Definition system.cxx:7525
std::string ss_tid_to_string(midas_thread_t thread_id)
Definition system.cxx:1643
DWORD ss_time()
Definition system.cxx:3541
midas_thread_t ss_gettid(void)
Definition system.cxx:1591
INT ss_sleep(INT millisec)
Definition system.cxx:3707
char * ss_crypt(const char *buf, const char *salt)
Definition system.cxx:7976
char * ss_gets(char *string, int size)
Definition system.cxx:7855
void * ss_ctrlc_handler(void(*func)(int))
Definition system.cxx:3978
INT cm_msg1(INT message_type, const char *filename, INT line, const char *facility, const char *routine, const char *format,...)
Definition midas.cxx:989
INT cm_msg_register(EVENT_HANDLER *func)
Definition midas.cxx:1067
INT cm_msg_flush_buffer()
Definition midas.cxx:881
std::string cm_get_error(INT code)
Definition midas.cxx:469
INT cm_msg(INT message_type, const char *filename, INT line, const char *routine, const char *format,...)
Definition midas.cxx:931
INT cm_msg_retrieve(INT n_message, char *message, INT buf_size)
Definition midas.cxx:1350
INT cm_set_msg_print(INT system_mask, INT user_mask, int(*func)(const char *))
Definition midas.cxx:661
BOOL equal_ustring(const char *str1, const char *str2)
Definition odb.cxx:3780
INT db_sprintfh(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:11566
INT db_get_data_index(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, INT idx, DWORD type)
Definition odb.cxx:7412
INT db_delete_key(HNDLE hDB, HNDLE hKey, BOOL follow_links)
Definition odb.cxx:4428
INT db_find_link(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4788
INT db_get_value(HNDLE hDB, HNDLE hKeyRoot, const char *key_name, void *data, INT *buf_size, DWORD type, BOOL create)
Definition odb.cxx:5680
INT db_reorder_key(HNDLE hDB, HNDLE hKey, INT idx)
Definition odb.cxx:6880
INT db_save_json(HNDLE hDB, HNDLE hKey, const char *filename, int flags)
Definition odb.cxx:11109
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:13883
INT db_get_open_records(HNDLE hDB, HNDLE hKey, char *str, INT buf_size, BOOL fix)
Definition odb.cxx:5450
INT db_save_xml(HNDLE hDB, HNDLE hKey, const char *filename)
Definition odb.cxx:9998
INT db_set_link_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7944
INT db_get_path(HNDLE hDB, HNDLE hKey, char *path, INT buf_size)
Definition odb.cxx:5270
INT db_copy(HNDLE hDB, HNDLE hKey, char *buffer, INT *buffer_size, const char *path)
Definition odb.cxx:8725
INT db_set_link_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:8268
std::string db_show_mem(HNDLE hDB, BOOL verbose)
Definition odb.cxx:812
INT db_get_record_size(HNDLE hDB, HNDLE hKey, INT align, INT *buf_size)
Definition odb.cxx:12201
INT db_get_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:7058
INT db_create_key(HNDLE hDB, HNDLE hKey, const char *key_name, DWORD type)
Definition odb.cxx:3887
INT db_copy_json_save(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:11057
INT db_save_struct(HNDLE hDB, HNDLE hKey, const char *file_name, const char *struct_name, BOOL append)
Definition odb.cxx:11209
INT db_unwatch(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:14481
INT db_set_mode(HNDLE hDB, HNDLE hKey, WORD mode, BOOL recurse)
Definition odb.cxx:8535
INT db_save(HNDLE hDB, HNDLE hKey, const char *filename, BOOL bRemote)
Definition odb.cxx:9758
INT db_scan_tree(HNDLE hDB, HNDLE hKey, INT level, INT(*callback)(HNDLE, HNDLE, KEY *, INT, void *), void *info)
Definition odb.cxx:5039
INT db_get_key(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6538
INT db_get_link(HNDLE hDB, HNDLE hKey, KEY *key)
Definition odb.cxx:6591
INT db_load(HNDLE hDB, HNDLE hKeyRoot, const char *filename, BOOL bRemote)
Definition odb.cxx:8634
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:14528
INT db_set_data_index(HNDLE hDB, HNDLE hKey, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:8163
INT db_save_string(HNDLE hDB, HNDLE hKey, const char *file_name, const char *string_name, BOOL append)
Definition odb.cxx:11270
INT db_paste(HNDLE hDB, HNDLE hKeyRoot, const char *buffer)
Definition odb.cxx:9000
INT db_watch(HNDLE hDB, HNDLE hKey, void(*dispatcher)(INT, INT, INT, void *), void *info)
Definition odb.cxx:14406
INT db_set_data(HNDLE hDB, HNDLE hKey, const void *data, INT buf_size, INT num_values, DWORD type)
Definition odb.cxx:7734
INT db_enum_link(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5990
INT db_copy_json_ls(HNDLE hDB, HNDLE hKey, char **buffer, int *buffer_size, int *buffer_end)
Definition odb.cxx:11003
void name2c(char *str)
Definition odb.cxx:9610
INT db_sprintf(char *string, const void *data, INT data_size, INT idx, DWORD type)
Definition odb.cxx:11426
INT db_get_free_mem(HNDLE hDB, size_t *pkey_size, size_t *pdata_size, size_t *pdata_biggest)
Definition odb.cxx:925
void strarrayindex(char *odbpath, int *index1, int *index2)
Definition odb.cxx:3852
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:11025
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:5523
INT db_find_key(HNDLE hDB, HNDLE hKey, const char *key_name, HNDLE *subhKey)
Definition odb.cxx:4751
INT db_get_link_data(HNDLE hDB, HNDLE hKey, void *data, INT *buf_size, DWORD type)
Definition odb.cxx:7175
INT db_rename_key(HNDLE hDB, HNDLE hKey, const char *name)
Definition odb.cxx:6780
INT db_get_key_time(HNDLE hDB, HNDLE hKey, DWORD *delta)
Definition odb.cxx:6651
INT db_find_keys(HNDLE hDB, HNDLE hKeyRoot, const char *odbpath, std::vector< HNDLE > &hKeyVector)
Definition odb.cxx:4847
INT db_enum_key(HNDLE hDB, HNDLE hKey, INT idx, HNDLE *subkey_handle)
Definition odb.cxx:5852
INT db_close_record(HNDLE hDB, HNDLE hKey)
Definition odb.cxx:14066
INT db_sscanf(const char *data_str, void *data, INT *data_size, INT i, DWORD tid)
Definition odb.cxx:11897
INT db_set_num_values(HNDLE hDB, HNDLE hKey, INT num_values)
Definition odb.cxx:8018
INT db_create_link(HNDLE hDB, HNDLE hKey, const char *link_name, const char *destination)
Definition odb.cxx:4183
INT rpc_client_call(HNDLE hConn, DWORD routine_id,...)
Definition midas.cxx:13935
bool rpc_is_remote(void)
Definition midas.cxx:12901
int rpc_test_rpc()
Definition midas.cxx:16540
void rpc_client_check()
Definition midas.cxx:12410
const char * rpc_tid_name(INT id)
Definition midas.cxx:11904
#define RPC_ANA_CLEAR_HISTOS
Definition mrpc.h:119
INT rpc_tid_size(INT id)
Definition midas.cxx:11897
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:1712
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:1711
#define JSFLAG_OMIT_LAST_WRITTEN
Definition midas.h:1715
#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:2920
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