448
|
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 #include "win32.h"
|
|
19 #include <winsock.h>
|
|
20 #include <stdio.h>
|
|
21 #include <stdarg.h>
|
|
22 #include <stdlib.h>
|
|
23
|
|
24 #include "simpsock.h"
|
|
25 #include "msg.h"
|
|
26
|
|
27 #define SSBUFSZ 1024
|
|
28
|
|
29 SimpleSocket::SimpleSocket (char *hostname, int port)
|
|
30 {
|
|
31 static int initted = 0;
|
|
32 if (!initted)
|
|
33 {
|
|
34 initted = 1;
|
|
35 WSADATA d;
|
|
36 WSAStartup (MAKEWORD (1,1), &d);
|
|
37 }
|
|
38
|
|
39 s = INVALID_SOCKET;
|
|
40 buf = (char *) malloc (SSBUFSZ + 3);
|
|
41 putp = getp = 0;
|
|
42
|
|
43 int i1, i2, i3, i4;
|
|
44 unsigned char ip[4];
|
|
45
|
|
46 if (sscanf (hostname, "%d.%d.%d.%d", &i1, &i2, &i3, &i4) == 4)
|
|
47 {
|
|
48 ip[0] = i1;
|
|
49 ip[1] = i2;
|
|
50 ip[2] = i3;
|
|
51 ip[3] = i4;
|
|
52 }
|
|
53 else
|
|
54 {
|
|
55 struct hostent *he;
|
|
56 he = gethostbyname (hostname);
|
|
57 if (!he)
|
|
58 {
|
|
59 msg ("Can't resolve `%s'\n", hostname);
|
|
60 return;
|
|
61 }
|
|
62 memcpy (ip, he->h_addr_list[0], 4);
|
|
63 }
|
|
64
|
|
65 s = socket (AF_INET, SOCK_STREAM, 0);
|
|
66 if (s == INVALID_SOCKET)
|
|
67 {
|
|
68 msg ("Can't create socket, %d", WSAGetLastError ());
|
|
69 return;
|
|
70 }
|
|
71
|
|
72 struct sockaddr_in name;
|
|
73
|
|
74 memset (&name, 0, sizeof (name));
|
|
75 name.sin_family = AF_INET;
|
|
76 name.sin_port = htons (port);
|
|
77 memcpy (&name.sin_addr, ip, 4);
|
|
78
|
|
79 if (connect (s, (sockaddr *)&name, sizeof(name)))
|
|
80 {
|
|
81 msg ("Can't connect to %s:%d", hostname, port);
|
|
82 closesocket (s);
|
|
83 s = INVALID_SOCKET;
|
|
84 return;
|
|
85 }
|
|
86
|
|
87 return;
|
|
88 }
|
|
89
|
|
90 SimpleSocket::~SimpleSocket ()
|
|
91 {
|
|
92 if (s != INVALID_SOCKET)
|
|
93 closesocket (s);
|
|
94 s = INVALID_SOCKET;
|
|
95 if (buf)
|
|
96 free (buf);
|
|
97 buf = 0;
|
|
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 (char *fmt, ...)
|
|
110 {
|
|
111 char localbuf[SSBUFSZ];
|
|
112 va_list args;
|
|
113 va_start (args, fmt);
|
|
114 vsprintf (localbuf, fmt, args);
|
|
115 return send (s, localbuf, strlen (localbuf), 0);
|
|
116 }
|
|
117
|
|
118 int
|
|
119 SimpleSocket::write (char *localbuf, int len)
|
|
120 {
|
|
121 return send (s, localbuf, len, 0);
|
|
122 }
|
|
123
|
|
124 int
|
|
125 SimpleSocket::fill ()
|
|
126 {
|
|
127 if (putp == getp)
|
|
128 putp = getp = 0;
|
|
129
|
|
130 int n = SSBUFSZ - putp;
|
|
131 if (n == 0)
|
|
132 return 0;
|
|
133 int r = recv (s, buf + putp, n, 0);
|
|
134 if (r > 0)
|
|
135 {
|
|
136 putp += r;
|
|
137 return r;
|
|
138 }
|
|
139 return 0;
|
|
140 }
|
|
141
|
|
142 char *
|
|
143 SimpleSocket::gets ()
|
|
144 {
|
|
145 if (getp > 0 && putp > getp)
|
|
146 {
|
|
147 memmove (buf, buf+getp, putp-getp);
|
|
148 putp -= getp;
|
|
149 getp = 0;
|
|
150 }
|
|
151 if (putp == getp)
|
|
152 fill();
|
|
153
|
|
154 // getp is zero, always, here, and putp is the count
|
|
155 char *nl;
|
|
156 while ((nl = (char *)memchr (buf, '\n', putp)) == NULL && putp < SSBUFSZ)
|
|
157 if (fill () <= 0)
|
|
158 break;
|
|
159
|
|
160 if (nl)
|
|
161 {
|
|
162 getp = nl - buf + 1;
|
|
163 while ((*nl == '\n' || *nl == '\r') && nl >= buf)
|
|
164 *nl-- = 0;
|
|
165 }
|
|
166 else
|
|
167 {
|
|
168 getp = putp;
|
|
169 nl = buf + putp;
|
|
170 nl[1] = 0;
|
|
171 }
|
|
172
|
|
173 return buf;
|
|
174 }
|
|
175
|
|
176 #define MIN(a,b) ((a) < (b) ? (a) : (b))
|
|
177
|
|
178 int
|
|
179 SimpleSocket::read (char *ubuf, int ulen)
|
|
180 {
|
|
181 int n, rv=0;
|
|
182 if (putp > getp)
|
|
183 {
|
|
184 n = MIN (ulen, putp-getp);
|
|
185 memmove (ubuf, buf+getp, n);
|
|
186 getp += n;
|
|
187 ubuf += n;
|
|
188 ulen -= n;
|
|
189 rv += n;
|
|
190 }
|
|
191 while (ulen > 0)
|
|
192 {
|
|
193 n = recv (s, ubuf, ulen, 0);
|
|
194 if (n <= 0)
|
|
195 return rv;
|
|
196 ubuf += n;
|
|
197 ulen -= n;
|
|
198 rv += n;
|
|
199 }
|
|
200 return rv;
|
|
201 }
|