(U+63B2): Add `shinjigen@rev' into `<-simplified@JP/Jouyou*sources'.
[chise/xemacs-chise.git.1] / netinstall / 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 #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 }