]> cygwin.com Git - cygwin-apps/setup.git/blob - simpsock.cc
2002-07-05 Robert Collins <rbtcollins@hotmail.com>
[cygwin-apps/setup.git] / simpsock.cc
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
18 #if 0
19 static const char *cvsid =
20 "\n%%% $Id$\n";
21 #endif
22
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
34 SimpleSocket::SimpleSocket (const char *hostname, int port)
35 {
36 static int initted = 0;
37 if (!initted)
38 {
39 initted = 1;
40 WSADATA d;
41 WSAStartup (MAKEWORD (1, 1), &d);
42 }
43
44 s = INVALID_SOCKET;
45 buf = 0;
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
84 if (connect (s, (sockaddr *) & name, sizeof (name)))
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 {
97 invalidate ();
98 }
99
100 int
101 SimpleSocket::ok ()
102 {
103 if (s == INVALID_SOCKET)
104 return 0;
105 return 1;
106 }
107
108 int
109 SimpleSocket::printf (const char *fmt, ...)
110 {
111 char buf[SSBUFSZ];
112 va_list args;
113 va_start (args, fmt);
114 vsprintf (buf, fmt, args);
115 return write (buf, strlen (buf));
116 }
117
118 int
119 SimpleSocket::write (const char *buf, int len)
120 {
121 int rv;
122 if (!ok ())
123 return -1;
124 if ((rv = send (s, buf, len, 0)) == -1)
125 invalidate ();
126 return rv;
127 }
128
129 int
130 SimpleSocket::fill ()
131 {
132 if (!ok ())
133 return -1;
134
135 if (buf == 0)
136 buf = new char [SSBUFSZ + 3];
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;
147 }
148 else if (r < 0 && putp == getp)
149 {
150 invalidate ();
151 }
152 return r;
153 }
154
155 char *
156 SimpleSocket::gets ()
157 {
158 if (getp > 0 && putp > getp)
159 {
160 memmove (buf, buf + getp, putp - getp);
161 putp -= getp;
162 getp = 0;
163 }
164 if (putp == getp)
165 if (fill () <= 0)
166 return 0;
167
168 // getp is zero, always, here, and putp is the count
169 char *nl;
170 while ((nl = (char *) memchr (buf, '\n', putp)) == NULL && putp < SSBUFSZ)
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 }
180 else if (putp > getp)
181 {
182 getp = putp;
183 nl = buf + putp;
184 nl[1] = 0;
185 }
186 else
187 return 0;
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 {
197 if (!ok ())
198 return -1;
199
200 int n, rv = 0;
201 if (putp > getp)
202 {
203 n = MIN (ulen, putp - getp);
204 memmove (ubuf, buf + getp, n);
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);
213 if (n < 0)
214 invalidate ();
215 if (n <= 0)
216 return rv > 0 ? rv : n;
217 ubuf += n;
218 ulen -= n;
219 rv += n;
220 }
221 return rv;
222 }
223
224 void
225 SimpleSocket::invalidate (void)
226 {
227 if (s != INVALID_SOCKET)
228 closesocket (s);
229 s = INVALID_SOCKET;
230 if (buf)
231 delete[] buf;
232 buf = 0;
233 getp = putp = 0;
234 }
This page took 0.043179 seconds and 5 git commands to generate.