0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include <string.h>
0037 #include <stdio.h>
0038 #include <stdlib.h>
0039 #include <memory.h>
0040 #include <errno.h>
0041
0042
0043 #include <fcntl.h> /* For O_* constants */
0044 #include <sys_mqueue.h>
0045 #include <sys/stat.h>
0046 #include <sys/time.h>
0047
0048 #include <ndrstandard.h>
0049 #include <ndebug.h>
0050 #include <ndrxd.h>
0051 #include <ndrxdcmn.h>
0052
0053 #include <cmd_processor.h>
0054 #include <signal.h>
0055 #include <userlog.h>
0056
0057
0058
0059 #define QUEUE_WAIT 1
0060
0061
0062
0063 command_state_t G_command_state;
0064 command_call_t * G_last_interactive_call=NULL;
0065
0066
0067
0068 exprivate int cmd_dummy (command_call_t * call, char *data, size_t len, int context);
0069 typedef struct
0070 {
0071 int command;
0072
0073 int (*p_cmd_call) (command_call_t * call, char *data, size_t len, int context);
0074 char *descr;
0075 char *contexts;
0076 int interactive;
0077 int entercontext;
0078 } command_map_t;
0079
0080 command_map_t M_command_map [] =
0081 {
0082 {NDRXD_COM_LDCF_RQ, cmd_config_load,"ldcf", ",0,", 0, NDRXD_CTX_NOCHG},
0083 {NDRXD_COM_LDCF_RP, cmd_dummy, "ldcf", "", 0, NDRXD_CTX_NOCHG},
0084 {NDRXD_COM_START_RQ, cmd_start, "start", ",0,", 1, NDRXD_CTX_START},
0085 {NDRXD_COM_START_RP, cmd_dummy, "start", "", 1, NDRXD_CTX_ZERO},
0086
0087 {NDRXD_COM_SVCINFO_RQ, cmd_srvinfo, "srvinfo", ",-1,",0,NDRXD_CTX_NOCHG},
0088 {NDRXD_COM_SVCINFO_RP, cmd_dummy, "srvinfo", "", 0,NDRXD_CTX_NOCHG},
0089
0090 {NDRXD_COM_PMNTIFY_RQ, cmd_notify, "notify", ",-1,", 0,NDRXD_CTX_NOCHG},
0091 {NDRXD_COM_PMNTIFY_RP, cmd_dummy, "notify", "", 0,NDRXD_CTX_NOCHG},
0092
0093 {NDRXD_COM_PSC_RQ, cmd_psc, "psc", ",-1,", 0,NDRXD_CTX_NOCHG},
0094 {NDRXD_COM_PSC_RP, cmd_dummy, "psc", "", 0,NDRXD_CTX_NOCHG},
0095
0096 {NDRXD_COM_STOP_RQ, cmd_stop, "stop", ",0,",1,NDRXD_CTX_STOP},
0097 {NDRXD_COM_STOP_RP, cmd_dummy, "stop", "", 1,NDRXD_CTX_ZERO},
0098
0099 {NDRXD_COM_SRVSTOP_RQ, cmd_dummy, "srvstop", "", 0,NDRXD_CTX_NOCHG},
0100 {NDRXD_COM_SRVSTOP_RP, cmd_dummy, "srvstop", "", 0,NDRXD_CTX_NOCHG},
0101
0102 {NDRXD_COM_AT_RQ, cmd_at, "at", ",-1,",0,NDRXD_CTX_NOCHG},
0103 {NDRXD_COM_AT_RP, cmd_at, "at", "", 0,NDRXD_CTX_NOCHG},
0104 {NDRXD_COM_RELOAD_RQ, cmd_reload, "reload", ",0,",0,NDRXD_CTX_NOCHG},
0105 {NDRXD_COM_RELOAD_RP, cmd_reload, "reload", "", 0,NDRXD_CTX_NOCHG},
0106 {NDRXD_COM_TESTCFG_RQ, cmd_testcfg, "testcfg", ",0,",0,NDRXD_CTX_NOCHG},
0107 {NDRXD_COM_TESTCFG_RP, cmd_testcfg, "testcfg", "", 0,NDRXD_CTX_NOCHG},
0108 {NDRXD_COM_SRVINFO_RQ, cmd_dummy, "srvinfo", ",0,",0,NDRXD_CTX_NOCHG},
0109 {NDRXD_COM_SRVINFO_RP, cmd_dummy, "srvinfo", "", 0,NDRXD_CTX_NOCHG},
0110 {NDRXD_COM_SRVUNADV_RQ, cmd_srvunadv, "srvunadv", ",-1,", 0,NDRXD_CTX_NOCHG},
0111 {NDRXD_COM_SRVUNADV_RP, cmd_dummy, "srvunadv", "", 0,NDRXD_CTX_NOCHG},
0112 {NDRXD_COM_XADUNADV_RQ, cmd_xadunadv, "xadunadv", ",0,", 0,NDRXD_CTX_NOCHG},
0113 {NDRXD_COM_XADUNADV_RP, cmd_dummy, "xadunadv", "", 0,NDRXD_CTX_NOCHG},
0114 {NDRXD_COM_NXDUNADV_RQ, cmd_dummy, "nxdunadv", ",-1,", 0,NDRXD_CTX_NOCHG},
0115 {NDRXD_COM_NXDUNADV_RP, cmd_dummy, "nxdunadv", "", 0,NDRXD_CTX_NOCHG},
0116 {NDRXD_COM_SRVADV_RQ, cmd_srvadv, "srvadv", ",-1,", 0,NDRXD_CTX_NOCHG},
0117 {NDRXD_COM_SRVADV_RP, cmd_dummy, "srvadv", "", 0,NDRXD_CTX_NOCHG},
0118 {NDRXD_COM_XAPPM_RQ, cmd_ppm, "xappm", ",-1,", 0,NDRXD_CTX_NOCHG},
0119 {NDRXD_COM_XAPPM_RP, cmd_dummy, "xappm", "", 0,NDRXD_CTX_NOCHG},
0120 {NDRXD_COM_XASHM_PSVC_RQ,cmd_shm_psvc, "xashm_psvc", ",-1,", 0,NDRXD_CTX_NOCHG},
0121 {NDRXD_COM_XASHM_PSVC_RP,cmd_dummy, "xashm_psvc", "", 0,NDRXD_CTX_NOCHG},
0122 {NDRXD_COM_XASHM_PSRV_RQ,cmd_shm_psrv, "xashm_psrv", ",-1,", 0,NDRXD_CTX_NOCHG},
0123 {NDRXD_COM_XASHM_PSRV_RP,cmd_dummy, "xashm_psrv", "", 0,NDRXD_CTX_NOCHG},
0124 {NDRXD_COM_NXDREADV_RQ, cmd_dummy, "nxdreadv", ",-1,", 0,NDRXD_CTX_NOCHG},
0125 {NDRXD_COM_NXDREADV_RP, cmd_dummy, "nxdreadv", "", 0,NDRXD_CTX_NOCHG},
0126 {NDRXD_COM_XADREADV_RQ, cmd_xadreadv, "xadreadv", ",0,", 0,NDRXD_CTX_NOCHG},
0127 {NDRXD_COM_XADREADV_RP, cmd_dummy, "xadreadv", "", 0,NDRXD_CTX_NOCHG},
0128 {NDRXD_COM_XACABORT_RQ, cmd_abort, "xaabort", ",1,2,", 0,NDRXD_CTX_NOCHG},
0129 {NDRXD_COM_XAABORT_RP, cmd_dummy, "xaabort", "", 0,NDRXD_CTX_NOCHG},
0130
0131 {NDRXD_COM_BRCON_RQ, cmd_brcon, "brcon", ",-1,", 0,NDRXD_CTX_NOCHG},
0132 {NDRXD_COM_BRCON_RP, cmd_dummy, "brcon", "", 0,NDRXD_CTX_NOCHG},
0133 {NDRXD_COM_BRDISCON_RQ, cmd_brdiscon, "brdiscon", ",-1,", 0,NDRXD_CTX_NOCHG},
0134 {NDRXD_COM_BRDISCON_RP, cmd_dummy, "brdiscon", "", 0,NDRXD_CTX_NOCHG},
0135 {NDRXD_COM_BRREFERSH_RQ,cmd_brrefresh, "brrefresh", ",-1,", 0,NDRXD_CTX_NOCHG},
0136 {NDRXD_COM_BRREFERSH_RP,cmd_dummy, "brrefresh", "", 0,NDRXD_CTX_NOCHG},
0137 {NDRXD_COM_BRCLOCK_RQ, cmd_dummy, "brclock", "", 0,NDRXD_CTX_NOCHG},
0138 {NDRXD_COM_BRCLOCK_RP, cmd_dummy, "brclock", "", 0,NDRXD_CTX_NOCHG},
0139 {NDRXD_COM_SRVGETBRS_RQ,cmd_getbrs, "getbrs", ",-1,", 0,NDRXD_CTX_NOCHG},
0140 {NDRXD_COM_SRVGETBRS_RP,cmd_dummy, "getbrs", "", 0,NDRXD_CTX_NOCHG},
0141 {NDRXD_COM_SRVPING_RQ,cmd_dummy, "srvping", ",-1,", 0,NDRXD_CTX_NOCHG},
0142 {NDRXD_COM_SRVPING_RP,cmd_srvpingrsp, "srvping", ",-1,", 0,NDRXD_CTX_NOCHG},
0143
0144 {NDRXD_COM_SRELOAD_RQ,cmd_sreload, "sreload", ",0,", 0,NDRXD_CTX_START},
0145 {NDRXD_COM_SRELOAD_RP,cmd_dummy, "sreload", ",0,", 0,NDRXD_CTX_START},
0146
0147 {NDRXD_COM_XAPQ_RQ, cmd_pq, "xapq", ",-1,", 0,NDRXD_CTX_NOCHG},
0148 {NDRXD_COM_XAPQ_RP, cmd_dummy, "xapq", "", 0,NDRXD_CTX_NOCHG},
0149
0150 {NDRXD_COM_PE_RQ, cmd_pe, "xape", ",-1,", 0,NDRXD_CTX_NOCHG},
0151 {NDRXD_COM_PE_RP, cmd_dummy, "xape", "", 0,NDRXD_CTX_NOCHG},
0152
0153 {NDRXD_COM_SET_RQ, cmd_set, "xaset", ",-1,", 0,NDRXD_CTX_NOCHG},
0154 {NDRXD_COM_SET_RP, cmd_dummy, "xaset", "", 0,NDRXD_CTX_NOCHG},
0155 {NDRXD_COM_UNSET_RQ, cmd_unset, "xaunset", ",-1,", 0,NDRXD_CTX_NOCHG},
0156 {NDRXD_COM_UNSET_RP, cmd_dummy, "xaunset", "", 0,NDRXD_CTX_NOCHG},
0157 {NDRXD_COM_SRELOADI_RQ,cmd_sreloadi, "sreloadi", ",0,", 0,NDRXD_CTX_START},
0158 {NDRXD_COM_SRELOADI_RP,cmd_dummy, "sreloadi", ",0,", 0,NDRXD_CTX_START},
0159 {NDRXD_COM_APPCONFIG_RQ,cmd_appconfig, "appconfig", ",-1,", 0,NDRXD_CTX_NOCHG},
0160 {NDRXD_COM_APPCONFIG_RP,cmd_dummy, "appconfig", ",-1,", 0,NDRXD_CTX_NOCHG},
0161 {NDRXD_COM_DPING_RQ, cmd_dping, "dping", ",-1,", 0,NDRXD_CTX_NOCHG},
0162 {NDRXD_COM_DPING_RP, cmd_dummy, "dping", ",-1,", 0,NDRXD_CTX_NOCHG},
0163 {NDRXD_COM_DSLEEP_RQ, cmd_dsleep, "dsleep", ",-1,", 0,NDRXD_CTX_NOCHG},
0164 {NDRXD_COM_DSLEEP_RP, cmd_dummy, "dsleep", ",-1,", 0,NDRXD_CTX_NOCHG},
0165 {NDRXD_COM_BLIST_RQ, cmd_blist, "blist", ",-1,", 0,NDRXD_CTX_NOCHG},
0166 {NDRXD_COM_BLIST_RP, cmd_dummy, "blist", "", 0,NDRXD_CTX_NOCHG}
0167
0168 };
0169
0170
0171
0172
0173
0174
0175
0176
0177 exprivate int cmd_dummy(command_call_t * call, char *data, size_t len, int context)
0178 {
0179 NDRX_LOG(log_debug, "Un-expected command call!");
0180 return EXSUCCEED;
0181 }
0182
0183
0184
0185
0186
0187 exprivate int cmd_open_queue(void)
0188 {
0189 int ret=EXSUCCEED;
0190
0191
0192 ndrx_mq_unlink(G_command_state.listenq_str);
0193 NDRX_LOG(log_debug, "About to open deamon queue: [%s]",
0194 G_command_state.listenq_str);
0195
0196 if ((mqd_t)EXFAIL==(G_command_state.listenq = ndrx_mq_open_at(
0197 G_command_state.listenq_str, O_RDWR | O_CREAT,
0198 S_IWUSR | S_IRUSR, NULL)))
0199 {
0200 NDRX_LOG(log_error, "Failed to open queue: [%s] err: %s",
0201 G_command_state.listenq_str, strerror(errno));
0202 userlog("Failed to open queue: [%s] err: %s",
0203 G_command_state.listenq_str, strerror(errno));
0204 ret=EXFAIL;
0205 goto out;
0206 }
0207
0208 NDRX_LOG(log_error, "Queue [%s] opened!", G_command_state.listenq_str);
0209
0210 out:
0211 return ret;
0212 }
0213
0214
0215
0216
0217
0218 expublic int cmd_close_queue(void)
0219 {
0220 int ret=EXSUCCEED;
0221
0222 if (EXSUCCEED!=ndrx_mq_close(G_command_state.listenq))
0223 {
0224 NDRX_LOG(log_error, "Failed to close: [%s] err: %s",
0225 G_command_state.listenq_str, strerror(errno));
0226 }
0227
0228
0229 if (EXSUCCEED!=ndrx_mq_unlink(G_command_state.listenq_str))
0230 {
0231 NDRX_LOG(log_error, "Failed to unlink: [%s] err: %s",
0232 G_command_state.listenq_str, strerror(errno));
0233 }
0234
0235 out:
0236 return ret;
0237 }
0238
0239
0240
0241
0242 expublic int cmd_processor_init(void)
0243 {
0244 int ret=EXSUCCEED;
0245
0246 memset(&G_command_state, 0, sizeof(G_command_state));
0247 snprintf(G_command_state.listenq_str, sizeof(G_command_state.listenq_str),
0248 NDRX_NDRXD, G_sys_config.qprefix);
0249
0250 if (EXFAIL==cmd_open_queue())
0251 {
0252 ret=EXFAIL;
0253 goto out;
0254 }
0255
0256 out:
0257 return ret;
0258 }
0259
0260
0261
0262
0263
0264
0265 expublic int get_cmdq_attr(struct mq_attr *attr)
0266 {
0267 int ret=EXSUCCEED;
0268
0269 if (EXFAIL==ndrx_mq_getattr(G_command_state.listenq, attr))
0270 {
0271 NDRX_LOG(log_error, "Failed to ex_mq_getattr on cmd q: %s",
0272 strerror(errno));
0273 ret=EXFAIL;
0274 }
0275
0276 return ret;
0277 }
0278
0279
0280
0281
0282
0283
0284 exprivate char * get_ctx_string(int ctx)
0285 {
0286
0287 static char* ctx_str[] = {"any", "normal", "starting", "stopping"};
0288
0289 return ctx_str[ctx+1];
0290 }
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 exprivate void get_cmd_wait_time(struct timespec *abs_timeout)
0302 {
0303 long wait_time_ms = G_sys_config.cmd_wait_time*1000;
0304 long sanity_wait_time;
0305 long nsec_tmp;
0306
0307 struct timeval timeval;
0308 ndrx_stopwatch_t *w;
0309
0310 gettimeofday (&timeval, NULL);
0311 memset(abs_timeout, 0, sizeof(struct timespec));
0312 w=ndrx_get_santiy_stopwatch();
0313
0314 if (NULL!=w)
0315 {
0316 sanity_wait_time = G_app_config->sanity*1000 - ndrx_stopwatch_get_delta(w);
0317
0318 if (sanity_wait_time < wait_time_ms)
0319 {
0320 wait_time_ms = sanity_wait_time;
0321 }
0322
0323 if (wait_time_ms<0)
0324 {
0325 wait_time_ms=0;
0326 }
0327 }
0328
0329 NDRX_LOG(log_dump, "planned cmd wait: %ld ms", wait_time_ms);
0330
0331
0332 abs_timeout->tv_sec = timeval.tv_sec + (wait_time_ms / 1000) ;
0333 nsec_tmp = (wait_time_ms % 1000) * 1000000 + timeval.tv_usec*1000;
0334 abs_timeout->tv_sec+= (nsec_tmp/1000000000);
0335 abs_timeout->tv_nsec = nsec_tmp%1000000000;
0336 }
0337
0338
0339
0340
0341
0342
0343 expublic int command_wait_and_run(int *finished, int *abort)
0344 {
0345 int ret=EXSUCCEED;
0346 char *msg_buffer_max=NULL;
0347 size_t buf_max;
0348 unsigned int prio = 0;
0349 struct timespec abs_timeout;
0350 command_call_t * call;
0351 size_t data_len;
0352 int error;
0353 command_map_t *cmd;
0354 int marked_interactive = EXFALSE;
0355 char context_check[16];
0356 int prev_context = NDRXD_CTX_NOCHG;
0357
0358 NDRX_SYSBUF_MALLOC_OUT(msg_buffer_max, buf_max, ret);
0359
0360 call = (command_call_t *)msg_buffer_max;
0361 memset(msg_buffer_max, 0, sizeof(command_call_t));
0362 snprintf(context_check, sizeof(context_check), ",%d,", G_command_state.context);
0363
0364
0365
0366
0367
0368
0369
0370
0371 if (G_sys_config.restarting)
0372 {
0373
0374 do_restart_chk();
0375 }
0376 else
0377 {
0378
0379 do_sanity_check(EXFALSE);
0380 }
0381
0382
0383
0384
0385
0386
0387
0388 ndrx_q_setblock(G_command_state.listenq, EXTRUE);
0389
0390
0391
0392
0393 get_cmd_wait_time(&abs_timeout);
0394
0395
0396
0397
0398
0399
0400
0401
0402 if (EXFAIL==(data_len = ndrx_mq_timedreceive (G_command_state.listenq,
0403 msg_buffer_max, buf_max, &prio, &abs_timeout)))
0404 {
0405 error = errno;
0406 }
0407 else
0408 {
0409 NDRX_LOG(log_info, ">>>>>>>>>>>>>>>>>>got message, len : %ld",
0410 data_len);
0411
0412
0413 NDRXD_unset_error();
0414 }
0415
0416
0417 if (EXFAIL==data_len && EINTR==error)
0418 {
0419 NDRX_LOG(log_warn, "ex_mq_timedreceive got interrupted!");
0420 ret=EXSUCCEED;
0421 goto out;
0422 }
0423 else if (EXFAIL==data_len && ETIMEDOUT==error)
0424 {
0425
0426 ret=EXSUCCEED;
0427 goto out;
0428 }
0429 else if (EXFAIL==data_len)
0430 {
0431 NDRX_LOG(log_error, "Error occurred when listening on :%s - %d/%s,"
0432 "issuing re-init",
0433 G_command_state.listenq_str, error, strerror(error));
0434
0435
0436
0437 sleep(5);
0438
0439
0440
0441
0442 cmd_close_queue();
0443
0444 if (EXFAIL==cmd_open_queue())
0445 {
0446 ret=EXFAIL;
0447 }
0448 else
0449 {
0450 NDRX_LOG(log_error, "Re-init OK");
0451 ret=EXSUCCEED;
0452 }
0453
0454 goto out;
0455 }
0456
0457
0458 if (NDRX_MAGIC!=call->magic)
0459 {
0460 NDRX_LOG(log_error, "Invalid request received, bad magic: got %ld expected %ld",
0461 call->magic, NDRX_MAGIC);
0462
0463 NDRX_DUMP(log_error, "Invalid request received", msg_buffer_max, data_len);
0464 goto out;
0465 }
0466 #if 0
0467
0468
0469
0470
0471 if (0 != call->command % 2)
0472 {
0473
0474 NDRX_DUMP(log_error, "Response recieved!", msg_buffer_max, data_len);
0475 goto out;
0476 }
0477 #endif
0478 NDRX_LOG(log_debug, "Command ID: %d", call->command);
0479 if (call->command < NDRXD_COM_MIN || call->command > NDRXD_COM_MAX)
0480 {
0481 NDRX_LOG(log_error, "Invalid command received: %d from [%s]!",
0482 call->command, call->reply_queue);
0483
0484
0485 NDRXD_set_error_fmt(NDRXD_ECMDNOTFOUND, "Unknown command %d", call->command);
0486 if (EXSUCCEED!=simple_command_reply(call, EXFAIL, 0L, NULL, NULL, 0L, 0, NULL))
0487 {
0488 userlog("Failed to send reply back to [%s]", call->reply_queue);
0489 }
0490 goto out;
0491 }
0492
0493
0494 cmd = &M_command_map[call->command];
0495
0496
0497 NDRX_LOG(log_debug, "Source: [%s] Command: %d Executing command: %s",
0498 call->reply_queue, call->command, cmd->descr);
0499
0500
0501 if (NULL==strstr(cmd->contexts, context_check) && NULL==strstr(cmd->contexts, ",-1,"))
0502 {
0503 char tmp_modes[128]="";
0504 char tmp_out[128]="";
0505 char *p;
0506 char *savePtr;
0507 int is_normal_only = EXFALSE;
0508
0509
0510 NDRX_STRCPY_SAFE(tmp_modes, cmd->contexts);
0511
0512
0513 p = strtok_r(tmp_modes, ",", &savePtr);
0514 while (p != NULL)
0515 {
0516 int ct = atoi(p);
0517
0518 if (EXEOS==tmp_out[0])
0519 {
0520 NDRX_STRCPY_SAFE(tmp_out, get_ctx_string(ct));
0521
0522 if (NDRXD_CTX_ZERO==ct)
0523 {
0524 is_normal_only=EXTRUE;
0525 }
0526 }
0527 else
0528 {
0529 NDRX_STRCAT_S(tmp_out, sizeof(tmp_out), ", ");
0530 NDRX_STRCAT_S(tmp_out, sizeof(tmp_out), get_ctx_string(ct));
0531
0532 is_normal_only=EXFALSE;
0533 }
0534
0535 p = strtok_r(NULL, ",", &savePtr);
0536 }
0537
0538 if (is_normal_only)
0539 {
0540 NDRXD_set_error_fmt(NDRXD_ENORMAL, "Invalid ndrxd mode. Current is "
0541 "'%s' but required '%s'", get_ctx_string(G_command_state.context), tmp_out);
0542 }
0543 else
0544 {
0545 NDRXD_set_error_fmt(NDRXD_ECONTEXT, "Invalid ndrxd mode. Current is "
0546 "'%s' but required '%s'", get_ctx_string(G_command_state.context), tmp_out);
0547 }
0548
0549 if (EXSUCCEED!=simple_command_reply(call, EXFAIL, 0L, NULL, NULL, 0L, 0, NULL))
0550 {
0551 userlog("Failed to send reply back to [%s]", call->reply_queue);
0552 }
0553
0554 goto out;
0555 }
0556
0557
0558
0559 if (cmd->interactive && NULL==G_last_interactive_call)
0560 {
0561 G_last_interactive_call = call;
0562 marked_interactive=EXTRUE;
0563 }
0564
0565
0566 if (NDRXD_CTX_NOCHG!=cmd->entercontext)
0567 {
0568 prev_context = G_command_state.context;
0569 NDRX_LOG(log_debug, "Entering context: %d", cmd->entercontext);
0570 G_command_state.context = cmd->entercontext;
0571 }
0572
0573
0574 if (NDRXD_COM_XACABORT_RQ==cmd->command)
0575 {
0576 NDRX_LOG(log_warn, "Abort requested from xadmin!");
0577 *abort = EXTRUE;
0578 }
0579
0580 ret = cmd->p_cmd_call(call, msg_buffer_max, data_len, G_command_state.context);
0581
0582
0583 if (marked_interactive)
0584 {
0585 G_last_interactive_call = NULL;
0586 marked_interactive=EXFALSE;
0587 }
0588
0589
0590 out:
0591
0592 if (NDRXD_CTX_NOCHG!=prev_context)
0593 {
0594 G_command_state.context = prev_context;
0595 NDRX_LOG(log_debug, "Restoring context: %d", G_command_state.context);
0596 }
0597
0598 if (NULL!=msg_buffer_max)
0599 {
0600 NDRX_SYSBUF_FREE(msg_buffer_max);
0601 }
0602
0603 return ret;
0604 }
0605
0606
0607
0608
0609
0610
0611