#include #include #include #define COMMANDLEN 10 #define sizeofarr(a) (sizeof(a) / sizeof(a[0])) namespace bpo = boost::program_options; typedef enum { CMD_HELP, CMD_CONNECT, CMD_DISCONNECT, CMD_PUT, CMD_REMOVE, CMD_GET, CMD_QUERY, CMD_SETUP, CMD_LOG, CMD_UNKNOWN } COMMANDTYPES; typedef struct { COMMANDTYPES cmd; const char *name; const char *desc; } CMD; CMD commands[]{{CMD_HELP, "help", "show help"}, {CMD_CONNECT, "connect", "connect to IP"}, {CMD_DISCONNECT, "disconnect", "disconnect from IP"}, {CMD_PUT, "put", "upload file to IP and add to queue"}, {CMD_REMOVE, "remove", "remove file from IP and queue (stops xfer if required)"}, {CMD_GET, "get", "retrieve file from IP"}, {CMD_QUERY, "query", "query status of IP"}, {CMD_SETUP, "setup", "configure server at IP"}, {CMD_LOG, "log", "show log from IP"}}; COMMANDTYPES getCommand(char *str, unsigned int isshort) { COMMANDTYPES ret = CMD_UNKNOWN; char temp[11] = {0}; if (strlen(str) > COMMANDLEN) return ret; if (isshort) temp[0] = tolower(str[0]); else for (int i = 0; i < 10; i++) temp[i] = tolower(str[i]); for (int i = 0; i < sizeofarr(commands); i++) { if (isshort) { if (tolower(str[0]) == commands[i].name[0]) ret = commands[i].cmd; } else { if (!strncmp(temp, commands[i].name, COMMANDLEN)) ret = commands[i].cmd; } } return ret; } void show_help(char *exec) { std::printf("ccats command line interface\n"); std::printf("usage: %s COMMAND IP [Options]\n", exec); std::printf("available COMMANDs are:\n"); for (int i = 0; i < sizeofarr(commands); i++) { std::printf("%10s - %s\n", commands[i].name, commands[i].desc); } std::printf("IP should be in the format \"xxx.xxx.xxx.xxx\"\n"); } int main(int argc, char **argv) { bpo::options_description desc{"Options"}; desc.add_options()("cooloption", "Cooloption to use with command FOON"); bpo::variables_map vm; if (argc < 2) { show_help(argv[0]); exit(1); } COMMANDTYPES cmd = getCommand(argv[1], (strlen(argv[1]) == 1)); switch (cmd) { case CMD_UNKNOWN: std::printf("unknown command\n"); case CMD_HELP: show_help(argv[0]); std::cout << desc; exit(1); } // have enough valid arguments switch (cmd) { case CMD_CONNECT: std::printf("connecting to %s\n", argv[2]); break; case CMD_DISCONNECT: std::printf("disconnecting from %s\n", argv[2]); break; default: std::printf("command %s not implemented\n", argv[1]); break; } try { store(parse_command_line(argc - 2, argv + 2, desc), vm); notify(vm); if (vm.count("help")) { std::cout << desc; } else { std::printf("no additional options\n"); } } catch (const bpo::error &ex) { std::fprintf(stderr, "%s\n", ex.what()); } }