[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.
This commit is contained in:
Matteo Cypriani 2013-09-13 09:58:48 -04:00
parent f181087d70
commit d6fb1c04fc
3 changed files with 128 additions and 18 deletions

View File

@ -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.

View File

@ -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 <assert.h>
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
) ;
}

View File

@ -21,10 +21,14 @@
#include <owlps-resultreader.h>
#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_