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