X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=src%2Fclient%2Fmain.c;fp=src%2Fclient%2Fmain.c;h=c0d6079b58d161c4ac6492fe460ac738fdb7fbed;hb=f95c37e3cf4d9ed5cb4ad1899e80d19fca888118;hp=5f177d2dd1425d90651ccbfadf835d41a368cec4;hpb=42d8264dd0ef02b7764c0cce18231eafc1062257;p=libcmdline.git diff --git a/src/client/main.c b/src/client/main.c index 5f177d2..c0d6079 100644 --- a/src/client/main.c +++ b/src/client/main.c @@ -26,9 +26,10 @@ */ #include +#include #include #include -#include +#include #include #include @@ -38,14 +39,117 @@ #include #include +static struct sockaddr addr; +static uint16_t port = 1234; -int main(void) +static void +usage(const char *prgname) { + printf("%s [-a ADDRESS] [-p PORT]\n" + "\n" + "Start a client to connect to a command line server, using\n" + "a TCP socket.\n" + "The default behaviour is to connect to 127.0.0.1:1234\n" + "\n" + " -a ADDR: IPv4 or IPv6 local address to listen on (default\n" + " is 127.0.0.1).\n" + " -p PORT: port to connect to (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; + + 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 termios oldterm, term; - struct sockaddr_in sin_ci; fd_set fds; int s; char c; + char buf[INET6_ADDRSTRLEN]; + + /* default */ + sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + sin->sin_family = AF_INET; + + if (parse_args(argc, argv) < 0) + exit(1); s = socket(PF_INET, SOCK_STREAM, 0); if (s < 0) { @@ -53,18 +157,33 @@ int main(void) return s; } - /* XXX specify address */ - memset(&sin_ci, 0, sizeof(sin_ci)); - sin_ci.sin_family = AF_INET; - inet_pton(AF_INET, "127.0.0.1", &sin_ci.sin_addr.s_addr); - sin_ci.sin_port = htons(1234); + switch (addr.sa_family) { + case AF_INET: + sin->sin_port = htons(port); #ifndef __linux__ - sin_ci.sin_len = sizeof(sin_ci); + sin->sin_len = sizeof(*sin); #endif + printf("Connecting to %s:%d\n", + inet_ntop(AF_INET, &sin->sin_addr, buf, + sizeof(*sin)), port); + break; + case AF_INET6: + sin6->sin6_port = htons(port); +#ifndef __linux__ + sin6->sin6_len = sizeof(*sin6); +#endif + printf("Connecting to %s:%d\n", + inet_ntop(AF_INET6, &sin6->sin6_addr, buf, + sizeof(*sin6)), port); + break; + default: + printf("bad address\n"); + return -1; + } - if (connect(s, (struct sockaddr *)&sin_ci, sizeof(sin_ci)) < 0) { + if (connect(s, &addr, sizeof(addr)) < 0) { printf("connect() failed\n"); - return s; + return -1; } tcgetattr(0, &oldterm); @@ -95,5 +214,3 @@ int main(void) return 0; } - -