Line data Source code
1 : /********************************************************************\
2 :
3 : Name: mserver.c
4 : Created by: Stefan Ritt
5 :
6 : Contents: Server program for midas RPC calls
7 :
8 : $Id$
9 :
10 : \********************************************************************/
11 :
12 : #undef NDEBUG // midas required assert() to be always enabled
13 :
14 : #include "midas.h"
15 : #include "msystem.h"
16 : #include "mstrlcpy.h"
17 :
18 : #ifdef OS_UNIX
19 : #include <sys/types.h>
20 : #endif
21 :
22 : struct callback_addr callback;
23 :
24 : BOOL use_callback_addr = TRUE;
25 :
26 : INT rpc_server_dispatch(INT index, void *prpc_param[]);
27 :
28 : /*---- debug_print -------------------------------------------------*/
29 :
30 0 : void debug_print(const char *msg)
31 : {
32 0 : std::string file_name;
33 0 : static std::string client_name;
34 : static DWORD start_time = 0;
35 :
36 0 : if (!start_time)
37 0 : start_time = ss_millitime();
38 :
39 : /* print message to file */
40 : #ifdef OS_LINUX
41 0 : file_name = "/tmp/mserver.log";
42 : #else
43 : file_name = ss_getcwd();
44 : if (!ends_with_char(file_name, DIR_SEPARATOR)) {
45 : file_name += DIR_SEPARATOR_STRING;
46 : }
47 : file_name += "mserver.log";
48 : #endif
49 :
50 0 : FILE *f = fopen(file_name.c_str(), "a");
51 :
52 0 : if (!f) {
53 0 : fprintf(stderr, "Cannot open \"%s\", errno %d (%s)\n", file_name.c_str(), errno, strerror(errno));
54 0 : return;
55 : }
56 :
57 0 : if (client_name.empty())
58 0 : client_name = cm_get_client_name();
59 :
60 0 : std::string str = msprintf("%10.3lf [%d,%s,%s] ", (ss_millitime() - start_time) / 1000.0,
61 0 : ss_getpid(), callback.host_name.c_str(), client_name.c_str());
62 0 : str += msg;
63 0 : str += "\n";
64 :
65 0 : fputs(str.c_str(), f);
66 0 : fclose(f);
67 0 : }
68 :
69 : /*---- main --------------------------------------------------------*/
70 :
71 0 : int main(int argc, char **argv)
72 : /********************************************************************\
73 :
74 : Routine: main (server.exe)
75 :
76 : Purpose: Main routine for MIDAS server process. If called one
77 : parameter, it listens for a connection under
78 : MIDAS_TCP_PORT. If a connection is requested, the action
79 : depends on the parameter:
80 :
81 : 0: Single process server: This process executes RPC calls
82 : even if there are several connections.
83 :
84 : 1: Multi thread server (only Windows NT): For each conn-
85 : ection, a seperate thread is started which servers this
86 : connection.
87 :
88 : 2: Multi process server (Not MS-DOS): For each conn-
89 : ection, a seperate subprocess is started which servers
90 : this connection. The subprocess is again server.exe, now
91 : with four parameters: the IP address of the calling
92 : host, the two port numbers used by the calling
93 : host and optionally the name of the experiment to connect
94 : to. With this information it calles back the client.
95 :
96 : This technique is necessary since the usual fork() doesn't
97 : work on some of the supported systems.
98 :
99 : Input:
100 : int argc Number of parameters in command line
101 : char **argv Command line parameters:
102 :
103 : ip-addr callback address as longword
104 : port-no port number
105 : program program name as string
106 : experiment experiment name as string
107 :
108 :
109 : Output:
110 : none
111 :
112 : Function value:
113 : BM_SUCCESS Successful completion
114 :
115 : \********************************************************************/
116 : {
117 : int i, flag;
118 : socklen_t size;
119 : //char name[256];
120 : char str[1000];
121 : BOOL inetd, daemon, debug;
122 :
123 : #if defined(SIGPIPE) && defined(SIG_IGN)
124 0 : signal(SIGPIPE, SIG_IGN);
125 : #endif
126 :
127 0 : setbuf(stdout, NULL);
128 0 : setbuf(stderr, NULL);
129 :
130 : ///* save executable file name */
131 : //if (argv[0] == NULL || argv[0][0] == 0)
132 : // mstrlcpy(name, "mserver", sizeof(name));
133 : //else
134 : // mstrlcpy(name, argv[0], sizeof(name));
135 :
136 : #ifdef OS_UNIX
137 : ///* if no full path given, assume /usr/local/bin */
138 : //if (strchr(name, '/') == 0) {
139 : // mstrlcpy(str, "/usr/local/bin/", sizeof(str));
140 : // mstrlcat(str, name, sizeof(str));
141 : // mstrlcpy(name, str, sizeof(name));
142 : //}
143 : #endif
144 :
145 : #if 0
146 : printf("mserver main, name [%s]\n", name);
147 : for (i=0; i<=argc; i++)
148 : printf("argv[%d] is [%s]\n", i, argv[i]);
149 : system("/bin/ls -la /proc/self/fd");
150 : #endif
151 :
152 0 : if (getenv("MIDAS_MSERVER_DO_NOT_USE_CALLBACK_ADDR"))
153 0 : use_callback_addr = FALSE;
154 :
155 : //rpc_set_mserver_path(name);
156 :
157 : /* find out if we were started by inetd */
158 0 : size = sizeof(int);
159 0 : inetd = (getsockopt(0, SOL_SOCKET, SO_TYPE, (void *) &flag, &size) == 0);
160 :
161 : /* check for debug flag */
162 0 : debug = FALSE;
163 0 : for (i = 1; i < argc; i++)
164 0 : if (argv[i][0] == '-' && argv[i][1] == 'd')
165 0 : debug = TRUE;
166 :
167 0 : if (debug) {
168 0 : debug_print("mserver startup");
169 0 : for (i = 0; i < argc; i++)
170 0 : debug_print(argv[i]);
171 0 : rpc_set_debug(debug_print, 1);
172 : }
173 :
174 0 : if (argc < 7 && inetd) {
175 : /* accept connection from stdin */
176 0 : rpc_server_accept(0);
177 0 : return 0;
178 : }
179 :
180 0 : if (!inetd && argc < 7)
181 0 : printf("%s started interactively\n", argv[0]);
182 :
183 0 : debug = daemon = FALSE;
184 :
185 0 : if (argc < 7 || argv[1][0] == '-') {
186 : int status;
187 : char expt_name[NAME_LENGTH];
188 0 : int port = 0;
189 :
190 : /* Get if existing the pre-defined experiment */
191 0 : expt_name[0] = 0;
192 0 : cm_get_environment(NULL, 0, expt_name, sizeof(expt_name));
193 :
194 : /* parse command line parameters */
195 0 : for (i = 1; i < argc; i++) {
196 0 : if (strncmp(argv[i], "-e", 2) == 0) {
197 0 : mstrlcpy(expt_name, argv[++i], sizeof(expt_name));
198 0 : } else if (argv[i][0] == '-' && argv[i][1] == 'd')
199 0 : debug = TRUE;
200 0 : else if (argv[i][0] == '-' && argv[i][1] == 'D')
201 0 : daemon = TRUE;
202 0 : else if (argv[i][0] == '-' && argv[i][1] == 'p')
203 0 : port = strtoul(argv[++i], NULL, 0);
204 0 : else if (argv[i][0] == '-') {
205 0 : if (i + 1 >= argc || argv[i + 1][0] == '-')
206 0 : goto usage;
207 : else {
208 0 : usage:
209 0 : printf("usage: mserver [-e Experiment] [-s][-t][-m][-d][-p port]\n");
210 0 : printf(" -e experiment to connect to\n");
211 0 : printf(" -m Multi process server (default)\n");
212 0 : printf(" -p port Listen for connections on specifed tcp port. Default value is taken from ODB \"/Experiment/midas server port\"\n");
213 : #ifdef OS_LINUX
214 0 : printf(" -D Become a daemon\n");
215 0 : printf(" -d Write debug info to stdout or to \"/tmp/mserver.log\"\n\n");
216 : #else
217 : printf(" -d Write debug info\"\n\n");
218 : #endif
219 0 : return 0;
220 : }
221 : }
222 : }
223 :
224 : /* turn on debugging */
225 0 : if (debug) {
226 0 : if (daemon || inetd)
227 0 : rpc_set_debug(debug_print, 1);
228 : else
229 0 : rpc_set_debug((void (*)(const char *)) puts, 1);
230 :
231 0 : sprintf(str, "Arguments: ");
232 0 : for (i = 0; i < argc; i++)
233 0 : sprintf(str + strlen(str), " %s", argv[i]);
234 0 : rpc_debug_printf(str);
235 :
236 0 : rpc_debug_printf("Debugging mode is on");
237 : }
238 :
239 : /* become a daemon */
240 0 : if (daemon) {
241 0 : printf("Becoming a daemon...\n");
242 0 : ss_daemon_init(FALSE);
243 : }
244 :
245 : /* connect to experiment */
246 0 : status = cm_connect_experiment(NULL, expt_name, "mserver", 0);
247 0 : if (status != CM_SUCCESS) {
248 0 : printf("cannot connect to experiment \"%s\", status %d\n", expt_name, status);
249 0 : exit(1);
250 : }
251 :
252 : HNDLE hDB;
253 : HNDLE hClient;
254 :
255 0 : status = cm_get_experiment_database(&hDB, &hClient);
256 0 : assert(status == CM_SUCCESS);
257 :
258 0 : int odb_port = MIDAS_TCP_PORT;
259 0 : int size = sizeof(odb_port);
260 :
261 0 : status = db_get_value(hDB, 0, "/Experiment/Midas server port", &odb_port, &size, TID_DWORD, TRUE);
262 0 : assert(status == DB_SUCCESS);
263 :
264 0 : if (port == 0)
265 0 : port = odb_port;
266 :
267 0 : if (port == 0)
268 0 : port = MIDAS_TCP_PORT;
269 :
270 0 : printf("mserver will listen on TCP port %d\n", port);
271 :
272 0 : int lsock = 0; // mserver main listener socket
273 0 : int lport = 0; // mserver listener port number
274 :
275 : /* register server */
276 0 : status = rpc_register_listener(port, rpc_server_dispatch, &lsock, &lport);
277 0 : if (status != RPC_SUCCESS) {
278 0 : printf("Cannot start server, rpc_register_server() status %d\n", status);
279 0 : return 1;
280 : }
281 :
282 : /* register path of mserver executable */
283 0 : rpc_set_mserver_path(argv[0]);
284 :
285 : /* register MIDAS library functions */
286 0 : rpc_register_functions(rpc_get_internal_list(1), rpc_server_dispatch);
287 :
288 0 : ss_suspend_set_server_listener(lsock);
289 :
290 : /* run forever */
291 : while (1) {
292 0 : status = cm_yield(1000);
293 : //printf("status %d\n", status);
294 0 : if (status == RPC_SHUTDOWN)
295 0 : break;
296 : }
297 :
298 0 : closesocket(lsock);
299 :
300 0 : cm_disconnect_experiment();
301 0 : } else {
302 :
303 : /* here we come if this program is started as a subprocess */
304 :
305 0 : callback.clear();
306 :
307 : /* extract callback arguments and start receiver */
308 : #ifdef OS_VMS
309 : mstrlcpy(callback.host_name, argv[2], sizeof(callback.host_name));
310 : callback.host_port1 = atoi(argv[3]);
311 : callback.host_port2 = atoi(argv[4]);
312 : callback.host_port3 = atoi(argv[5]);
313 : callback.debug = atoi(argv[6]);
314 : if (argc > 7)
315 : mstrlcpy(callback.experiment, argv[7], sizeof(callback.experiment));
316 : if (argc > 8)
317 : mstrlcpy(callback.directory, argv[8], sizeof(callback.directory));
318 : if (argc > 9)
319 : mstrlcpy(callback.user, argv[9], sizeof(callback.user));
320 : #else
321 0 : callback.host_name = argv[1];
322 0 : callback.host_port1 = atoi(argv[2]);
323 0 : callback.host_port2 = atoi(argv[3]);
324 0 : callback.host_port3 = atoi(argv[4]);
325 0 : callback.debug = atoi(argv[5]);
326 0 : if (argc > 6)
327 0 : callback.experiment = argv[6];
328 0 : if (argc > 7)
329 0 : callback.directory = argv[7];
330 0 : if (argc > 8)
331 0 : callback.user = argv[8];
332 : #endif
333 : //callback.index = 0;
334 :
335 0 : if (callback.debug) {
336 0 : rpc_set_debug(debug_print, 1);
337 0 : if (callback.directory[0]) {
338 0 : if (callback.user[0])
339 0 : rpc_debug_printf("Start subprocess in %s under user %s", callback.directory.c_str(), callback.user.c_str());
340 : else
341 0 : rpc_debug_printf("Start subprocess in %s", callback.directory.c_str());
342 :
343 : } else
344 0 : rpc_debug_printf("Start subprocess in current directory");
345 : }
346 :
347 : /* change the directory and uid */
348 0 : if (callback.directory.length() > 0)
349 0 : if (chdir(callback.directory.c_str()) != 0)
350 0 : rpc_debug_printf("Cannot change to directory \"%s\"", callback.directory.c_str());
351 :
352 0 : cm_msg_early_init();
353 :
354 : /* set the experiment name and expt path name */
355 :
356 0 : if (callback.directory.length() > 0)
357 0 : cm_set_path(callback.directory.c_str());
358 :
359 0 : if (callback.experiment.length() > 0)
360 0 : cm_set_experiment_name(callback.experiment.c_str());
361 :
362 : /* must be done after cm_set_path() */
363 0 : ss_suspend_init_odb_port();
364 :
365 : /* register system functions */
366 0 : rpc_register_functions(rpc_get_internal_list(0), rpc_server_dispatch);
367 :
368 : /* register MIDAS library functions */
369 0 : rpc_register_functions(rpc_get_internal_list(1), rpc_server_dispatch);
370 :
371 0 : int status = rpc_server_callback(&callback);
372 :
373 0 : if (status != RPC_SUCCESS) {
374 0 : cm_msg_flush_buffer();
375 0 : printf("Cannot start mserver, rpc_server_callback() status %d\n", status);
376 0 : return 1;
377 : }
378 :
379 : /* create alarm and elog semaphores */
380 : int semaphore_alarm, semaphore_elog, semaphore_history, semaphore_msg;
381 0 : ss_semaphore_create("ALARM", &semaphore_alarm);
382 0 : ss_semaphore_create("ELOG", &semaphore_elog);
383 0 : ss_semaphore_create("HISTORY", &semaphore_history);
384 0 : ss_semaphore_create("MSG", &semaphore_msg);
385 0 : cm_set_experiment_semaphore(semaphore_alarm, semaphore_elog, semaphore_history, semaphore_msg);
386 :
387 0 : rpc_server_loop();
388 0 : rpc_server_shutdown();
389 :
390 0 : ss_suspend_exit();
391 : }
392 :
393 0 : return 0;
394 : }
395 :
396 : /*------------------------------------------------------------------*/
397 :
398 : /* just a small test routine which doubles numbers */
399 0 : INT rpc_test(BYTE b, WORD w, INT i, float f, double d, BYTE * b1, WORD * w1, INT * i1, float *f1, double *d1)
400 : {
401 0 : printf("rpc_test: %d %d %d %1.1f %1.1lf\n", b, w, i, f, d);
402 :
403 0 : *b1 = b * 2;
404 0 : *w1 = w * 2;
405 0 : *i1 = i * 2;
406 0 : *f1 = f * 2;
407 0 : *d1 = d * 2;
408 :
409 0 : return 1;
410 : }
411 :
412 : /*----- rpc_server_dispatch ----------------------------------------*/
413 :
414 0 : INT rpc_server_dispatch(INT index, void *prpc_param[])
415 : /********************************************************************\
416 :
417 : Routine: rpc_server_dispatch
418 :
419 : Purpose: This routine gets registered as the callback function
420 : for all RPC calls via rpc_server_register. It acts as a
421 : stub to call the local midas subroutines. It uses the
422 : Cxxx(i) macros to cast parameters in prpc_param to
423 : their appropriate types.
424 :
425 : Input:
426 : int index RPC index defined in RPC.H
427 : void *prpc_param pointer to rpc parameter array
428 :
429 : Output:
430 : none
431 :
432 : Function value:
433 : status status returned from local midas function
434 :
435 : \********************************************************************/
436 : {
437 0 : INT status = 0;
438 :
439 0 : int convert_flags = rpc_get_convert_flags();
440 :
441 0 : switch (index) {
442 : /* common functions */
443 :
444 0 : case RPC_CM_SET_CLIENT_INFO:
445 0 : status = cm_set_client_info(CHNDLE(0), CPHNDLE(1), (use_callback_addr?callback.host_name.c_str():CSTRING(2)),
446 0 : CSTRING(3), CINT(4), CSTRING(5), CINT(6));
447 0 : break;
448 :
449 0 : case RPC_CM_CHECK_CLIENT:
450 0 : status = cm_check_client(CHNDLE(0), CHNDLE(1));
451 0 : break;
452 :
453 0 : case RPC_CM_SET_WATCHDOG_PARAMS:
454 0 : status = cm_set_watchdog_params(CBOOL(0), CINT(1));
455 0 : break;
456 :
457 0 : case RPC_CM_CLEANUP:
458 0 : status = cm_cleanup(CSTRING(0), CBOOL(1));
459 0 : break;
460 :
461 0 : case RPC_CM_GET_WATCHDOG_INFO:
462 0 : status = cm_get_watchdog_info(CHNDLE(0), CSTRING(1), CPDWORD(2), CPDWORD(3));
463 0 : break;
464 :
465 0 : case RPC_CM_MSG:
466 0 : status = cm_msg(CINT(0), CSTRING(1), CINT(2), CSTRING(3), "%s", CSTRING(4));
467 0 : break;
468 :
469 0 : case RPC_CM_MSG_LOG:
470 0 : status = cm_msg_log(CINT(0), CSTRING(1), CSTRING(2));
471 0 : break;
472 :
473 0 : case RPC_CM_EXECUTE:
474 0 : status = cm_execute(CSTRING(0), CSTRING(1), CINT(2));
475 0 : break;
476 :
477 0 : case RPC_CM_EXIST:
478 0 : status = cm_exist(CSTRING(0), CBOOL(1));
479 0 : break;
480 :
481 0 : case RPC_CM_SYNCHRONIZE:
482 0 : status = cm_synchronize(CPDWORD(0));
483 0 : break;
484 :
485 0 : case RPC_CM_ASCTIME: {
486 0 : std::string now = cm_asctime();
487 0 : mstrlcpy(CSTRING(0), now.c_str(), CINT(1));
488 0 : status = CM_SUCCESS;
489 0 : break;
490 0 : }
491 :
492 0 : case RPC_CM_TIME:
493 0 : status = cm_time(CPDWORD(0));
494 0 : break;
495 :
496 0 : case RPC_CM_MSG_RETRIEVE:
497 0 : status = cm_msg_retrieve(CINT(0), CSTRING(1), CINT(2));
498 0 : break;
499 :
500 : /* buffer manager functions */
501 :
502 0 : case RPC_BM_OPEN_BUFFER:
503 0 : status = bm_open_buffer(CSTRING(0), CINT(1), CPINT(2));
504 0 : break;
505 :
506 0 : case RPC_BM_CLOSE_BUFFER:
507 : //printf("RPC_BM_CLOSE_BUFFER(%d)!\n", CINT(0));
508 0 : status = bm_close_buffer(CINT(0));
509 0 : break;
510 :
511 0 : case RPC_BM_CLOSE_ALL_BUFFERS:
512 : //printf("RPC_BM_CLOSE_ALL_BUFFERS!\n");
513 0 : status = bm_close_all_buffers();
514 0 : break;
515 :
516 0 : case RPC_BM_GET_BUFFER_INFO:
517 0 : status = bm_get_buffer_info(CINT(0), (BUFFER_HEADER*)CARRAY(1));
518 0 : if (convert_flags) {
519 : BUFFER_HEADER *pb;
520 :
521 : /* convert event header */
522 0 : pb = (BUFFER_HEADER *) CARRAY(1);
523 0 : rpc_convert_single(&pb->num_clients, TID_INT, RPC_OUTGOING, convert_flags);
524 0 : rpc_convert_single(&pb->max_client_index, TID_INT, RPC_OUTGOING, convert_flags);
525 0 : rpc_convert_single(&pb->size, TID_INT, RPC_OUTGOING, convert_flags);
526 0 : rpc_convert_single(&pb->read_pointer, TID_INT, RPC_OUTGOING, convert_flags);
527 0 : rpc_convert_single(&pb->write_pointer, TID_INT, RPC_OUTGOING, convert_flags);
528 0 : rpc_convert_single(&pb->num_in_events, TID_INT, RPC_OUTGOING, convert_flags);
529 0 : rpc_convert_single(&pb->num_out_events, TID_INT, RPC_OUTGOING, convert_flags);
530 : }
531 0 : break;
532 :
533 0 : case RPC_BM_GET_BUFFER_LEVEL:
534 0 : status = bm_get_buffer_level(CINT(0), CPINT(1));
535 0 : break;
536 :
537 0 : case RPC_BM_INIT_BUFFER_COUNTERS:
538 0 : status = bm_init_buffer_counters(CINT(0));
539 0 : break;
540 :
541 0 : case RPC_BM_SET_CACHE_SIZE:
542 0 : status = bm_set_cache_size(CINT(0), CINT(1), CINT(2));
543 0 : break;
544 :
545 0 : case RPC_BM_ADD_EVENT_REQUEST:
546 0 : status = bm_add_event_request(CINT(0), CSHORT(1),
547 0 : CSHORT(2), CINT(3), (void (*)(HNDLE, HNDLE, EVENT_HEADER *, void *))
548 0 : (POINTER_T)
549 0 : CINT(4), CINT(5));
550 0 : break;
551 :
552 0 : case RPC_BM_REMOVE_EVENT_REQUEST:
553 0 : status = bm_remove_event_request(CINT(0), CINT(1));
554 0 : break;
555 :
556 0 : case RPC_BM_SEND_EVENT:
557 0 : if (convert_flags) {
558 : EVENT_HEADER *pevent;
559 :
560 : /* convert event header */
561 0 : pevent = (EVENT_HEADER *) CARRAY(1);
562 0 : rpc_convert_single(&pevent->event_id, TID_SHORT, 0, convert_flags);
563 0 : rpc_convert_single(&pevent->trigger_mask, TID_SHORT, 0, convert_flags);
564 0 : rpc_convert_single(&pevent->serial_number, TID_DWORD, 0, convert_flags);
565 0 : rpc_convert_single(&pevent->time_stamp, TID_DWORD, 0, convert_flags);
566 0 : rpc_convert_single(&pevent->data_size, TID_DWORD, 0, convert_flags);
567 : }
568 :
569 0 : status = bm_send_event(CINT(0), (const EVENT_HEADER*)(CARRAY(1)), CINT(2), CINT(3));
570 0 : break;
571 :
572 0 : case RPC_BM_RECEIVE_EVENT:
573 0 : status = bm_receive_event(CINT(0), CARRAY(1), CPINT(2), CINT(3));
574 0 : break;
575 :
576 0 : case RPC_BM_SKIP_EVENT:
577 0 : status = bm_skip_event(CINT(0));
578 0 : break;
579 :
580 0 : case RPC_BM_FLUSH_CACHE:
581 : //printf("RPC_BM_FLUSH_CACHE(%d,%d)!\n", CINT(0), CINT(1));
582 0 : if (CINT(0) == 0) {
583 0 : status = rpc_flush_event_socket(CINT(1));
584 : } else {
585 0 : status = bm_flush_cache(CINT(0), CINT(1));
586 : }
587 0 : break;
588 :
589 0 : case RPC_BM_MARK_READ_WAITING:
590 0 : status = BM_SUCCESS;
591 0 : break;
592 :
593 0 : case RPC_BM_EMPTY_BUFFERS:
594 0 : status = bm_empty_buffers();
595 0 : break;
596 :
597 : /* database functions */
598 :
599 0 : case RPC_DB_OPEN_DATABASE:
600 0 : status = db_open_database(CSTRING(0), CINT(1), CPHNDLE(2), CSTRING(3));
601 0 : break;
602 :
603 0 : case RPC_DB_CLOSE_DATABASE:
604 0 : status = db_close_database(CINT(0));
605 0 : break;
606 :
607 0 : case RPC_DB_FLUSH_DATABASE:
608 0 : status = db_flush_database(CINT(0));
609 0 : break;
610 :
611 0 : case RPC_DB_CLOSE_ALL_DATABASES:
612 0 : status = db_close_all_databases();
613 0 : break;
614 :
615 0 : case RPC_DB_CREATE_KEY:
616 0 : status = db_create_key(CHNDLE(0), CHNDLE(1), CSTRING(2), CDWORD(3));
617 0 : break;
618 :
619 0 : case RPC_DB_CREATE_LINK:
620 0 : status = db_create_link(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3));
621 0 : break;
622 :
623 0 : case RPC_DB_SET_VALUE:
624 0 : rpc_convert_data(CARRAY(3), CDWORD(6), RPC_FIXARRAY, CINT(4), convert_flags);
625 0 : status = db_set_value(CHNDLE(0), CHNDLE(1), CSTRING(2), CARRAY(3), CINT(4), CINT(5), CDWORD(6));
626 0 : break;
627 :
628 0 : case RPC_DB_GET_VALUE:
629 0 : rpc_convert_data(CARRAY(3), CDWORD(5), RPC_FIXARRAY, CINT(4), convert_flags);
630 0 : status = db_get_value(CHNDLE(0), CHNDLE(1), CSTRING(2), CARRAY(3), CPINT(4), CDWORD(5), CBOOL(6));
631 0 : rpc_convert_data(CARRAY(3), CDWORD(5), RPC_FIXARRAY | RPC_OUTGOING, CINT(4), convert_flags);
632 0 : break;
633 :
634 0 : case RPC_DB_FIND_KEY:
635 0 : status = db_find_key(CHNDLE(0), CHNDLE(1), CSTRING(2), CPHNDLE(3));
636 0 : break;
637 :
638 0 : case RPC_DB_FIND_LINK:
639 0 : status = db_find_link(CHNDLE(0), CHNDLE(1), CSTRING(2), CPHNDLE(3));
640 0 : break;
641 :
642 0 : case RPC_DB_GET_PATH: {
643 0 : std::string path = db_get_path(CHNDLE(0), CHNDLE(1));
644 0 : mstrlcpy(CSTRING(2), path.c_str(), CINT(3));
645 0 : status = DB_SUCCESS;
646 0 : break;
647 0 : }
648 :
649 0 : case RPC_DB_GET_PARENT:
650 0 : status = db_get_parent(CHNDLE(0), CHNDLE(1), CPHNDLE(2));
651 0 : break;
652 :
653 0 : case RPC_DB_DELETE_KEY:
654 0 : status = db_delete_key(CHNDLE(0), CHNDLE(1), CBOOL(2));
655 0 : break;
656 :
657 0 : case RPC_DB_ENUM_KEY:
658 0 : status = db_enum_key(CHNDLE(0), CHNDLE(1), CINT(2), CPHNDLE(3));
659 0 : break;
660 :
661 0 : case RPC_DB_ENUM_LINK:
662 0 : status = db_enum_link(CHNDLE(0), CHNDLE(1), CINT(2), CPHNDLE(3));
663 0 : break;
664 :
665 0 : case RPC_DB_GET_NEXT_LINK:
666 0 : status = db_get_next_link(CHNDLE(0), CHNDLE(1), CPHNDLE(2));
667 0 : break;
668 :
669 0 : case RPC_DB_GET_KEY:
670 0 : status = db_get_key(CHNDLE(0), CHNDLE(1), (KEY*)CARRAY(2));
671 0 : if (convert_flags) {
672 : KEY *pkey;
673 :
674 0 : pkey = (KEY *) CARRAY(2);
675 0 : rpc_convert_single(&pkey->type, TID_DWORD, RPC_OUTGOING, convert_flags);
676 0 : rpc_convert_single(&pkey->num_values, TID_INT, RPC_OUTGOING, convert_flags);
677 0 : rpc_convert_single(&pkey->data, TID_INT, RPC_OUTGOING, convert_flags);
678 0 : rpc_convert_single(&pkey->total_size, TID_INT, RPC_OUTGOING, convert_flags);
679 0 : rpc_convert_single(&pkey->item_size, TID_INT, RPC_OUTGOING, convert_flags);
680 0 : rpc_convert_single(&pkey->access_mode, TID_WORD, RPC_OUTGOING, convert_flags);
681 0 : rpc_convert_single(&pkey->notify_count, TID_WORD, RPC_OUTGOING, convert_flags);
682 0 : rpc_convert_single(&pkey->next_key, TID_INT, RPC_OUTGOING, convert_flags);
683 0 : rpc_convert_single(&pkey->parent_keylist, TID_INT, RPC_OUTGOING, convert_flags);
684 0 : rpc_convert_single(&pkey->last_written, TID_INT, RPC_OUTGOING, convert_flags);
685 : }
686 0 : break;
687 :
688 0 : case RPC_DB_GET_LINK:
689 0 : status = db_get_link(CHNDLE(0), CHNDLE(1), (KEY*)CARRAY(2));
690 0 : if (convert_flags) {
691 : KEY *pkey;
692 :
693 0 : pkey = (KEY *) CARRAY(2);
694 0 : rpc_convert_single(&pkey->type, TID_DWORD, RPC_OUTGOING, convert_flags);
695 0 : rpc_convert_single(&pkey->num_values, TID_INT, RPC_OUTGOING, convert_flags);
696 0 : rpc_convert_single(&pkey->data, TID_INT, RPC_OUTGOING, convert_flags);
697 0 : rpc_convert_single(&pkey->total_size, TID_INT, RPC_OUTGOING, convert_flags);
698 0 : rpc_convert_single(&pkey->item_size, TID_INT, RPC_OUTGOING, convert_flags);
699 0 : rpc_convert_single(&pkey->access_mode, TID_WORD, RPC_OUTGOING, convert_flags);
700 0 : rpc_convert_single(&pkey->notify_count, TID_WORD, RPC_OUTGOING, convert_flags);
701 0 : rpc_convert_single(&pkey->next_key, TID_INT, RPC_OUTGOING, convert_flags);
702 0 : rpc_convert_single(&pkey->parent_keylist, TID_INT, RPC_OUTGOING, convert_flags);
703 0 : rpc_convert_single(&pkey->last_written, TID_INT, RPC_OUTGOING, convert_flags);
704 : }
705 0 : break;
706 :
707 0 : case RPC_DB_GET_KEY_INFO:
708 0 : status = db_get_key_info(CHNDLE(0), CHNDLE(1), CSTRING(2), CINT(3), CPINT(4), CPINT(5), CPINT(6));
709 0 : break;
710 :
711 0 : case RPC_DB_GET_KEY_TIME:
712 0 : status = db_get_key_time(CHNDLE(0), CHNDLE(1), CPDWORD(2));
713 0 : break;
714 :
715 0 : case RPC_DB_RENAME_KEY:
716 0 : status = db_rename_key(CHNDLE(0), CHNDLE(1), CSTRING(2));
717 0 : break;
718 :
719 0 : case RPC_DB_REORDER_KEY:
720 0 : status = db_reorder_key(CHNDLE(0), CHNDLE(1), CINT(2));
721 0 : break;
722 :
723 0 : case RPC_DB_GET_DATA:
724 0 : status = db_get_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4));
725 0 : rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
726 0 : break;
727 :
728 0 : case RPC_DB_GET_LINK_DATA:
729 0 : status = db_get_link_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4));
730 0 : rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
731 0 : break;
732 :
733 0 : case RPC_DB_GET_DATA1:
734 0 : status = db_get_data1(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CDWORD(4), CPINT(5));
735 0 : rpc_convert_data(CARRAY(2), CDWORD(4), RPC_FIXARRAY | RPC_OUTGOING, CINT(3), convert_flags);
736 0 : break;
737 :
738 0 : case RPC_DB_GET_DATA_INDEX:
739 0 : status = db_get_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CINT(4), CDWORD(5));
740 0 : rpc_convert_single(CARRAY(2), CDWORD(5), RPC_OUTGOING, convert_flags);
741 0 : break;
742 :
743 0 : case RPC_DB_SET_DATA:
744 0 : rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
745 0 : status = db_set_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
746 0 : break;
747 :
748 0 : case RPC_DB_SET_DATA1:
749 0 : rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
750 0 : status = db_set_data1(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
751 0 : break;
752 :
753 0 : case RPC_DB_NOTIFY_CLIENTS_ARRAY:
754 0 : rpc_convert_data(CARRAY(1), CINT(2), RPC_FIXARRAY, TID_DWORD, convert_flags);
755 0 : status = db_notify_clients_array(CHNDLE(0), (HNDLE*)CARRAY(1), CINT(2));
756 0 : break;
757 :
758 0 : case RPC_DB_SET_LINK_DATA:
759 0 : rpc_convert_data(CARRAY(2), CDWORD(5), RPC_FIXARRAY, CINT(3), convert_flags);
760 0 : status = db_set_link_data(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
761 0 : break;
762 :
763 0 : case RPC_DB_SET_DATA_INDEX:
764 0 : rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
765 0 : status = db_set_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
766 0 : break;
767 :
768 0 : case RPC_DB_SET_LINK_DATA_INDEX:
769 0 : rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
770 0 : status = db_set_link_data_index(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5));
771 0 : break;
772 :
773 0 : case RPC_DB_SET_DATA_INDEX1:
774 0 : rpc_convert_single(CARRAY(2), CDWORD(5), 0, convert_flags);
775 0 : status = db_set_data_index1(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4), CDWORD(5), CBOOL(6));
776 0 : break;
777 :
778 0 : case RPC_DB_SET_NUM_VALUES:
779 0 : status = db_set_num_values(CHNDLE(0), CHNDLE(1), CINT(2));
780 0 : break;
781 :
782 0 : case RPC_DB_SET_MODE:
783 0 : status = db_set_mode(CHNDLE(0), CHNDLE(1), CWORD(2), CBOOL(3));
784 0 : break;
785 :
786 0 : case RPC_DB_GET_RECORD:
787 0 : status = db_get_record(CHNDLE(0), CHNDLE(1), CARRAY(2), CPINT(3), CINT(4));
788 0 : break;
789 :
790 0 : case RPC_DB_SET_RECORD:
791 0 : status = db_set_record(CHNDLE(0), CHNDLE(1), CARRAY(2), CINT(3), CINT(4));
792 0 : break;
793 :
794 0 : case RPC_DB_GET_RECORD_SIZE:
795 0 : status = db_get_record_size(CHNDLE(0), CHNDLE(1), CINT(2), CPINT(3));
796 0 : break;
797 :
798 0 : case RPC_DB_CREATE_RECORD:
799 0 : status = db_create_record(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3));
800 0 : break;
801 :
802 0 : case RPC_DB_CHECK_RECORD:
803 0 : status = db_check_record(CHNDLE(0), CHNDLE(1), CSTRING(2), CSTRING(3), CBOOL(4));
804 0 : break;
805 :
806 0 : case RPC_DB_ADD_OPEN_RECORD:
807 0 : status = db_add_open_record(CHNDLE(0), CHNDLE(1), CWORD(2));
808 0 : break;
809 :
810 0 : case RPC_DB_REMOVE_OPEN_RECORD:
811 0 : status = db_remove_open_record(CHNDLE(0), CHNDLE(1), CBOOL(2));
812 0 : break;
813 :
814 0 : case RPC_DB_LOAD:
815 0 : status = db_load(CHNDLE(0), CHNDLE(1), CSTRING(2), CBOOL(3));
816 0 : break;
817 :
818 0 : case RPC_DB_SAVE:
819 0 : status = db_save(CHNDLE(0), CHNDLE(1), CSTRING(2), CBOOL(3));
820 0 : break;
821 :
822 0 : case RPC_DB_SET_CLIENT_NAME:
823 0 : status = db_set_client_name(CHNDLE(0), CSTRING(1));
824 0 : break;
825 :
826 0 : case RPC_DB_GET_OPEN_RECORDS:
827 0 : status = db_get_open_records(CHNDLE(0), CHNDLE(1), CSTRING(2), CINT(3), CBOOL(4));
828 0 : break;
829 :
830 0 : case RPC_DB_COPY_XML:
831 0 : status = db_copy_xml(CHNDLE(0), CHNDLE(1), CSTRING(2), CPINT(3), CBOOL(4));
832 0 : break;
833 :
834 0 : case RPC_EL_SUBMIT:
835 0 : status = el_submit(CINT(0), CSTRING(1), CSTRING(2), CSTRING(3), CSTRING(4),
836 0 : CSTRING(5), CSTRING(6), CSTRING(7),
837 0 : CSTRING(8), (char*)CARRAY(9), CINT(10),
838 0 : CSTRING(11), (char*)CARRAY(12), CINT(13),
839 0 : CSTRING(14), (char*)CARRAY(15), CINT(16), CSTRING(17), CINT(18));
840 0 : break;
841 :
842 0 : case RPC_AL_CHECK:
843 0 : status = al_check();
844 0 : break;
845 :
846 0 : case RPC_AL_TRIGGER_ALARM:
847 0 : status = al_trigger_alarm(CSTRING(0), CSTRING(1), CSTRING(2), CSTRING(3), CINT(4));
848 0 : break;
849 :
850 : /* exit functions */
851 0 : case RPC_ID_EXIT:
852 : //printf("RPC_ID_EXIT!\n");
853 0 : status = RPC_SUCCESS;
854 0 : break;
855 :
856 0 : case RPC_ID_SHUTDOWN:
857 0 : status = RPC_SUCCESS;
858 0 : break;
859 :
860 : /* various functions */
861 :
862 0 : case RPC_TEST:
863 0 : status = rpc_test(CBYTE(0), CWORD(1), CINT(2), CFLOAT(3), CDOUBLE(4),
864 0 : CPBYTE(5), CPWORD(6), CPINT(7), CPFLOAT(8), CPDOUBLE(9));
865 0 : break;
866 :
867 0 : case RPC_TEST2: {
868 :
869 0 : status = RPC_SUCCESS;
870 :
871 0 : if (CINT(0) != 123) {
872 0 : cm_msg(MERROR, "rpc_test2", "CINT(0) mismatch");
873 0 : status = 0;
874 : }
875 :
876 0 : CINT(1) = 789;
877 :
878 0 : if (CINT(2) != 456) {
879 0 : cm_msg(MERROR, "rpc_test2", "CINT(2) mismatch");
880 0 : status = 0;
881 : }
882 :
883 0 : CINT(2) = 2*CINT(2);
884 :
885 0 : if (strcmp(CSTRING(3), "test string") != 0) {
886 0 : cm_msg(MERROR, "rpc_test2", "CSTRING(3) mismatch");
887 0 : status = 0;
888 : }
889 :
890 0 : if (CINT(5) != 32) {
891 0 : cm_msg(MERROR, "rpc_test2", "CINT(5) string_out size mismatch");
892 0 : status = 0;
893 : }
894 :
895 0 : strcpy(CSTRING(4), "string_out");
896 :
897 0 : if (CINT(7) != 48) {
898 0 : cm_msg(MERROR, "rpc_test2", "CINT(7) string2_out size mismatch");
899 0 : status = 0;
900 : }
901 :
902 0 : strcpy(CSTRING(6), "second string_out");
903 :
904 0 : if (CINT(9) != 25) {
905 0 : cm_msg(MERROR, "rpc_test2", "CINT(9) string_inout size mismatch");
906 0 : status = 0;
907 : }
908 :
909 0 : if (strcmp(CSTRING(8), "string_inout") != 0) {
910 0 : cm_msg(MERROR, "rpc_test2", "CSTRING(8) mismatch");
911 0 : status = 0;
912 : }
913 :
914 0 : strcpy(CSTRING(8), "return string_inout");
915 :
916 : // 10, 11, 12 is TID_STRUCT of type KEY
917 :
918 : KEY *pkey;
919 :
920 0 : pkey = (KEY*)CARRAY(10);
921 :
922 0 : if (pkey->type != 111 || pkey->num_values != 222 || strcmp(pkey->name, "name") || pkey->last_written != 333) {
923 0 : printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
924 :
925 0 : cm_msg(MERROR, "rpc_test2", "CARRAY(10) KEY mismatch");
926 0 : status = 0;
927 : }
928 :
929 0 : pkey = (KEY*)CARRAY(11);
930 :
931 0 : pkey->type = 444;
932 0 : pkey->num_values = 555;
933 0 : strcpy(pkey->name, "out_name");
934 0 : pkey->last_written = 666;
935 :
936 : //printf("CKEY(11): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
937 :
938 0 : pkey = (KEY*)CARRAY(12);
939 :
940 0 : if (pkey->type != 111111 || pkey->num_values != 222222 || strcmp(pkey->name, "name_name") || pkey->last_written != 333333) {
941 0 : printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
942 :
943 0 : cm_msg(MERROR, "rpc_test2", "CARRAY(12) KEY mismatch");
944 0 : status = 0;
945 : }
946 :
947 0 : pkey->type = 444444;
948 0 : pkey->num_values = 555555;
949 0 : strcpy(pkey->name, "inout_name");
950 0 : pkey->last_written = 666666;
951 :
952 : //printf("CKEY(10): type %d, num_values %d, name [%s], last_written %d\n", pkey->type, pkey->num_values, pkey->name, pkey->last_written);
953 :
954 0 : if (CINT(14) != 40) {
955 0 : cm_msg(MERROR, "rpc_test2", "CINT(14) array_in size mismatch");
956 0 : status = 0;
957 : } else {
958 : //printf("CARRAY(13): %p, 0x%08x [%s]\n", CARRAY(9), *(uint32_t*)CARRAY(9), (char*)CARRAY(9));
959 :
960 0 : uint32_t size = CINT(14)/4;
961 0 : for (uint32_t i=0; i<size; i++) {
962 0 : if (((uint32_t*)CARRAY(13))[i] != i*10) {
963 0 : cm_msg(MERROR, "rpc_test2", "CARRAY(13) dwordarray_inout mismatch at %d, %d vs %d", i, ((uint32_t*)CARRAY(13))[i], i*10);
964 0 : status = 0;
965 : }
966 : }
967 : }
968 :
969 0 : for (int i=0; i<5; i++) {
970 0 : ((uint32_t*)CARRAY(13))[i] = i*10 + i;
971 : }
972 :
973 0 : CINT(14) = 20;
974 :
975 0 : if (CINT(16) != 10) {
976 0 : cm_msg(MERROR, "rpc_test2", "CINT(16) array_in size mismatch");
977 0 : status = 0;
978 : } else {
979 : //printf("CARRAY(15): %p, 0x%08x [%s]\n", CARRAY(15), *(uint32_t*)CARRAY(15), (char*)CARRAY(15));
980 :
981 0 : for (int i=0; i<CINT(16); i++) {
982 0 : if (((char*)CARRAY(15))[i] != 'a'+i) {
983 0 : cm_msg(MERROR, "rpc_test2", "CARRAY(15) array_in data mismatch at %d, %d vs %d", i, ((char*)CARRAY(15))[i], 'a'+i);
984 0 : status = 0;
985 : }
986 : }
987 : }
988 :
989 0 : if (CINT(18) != 16) {
990 0 : cm_msg(MERROR, "rpc_test2", "CINT(14) array_out size mismatch");
991 0 : status = 0;
992 : }
993 :
994 0 : break;
995 : }
996 :
997 0 : default:
998 0 : cm_msg(MERROR, "rpc_server_dispatch", "received unrecognized command %d", index);
999 0 : status = RPC_INVALID_ID;
1000 : }
1001 :
1002 0 : return status;
1003 : }
1004 :
1005 : /* emacs
1006 : * Local Variables:
1007 : * tab-width: 8
1008 : * c-basic-offset: 3
1009 : * indent-tabs-mode: nil
1010 : * End:
1011 : */
|