]>
Commit | Line | Data |
---|---|---|
4a83b7b0 DD |
1 | /* |
2 | * Copyright (c) 2000, Red Hat, Inc. | |
3 | * | |
4 | * This program is free software; you can redistribute it and/or modify | |
5 | * it under the terms of the GNU General Public License as published by | |
6 | * the Free Software Foundation; either version 2 of the License, or | |
7 | * (at your option) any later version. | |
8 | * | |
9 | * A copy of the GNU General Public License can be found at | |
10 | * http://www.gnu.org/ | |
11 | * | |
12 | * Written by DJ Delorie <dj@cygnus.com> | |
13 | * | |
14 | */ | |
15 | ||
16 | /* Simplified socket access functions */ | |
17 | ||
5898e300 | 18 | #if 0 |
b24c88b3 RC |
19 | static const char *cvsid = |
20 | "\n%%% $Id$\n"; | |
5898e300 | 21 | #endif |
946fc045 | 22 | |
4a83b7b0 DD |
23 | #include "win32.h" |
24 | #include <winsock.h> | |
25 | #include <stdio.h> | |
26 | #include <stdarg.h> | |
27 | #include <stdlib.h> | |
28 | ||
29 | #include "simpsock.h" | |
30 | #include "msg.h" | |
31 | ||
32 | #define SSBUFSZ 1024 | |
33 | ||
5898e300 | 34 | SimpleSocket::SimpleSocket (const char *hostname, int port) |
4a83b7b0 DD |
35 | { |
36 | static int initted = 0; | |
37 | if (!initted) | |
38 | { | |
39 | initted = 1; | |
40 | WSADATA d; | |
b24c88b3 | 41 | WSAStartup (MAKEWORD (1, 1), &d); |
4a83b7b0 DD |
42 | } |
43 | ||
44 | s = INVALID_SOCKET; | |
67a55ad9 | 45 | buf = 0; |
4a83b7b0 DD |
46 | putp = getp = 0; |
47 | ||
48 | int i1, i2, i3, i4; | |
49 | unsigned char ip[4]; | |
50 | ||
51 | if (sscanf (hostname, "%d.%d.%d.%d", &i1, &i2, &i3, &i4) == 4) | |
52 | { | |
53 | ip[0] = i1; | |
54 | ip[1] = i2; | |
55 | ip[2] = i3; | |
56 | ip[3] = i4; | |
57 | } | |
58 | else | |
59 | { | |
60 | struct hostent *he; | |
61 | he = gethostbyname (hostname); | |
62 | if (!he) | |
63 | { | |
64 | msg ("Can't resolve `%s'\n", hostname); | |
65 | return; | |
66 | } | |
67 | memcpy (ip, he->h_addr_list[0], 4); | |
68 | } | |
69 | ||
70 | s = socket (AF_INET, SOCK_STREAM, 0); | |
71 | if (s == INVALID_SOCKET) | |
72 | { | |
73 | msg ("Can't create socket, %d", WSAGetLastError ()); | |
74 | return; | |
75 | } | |
76 | ||
77 | struct sockaddr_in name; | |
78 | ||
79 | memset (&name, 0, sizeof (name)); | |
80 | name.sin_family = AF_INET; | |
81 | name.sin_port = htons (port); | |
82 | memcpy (&name.sin_addr, ip, 4); | |
83 | ||
b24c88b3 | 84 | if (connect (s, (sockaddr *) & name, sizeof (name))) |
4a83b7b0 DD |
85 | { |
86 | msg ("Can't connect to %s:%d", hostname, port); | |
87 | closesocket (s); | |
88 | s = INVALID_SOCKET; | |
89 | return; | |
90 | } | |
91 | ||
92 | return; | |
93 | } | |
94 | ||
95 | SimpleSocket::~SimpleSocket () | |
96 | { | |
67a55ad9 | 97 | invalidate (); |
4a83b7b0 DD |
98 | } |
99 | ||
100 | int | |
101 | SimpleSocket::ok () | |
102 | { | |
103 | if (s == INVALID_SOCKET) | |
104 | return 0; | |
105 | return 1; | |
106 | } | |
107 | ||
108 | int | |
5898e300 | 109 | SimpleSocket::printf (const char *fmt, ...) |
4a83b7b0 DD |
110 | { |
111 | char buf[SSBUFSZ]; | |
112 | va_list args; | |
113 | va_start (args, fmt); | |
114 | vsprintf (buf, fmt, args); | |
67a55ad9 | 115 | return write (buf, strlen (buf)); |
4a83b7b0 DD |
116 | } |
117 | ||
118 | int | |
5898e300 | 119 | SimpleSocket::write (const char *buf, int len) |
4a83b7b0 | 120 | { |
67a55ad9 RC |
121 | int rv; |
122 | if (!ok ()) | |
123 | return -1; | |
124 | if ((rv = send (s, buf, len, 0)) == -1) | |
125 | invalidate (); | |
126 | return rv; | |
4a83b7b0 DD |
127 | } |
128 | ||
129 | int | |
130 | SimpleSocket::fill () | |
131 | { | |
67a55ad9 RC |
132 | if (!ok ()) |
133 | return -1; | |
134 | ||
135 | if (buf == 0) | |
5e0464a1 | 136 | buf = new char [SSBUFSZ + 3]; |
4a83b7b0 DD |
137 | if (putp == getp) |
138 | putp = getp = 0; | |
139 | ||
140 | int n = SSBUFSZ - putp; | |
141 | if (n == 0) | |
142 | return 0; | |
143 | int r = recv (s, buf + putp, n, 0); | |
144 | if (r > 0) | |
145 | { | |
146 | putp += r; | |
4a83b7b0 | 147 | } |
67a55ad9 RC |
148 | else if (r < 0 && putp == getp) |
149 | { | |
b24c88b3 | 150 | invalidate (); |
67a55ad9 RC |
151 | } |
152 | return r; | |
4a83b7b0 DD |
153 | } |
154 | ||
155 | char * | |
156 | SimpleSocket::gets () | |
157 | { | |
158 | if (getp > 0 && putp > getp) | |
159 | { | |
b24c88b3 | 160 | memmove (buf, buf + getp, putp - getp); |
4a83b7b0 DD |
161 | putp -= getp; |
162 | getp = 0; | |
163 | } | |
164 | if (putp == getp) | |
67a55ad9 RC |
165 | if (fill () <= 0) |
166 | return 0; | |
4a83b7b0 DD |
167 | |
168 | // getp is zero, always, here, and putp is the count | |
169 | char *nl; | |
b24c88b3 | 170 | while ((nl = (char *) memchr (buf, '\n', putp)) == NULL && putp < SSBUFSZ) |
4a83b7b0 DD |
171 | if (fill () <= 0) |
172 | break; | |
173 | ||
174 | if (nl) | |
175 | { | |
176 | getp = nl - buf + 1; | |
177 | while ((*nl == '\n' || *nl == '\r') && nl >= buf) | |
178 | *nl-- = 0; | |
179 | } | |
67a55ad9 | 180 | else if (putp > getp) |
4a83b7b0 DD |
181 | { |
182 | getp = putp; | |
183 | nl = buf + putp; | |
184 | nl[1] = 0; | |
185 | } | |
67a55ad9 RC |
186 | else |
187 | return 0; | |
4a83b7b0 DD |
188 | |
189 | return buf; | |
190 | } | |
191 | ||
192 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | |
193 | ||
194 | int | |
195 | SimpleSocket::read (char *ubuf, int ulen) | |
196 | { | |
67a55ad9 RC |
197 | if (!ok ()) |
198 | return -1; | |
199 | ||
b24c88b3 | 200 | int n, rv = 0; |
4a83b7b0 DD |
201 | if (putp > getp) |
202 | { | |
b24c88b3 RC |
203 | n = MIN (ulen, putp - getp); |
204 | memmove (ubuf, buf + getp, n); | |
4a83b7b0 DD |
205 | getp += n; |
206 | ubuf += n; | |
207 | ulen -= n; | |
208 | rv += n; | |
209 | } | |
210 | while (ulen > 0) | |
211 | { | |
212 | n = recv (s, ubuf, ulen, 0); | |
67a55ad9 | 213 | if (n < 0) |
b24c88b3 | 214 | invalidate (); |
4a83b7b0 | 215 | if (n <= 0) |
b24c88b3 | 216 | return rv > 0 ? rv : n; |
4a83b7b0 DD |
217 | ubuf += n; |
218 | ulen -= n; | |
219 | rv += n; | |
220 | } | |
221 | return rv; | |
222 | } | |
67a55ad9 RC |
223 | |
224 | void | |
225 | SimpleSocket::invalidate (void) | |
226 | { | |
227 | if (s != INVALID_SOCKET) | |
228 | closesocket (s); | |
229 | s = INVALID_SOCKET; | |
230 | if (buf) | |
5e0464a1 | 231 | delete[] buf; |
67a55ad9 RC |
232 | buf = 0; |
233 | getp = putp = 0; | |
234 | } |