/* * Copyright (c) 2000, Red Hat, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * A copy of the GNU General Public License can be found at * http://www.gnu.org/ * * Written by DJ Delorie <dj@cygnus.com> * *//* Simplified socket access functions */#include "win32.h"#include <winsock.h>#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include "simpsock.h"#include "msg.h"#define SSBUFSZ 1024SimpleSocket::SimpleSocket(char*hostname,intport){staticintinitted=0;if(!initted){initted=1;WSADATAd;WSAStartup(MAKEWORD(1,1),&d);}s=INVALID_SOCKET;buf=(char*)malloc(SSBUFSZ+3);putp=getp=0;inti1,i2,i3,i4;unsignedcharip[4];if(sscanf(hostname,"%d.%d.%d.%d",&i1,&i2,&i3,&i4)==4){ip[0]=i1;ip[1]=i2;ip[2]=i3;ip[3]=i4;}else{structhostent*he;he=gethostbyname(hostname);if(!he){msg("Can't resolve `%s'\n",hostname);return;}memcpy(ip,he->h_addr_list[0],4);}s=socket(AF_INET,SOCK_STREAM,0);if(s==INVALID_SOCKET){msg("Can't create socket, %d",WSAGetLastError());return;}structsockaddr_inname;memset(&name,0,sizeof(name));name.sin_family=AF_INET;name.sin_port=htons(port);memcpy(&name.sin_addr,ip,4);if(connect(s,(sockaddr*)&name,sizeof(name))){msg("Can't connect to %s:%d",hostname,port);closesocket(s);s=INVALID_SOCKET;return;}return;}SimpleSocket::~SimpleSocket(){if(s!=INVALID_SOCKET)closesocket(s);s=INVALID_SOCKET;if(buf)free(buf);buf=0;}intSimpleSocket::ok(){if(s==INVALID_SOCKET)return0;return1;}intSimpleSocket::printf(char*fmt,...){charlocalbuf[SSBUFSZ];va_listargs;va_start(args,fmt);vsprintf(localbuf,fmt,args);returnsend(s,localbuf,strlen(localbuf),0);}intSimpleSocket::write(char*localbuf,intlen){returnsend(s,localbuf,len,0);}intSimpleSocket::fill(){if(putp==getp)putp=getp=0;intn=SSBUFSZ-putp;if(n==0)return0;intr=recv(s,buf+putp,n,0);if(r>0){putp+=r;returnr;}return0;}char*SimpleSocket::gets(){if(getp>0&&putp>getp){memmove(buf,buf+getp,putp-getp);putp-=getp;getp=0;}if(putp==getp)fill();// getp is zero, always, here, and putp is the countchar*nl;while((nl=(char*)memchr(buf,'\n',putp))==NULL&&putp<SSBUFSZ)if(fill()<=0)break;if(nl){getp=nl-buf+1;while((*nl=='\n'||*nl=='\r')&&nl>=buf)*nl--=0;}else{getp=putp;nl=buf+putp;nl[1]=0;}returnbuf;}#define MIN(a,b) ((a) < (b) ? (a) : (b))intSimpleSocket::read(char*ubuf,intulen){intn,rv=0;if(putp>getp){n=MIN(ulen,putp-getp);memmove(ubuf,buf+getp,n);getp+=n;ubuf+=n;ulen-=n;rv+=n;}while(ulen>0){n=recv(s,ubuf,ulen,0);if(n<=0)returnrv;ubuf+=n;ulen-=n;rv+=n;}returnrv;}