summaryrefslogtreecommitdiff
path: root/other/guess-who/misc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'other/guess-who/misc.cc')
-rw-r--r--other/guess-who/misc.cc178
1 files changed, 178 insertions, 0 deletions
diff --git a/other/guess-who/misc.cc b/other/guess-who/misc.cc
new file mode 100644
index 0000000..b61417c
--- /dev/null
+++ b/other/guess-who/misc.cc
@@ -0,0 +1,178 @@
1/*
2 * Copyright (C) 2002 Sebastian Krahmer.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Sebastian Krahmer.
16 * 4. The name Sebastian Krahmer may not be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
21 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32#include <stdio.h>
33#include <unistd.h>
34#include <sys/types.h>
35#include <sys/socket.h>
36#include <netinet/in.h>
37#include <netinet/tcp.h>
38#include <arpa/inet.h>
39#include <netdb.h>
40#include <stdlib.h>
41#include <errno.h>
42#include <string.h>
43#include <assert.h>
44#include <fcntl.h>
45#include <sys/time.h>
46
47
48void die(const char *s)
49{
50 perror(s);
51 exit(errno);
52}
53
54
55int writen(int fd, const void *buf, size_t len)
56{
57 int o = 0, n;
58 char *ptr = (char*)buf;
59
60 while (len > 0) {
61 if ((n = write(fd, ptr+o, len)) < 0)
62 return n;
63 len -= n;
64 o += n;
65 }
66 return o;
67}
68
69
70/* Simple tcp_connect(). Disables Nagle.
71 */
72int tcp_connect(const char *host, u_short port = 22)
73{
74 int sock, one = 1, len = sizeof(one), r;
75 char service[20];
76 struct addrinfo *res, hints = {0, PF_INET, SOCK_STREAM, 0};
77
78 if ((sock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
79 die("sock");
80
81 sprintf(service, "%d", port);
82 if ((r = getaddrinfo(host, service, &hints, &res)) != 0) {
83 fprintf(stderr, "tcp_connect::getaddrinfo: %s\n", gai_strerror(r));
84 exit(EXIT_FAILURE);
85 }
86#ifdef DONT_BLOCK
87 int f = fcntl(sock, F_GETFL);
88 f |= O_NONBLOCK;
89 if (fcntl(sock, F_SETFL, f) < 0)
90 die("fcntl");
91#endif
92 if (connect(sock, res->ai_addr, res->ai_addrlen) < 0 &&
93 errno != EINPROGRESS)
94 return -1;
95#ifdef DONT_BLOCK
96 struct timeval tv;
97 tv.tv_sec = 2;
98 tv.tv_usec = 0;
99 fd_set rset;
100 FD_ZERO(&rset); FD_SET(sock, &rset);
101 if (select(sock+1, &rset, &rset, NULL, &tv) <= 0) {
102 close(sock);
103 return -1;
104 }
105
106 // fetch pending error
107 int pe = 0; size_t pe_len = sizeof(pe);
108 if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &pe, &pe_len) < 0)
109 die("getsockopt");
110 if (pe != 0) {
111 errno = pe;
112 close(sock);
113 return -1;
114 }
115
116 if (fcntl(sock, F_SETFL, f&~O_NONBLOCK) < 0)
117 die("fcntl");
118#endif
119 if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &one, len) < 0)
120 die("setsockopt");
121
122 freeaddrinfo(res);
123 return sock;
124}
125
126void buffer_dump(const char *desc, unsigned char *buffer, size_t blen)
127{
128 unsigned int i;
129
130 printf("%s=\n", desc);
131 for (i = 0; i < blen; i++) {
132 printf("%02x", buffer[i]);
133 if (i%16==15)
134 printf("\r\n");
135 else if (i%2==1)
136 printf(" ");
137 }
138 printf("\r\n");
139}
140
141
142/* accept "1.2.3.4" or "1.2.3.4-5.6.7.8".
143 * use old := 0 to get first address, and pass
144 * return value in subsequent calls as 'old'.
145 * returns 0 when no more adresses.
146 */
147int next_ip(char *addr, unsigned long old)
148{
149 char *ptr;
150 unsigned long ip, eip, sip;
151
152 assert(addr);
153
154 if (old == 0xffffffff)
155 return -1;
156
157 if ((ptr = strchr(addr, '-')) != NULL) {
158 *ptr++ = 0;
159 eip = inet_addr(ptr);
160 sip = inet_addr(addr);
161 ptr[-1] = '-';
162 } else {
163 eip = inet_addr(addr);
164 if (eip == old)
165 return -1;
166 return eip;
167 }
168
169 if (old == 0)
170 return sip;
171 if (ntohl(old)+1 > ntohl(eip))
172 return -1;
173
174 ip = htonl(ntohl(old)+1);
175 return ip;
176}
177
178