Back to home page

Enduro/X

 
 

    


0001 /**
0002  * @brief API Part of the LCF
0003  *
0004  * @file lcf_api.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-2023, Mavimax, Ltd. All Rights Reserved.
0010  * This software is released under one of the following licenses:
0011  * AGPL (with Java and Go exceptions) or Mavimax's license for commercial use.
0012  * See LICENSE file for full text.
0013  * -----------------------------------------------------------------------------
0014  * AGPL license:
0015  *
0016  * This program is free software; you can redistribute it and/or modify it under
0017  * the terms of the GNU Affero General Public License, version 3 as published
0018  * by the Free Software Foundation;
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 Affero General Public License, version 3
0023  * for more details.
0024  *
0025  * You should have received a copy of the GNU Affero General Public License along 
0026  * with this program; if not, write to the Free Software Foundation, Inc.,
0027  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0028  *
0029  * -----------------------------------------------------------------------------
0030  * A commercial use license is available from Mavimax, Ltd
0031  * contact@mavimax.com
0032  * -----------------------------------------------------------------------------
0033  */
0034 
0035 /*---------------------------Includes-----------------------------------*/
0036 #include <ndrstandard.h>
0037 #include <lcfint.h>
0038 #include <ndebug.h>
0039 #include <nstd_shm.h>
0040 #include <ndebugcmn.h>
0041 #include <sys_unix.h>
0042 #include <nerror.h>
0043 #include <lcf.h>
0044 /*---------------------------Externs------------------------------------*/
0045 /*---------------------------Macros-------------------------------------*/
0046 
0047 #define API_ENTRY {_Nunset_error();}
0048 
0049 /*---------------------------Enums--------------------------------------*/
0050 /*---------------------------Typedefs-----------------------------------*/
0051 /*---------------------------Globals------------------------------------*/
0052 /*---------------------------Statics------------------------------------*/
0053 /*---------------------------Prototypes---------------------------------*/
0054 
0055 /**
0056  * Register xadmin lcf command
0057  * Code cannot be internal one
0058  * @param xcmd filled structure of the command
0059  * @return EXSUCCEED/EXFAIL
0060  */
0061 expublic int ndrx_lcf_xadmin_add(ndrx_lcf_reg_xadmin_t *xcmd)
0062 {
0063     int ret = EXSUCCEED;
0064     long allow_flags;
0065     API_ENTRY;
0066     
0067     if (NULL==xcmd)
0068     {
0069         _Nset_error_fmt(NEINVAL, "xcmd cannot be NULL");
0070         NDRX_LOG_EARLY(log_error, "ERROR: xcmd cannot be NULL");
0071         EXFAIL_OUT(ret);
0072     }
0073     
0074     if (xcmd->version < NDRX_LCF_XCMD_VERSION)
0075     {
0076         _Nset_error_fmt(NEVERSION, "Invalid argument - version minimum: %d got: %d",
0077                 NDRX_LCF_XCMD_VERSION, xcmd->version);
0078         NDRX_LOG_EARLY(log_error, "Invalid argument - version minimum: %d got: %d",
0079                 NDRX_LCF_XCMD_VERSION, xcmd->version);
0080         EXFAIL_OUT(ret);
0081     }
0082     
0083     if (EXEOS==xcmd->cmdstr[0])
0084     {
0085         _Nset_error_fmt(NEINVAL, "xcmd->cmdstr cannot be empty");
0086         NDRX_LOG_EARLY(log_error, "xcmd->cmdstr cannot be NULL");
0087         EXFAIL_OUT(ret);
0088     }
0089     
0090     if (EXTRUE!=ndrx_str_valid_cid(xcmd->cmdstr, NDRX_LCF_ADMINCMD_MAX))
0091     {
0092         _Nset_error_fmt(NEINVAL, "xcmd->cmdstr has invalid characters or empty val");
0093         NDRX_LOG_EARLY(log_error, "xcmd->cmdstr has invalid characters or empty val");
0094         EXFAIL_OUT(ret);
0095     }
0096     
0097     /* check flags */
0098     allow_flags = NDRX_LCF_FLAG_ALL
0099             |NDRX_LCF_FLAG_ARGA
0100             |NDRX_LCF_FLAG_ARGB
0101             |NDRX_LCF_FLAG_DOSTARTUP
0102             |NDRX_LCF_FLAG_DOSTARTUPEXP;
0103     
0104     allow_flags = ~allow_flags;
0105     
0106     if (xcmd->dfltflags & allow_flags)
0107     {
0108         _Nset_error_fmt(NEINVAL, "Invalid flags given: 0x%lx", xcmd->dfltflags & allow_flags);
0109         NDRX_LOG_EARLY(log_error, "Invalid flags given: 0x%lx", xcmd->dfltflags & allow_flags);
0110         EXFAIL_OUT(ret);
0111     }
0112     
0113     if (! (xcmd->command>=NDRX_LCF_CMD_MIN_CUST && xcmd->command<=NDRX_LCF_CMD_MAX_CUST))
0114     {
0115         _Nset_error_fmt(NEINVAL, "xcmd->command code out of the range: min %d max %d got %d",
0116                 NDRX_LCF_CMD_MIN_CUST, NDRX_LCF_CMD_MAX_CUST, xcmd->command);
0117         NDRX_LOG_EARLY(log_error, "xcmd->command code out of the range: min %d max %d got %d",
0118                 NDRX_LCF_CMD_MIN_CUST, NDRX_LCF_CMD_MAX_CUST, xcmd->command);
0119         EXFAIL_OUT(ret);
0120     }
0121     
0122     ret=ndrx_lcf_xadmin_add_int(xcmd);
0123     
0124 out:
0125     return ret;
0126     
0127 }
0128 
0129 
0130 /**
0131  * Register callback function. Uses may only add the functions.
0132  * No chance to delete to avoid any issues with threads performing the lookups
0133  * @param cfunc callback def with command code
0134  * @return EXSUCCEED/EXFAIL
0135  */
0136 expublic int ndrx_lcf_func_add(ndrx_lcf_reg_func_t *cfunc)
0137 {
0138     int ret = EXSUCCEED;
0139     API_ENTRY;
0140 
0141     if (NULL==cfunc)
0142     {
0143         _Nset_error_fmt(NEINVAL, "cfunc cannot be NULL");
0144         NDRX_LOG_EARLY(log_error, "cfunc cannot be NULL");
0145         EXFAIL_OUT(ret);
0146     }
0147     
0148     if (cfunc->version < NDRX_LCF_CCMD_VERSION)
0149     {
0150         _Nset_error_fmt(NEVERSION, "Invalid argument version minimum: %d got: %d",
0151                 NDRX_LCF_CCMD_VERSION, cfunc->version);
0152         NDRX_LOG_EARLY(log_error, "Invalid argument version minimum: %d got: %d",
0153                 NDRX_LCF_CCMD_VERSION, cfunc->version);
0154         EXFAIL_OUT(ret);
0155     }
0156     
0157     if (NULL==cfunc->pf_callback)
0158     {
0159         _Nset_error_fmt(NEINVAL, "pf_callback cannot be NULL");
0160         NDRX_LOG_EARLY(log_error, "pf_callback cannot be NULL");
0161         EXFAIL_OUT(ret);
0162     }
0163     
0164     if (EXEOS==cfunc->cmdstr[0])
0165     {
0166         _Nset_error_fmt(NEINVAL, "cfunc->cmdstr cannot be empty");
0167         NDRX_LOG_EARLY(log_error, "cfunc->cmdstr cannot be NULL");
0168         EXFAIL_OUT(ret);
0169     }
0170     
0171     if (EXTRUE!=ndrx_str_valid_cid(cfunc->cmdstr, NDRX_LCF_ADMINCMD_MAX))
0172     {
0173         _Nset_error_fmt(NEINVAL, "xcmd->cmdstr has invalid characters or empty val");
0174         NDRX_LOG_EARLY(log_error, "xcmd->cmdstr has invalid characters or empty val");
0175         EXFAIL_OUT(ret);
0176     }
0177         
0178     ret = ndrx_lcf_func_add_int(cfunc);
0179     
0180 out:
0181     return ret;
0182     
0183 }
0184 
0185 /**
0186  * Public API function for publishing LCF command
0187  * @param slot slot number where to publish. Note
0188  * @param cmd
0189  * @return EXSUCCEED/EXFAIL
0190  */
0191 expublic int ndrx_lcf_publish(int slot, ndrx_lcf_command_t *cmd)
0192 {
0193     int ret = EXSUCCEED;
0194     API_ENTRY;
0195     /* pull in the debug init, as LCF must be open */
0196     NDRX_DBG_INIT_ENTRY;
0197     
0198     if (NULL==cmd)
0199     {
0200         _Nset_error_msg(NEINVAL, "cmd cannot be NULL");
0201         NDRX_LOG(log_error, "cmd cannot be NULL");
0202         EXFAIL_OUT(ret);
0203     }
0204     
0205     if (cmd->version < NDRX_LCF_LCMD_VERSION)
0206     {
0207         _Nset_error_fmt(NEVERSION, "Invalid argument version minimum: %d got: %d",
0208                 NDRX_LCF_CCMD_VERSION, cmd->version);
0209         NDRX_LOG_EARLY(log_error, "Invalid argument version minimum: %d got: %d",
0210                 NDRX_LCF_CCMD_VERSION, cmd->version);
0211         EXFAIL_OUT(ret);
0212     }
0213     
0214     /* flags shall not contain feedback fields */
0215     
0216     if ((cmd->flags & NDRX_LCF_FLAG_FBACK_CODE) ||
0217             (cmd->flags & NDRX_LCF_FLAG_FBACK_MSG))
0218     {
0219         _Nset_error_fmt(NEINVAL, "Found feedback flags - not allowed in publishing");
0220         NDRX_LOG(log_error, "Found feedback flags - not allowed in publishing");
0221         EXFAIL_OUT(ret);
0222     }
0223     
0224     if (0!=cmd->fbackcode)
0225     {
0226         _Nset_error_fmt(NEINVAL, "cmd->fbackcode is not 0 (%ld)", cmd->fbackcode);
0227         NDRX_LOG(log_error, "cmd->fbackcode is not 0 (%ld)", cmd->fbackcode);
0228         EXFAIL_OUT(ret);
0229     }
0230     
0231     if (EXEOS!=cmd->fbackmsg[0])
0232     {
0233         _Nset_error_fmt(NEINVAL, "cmd->fbackmsg is not empty");
0234         NDRX_LOG(log_error, "cmd->fbackmsg is not empty");
0235         EXFAIL_OUT(ret);
0236     }
0237     
0238     if (EXEOS==cmd->cmdstr[0])
0239     {
0240         _Nset_error_msg(NEINVAL, "cmd->cmdstr is empty");
0241         NDRX_LOG(log_error, "cmd->cmdstr is empty");
0242         EXFAIL_OUT(ret);
0243     }
0244     
0245     /* check that buffers are OK, maybe this process will die
0246      * but at least others will be safe and sound
0247      */
0248     if (strlen(cmd->cmdstr) > NDRX_LCF_ADMINCMD_MAX)
0249     {
0250         _Nset_error_msg(NEINVAL, "cmd->cmdstr invalid length");
0251         NDRX_LOG(log_error, "cmd->cmdstr invalid length");
0252         EXFAIL_OUT(ret);
0253     }
0254     
0255     if (strlen(cmd->arg_a) > PATH_MAX)
0256     {
0257         _Nset_error_msg(NEINVAL, "cmd->arg_a invalid length");
0258         NDRX_LOG(log_error, "cmd->arg_a invalid length");
0259         EXFAIL_OUT(ret);
0260     }
0261     
0262     if (strlen(cmd->arg_b) > NDRX_NAME_MAX)
0263     {
0264         _Nset_error_msg(NEINVAL, "cmd->arg_b invalid length");
0265         NDRX_LOG(log_error, "cmd->arg_b invalid length");
0266         EXFAIL_OUT(ret);
0267     }
0268     
0269     if (strlen(cmd->procid) > NDRX_NAME_MAX)
0270     {
0271         _Nset_error_msg(NEINVAL, "cmd->procid invalid length");
0272         NDRX_LOG(log_error, "cmd->procid invalid length");
0273         EXFAIL_OUT(ret);
0274     }
0275     
0276     if (EXEOS==cmd->procid[0] && !(cmd->flags & NDRX_LCF_FLAG_ALL) && 
0277             cmd->command!=NDRX_LCF_CMD_DISABLE)
0278     {
0279         _Nset_error_msg(NEINVAL, "Target is not selected (not NDRX_LCF_FLAG_ALL and procid empty)");
0280         NDRX_LOG(log_error, "Target is not selected (not NDRX_LCF_FLAG_ALL and procid empty)");
0281         EXFAIL_OUT(ret);
0282     }
0283     
0284     if (EXEOS==cmd->procid[0] && (cmd->flags & NDRX_LCF_FLAG_DOREX))
0285     {
0286         _Nset_error_msg(NEINVAL, "procid is empty, cannot have NDRX_LCF_FLAG_DOREX");
0287         NDRX_LOG(log_error, "procid is empty, cannot have NDRX_LCF_FLAG_DOREX");
0288         EXFAIL_OUT(ret);
0289     }
0290     
0291     if (cmd->applied || cmd->failed ||cmd->seen)
0292     {
0293         _Nset_error_msg(NEINVAL, "applied/failed/seen must contain 0");
0294         NDRX_LOG(log_error, "applied/failed/seen must contain 0");
0295         EXFAIL_OUT(ret);
0296     }
0297     
0298     ret = ndrx_lcf_publish_int(slot, cmd);
0299     
0300 out:
0301     return ret;
0302 }
0303 
0304 
0305 /* vim: set ts=4 sw=4 et smartindent: */