C语言argp库如何将-u、-w命令行选项设置为必填项
C语言argp库必填选项校验实现方案
问题描述
使用C语言argp库开发命令行工具时,需要将-u(--url)和-w(--wordlist)两个选项设置为必填项:用户未传入任意一个参数时自动输出错误提示,两个参数必须同时提供程序才可以正常运行,网上未检索到同类问题的现成解决方案。
初始错误实现
最初将参数校验逻辑写在parse_opt函数的选项处理分支之后,即使在main函数中完成了参数结构体初始化,该校验代码始终无法触发,相关代码如下:
argp.c
#include "../header/argp.h" #include <argp.h> #include <stdbool.h> #include <string.h> #include <stdlib.h> const char *argp_program_version = "WiBreak 0.0.1"; static char doc[] = "Program used to brute force URL."; static char args_doc[] = "[-u URL] [-w WORDLIST]"; static struct argp_option options[] = { {"url", 'u', "URL_TO_QUERY", 0, "Compare lines instead of characters."}, {"wordlist", 'w', "WORDLIST", 0, "Compare words instead of characters."}, {"verbose", 'v', 0, OPTION_ARG_OPTIONAL, "Show more info"}, {0}}; // TODO: Need to handle when no argument are given. static error_t parse_opt(int key, char *arg, struct argp_state *state) { struct arguments *arguments = state->input; int *arg_cout = state->input; switch (key) { case 'u': arguments->url_to_query = arg; // printf("arg : %s\n", arg); break; case 'w': arguments->wordlist = arg; break; case 'v': arguments->verbose = 1; break; default: // argp_usage(state); return ARGP_ERR_UNKNOWN; } // Code never reach even when i initialyze arguments in the main. if (arguments->wordlist == "" || arguments->url_to_query == ""){ argp_failure(state, 1, 0, "too few arguments"); exit(ARGP_ERR_UNKNOWN); } return 0; } struct argp argp = {options, parse_opt, args_doc, doc};
argp.h
#ifndef __ARGP__H #define __ARGP__H #include <argp.h> #include <stdbool.h> // static error_t parse_opt(int key, char *arg, struct argp_state *state) extern struct argp argp; struct arguments { // enum { CHARACTER_MODE, WORD_MODE, LINE_MODE } mode; char *wordlist; char *url_to_query; bool verbose; // bool isCaseInsensitive; }; #endif
main.c
int main(int argc, char *argv[]) { struct arguments arguments; // arguments.mode = CHARACTER_MODE; // arguments.isCaseInsensitive = false; arguments.wordlist = ""; arguments.url_to_query = ""; argp_parse(&argp, argc, argv, 0, 0, &arguments); // printf("Wordlist : %s, Url : %s\n", arguments.wordlist, // arguments.url_to_query); // ... }
问题原因
parse_opt函数每解析到一个参数就会被触发一次,写在switch分支后的校验逻辑只有在解析到u/w/v三个选项时才会执行,此时另一个必填参数大概率还没完成解析,自然无法实现两个参数都填完后的校验逻辑。另外代码中用==比较字符串指针的写法也存在逻辑问题,无法正确判断空字符串。
最终解决方案
在parse_opt函数的switch分支中新增ARGP_KEY_END处理逻辑,该key会在所有参数全部解析完成后触发,此时再做必填项校验即可生效,修改后的代码片段如下:
case ARGP_KEY_END: // printf("arguments->wordlist : %s, arguments->url_to_query : %s\n", arguments->wordlist, arguments->url_to_query); if (arguments->wordlist == NULL || arguments->url_to_query == NULL){ argp_failure(state, 1, 0, "required -u and -w. See --help for more information"); exit(ARGP_ERR_UNKNOWN); }
注意:使用该逻辑时需要将main函数中参数结构体的初始化值从空字符串""改为NULL,和校验逻辑的判断条件保持一致。
内容的提问来源于stack exchange,提问作者RaiZy_Style
相关产品推荐
相关产品推荐

