#include <stdio.h>
#include <string.h>
#include <stdint.h>
-#include <math.h>
#include <stdlib.h>
#include <stdarg.h>
#include <inttypes.h>
#include <ctype.h>
-#include <ctype.h>
#include <unistd.h>
-#include <termios.h>
#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <getopt.h>
#include <cmdline_rdline.h>
#include <cmdline_parse.h>
extern cmdline_parse_ctx_t main_ctx[];
-struct cmdline *cl;
+static struct sockaddr addr;
+static uint16_t port = 1234;
+
+static void
+usage(const char *prgname)
+{
+ printf("%s [-a ADDRESS] [-p PORT]\n"
+ "\n"
+ "Start a command line server on a TCP listen socket. Only\n"
+ "one connection is accepted, then the program exits.\n"
+ "The default behaviour is to listen on 0.0.0.0:1234\n"
+ "\n"
+ " -a ADDR: IPv4 or IPv6 local address to listen on (default\n"
+ " is 0.0.0.0).\n"
+ " -p PORT: port to listen on (default is 1234).\n",
+ prgname);
+}
+
+/* Parse the argument given in the command line of the application */
+static int
+parse_args(int argc, char **argv)
+{
+ int opt, ret;
+ char **argvopt;
+ int option_index;
+ char *prgname = argv[0];
+ char *end = NULL;
+ static struct option lgopts[] = {
+ {0, 0, 0, 0}
+ };
+
+ argvopt = argv;
+
+ while ((opt = getopt_long(argc, argvopt, "a:p:",
+ lgopts, &option_index)) != EOF) {
+
+ switch (opt) {
+
+ case 'a':
+ if (strchr(optarg, '.') != NULL) {
+ struct sockaddr_in *sin =
+ (struct sockaddr_in *)&addr;
+ addr.sa_family = AF_INET;
+ ret = inet_pton(AF_INET, optarg,
+ &sin->sin_addr);
+ }
+ else {
+ struct sockaddr_in6 *sin6 =
+ (struct sockaddr_in6 *)&addr;
+ addr.sa_family = AF_INET6;
+ ret = inet_pton(AF_INET6, optarg,
+ &sin6->sin6_addr);
+ }
+
+ if (ret != 1) {
+ printf("Bad address\n");
+ usage(prgname);
+ return -1;
+ }
+ break;
-int main(void)
+ case 'p':
+ port = strtoul(optarg, &end, 0);
+ if ((optarg[0] == '\0') ||
+ (end == NULL) ||
+ (*end != '\0')) {
+ printf("Invalid port\n");
+ usage(prgname);
+ return -1;
+ }
+
+ break;
+
+ /* long options */
+ case 0:
+ /* if (!strcmp(lgopts[option_index].name, "option")) */
+ break;
+
+ default:
+ usage(prgname);
+ return -1;
+ }
+ }
+
+ if (argc != optind) {
+ printf("Invalid argument\n");
+ usage(prgname);
+ return -1;
+ }
+
+ ret = optind-1;
+
+ return ret;
+}
+
+int main(int argc, char **argv)
{
+ struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
+ struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
+ struct cmdline *cl;
int s;
- s = cmdline_tcpv4_listen(INADDR_ANY, 1234);
+
+ if (parse_args(argc, argv) < 0)
+ exit(1);
+
+ printf("Listening on port %d\n", port);
+
+ /* open a tcp server on specified port */
+ if (addr.sa_family == AF_INET)
+ s = cmdline_tcpv4_listen(sin->sin_addr.s_addr, port);
+ else
+ s = cmdline_tcpv6_listen(sin6->sin6_addr, port);
+
cl = cmdline_accept(main_ctx, "example> ", s);
- if (cl == NULL)
+ if (cl == NULL) {
+ printf("accept() failed\n");
return 1;
+ }
cmdline_interact(cl);
cmdline_free(cl);
return 0;