#include <stdio.h> #include <string.h> #include <err.h> #include <libgen.h> #include <getopt.h> #include "cli.h" int main(int argc, char **argv) { int cmdID = -1; char * command; int c; int i , useSymlink = 0; struct backend_conn *conn; int needCliHelp = 0, needCommandHelp = 0; // Determine if the cli was called using a symlink command = basename(argv[0]); for(i = 0; i < MAX_COMMANDS; ++i) { if (strncmp(command, commandNames[i], strlen(commandNames[i])) == 0) { cmdID = i; useSymlink = 1; } } // Verify the user has entered enough information to continue if (argc < 2 && !useSymlink) { printf("Incorrect usage :\n"); printf("Usage Syntax: \n\t./Cli command [options...]\n\n"); printf("For a list of available 'command' names\n\t./Cli --help\n\n"); printf("For a list of available options for a 'command'\n\t./Cli command --help\n"); return -1; } if (!useSymlink) { // Determine if the user called for help on the cli needCliHelp = (strncmp("--help", argv[1], strlen(argv[1])) == 0); } // If the user runs './Cli help' , provide the user with a list of commands available. if (needCliHelp) { printf("Usage Syntax: \n\t./Cli command [options...]\n\n"); printf("Available 'command' names include the following\n"); for(int i = 0; i < MAX_COMMANDS; ++i) { printf("\t '%s'\n",commandNames[i]); } return 0; } // recognize which cli command the user has entered if (cmdID == -1) { command = argv[1]; for (i = 0; i < MAX_COMMANDS; ++i) { if (strncmp(command, commandNames[i], strlen(commandNames[i])) == 0) { cmdID = i; } } } if (cmdID == -1){ printf("Could not match '%s' with a command. Please try again...\n", command); printf("For help running the program, run ./Cli --help\n"); return -1; } // Determine if the user called for help on the command if (!useSymlink && argc > 2) { if (strncmp("--help", argv[2], strlen(argv[2])) == 0) { needCommandHelp = 1; } } else if (useSymlink && argc > 1) { if (strncmp("--help", argv[1], strlen(argv[1])) == 0) { needCommandHelp = 1; } } /** * If the user has asked for help, and we have already found * the command that they are trying to use. Then we need * to be able to provide the help info wihtout the * requirement of the backend * * It is important to note that this will only work if the * command the user has asked for handles this help case * */ // Only require the backend if we will need to use it. if (!needCommandHelp) { // Create the connection to the backend conn = ucart_backendConnect(); if (conn == NULL) { return -1; } } // Call the appropriate function if (useSymlink) { (*cli_functions[cmdID]) (conn, argc, &argv[0]); } else { (*cli_functions[cmdID]) (conn, argc-1, &argv[1]); } // Disconnect from the backend if (!needCommandHelp) { ucart_backendDisconnect(conn); } return 0; } /* This function is called by other cli functions to check for a help condition */ int help_check(int argc, char ** argv) { int c; static int needHelp = 0; static struct option long_options[] = { /* These options don’t set a flag. We distinguish them by their indices. */ {"help", no_argument, &needHelp, 1}, {0, 0, 0, 0} }; while (1) { /* getopt_long stores the option index here. */ int option_index = 0; c = getopt_long(argc, argv, "h", long_options, &option_index); /* Detect the end of the options. */ if (c == -1) break; if (c == 'h') { needHelp = 1; } } return needHelp; } int isNumber(char *number) { int i = 0; //checking for negative numbers if (number[0] == '-') i = 1; for (; number[i] != 0; i++) { //if (number[i] > '9' || number[i] < '0') if (!isdigit(number[i])) return 0; } return 1; } int convert_to_id(struct backend_conn * conn, char **argv, struct convert_data * convert_data, int conversion_requirement) { /* variables used to search for id values */ size_t num_nodes = 0, i; struct frontend_node_data* search_data = NULL; int search_1 = 0, search_2 = 0; const struct graph_node_type * node_definition; if (!isNumber(argv[1])) { search_1 = 1; } else { convert_data->val_1 = atoi(argv[1]); } if (!isNumber(argv[2])) { search_2 = 1; } else { convert_data->val_2 = atoi(argv[2]); } if (!search_1 && !search_2) { return 0; } /** * node_data must be NULL, * num_nodes must equal zero. */ if (frontend_getnodes(conn, &search_data, &num_nodes)) { return 1; } if (search_1) { for (i = 0; i < num_nodes; ++i) { if (strncasecmp(search_data[i].name, argv[1], strlen(search_data[i].name)) == 0) { convert_data->val_1 = search_data[i].block; node_definition = blockDefs[search_data[i].type]; break; } } } if (i == num_nodes) return 1; if (search_2) { const int *num_s2_options; const char* const* s2_options_arr; if (!search_1) { node_definition = blockDefs[search_data[convert_data->val_1].type]; } switch (conversion_requirement) { case PARAM: num_s2_options = &node_definition->n_params; s2_options_arr = node_definition->param_names; break; case INPUT: num_s2_options = &node_definition->n_inputs; s2_options_arr = node_definition->input_names; break; case OUTPUT: num_s2_options = &node_definition->n_outputs; s2_options_arr = node_definition->output_names; break; } for (i = 0; i < (size_t)*num_s2_options; ++i) { if (strncasecmp(s2_options_arr[i], argv[2], strlen(s2_options_arr[i])) == 0) { convert_data->val_2 = i; search_2 = 0; break; } } } frontend_free_node_data(search_data, num_nodes); return search_2; }