2 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #include <sys/socket.h>
35 #include <netinet/in.h>
36 #include <sys/socket.h>
37 #include <arpa/inet.h>
42 static struct sockaddr addr;
43 static uint16_t port = 1234;
46 usage(const char *prgname)
48 printf("%s [-a ADDRESS] [-p PORT]\n"
50 "Start a client to connect to a command line server, using\n"
52 "The default behaviour is to connect to 127.0.0.1:1234\n"
54 " -a ADDR: IPv4 or IPv6 local address to listen on (default\n"
56 " -p PORT: port to connect to (default is 1234).\n",
60 /* Parse the argument given in the command line of the application */
62 parse_args(int argc, char **argv)
67 char *prgname = argv[0];
69 static struct option lgopts[] = {
75 while ((opt = getopt_long(argc, argvopt, "a:p:",
76 lgopts, &option_index)) != EOF) {
81 if (strchr(optarg, '.') != NULL) {
82 struct sockaddr_in *sin =
83 (struct sockaddr_in *)&addr;
84 addr.sa_family = AF_INET;
85 ret = inet_pton(AF_INET, optarg,
89 struct sockaddr_in6 *sin6 =
90 (struct sockaddr_in6 *)&addr;
91 addr.sa_family = AF_INET6;
92 ret = inet_pton(AF_INET6, optarg,
97 printf("Bad address\n");
104 port = strtoul(optarg, &end, 0);
105 if ((optarg[0] == '\0') ||
108 printf("Invalid port\n");
117 /* if (!strcmp(lgopts[option_index].name, "option")) */
126 if (argc != optind) {
127 printf("Invalid argument\n");
137 int main(int argc, char **argv)
139 struct sockaddr_in *sin = (struct sockaddr_in *)&addr;
140 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
141 struct termios oldterm, term;
145 char buf[INET6_ADDRSTRLEN];
148 sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
149 sin->sin_family = AF_INET;
151 if (parse_args(argc, argv) < 0)
154 s = socket(PF_INET, SOCK_STREAM, 0);
156 printf("socket() failed\n");
160 switch (addr.sa_family) {
162 sin->sin_port = htons(port);
164 sin->sin_len = sizeof(*sin);
166 printf("Connecting to %s:%d\n",
167 inet_ntop(AF_INET, &sin->sin_addr, buf,
168 sizeof(*sin)), port);
171 sin6->sin6_port = htons(port);
173 sin6->sin6_len = sizeof(*sin6);
175 printf("Connecting to %s:%d\n",
176 inet_ntop(AF_INET6, &sin6->sin6_addr, buf,
177 sizeof(*sin6)), port);
180 printf("bad address\n");
184 if (connect(s, &addr, sizeof(addr)) < 0) {
185 printf("connect() failed\n");
189 tcgetattr(0, &oldterm);
190 memcpy(&term, &oldterm, sizeof(term));
191 term.c_lflag &= ~(ICANON | ECHO | ISIG);
192 tcsetattr(0, TCSANOW, &term);
199 if (select(s+1, &fds, NULL, NULL, NULL) < 0)
201 if (FD_ISSET(0, &fds)) {
202 if (read(0, &c, 1) <= 0)
206 if (FD_ISSET(s, &fds)) {
207 if (read(s, &c, 1) <= 0)
212 tcsetattr(0, TCSANOW, &oldterm);