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 #include <string.h>
0035 #include <stdio.h>
0036 #include <stdlib.h>
0037 #include <memory.h>
0038 #include <sys/param.h>
0039
0040 #include <ndrstandard.h>
0041 #include <ndebug.h>
0042 #include <nstdutil.h>
0043
0044 #include <ndrxdcmn.h>
0045 #include <atmi_int.h>
0046 #include <gencall.h>
0047 #include <utlist.h>
0048 #include <Exfields.h>
0049 #include <xa.h>
0050
0051 #include "xa_cmn.h"
0052 #include "exbase64.h"
0053 #include <ndrx.h>
0054 #include <nclopt.h>
0055
0056
0057
0058
0059
0060
0061 exprivate int M_rcv_count;
0062
0063
0064
0065
0066
0067
0068
0069
0070
0071 exprivate int print_buffer(UBFH *p_ub, char *svcnm, short parse)
0072 {
0073 int ret = EXSUCCEED;
0074 char tmxid[1024];
0075 BFLDLEN len;
0076
0077
0078 if (EXSUCCEED!=Bget(p_ub, TMXID, 0, (char *)tmxid, 0L))
0079 {
0080 fprintf(stderr, "Protocol error - TM did not return data, see logs!\n");
0081 NDRX_LOG(log_error, "Failed to read fields: [%s]",
0082 Bstrerror(Berror));
0083 EXFAIL_OUT(ret);
0084 }
0085
0086
0087 printf("XID: -s %s -x %s\n", svcnm, tmxid);
0088
0089
0090
0091 if (parse)
0092 {
0093 XID xid;
0094 size_t sz;
0095
0096 memset(&xid, 0, sizeof(xid));
0097
0098 sz = sizeof(xid);
0099 if (NULL==ndrx_xa_base64_decode((unsigned char *)tmxid, strlen(tmxid),
0100 &sz, (char *)&xid))
0101 {
0102 NDRX_LOG(log_warn, "Failed to parse XID -> Corrupted base64?");
0103 }
0104 else
0105 {
0106
0107 printf("DATA: formatID: 0x%lx (%s) gtrid_length: %ld bqual_length: %ld\n",
0108 xid.formatID,
0109 ((NDRX_XID_FORMAT_ID==xid.formatID ||
0110 NDRX_XID_FORMAT_ID==(long)ntohll(xid.formatID))?
0111 "fmt OK":"Not Enduro/X or different arch"),
0112 xid.gtrid_length, xid.bqual_length);
0113
0114
0115 STDOUT_DUMP(log_info,"RAW XID", &xid, sizeof(xid));
0116
0117 if (NDRX_XID_FORMAT_ID==xid.formatID ||
0118 NDRX_XID_FORMAT_ID==(long)ntohll(xid.formatID))
0119 {
0120 short nodeid;
0121 short srvid;
0122 unsigned char rmid_start;
0123 unsigned char rmid_cur;
0124 long btid;
0125 char xid_str[NDRX_XID_SERIAL_BUFSIZE];
0126
0127 NDRX_LOG(log_debug, "Format OK");
0128
0129
0130
0131 atmi_xa_xid_get_info(&xid, &nodeid,
0132 &srvid, &rmid_start, &rmid_cur, &btid);
0133
0134
0135
0136
0137 memset(xid.data + xid.gtrid_length -
0138 sizeof(long) - sizeof(unsigned char),
0139 0, sizeof(long)+sizeof(unsigned char));
0140
0141 atmi_xa_serialize_xid(&xid, xid_str);
0142
0143 printf("DETAILS: tm_nodeid: %hd tm_srvid: %hd tm_rmid: %d cur_rmid: %d btid: %ld\n",
0144 nodeid, srvid, (int)rmid_start, (int)rmid_cur, btid);
0145 printf("XID_STR: [%s]\n", xid_str);
0146 }
0147
0148 }
0149 }
0150
0151
0152
0153 if (Bpres(p_ub, TMERR_CODE, 0))
0154 {
0155 char msg[MAX_TP_ERROR_LEN+1] = {EXEOS};
0156 short code;
0157 short reason = 0;
0158
0159 Bget(p_ub, TMERR_CODE, 0, (char *)&code, 0L);
0160 Bget(p_ub, TMERR_REASON, 0, (char *)&reason, 0L);
0161 len = sizeof(msg);
0162 Bget(p_ub, TMERR_MSG, 0, msg, &len);
0163
0164 if (0==code && EXEOS==msg[0])
0165 {
0166 NDRX_STRCPY_SAFE(msg, "SUCCEED");
0167 }
0168
0169 printf("RESULT: tp code: %hd, xa reason: %hd, msg: %s\n", code, reason, msg);
0170
0171 }
0172
0173 out:
0174 return ret;
0175 }
0176
0177
0178
0179
0180
0181 exprivate int call_tm(UBFH *p_ub, char *svcnm, short parse)
0182 {
0183 int ret=EXSUCCEED;
0184 int cd;
0185 long revent;
0186 int recv_continue = 1;
0187 int tp_errno;
0188
0189
0190 if (NULL==p_ub)
0191 {
0192 NDRX_LOG(log_error, "Failed to alloc FB!");
0193 EXFAIL_OUT(ret);
0194 }
0195
0196
0197 if (EXSUCCEED!=atmi_xa_reset_tm_call(p_ub))
0198 {
0199 NDRX_LOG(log_error, "Failed to prepare UBF for TM call!");
0200 EXFAIL_OUT(ret);
0201 }
0202
0203 if (EXFAIL == (cd = tpconnect(svcnm,
0204 (char *)p_ub,
0205 0,
0206 TPNOTRAN |
0207 TPRECVONLY)))
0208 {
0209 NDRX_LOG(log_error, "Connect error [%s]", tpstrerror(tperrno) );
0210 ret = EXFAIL;
0211 goto out;
0212 }
0213 NDRX_LOG(log_debug, "Connected OK, cd = %d", cd );
0214
0215 while (recv_continue)
0216 {
0217 recv_continue=0;
0218 if (EXFAIL == tprecv(cd,
0219 (char **)&p_ub,
0220 0L,
0221 0L,
0222 &revent))
0223 {
0224 ret = EXFAIL;
0225 tp_errno = tperrno;
0226 if (TPEEVENT == tp_errno)
0227 {
0228 if (TPEV_SVCSUCC == revent)
0229 ret = EXSUCCEED;
0230 else
0231 {
0232 NDRX_LOG(log_error,
0233 "Unexpected conv event %lx", revent );
0234 EXFAIL_OUT(ret);
0235 }
0236 }
0237 else
0238 {
0239 NDRX_LOG(log_error, "recv error %d", tp_errno );
0240 EXFAIL_OUT(ret);
0241 }
0242 }
0243 else
0244 {
0245
0246
0247 if (EXSUCCEED!=print_buffer(p_ub, svcnm, parse))
0248 {
0249 EXFAIL_OUT(ret);
0250 }
0251 M_rcv_count++;
0252 recv_continue=1;
0253 }
0254 }
0255
0256 out:
0257
0258
0259
0260
0261 return ret;
0262 }
0263
0264
0265
0266
0267
0268
0269
0270
0271 expublic int cmd_recoverlocal(cmd_mapping_t *p_cmd_map, int argc,
0272 char **argv, int *p_have_next)
0273 {
0274 int ret = EXSUCCEED;
0275 atmi_svc_list_t *el, *tmp, *list;
0276 char svcnm[MAXTIDENT+1]={EXEOS};
0277 UBFH *p_ub = atmi_xa_alloc_tm_call(ATMI_XA_RECOVERLOCAL);
0278 short parse = EXFALSE;
0279
0280 ncloptmap_t clopt[] =
0281 {
0282 {'s', BFLD_STRING, (void *)svcnm, sizeof(svcnm),
0283 NCLOPT_OPT|NCLOPT_HAVE_VALUE, "TM Service Name"},
0284 {'p', BFLD_SHORT, (void *)&parse, 0,
0285 NCLOPT_OPT | NCLOPT_TRUEBOOL, "Parse xid"},
0286 {0}
0287 };
0288
0289 if (NULL==p_ub)
0290 {
0291 NDRX_LOG(log_error, "Failed to alloc UBF!");
0292 EXFAIL_OUT(ret);
0293 }
0294
0295
0296 if (nstd_parse_clopt(clopt, EXTRUE, argc, argv, EXFALSE))
0297 {
0298 fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0299 EXFAIL_OUT(ret);
0300 }
0301
0302
0303 if (EXSUCCEED!=tpinit(NULL))
0304 {
0305 fprintf(stderr, "Failed to tpinit(): %s\n", tpstrerror(tperrno));
0306 EXFAIL_OUT(ret);
0307 }
0308
0309 M_rcv_count = 0;
0310
0311 if (EXEOS!=svcnm[0])
0312 {
0313 NDRX_LOG(log_debug, "TM Service name specified: [%s]", svcnm);
0314 ret = call_tm(p_ub, svcnm, parse);
0315 }
0316 else
0317 {
0318 NDRX_LOG(log_debug, "TM Service name not specified - query all");
0319
0320 list = ndrx_get_svc_list(ndrx_tmfilter_common);
0321
0322 LL_FOREACH_SAFE(list,el,tmp)
0323 {
0324
0325 NDRX_LOG(log_info, "About to call service: [%s]\n", el->svcnm);
0326
0327 ret = call_tm(p_ub, el->svcnm, parse);
0328
0329 LL_DELETE(list,el);
0330 NDRX_FREE(el);
0331 }
0332 }
0333
0334 fprintf(stderr, "Recovered %d transactions\n", M_rcv_count);
0335
0336 out:
0337
0338 if (NULL!=p_ub)
0339 {
0340 tpfree((char *)p_ub);
0341 }
0342
0343 return ret;
0344 }
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 exprivate int cmd_x_local(char *msg, char tmcmd, cmd_mapping_t *p_cmd_map,
0357 int argc, char **argv, int *p_have_next)
0358 {
0359 int ret = EXSUCCEED;
0360 atmi_svc_list_t *el, *tmp, *list;
0361 char svcnm[MAXTIDENT+1]={EXEOS};
0362 char xid[sizeof(XID)*2] = {EXEOS};
0363 char msgfmt[128];
0364 short confirm = EXFALSE;
0365 short parse = EXFALSE;
0366
0367 UBFH *p_ub = atmi_xa_alloc_tm_call(tmcmd);
0368
0369 ncloptmap_t clopt[] =
0370 {
0371 {'s', BFLD_STRING, (void *)svcnm, sizeof(svcnm),
0372 NCLOPT_OPT|NCLOPT_HAVE_VALUE, "TM Service Name"},
0373 {'x', BFLD_STRING, (void *)xid, sizeof(xid),
0374 NCLOPT_OPT|NCLOPT_HAVE_VALUE,
0375 "XID to process (for recoverlocal output)"},
0376 {'y', BFLD_SHORT, (void *)&confirm, 0,
0377 NCLOPT_OPT | NCLOPT_TRUEBOOL, "Confirm"},
0378 {'p', BFLD_SHORT, (void *)&parse, 0,
0379 NCLOPT_OPT | NCLOPT_TRUEBOOL, "Parse xid"},
0380
0381 {0}
0382 };
0383
0384
0385 if (EXSUCCEED!=tpinit(NULL))
0386 {
0387 fprintf(stderr, "Failed to tpinit(): %s\n", tpstrerror(tperrno));
0388 EXFAIL_OUT(ret);
0389 }
0390
0391 if (NULL==p_ub)
0392 {
0393 NDRX_LOG(log_error, "Failed to alloc UBF!");
0394 EXFAIL_OUT(ret);
0395 }
0396
0397
0398 if (nstd_parse_clopt(clopt, EXTRUE, argc, argv, EXFALSE))
0399 {
0400 fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0401 EXFAIL_OUT(ret);
0402 }
0403
0404
0405 if (EXEOS!=xid[0] && EXEOS==svcnm[0])
0406 {
0407 fprintf(stderr, "ERROR ! If -x is specified, the -s must be set too!\n");
0408 }
0409
0410 snprintf(msgfmt, sizeof(msgfmt), "Are you sure you want to %s the transaction?",
0411 msg);
0412
0413
0414 if (!ndrx_chk_confirm(msgfmt, confirm))
0415 {
0416 EXFAIL_OUT(ret);
0417 }
0418
0419
0420 M_rcv_count = 0;
0421
0422 if (EXEOS!=xid[0] && EXSUCCEED!=Bchg(p_ub, TMXID, 0, xid, 0))
0423 {
0424 NDRX_LOG(log_error, "Failed to set TMXID: %s", Bstrerror(Berror));
0425 EXFAIL_OUT(ret);
0426 }
0427
0428 if (EXEOS!=svcnm[0])
0429 {
0430 NDRX_LOG(log_debug, "TM Service name specified: [%s]", svcnm);
0431 ret = call_tm(p_ub, svcnm, parse);
0432 }
0433 else
0434 {
0435 NDRX_LOG(log_debug, "TM Service name not specified - query all");
0436
0437 list = ndrx_get_svc_list(ndrx_tmfilter_common);
0438
0439 LL_FOREACH_SAFE(list,el,tmp)
0440 {
0441
0442 NDRX_LOG(log_info, "About to call service: [%s]\n", el->svcnm);
0443
0444 ret = call_tm(p_ub, el->svcnm, parse);
0445
0446 LL_DELETE(list,el);
0447 NDRX_FREE(el);
0448 }
0449 }
0450
0451 fprintf(stderr, "Processed %d transactions\n", M_rcv_count);
0452
0453 out:
0454
0455 if (NULL!=p_ub)
0456 {
0457 tpfree((char *)p_ub);
0458 }
0459
0460 return ret;
0461 }
0462
0463
0464
0465
0466 expublic int cmd_commitlocal(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0467 {
0468 return cmd_x_local("commit", ATMI_XA_COMMITLOCAL, p_cmd_map, argc, argv, p_have_next);
0469 }
0470
0471
0472
0473
0474 expublic int cmd_abortlocal(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0475 {
0476 return cmd_x_local("abort", ATMI_XA_ABORTLOCAL, p_cmd_map, argc, argv, p_have_next);
0477 }
0478
0479
0480
0481
0482 expublic int cmd_forgetlocal(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0483 {
0484 return cmd_x_local("forget", ATMI_XA_FORGETLOCAL, p_cmd_map, argc, argv, p_have_next);
0485 }
0486
0487
0488