// // Created by xajhu on 2021/8/3 0003. // #include #include #if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L #include #else #include #endif #include "args/argtable3.h" #include "cmdline.h" #include "user_errno.h" #include "task_manager.h" #include "init.h" #include "crypto.h" #include "misc.h" #include "config.h" #include "s2j/s2j.h" #include "msg_queue.h" #include "dhcpd.h" #include "prj_config.h" #define REG_ICASE (ARG_REX_ICASE) typedef void (*HelpCmdCb)(void *, const char *, void *); typedef int (*ProcessCmdCb)(void **, const char *, void *); typedef struct { void *argTbl; int nArgItem; int *pErrCode; ProcessCmdCb pCmd; HelpCmdCb pHelp; const char *pDesc; } ARG_TBL_INFO, *PARG_TBL_INFO; static PARG_TBL_INFO g_pArgTbl = NULL; static unsigned int g_nArgTbl = 0; static const char *g_toolsKey[][2] = { {"cfg_all", "get all configuration information" }, {"mem_info", "show the memory alloc information" }, {"sys_info", "show the system and hardware information"}, }; static int get_reg_cmd(void *pTbl[]) { return ((arg_rex_t *)pTbl[0])->count; } static void *get_arg_err(void *pTbl[], PARG_TBL_INFO pInfo) { return pTbl[pInfo->nArgItem - 1]; } static arg_lit_t *get_help_cmd(void *pTbl[], PARG_TBL_INFO pInfo) { return pTbl[pInfo->nArgItem - 2]; } static void show_help(const char *pAppName) { int i; for (i = 0; i < g_nArgTbl; i++) { if (i == 0) { printf("Usage: \033[1;33m%s", pAppName); } else { printf(" \033[1;33m%s", pAppName); } arg_print_syntax(stdout, g_pArgTbl[i].argTbl, "\n"); } printf("\033[0m\nThe Intrusion Detection Systems agent application\n"); printf("\nMandatory arguments to long options are mandatory for short options too.\n"); arg_print_glossary(stdout, g_pArgTbl[i - 1].argTbl, " \033[1;32m%-30s %s\033[0m\n"); printf("\nSupport subcommand: \n"); for (i = 0; i < g_nArgTbl - 1; i++) { if (g_pArgTbl[i].pDesc) { printf("%s", g_pArgTbl[i].pDesc); arg_print_glossary(stdout, g_pArgTbl[i].argTbl, " %-30s %s\n"); } } printf("\n\nTry '\033[1;31m%s --help\033[0m' for more information.\n", pAppName); } static void cmdn_help(void *pTbl, const char *pName, void *pErr) { if (pErr != NULL) { printf("\033[1;31m"); arg_print_errors(stdout, pErr, ""); printf("\033[0m\n"); } printf("usage : %s", pName); arg_print_syntax(stdout, pTbl, "\n"); printf("\nMandatory arguments to long options are mandatory for short options too.\n"); arg_print_glossary(stdout, pTbl, "%-30s %s\n"); } static void cmd2_help(void *pTbl, const char *pName, void *pErr) { int i; cmdn_help(pTbl, pName, pErr); printf("\n\nSupport keys:\n"); printf(" \033[1;4;35mConfiguration\033[0m:\n"); for (i = 0; i < ARRAY_SIZE(g_toolsKey); i++) { printf(" \033[4m%s\033[0m:\t %s\n", g_toolsKey[i][0], g_toolsKey[i][1]); } } static int on_cmd1(void *pTbl[], const char *pName, void *pInfo) { int ret; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; const char *pCfgFile = ((arg_file_t *)pTbl[1])->filename[0]; const char *pCfgDir = ((arg_file_t *)pTbl[2])->filename[0]; const char *pKey = ((arg_str_t *)pTbl[3])->sval[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } if ((ret = user_init(pCfgFile, pCfgDir, pKey, 0)) != ERR_SUCCESS) { printf("System init error: %d\n", ret); return ret; } return ret; } static cJSON *s2j_mq_msg(void *pObj) { PMQ_CMD_MSG pMsg = (PMQ_CMD_MSG)pObj; s2j_create_json_obj(pJsonObj); s2j_json_set_basic_element(pJsonObj, pMsg, string, cmd); s2j_json_set_basic_element(pJsonObj, pMsg, string, key); s2j_json_set_basic_element(pJsonObj, pMsg, string, value); return pJsonObj; } static int on_cmd2(void *pTbl[], const char *pName, void *pInfo) { int ret, i; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; MQ_CMD_MSG msg; cJSON *pJsonObj; const char *pJsonStr; const char *pSvr = ((arg_str_t *)pTbl[1])->sval[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } memset(&msg, 0, sizeof(MQ_CMD_MSG)); strncpy(msg.cmd, ((arg_str_t *)pTbl[2])->sval[0], MAX_PATH - 1); strncpy(msg.key, ((arg_str_t *)pTbl[3])->sval[0], MAX_PATH - 1); strncpy(msg.value, ((arg_str_t *)pTbl[4])->sval[0], MAX_PATH - 1); if (strcmp(msg.cmd, "get") != 0 && strcmp(msg.cmd, "set") != 0) { printf("Error command: %s\n", msg.cmd); return -ERR_INPUT_PARAMS; } ret = FALSE; for (i = 0; i < ARRAY_SIZE(g_toolsKey); i++) { if (strcmp(g_toolsKey[i][0], msg.key) == 0) { ret = TRUE; break; } } if (ret == FALSE) { printf("Error key: %s\n", msg.key); return -ERR_INPUT_PARAMS; } pJsonObj = s2j_mq_msg(&msg); if (pJsonObj == NULL) { return -ERR_JSON_CREAT_OBJ; } pJsonStr = cJSON_PrintUnformatted(pJsonObj); #ifdef ZEROMQ_ON ret = mq_cmd_run(pSvr, pJsonStr); #else ret = ERR_SUCCESS; #endif cJSON_Delete(pJsonObj); free((void *)pJsonStr); return (ret == ERR_SUCCESS) ? ERR_MENU_EXIT : ret; } static int on_cmd3(void *pTbl[], const char *pName, void *pInfo) { const char *pRet; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; int type = ((arg_lit_t *)pTbl[1])->count; const char *pValue = ((arg_str_t *)pTbl[2])->sval[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } if (type == 0) { pRet = base64_encode((unsigned char *)pValue, strlen(pValue)); } else { pRet = (const char *)base64_decode(pValue, NULL); } if (pRet == NULL) { return type == 0 ? -ERR_EVP_ENCRYPTION : -ERR_EVP_DECRYPTION; } printf("Base64 %s: {%s} --> [%s]\n", type == 0 ? "encode" : "decode", pValue, pRet); free((void *)pRet); return ERR_MENU_EXIT; } static int on_cmd4(void *pTbl[], const char *pName, void *pInfo) { char *pHashValue = NULL; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; const char *type = ((arg_str_t *)pTbl[1])->sval[0]; const char *pFile = ((arg_file_t *)pTbl[2])->filename[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } if (strcmp(type, "sha256") == 0) { hash_digest_file(HASH_TYPE_SHA256, pFile, &pHashValue); } else if (strcmp(type, "sha1") == 0) { hash_digest_file(HASH_TYPE_SHA1, pFile, &pHashValue); } else if (strcmp(type, "md5") == 0) { hash_digest_file(HASH_TYPE_MD5, pFile, &pHashValue); } else { printf("Unsupported type: %s\n", type); return -ERR_UNSUP_EVP_TYPE; } printf("%s %s hash value: [%s]\n", type, pFile, pHashValue); free(pHashValue); return ERR_MENU_EXIT; } static int on_cmd5(void *pTbl[], const char *pName, void *pInfo) { int algType; const char *strRet; unsigned char *buf; int outSize = 0; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; int encrypt = ((arg_lit_t *)pTbl[1])->count; const char *alg = ((arg_str_t *)pTbl[2])->sval[0]; const char *key = ((arg_str_t *)pTbl[3])->sval[0]; const char *data = ((arg_str_t *)pTbl[4])->sval[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } if (strcmp(alg, "3des_ecb") == 0) { algType = DES3_ECB_PKCS7PADDING; } else if (strcmp(alg, "3des_cbc") == 0) { algType = DES3_CBC_PKCS7PADDING; } else if (strcmp(alg, "3des_ofb") == 0) { algType = DES3_OFB_PKCS7PADDING; } else if (strcmp(alg, "aes128_ecb") == 0) { algType = AES128_ECB_PKCS7PADDING; } else if (strcmp(alg, "aes128_ecb_sha1") == 0) { algType = AES128_ECB_PKCS7PADDING_SHA1PRNG; } else if (strcmp(alg, "aes128_cbc") == 0) { algType = AES128_CBC_PKCS7PADDING; } else if (strcmp(alg, "aes128_ofb") == 0) { algType = AES128_OFB_PKCS7PADDING; } else if (strcmp(alg, "aes192_ecb") == 0) { algType = AES192_ECB_PKCS7PADDING; } else if (strcmp(alg, "aes192_cbc") == 0) { algType = AES192_CBC_PKCS7PADDING; } else if (strcmp(alg, "aes192_ofb") == 0) { algType = AES192_OFB_PKCS7PADDING; } else if (strcmp(alg, "aes256_ecb") == 0) { algType = AES256_ECB_PKCS7PADDING; } else if (strcmp(alg, "aes256_cbc") == 0) { algType = AES256_CBC_PKCS7PADDING; } else if (strcmp(alg, "aes256_ofb") == 0) { algType = AES256_OFB_PKCS7PADDING; } else { printf("Unsupported cipher algorithms: %s\n", alg); return -ERR_UNSUP_EVP_TYPE; } if (encrypt > 0) { if (symmetric_encrypto(algType, (unsigned char *)data, strlen(data), &buf, &outSize, key) != ERR_SUCCESS) { printf("Unsupported aes algorithms: %s\n", alg); return -ERR_EVP_ENCRYPTION; } else { strRet = base64_encode((unsigned char *)buf, outSize); } } else { unsigned char *pBase64 = (unsigned char *)base64_decode(data, (unsigned int *)&outSize); if (pBase64 == NULL) { printf("Base64 decode error: %s\n", data); return -ERR_EVP_DECRYPTION; } if (symmetric_decrypto(algType, pBase64, outSize, &buf, &outSize, key) != ERR_SUCCESS) { printf("Unsupported aes algorithms: %s\n", alg); free((void *)pBase64); return -ERR_EVP_DECRYPTION; } else { buf[outSize] = 0; strRet = strdup((const char *)buf); } } printf("AES %s: {%s} --> [%s]\n", encrypt > 0 ? "encryption" : "decryption", data, strRet); free(buf); free((void *)strRet); return ERR_MENU_EXIT; } static int on_cmd6(void *pTbl[], const char *pName, void *pInfo) { unsigned char *buf; int outSize = 0; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; const char *pKeygen = get_config_keygen(); const char *pKey = ((arg_str_t *)pTbl[1])->sval[0]; int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, NULL); return ERR_MENU_EXIT; } if (symmetric_encrypto(DES3_CBC_PKCS7PADDING, (unsigned char *)pKey, strlen(pKey), &buf, &outSize, pKeygen) != ERR_SUCCESS) { free((void *)pKeygen); return -ERR_EVP_ENCRYPTION; } else { const char *strRet = base64_encode((unsigned char *)buf, outSize); printf("Key: [%s]\n", strRet); printf("Keygen: {%s} --> [%s]\n", pKey, strRet); free((void *)strRet); } free(buf); free((void *)pKeygen); return ERR_MENU_EXIT; } typedef struct { int mode; const char *pIni; const char *pStatus; const char *pIfName; } DHCPD_SETUP, *PDHCPD_SETUP; #ifdef OPENDHCPD_ON static void dhcpd_task(void *pArg) { PDHCPD_SETUP p = (PDHCPD_SETUP)pArg; if (p) { dhcpd_main(p->mode, p->pIni, p->pStatus, p->pIfName); if (p->pIni) { free((void *)p->pIni); } if (p->pStatus) { free((void *)p->pStatus); } if (p->pIfName) { free((void *)p->pIfName); } free(p); } } static int on_cmd7(void *pTbl[], const char *pName, void *pInfo) { int ret; PDHCPD_SETUP p; static uv_thread_t uvThread; PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; int mode = ((arg_lit_t *)pTbl[1])->count; const char *pCfgFile = ((arg_file_t *)pTbl[2])->filename[0]; const char *pCfgDir = ((arg_file_t *)pTbl[3])->filename[0]; const char *piniFile = ((arg_file_t *)pTbl[4])->filename[0]; const char *pstatFile = ((arg_file_t *)pTbl[5])->filename[0]; const char *pIfName = ((arg_str_t *)pTbl[6])->sval[0]; #ifdef USERVNI_ON int *pVni = ((arg_int_t *)pTbl[7])->ival; const char *pKey = ((arg_str_t *)pTbl[8])->sval[0]; #else const char *pKey = ((arg_str_t *)pTbl[7])->sval[0]; #endif int help = get_help_cmd(pTbl, pArg)->count; if (pArg->pHelp && help > 0) { pArg->pHelp(pArg->argTbl, pName, pTbl); return ERR_MENU_EXIT; } #ifdef USERVNI_ON if (pVni && *pVni > 0) { cfg_set_user_vni_id(*pVni); } else { cfg_set_user_vni_id(0); } #endif if ((ret = user_init(pCfgFile, pCfgDir, pKey, 0)) != ERR_SUCCESS) { printf("System init error: %d\n", ret); return ret; } p = (PDHCPD_SETUP)malloc(sizeof(DHCPD_SETUP)); if (p) { p->mode = mode; p->pIni = piniFile ? strdup(piniFile) : NULL; p->pStatus = pstatFile ? strdup(pstatFile) : NULL; p->pIfName = pIfName ? strdup(pIfName) : NULL; uv_thread_create(&uvThread, dhcpd_task, p); } return ERR_SUCCESS; } #endif static int on_cmd_(void *pTbl[], const char *pName, void *pInfo) { PARG_TBL_INFO pArg = (PARG_TBL_INFO)pInfo; int help = get_help_cmd(pTbl, pArg)->count; //int version = ((arg_lit_t *)pTbl[0])->count; if (help > 0) { show_help(pName); } else { printf("Application information: %s (Build: %s %s GCC Ver:%s) With %lu(bits) OS\n", VCPE_GIT_VERSION, __DATE__, __TIME__, __VERSION__, sizeof(int *) * 8); #if !defined(OPENSSL_VERSION_NUMBER) || OPENSSL_VERSION_NUMBER < 0x10100000L printf("OpenSSL information: %s (%s, %s)\n", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_BUILT_ON), SSLeay_version(SSLEAY_PLATFORM)); #else printf("OpenSSL information: %s (%s, %s)\n", OPENSSL_VERSION_TEXT, OpenSSL_version(OPENSSL_BUILT_ON), OpenSSL_version(OPENSSL_PLATFORM)); #endif } return ERR_MENU_EXIT; } int menu_run(int argc, char **argv) { int ret = ERR_MENU_EXIT; int i, flag = FALSE; const char *pAppName = basename_v2(argv[0]); /***************************************************************** * 系统服务启动参数 ******************************************************************/ // clang-format off arg_rex_t *cmd1 = arg_rex1(NULL, NULL, "start", NULL, REG_ICASE, NULL); arg_file_t *cfgfile = arg_filen("c", "config", "[file]", 0, 1, "\tSpecify the current application configuration file path"); arg_file_t *cfgdir = arg_file1("d", "directory", "", "\tSpecify the configuration directory path"); arg_str_t *key1 = arg_str0("k", "key", "Key", "\tSpecify the configuration file cryptographic key."); arg_lit_t *helpCmd1 = arg_lit0("h", "help", NULL); arg_end_t *end1 = arg_end(20); void *pArgTbl1[] = {cmd1, cfgfile, cfgdir, key1, helpCmd1, end1}; int errCode1 = 0; arg_rex_t *cmd2 = arg_rex1(NULL, NULL, "if", NULL, REG_ICASE, NULL); arg_str_t *server = arg_str1("s", "server", "", "\tMessage queue server address."); arg_str_t *type = arg_str1("t", "command", "", "\tMessage queue command."); arg_str_t *key2 = arg_str1("k", "key", "", "\tSystem predefine command \033[1;7mKEY\033[0m value."); arg_str_t *value2 = arg_str0("v", "value", "value", "\tValue of key when command is need"); arg_lit_t *helpCmd2 = arg_lit0("h", "help", NULL); arg_end_t *end2 = arg_end(20); void *pArgTbl2[] = {cmd2, server, type, key2, value2, helpCmd2, end2}; int errCode2 = 0; arg_rex_t *cmd3 = arg_rex1(NULL, NULL, "base64", NULL, REG_ICASE, NULL); arg_lit_t *operate3 = arg_litn("o", "operate", 0, 1, "\tBase64 decode, otherwise mean base64 encode"); arg_str_t *value3 = arg_str0(NULL, NULL, "", NULL); arg_lit_t *helpCmd3 = arg_lit0("h", "help", NULL); arg_end_t *end3 = arg_end(20); void *pArgTbl3[] = {cmd3, operate3, value3, helpCmd3, end3}; int errCode3 = 0; arg_rex_t *cmd4 = arg_rex1(NULL, NULL, "hash", NULL, REG_ICASE, NULL); arg_file_t *file4 = arg_file0(NULL, NULL, "", NULL); arg_str_t *alg4 = arg_str0("a", "algorithms", "algorithms", "\tChose \033[1;7mHASH\033[0m algorithms."); arg_lit_t *helpCmd4 = arg_lit0("h", "help", NULL); arg_end_t *end4 = arg_end(20); void *pArgTbl4[] = {cmd4, alg4, file4, arg_rem(NULL, "\tSupport algorithms:"), arg_rem(NULL, "\t \033[4mmd5\033[0m: file md5 value"), arg_rem(NULL, "\t \033[4msha1\033[0m: file sha1 value"), arg_rem(NULL, "\t \033[4msha256\033[0m: file sha256 value"), helpCmd4, end4}; int errCode4 = 0; arg_rex_t *cmd5 = arg_rex1(NULL, NULL, "cipher", NULL, REG_ICASE, NULL); arg_lit_t *operate5 = arg_litn("e", "encrypt", 0, 1, "\tEncryption, Ignore means decryption."); arg_str_t *alg5 = arg_str0("a", "algorithms", "algorithms", "\tChose \033[1;7mCryptography\033[0m algorithms."); arg_str_t *key5 = arg_str0("k", "key", "Key", "\tCryptographic key"); arg_str_t *value5 = arg_str0(NULL, NULL, "", NULL); arg_lit_t *helpCmd5 = arg_lit0("h", "help", NULL); arg_end_t *end5 = arg_end(20); void *pArgTbl5[] = {cmd5, operate5, alg5, key5, value5, arg_rem(NULL, "\tSupport algorithms:"), arg_rem(NULL, "\t \033[4m3des_ecb\033[0m: 3DES ECB with PKCS7 padding"), arg_rem(NULL, "\t \033[4m3des_cbc\033[0m: 3DES CBC with PKCS7 padding"), arg_rem(NULL, "\t \033[4m3des_ofb\033[0m: 3DES OFB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes128_ecb\033[0m: 128 bit AES ECB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes128_ecb_sha1\033[0m: 128 bit AES ECB and used SHA1 key with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes128_cbc\033[0m: 128 bit AES CBC with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes128_ofb\033[0m: 128 bit AES OFB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes192_ecb\033[0m: 192 bit AES ECB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes192_cbc\033[0m: 192 bit AES CBC with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes192_ofb\033[0m: 192 bit AES OFB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes256_ecb\033[0m: 256 bit AES ECB with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes256_cbc\033[0m: 256 bit AES CBC with PKCS7 padding"), arg_rem(NULL, "\t \033[4maes256_ofb\033[0m: 256 bit AES OFB with PKCS7 padding"), helpCmd5, end5}; int errCode5 = 0; arg_rex_t *cmd6 = arg_rex1(NULL, NULL, "config", NULL, REG_ICASE, NULL); arg_str_t *keyGen = arg_str0("k", "keygen", "", "\tCreate configuration file cryptographic key."); arg_lit_t *helpCmd6 = arg_lit0("h", "help", NULL); arg_end_t *end6 = arg_end(20); void *pArgTbl6[] = {cmd6, keyGen, helpCmd6, end6}; int errCode6 = 0; #ifdef OPENDHCPD_ON arg_rex_t *cmd7 = arg_rex1(NULL, NULL, "dhcpd", NULL, REG_ICASE, NULL); arg_lit_t *operate7 = arg_lit0("m", "mode", "\tService works on verbatim mode."); arg_file_t *cfgfile7 = arg_filen("c", "config", "[file]", 0, 1, "\tSpecify the current application configuration file path"); arg_file_t *cfgdir7 = arg_file1("d", "directory", "", "\tSpecify the configuration directory path"); arg_str_t *key7 = arg_str0("k", "key", "Key", "\tSpecify the configuration file cryptographic key."); arg_file_t *inifile = arg_filen("i", "ini", "", 0, 1, "\tSpecify the dhcpd service configuration file path"); arg_file_t *statfile = arg_filen("s", "state", "", 0, 1, "\tSpecify the dhcpd service state cache file path"); arg_str_t *ifname = arg_str1("n", "nic", "", "\tSpecify the dhcpd service network interface name."); arg_int_t *vni = arg_intn("v", "vni", "", 0, 1, "\tSpecify user vxlan vni id."); arg_lit_t *helpCmd7 = arg_lit0("h", "help", NULL); arg_end_t *end7 = arg_end(20); void *pArgTbl7[] = {cmd7, operate7, cfgfile7, cfgdir7, inifile, statfile, ifname, vni, key7, helpCmd7, end7}; int errCode7 = 0; #endif /***************************************************************** * 系统帮助参数定义 ******************************************************************/ arg_lit_t *help_ = arg_lit0("h", "help", "\tDisplay this help and exit"); arg_lit_t *version_ = arg_lit0("v", "version", "\tDisplay application version information and exit"); arg_end_t *end_ = arg_end(20); void *pArgTbl_[] = {version_, help_, end_}; int errCode_ = 0; ARG_TBL_INFO argTblInfo[] = { {pArgTbl1, ARRAY_SIZE(pArgTbl1), &errCode1, on_cmd1, cmdn_help, "\r \033[1;4;36mstart\033[0m: \033[1mRun agent service normally.\033[0m\n"}, #ifdef OPENDHCPD_ON {pArgTbl7, ARRAY_SIZE(pArgTbl7), &errCode7, on_cmd7, cmdn_help, "\n \033[1;4;36mdhcpd\033[0m: \033[1mRun DHCP service normally.\033[0m\n"}, #endif {pArgTbl2, ARRAY_SIZE(pArgTbl2), &errCode2, on_cmd2, cmd2_help, "\n \033[1;4;36mif\033[0m: \033[1mRun agent interface tools.\033[0m\n"}, {pArgTbl3, ARRAY_SIZE(pArgTbl3), &errCode3, on_cmd3, cmdn_help, "\n \033[1;4;36mbase64\033[0m: \033[1mString base64 encode/decode.\033[0m\n"}, {pArgTbl4, ARRAY_SIZE(pArgTbl4), &errCode4, on_cmd4, cmdn_help, "\n \033[1;4;36mhash\033[0m: \033[1mCalculate file's hash value.\033[0m\n"}, {pArgTbl5, ARRAY_SIZE(pArgTbl5), &errCode5, on_cmd5, cmdn_help, "\n \033[1;4;36mcipher\033[0m: \033[1mSymmetric cryptography for string.\033[0m\n"}, {pArgTbl6, ARRAY_SIZE(pArgTbl6), &errCode6, on_cmd6, cmdn_help, "\n \033[1;4;36mconfig\033[0m: \033[1mConfiguration file tools.\033[0m\n"}, {pArgTbl_, ARRAY_SIZE(pArgTbl_), &errCode_, on_cmd_, NULL, NULL}, }; // clang-format on g_pArgTbl = argTblInfo; g_nArgTbl = ARRAY_SIZE(argTblInfo); for (i = 0; i < g_nArgTbl; i++) { if (arg_nullcheck(argTblInfo[i].argTbl) != 0) { printf("%s insufficient memory\n", pAppName); return -ERR_SYS_INIT; } } cfgfile->filename[0] = "-"; for (i = 0; i < g_nArgTbl; i++) { *argTblInfo[i].pErrCode = arg_parse(argc, argv, argTblInfo[i].argTbl); } for (i = 0; i < g_nArgTbl; i++) { PARG_TBL_INFO pArg = &argTblInfo[i]; if (*pArg->pErrCode == 0 && pArg->pCmd) { ret = pArg->pCmd(pArg->argTbl, pAppName, pArg); if (ret != ERR_SUCCESS && ret != ERR_MENU_EXIT) { if (pArg->pHelp) { pArg->pHelp(pArg->argTbl, pAppName, NULL); } } else { flag = TRUE; } } } if (flag == FALSE) { for (i = 0; i < g_nArgTbl - 1; i++) { PARG_TBL_INFO pArg = &argTblInfo[i]; if (*pArg->pErrCode != 0) { if (get_reg_cmd(pArg->argTbl) > 0 && pArg->pHelp) { int help = get_help_cmd(pArg->argTbl, pArg)->count; pArg->pHelp(pArg->argTbl, pAppName, help > 0 ? NULL : get_arg_err(pArg->argTbl, pArg)); flag = TRUE; break; } } } if (flag == FALSE) { show_help(pAppName); } } for (i = 0; i < g_nArgTbl; i++) { arg_freetable(argTblInfo[i].argTbl, argTblInfo[i].nArgItem); } return ret; }