From d6fb1c04fcb6da643ce7d4397814ec28c80e4ca9 Mon Sep 17 00:00:00 2001 From: Matteo Cypriani Date: Fri, 13 Sep 2013 09:58:48 -0400 Subject: [PATCH] [UDP-HTTP] Command-line options -h, -V, -l, -t Add support for basic command-line options: -h (help), -V (version), and -l and -t for the port numbers. --- TODO.t2t | 2 +- owlps-udp-to-http/owlps-udp-to-http.c | 125 +++++++++++++++++++++++--- owlps-udp-to-http/owlps-udp-to-http.h | 19 ++-- 3 files changed, 128 insertions(+), 18 deletions(-) diff --git a/TODO.t2t b/TODO.t2t index 7cc6e7b..0886348 100644 --- a/TODO.t2t +++ b/TODO.t2t @@ -164,7 +164,7 @@ Work to do in OwlPS = UDP to HTTP = -- Command-line options (port numbers, -v/-q, -h, -V). +- Command-line options (-v/-q). - Delete inactive clients after a given amount of time. diff --git a/owlps-udp-to-http/owlps-udp-to-http.c b/owlps-udp-to-http/owlps-udp-to-http.c index 652ca40..8152463 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.c +++ b/owlps-udp-to-http/owlps-udp-to-http.c @@ -22,9 +22,9 @@ * http://localhost:8080/?request=ReadSimpleResults * (assuming the host running this program is localhost). * - * The UDP listening port is the port on which OwlPS Positioner sends - * result by default. - * The TCP listening port is 8080. + * The default UDP listening port is the port on which OwlPS Positioner + * sends the result by default, and the default TCP (HTTP) listening + * port is 8080. * * Only the last result read from the positioning server, for each * mobile, is memorised and provided to the HTTP client. @@ -76,6 +76,15 @@ #include +struct { + uint_fast16_t result_port ; + uint_fast16_t http_port ; + int nb_connections ; +} options = { + OWL_DEFAULT_RESULT_PORT, // result_port + DEFAULT_HTTP_PORT, // http_port + DEFAULT_NB_CONNECTIONS // nb_connections +} ; char *program_name = NULL ; @@ -100,12 +109,10 @@ int main(int argc, char *argv[]) int ret = 0 ; // Program return value pthread_t tcp_server_thread ; - program_name = argv[0] ; owl_run = true ; - if (argc > 1) - fprintf(stderr, - "Sorry, this program does not take any argument yet.\n") ; + program_name = argv[0] ; + parse_command_line(argc, argv) ; /* Set up signal handlers */ action.sa_flags = 0 ; @@ -165,6 +172,60 @@ int main(int argc, char *argv[]) } +void parse_command_line(int argc, char **argv) +{ + parse_options(argc, argv) ; + check_configuration() ; +} + + +void parse_options(int argc, char **argv) +{ + int opt ; + + while ((opt = getopt(argc, argv, OPTIONS)) != -1) + { + switch (opt) + { + case 'h' : + print_usage() ; + exit(0) ; + case 'l' : + options.result_port = strtoul(optarg, NULL, 0) ; + break ; + case 't' : + options.http_port = strtoul(optarg, NULL, 0) ; + break ; + case 'V' : + print_version() ; + exit(0) ; + default : + print_usage() ; + exit(OWL_ERR_BAD_USAGE) ; + } + } +} + + +void check_configuration() +{ + if (options.result_port > 65535) + { + fprintf(stderr, "Warning! result_port too high: using default" + " value (%d).\n", OWL_DEFAULT_RESULT_PORT) ; + options.result_port = OWL_DEFAULT_RESULT_PORT ; + } + + if (options.http_port > 65535) + { + fprintf(stderr, "Warning! http_port too high: using default" + " value (%d).\n", DEFAULT_HTTP_PORT) ; + options.http_port = DEFAULT_HTTP_PORT ; + } +} + + + /* * Opens the UDP socket and reads from it the results sent by OwlPS * Positioning. @@ -175,7 +236,7 @@ int receive_udp() owl_result *result ; /* Open the UDP socket */ - udp_sockfd = owl_create_udp_listening_socket(OWL_DEFAULT_RESULT_PORT) ; + udp_sockfd = owl_create_udp_listening_socket(options.result_port) ; if (udp_sockfd < 0) return OWL_ERR_SOCKET_CREATE ; @@ -272,7 +333,7 @@ int init_tcp_socket() bzero((char *) &server_addr, sizeof(server_addr)) ; server_addr.sin_family = AF_INET ; server_addr.sin_addr.s_addr = INADDR_ANY ; - server_addr.sin_port = htons(TCP_PORT) ; + server_addr.sin_port = htons(options.http_port) ; if (bind(tcp_sockfd, (struct sockaddr *) &server_addr, @@ -299,7 +360,7 @@ void* tcp_server(void *NULL_value) char client_request[CLIENT_REQUEST_STRLEN] ; int request_id ; - listen(tcp_sockfd, NB_CONNECTIONS) ; + listen(tcp_sockfd, options.nb_connections) ; client_len = sizeof(client_addr) ; // Prepare the answer, assuming there is only 1 full result (an error @@ -550,3 +611,47 @@ void free_results_list() } nb_results = 0 ; } + + + +/* + * Prints the usage message on the standard output. + * + * /!\ Don't forget to update the documentation when modifying something + * here! + */ +void print_usage() +{ + printf("Usage:\n" + "\t%s" + /* " [-v | -q]" */ + " [-l result_port]" + " [-t http_port]\n" + + "Options:\n" + "\t-h\t\tPrint this help.\n" + "\t-V\t\tPrint version information.\n" + "\t-l result_port\tPort on which the results are received" + " (default: %d).\n" + "\t-t http_port\tPort on which the HTTP server listens" + " (default: %d).\n" + , + program_name, + OWL_DEFAULT_RESULT_PORT, + DEFAULT_HTTP_PORT + ) ; +} + + +void print_version() +{ + printf("This is OwlPS UDP-to-HTTP, part of the Owl Positioning System" + " project.\n" + "Version: %s.\n", +#ifdef OWLPS_VERSION + OWLPS_VERSION +#else // OWLPS_VERSION + "unknown version" +#endif // OWLPS_VERSION + ) ; +} diff --git a/owlps-udp-to-http/owlps-udp-to-http.h b/owlps-udp-to-http/owlps-udp-to-http.h index 6a199d9..eaaa3e0 100644 --- a/owlps-udp-to-http/owlps-udp-to-http.h +++ b/owlps-udp-to-http/owlps-udp-to-http.h @@ -21,10 +21,14 @@ #include -#define TCP_PORT 8080 -#define NB_CONNECTIONS 1 -#define CLIENT_MESSAGE_STRLEN 2500 +/* Arguments & program configuration */ +#define OPTIONS "hl:t:V" // getopt string + +#define DEFAULT_HTTP_PORT 8080 +#define DEFAULT_NB_CONNECTIONS 1 + +#define CLIENT_MESSAGE_STRLEN 2500 #define CLIENT_REQUEST_STRLEN 21 #define SIMPLE_RESULTS_ID 1 #define SIMPLE_RESULTS_REQUEST "ReadSimpleResults" @@ -33,10 +37,6 @@ #define RESULTS_REQUEST "ReadResults" #define RESULTS_ANSWER "Results" -#ifndef OWLPS_VERSION -# define OWLPS_VERSION "unknown version" -#endif // OWLPS_VERSION - #define ANSWER_HDR \ "HTTP/1.1 200 OK\n" \ "Date: Sat, 01 Jan 0001 00:00:01 GMT\n" \ @@ -55,6 +55,9 @@ typedef struct _results_list } results_list ; +void parse_command_line(int argc, char **argv) ; +void parse_options(int argc, char **argv) ; +void check_configuration(void) ; int receive_udp(void) ; void store_result(owl_result *result) ; int init_tcp_socket(void) ; @@ -65,6 +68,8 @@ extract_request_from_message(char client_request[CLIENT_REQUEST_STRLEN], void prepare_answer(int request_id) ; void realloc_answer(size_t new_size) ; void free_results_list(void) ; +void print_usage(void) ; +void print_version(void) ; #endif // _OWLPS_UDP_TO_HTTP_H_