Back to home page

Enduro/X

 
 

    


0001 /* 
0002 ** `pc' (print clients) command implementation
0003 **
0004 ** @file cmd_pc.c
0005 ** 
0006 ** -----------------------------------------------------------------------------
0007 ** Enduro/X Middleware Platform for Distributed Transaction Processing
0008 ** Copyright (C) 2015, Mavimax, Ltd. All Rights Reserved.
0009 ** This software is released under one of the following licenses:
0010 ** GPL or Mavimax's license for commercial use.
0011 ** -----------------------------------------------------------------------------
0012 ** GPL license:
0013 ** 
0014 ** This program is free software; you can redistribute it and/or modify it under
0015 ** the terms of the GNU General Public License as published by the Free Software
0016 ** Foundation; either version 2 of the License, or (at your option) any later
0017 ** version.
0018 **
0019 ** This program is distributed in the hope that it will be useful, but WITHOUT ANY
0020 ** WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
0021 ** PARTICULAR PURPOSE. See the GNU General Public License for more details.
0022 **
0023 ** You should have received a copy of the GNU General Public License along with
0024 ** this program; if not, write to the Free Software Foundation, Inc., 59 Temple
0025 ** Place, Suite 330, Boston, MA 02111-1307 USA
0026 **
0027 ** -----------------------------------------------------------------------------
0028 ** A commercial use license is available from Mavimax, Ltd
0029 ** contact@mavimax.com
0030 ** -----------------------------------------------------------------------------
0031 */
0032 #include <string.h>
0033 #include <stdio.h>
0034 #include <stdlib.h>
0035 #include <memory.h>
0036 #include <sys/param.h>
0037 #include <string.h>
0038 
0039 #include <ndrstandard.h>
0040 #include <ndebug.h>
0041 #include <nstdutil.h>
0042 
0043 #include <ndrxdcmn.h>
0044 #include <atmi_int.h>
0045 #include <gencall.h>
0046 #include <utlist.h>
0047 #include <Exfields.h>
0048 
0049 #include "xa_cmn.h"
0050 #include <ndrx.h>
0051 #include <cpm.h>
0052 #include <nclopt.h>
0053 /*---------------------------Externs------------------------------------*/
0054 /*---------------------------Macros-------------------------------------*/
0055 #define SUBSECT_SEP     "/"
0056 /*---------------------------Enums--------------------------------------*/
0057 /*---------------------------Typedefs-----------------------------------*/
0058 /*---------------------------Globals------------------------------------*/
0059 /*---------------------------Statics------------------------------------*/
0060 /*---------------------------Prototypes---------------------------------*/
0061 
0062 /**
0063  * Print the processes
0064  * We will run in conversation mode.
0065  * @param svcnm
0066  * @return SUCCEED/FAIL
0067  */
0068 exprivate int print_buffer(UBFH *p_ub, char *svcnm)
0069 {
0070     int ret = EXSUCCEED;
0071     char output[CPM_OUTPUT_SIZE];
0072     
0073     if (EXSUCCEED!=Bget(p_ub, EX_CPMOUTPUT, 0, (char *)output, 0L))
0074     {
0075         NDRX_LOG(log_error, "Failed to read fields: [%s]", 
0076                 Bstrerror(Berror));
0077         EXFAIL_OUT(ret);
0078     }
0079 
0080     printf("%s\n", output);
0081     
0082 out:
0083     return ret;
0084 }
0085 
0086 /**
0087  * This basically tests the normal case when all have been finished OK!
0088  * @return
0089  */
0090 exprivate int call_cpm(char *svcnm, char *cmd, char *tag, char *subsect, long twait)
0091 {
0092     UBFH *p_ub = (UBFH *)tpalloc("UBF", NULL, CPM_DEF_BUFFER_SZ);
0093     int ret=EXSUCCEED;
0094     int cd;
0095     long revent;
0096     int recv_continue = 1;
0097     int tp_errno;
0098     int rcv_count = 0;
0099     long flags = TPNOTRAN | TPRECVONLY;
0100     
0101     /* Setup the call buffer... */
0102     if (NULL==p_ub)
0103     {
0104         NDRX_LOG(log_error, "Failed to alloc FB!");        
0105         EXFAIL_OUT(ret);
0106     }
0107     
0108     if (twait > 0)
0109     {
0110         if (EXSUCCEED!=Bchg(p_ub, EX_CPMWAIT, 0, (char *)&twait, 0L))
0111         {
0112             NDRX_LOG(log_error, "Failed to set EX_CPMWAIT: %s!", Bstrerror(Berror));
0113             EXFAIL_OUT(ret);
0114         }
0115     }
0116     
0117     if (EXSUCCEED!=Bchg(p_ub, EX_CPMCOMMAND, 0, cmd, 0L))
0118     {
0119         NDRX_LOG(log_error, "Failed to set EX_CPMCOMMAND to %s!", EX_CPMCOMMAND);        
0120         EXFAIL_OUT(ret);
0121     }
0122     
0123     if (0!=strcmp(CPM_CMD_PC, cmd))
0124     {
0125         if (EXSUCCEED!=Bchg(p_ub, EX_CPMTAG, 0, tag, 0L))
0126         {
0127             NDRX_LOG(log_error, "Failed to set EX_CPMCOMMAND to %s!", tag);        
0128             EXFAIL_OUT(ret);
0129         }
0130 
0131         if (EXSUCCEED!=Bchg(p_ub, EX_CPMSUBSECT, 0, subsect, 0L))
0132         {
0133             NDRX_LOG(log_error, "Failed to set EX_CPMSUBSECT to %s!", subsect);        
0134             EXFAIL_OUT(ret);
0135         }
0136     }
0137     
0138     /* if we run batch commands, the no time-out please */
0139     
0140     if (EXFAIL == (cd = tpconnect(svcnm,
0141                                     (char *)p_ub,
0142                                     0,
0143                                     TPNOTRAN |
0144                                     TPRECVONLY)))
0145     {
0146         NDRX_LOG(log_error, "Connect error [%s]", tpstrerror(tperrno) );
0147         
0148         ret = EXFAIL;
0149         goto out;
0150     }
0151     NDRX_LOG(log_debug, "Connected OK, cd = %d", cd );
0152 
0153     while (recv_continue)
0154     {
0155         recv_continue=0;
0156         if (EXFAIL == tprecv(cd,
0157                             (char **)&p_ub,
0158                             0L,
0159                             0L,
0160                             &revent))
0161         {
0162             ret = EXFAIL;
0163             tp_errno = tperrno;
0164             if (TPEEVENT == tp_errno)
0165             {
0166                 if (TPEV_SVCSUCC == revent)
0167                         ret = EXSUCCEED;
0168                 else
0169                 {
0170                     NDRX_LOG(log_error,
0171                              "Unexpected conv event %lx", revent );
0172                     EXFAIL_OUT(ret);
0173                 }
0174             }
0175             else if (TPETIME == tp_errno)
0176             {
0177                 fprintf(stderr, "Error ! Timeout waiting on server reply, -w shall be smaller than NDRX_TOUT env.\n");
0178                 fprintf(stderr, "The cpmsrv will complete the operation in background...\n");
0179             }
0180             else
0181             {
0182                 NDRX_LOG(log_error, "recv error %d", tp_errno  );
0183                 EXFAIL_OUT(ret);
0184             }
0185         }
0186         else
0187         {
0188             /*
0189             fprintf(stderr, "Response: \n");
0190             Bfprint(p_ub, stderr);
0191             */
0192             if (EXSUCCEED!=print_buffer(p_ub, svcnm))
0193             {
0194                 EXFAIL_OUT(ret);
0195             }
0196             rcv_count++;
0197             recv_continue=1;
0198         }
0199     }
0200 
0201 out:
0202 
0203     if (NULL!=p_ub)
0204     {
0205         tpfree((char *)p_ub);
0206     }
0207 /*
0208     tpdiscon(cd);
0209 */
0210     return ret;
0211 }
0212 
0213 /**
0214  * Print Clients
0215  * @param p_cmd_map
0216  * @param argc
0217  * @param argv
0218  * @return SUCCEED
0219  */
0220 expublic int cmd_pc(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0221 {
0222     int ret = EXSUCCEED;
0223     
0224     call_cpm(NDRX_SVC_CPM, CPM_CMD_PC, NULL, NULL, 0);
0225     
0226 out:
0227     return ret;
0228 }
0229 
0230 /**
0231  * Stop client
0232  * @param p_cmd_map
0233  * @param argc
0234  * @param argv
0235  * @return SUCCEED
0236  */
0237 expublic int cmd_sc(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0238 {
0239     int ret = EXSUCCEED;
0240     char tag[CPM_TAG_LEN];
0241     char subsect[CPM_SUBSECT_LEN] = {"-"};
0242     long twait = 0;
0243     char *p;
0244     ncloptmap_t clopt[] =
0245     {
0246         {'t', BFLD_STRING, (void *)tag, sizeof(tag), 
0247                                 NCLOPT_MAND | NCLOPT_HAVE_VALUE, "Tag"},
0248         {'s', BFLD_STRING, (void *)subsect, sizeof(subsect), 
0249                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Subsection"},
0250         {'w', BFLD_LONG, (void *)&twait, sizeof(twait), 
0251                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Wait milliseconds"},
0252         {0}
0253     };
0254     
0255     if (argc>=2 && '-'!=argv[1][0])
0256     {
0257         /* parse the tag/sub */
0258         p = strtok(argv[1], SUBSECT_SEP);
0259         
0260         if (NULL!=p)
0261         {
0262             NDRX_STRCPY_SAFE(tag, p);
0263         }
0264         else
0265         {
0266             fprintf(stderr, "Missing tag! Syntax sc <TAG>[/SUBSECT], e.g. sc POS/1\n");
0267             EXFAIL_OUT(ret);
0268         }
0269         
0270         p = strtok(NULL, SUBSECT_SEP);
0271         
0272         if (NULL!=p)
0273         {
0274             NDRX_STRCPY_SAFE(subsect, p);
0275         }
0276     }
0277     else
0278     {
0279         /* parse command line */
0280         if (nstd_parse_clopt(clopt, EXTRUE,  argc, argv, EXFALSE))
0281         {
0282             fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0283             EXFAIL_OUT(ret);
0284         }
0285     }
0286     
0287     ret = call_cpm(NDRX_SVC_CPM, CPM_CMD_SC, tag, subsect, twait);
0288     
0289 out:
0290     return ret;
0291 }
0292 
0293 /**
0294  * Boot client
0295  * @param p_cmd_map
0296  * @param argc
0297  * @param argv
0298  * @return SUCCEED
0299  */
0300 expublic int cmd_bc(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0301 {
0302     int ret = EXSUCCEED;
0303     char tag[CPM_TAG_LEN];
0304     char subsect[CPM_SUBSECT_LEN] = {"-"};
0305     long twait = 0;
0306     char *p;
0307     ncloptmap_t clopt[] =
0308     {
0309         {'t', BFLD_STRING, (void *)tag, sizeof(tag), 
0310                                 NCLOPT_MAND | NCLOPT_HAVE_VALUE, "Tag"},
0311         {'s', BFLD_STRING, (void *)subsect, sizeof(subsect), 
0312                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Subsection"},
0313         {'w', BFLD_LONG, (void *)&twait, sizeof(twait), 
0314                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Wait milliseconds"},
0315         {0}
0316     };
0317     
0318     /* parse command line */
0319     if (argc>=2 && '-'!=argv[1][0])
0320     {
0321         /* parse the tag/sub */
0322         p = strtok(argv[1], SUBSECT_SEP);
0323         
0324         if (NULL!=p)
0325         {
0326             NDRX_STRCPY_SAFE(tag, p);
0327         }
0328         else
0329         {
0330             fprintf(stderr, "Missing tag! Syntax bc <TAG>[/SUBSECT], e.g. sc POS/1\n");
0331             EXFAIL_OUT(ret);
0332         }
0333         
0334         p = strtok(NULL, SUBSECT_SEP);
0335         
0336         if (NULL!=p)
0337         {
0338             NDRX_STRCPY_SAFE(subsect, p);
0339         }
0340     }
0341     else if (nstd_parse_clopt(clopt, EXTRUE,  argc, argv, EXFALSE))
0342     {
0343         fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0344         EXFAIL_OUT(ret);
0345     }
0346     
0347     ret = call_cpm(NDRX_SVC_CPM, CPM_CMD_BC, tag, subsect, twait);
0348     
0349 out:
0350     return ret;
0351 }
0352 
0353 /**
0354  * Reload client
0355  * @param p_cmd_map
0356  * @param argc
0357  * @param argv
0358  * @return SUCCEED
0359  */
0360 expublic int cmd_rc(cmd_mapping_t *p_cmd_map, int argc, char **argv, int *p_have_next)
0361 {
0362     int ret = EXSUCCEED;
0363     char tag[CPM_TAG_LEN];
0364     char subsect[CPM_SUBSECT_LEN] = {"-"};
0365     long twait = 0;
0366     char *p;
0367     
0368     ncloptmap_t clopt[] =
0369     {
0370         {'t', BFLD_STRING, (void *)tag, sizeof(tag), 
0371                                 NCLOPT_MAND | NCLOPT_HAVE_VALUE, "Tag"},
0372         {'s', BFLD_STRING, (void *)subsect, sizeof(subsect), 
0373                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Subsection"},
0374         {'w', BFLD_LONG, (void *)&twait, sizeof(twait), 
0375                                 NCLOPT_OPT | NCLOPT_HAVE_VALUE, "Wait milliseconds"},
0376         {0}
0377     };
0378     
0379     /* parse command line */
0380     if (argc>=2 && '-'!=argv[1][0])
0381     {
0382         /* parse the tag/sub */
0383         p = strtok(argv[1], SUBSECT_SEP);
0384         
0385         if (NULL!=p)
0386         {
0387             NDRX_STRCPY_SAFE(tag, p);
0388         }
0389         else
0390         {
0391             fprintf(stderr, "Missing tag! Syntax rc <TAG>[/SUBSECT], e.g. sc POS/1\n");
0392             EXFAIL_OUT(ret);
0393         }
0394         
0395         p = strtok(NULL, SUBSECT_SEP);
0396         
0397         if (NULL!=p)
0398         {
0399             NDRX_STRCPY_SAFE(subsect, p);
0400         }
0401     }
0402     else if (nstd_parse_clopt(clopt, EXTRUE,  argc, argv, EXFALSE))
0403     {
0404         fprintf(stderr, XADMIN_INVALID_OPTIONS_MSG);
0405         EXFAIL_OUT(ret);
0406     }
0407     
0408     ret = call_cpm(NDRX_SVC_CPM, CPM_CMD_RC, tag, subsect, twait);
0409     
0410 out:
0411     return ret;
0412 }