Back to home page

Enduro/X

 
 

    


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