]> Pileus Git - ~andy/fetchmail/blob - socket.c
STEP 9: Eliminate the static buffer in the socket library.
[~andy/fetchmail] / socket.c
1 /*
2  * socket.c -- socket library functions
3  *
4  * These were designed and coded by Carl Harris <ceharris@mal.com>
5  * and are essentially unchanged from the ancestral popclient.
6  *
7  * The file pointer arguments are currently misleading -- there
8  * is only one shared internal buffer for all sockets.
9  *
10  * For license terms, see the file COPYING in this directory.
11  */
12
13 #include <config.h>
14
15 #include <stdio.h>
16 #include <fcntl.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <netinet/in.h>
20 #include <arpa/inet.h>
21 #include <netdb.h>
22 #include <sys/time.h>
23 #include <sys/ioctl.h>
24 #if defined(STDC_HEADERS)
25 #include <string.h>
26 #include <stdlib.h>
27 #endif
28 #if defined(HAVE_UNISTD_H)
29 #include <unistd.h>
30 #endif
31 #if defined(HAVE_STDARG_H)
32 #include <stdarg.h>
33 #else
34 #include <varargs.h>
35 #endif
36 #include <errno.h>
37 #include "socket.h"
38
39 /* Size of buffer for internal buffering read function 
40    don't increase beyond the maximum atomic read/write size for
41    your sockets, or you'll take a potentially huge performance hit */
42
43 #define  INTERNAL_BUFSIZE       2048
44
45 FILE *Socket(host, clientPort)
46 char *host;
47 int clientPort;
48 {
49     int sock;
50     unsigned long inaddr;
51     struct sockaddr_in ad;
52     struct hostent *hp;
53     
54     memset(&ad, 0, sizeof(ad));
55     ad.sin_family = AF_INET;
56
57     inaddr = inet_addr(host);
58     if (inaddr != INADDR_NONE)
59         memcpy(&ad.sin_addr, &inaddr, sizeof(inaddr));
60     else
61     {
62         hp = gethostbyname(host);
63         if (hp == NULL)
64             return (FILE *)NULL;
65         memcpy(&ad.sin_addr, hp->h_addr, hp->h_length);
66     }
67     ad.sin_port = htons(clientPort);
68     
69     sock = socket(AF_INET, SOCK_STREAM, 0);
70     if (sock < 0)
71         return (FILE *)NULL;
72     if (connect(sock, (struct sockaddr *) &ad, sizeof(ad)) < 0)
73         return (FILE *)NULL;
74     return fdopen(sock, "r+");
75 }
76
77 int SockWrite(buf,len,sockfp)
78 char *buf;
79 int len;
80 FILE *sockfp;
81 {
82     int n, wrlen = 0;
83     
84     while (len)
85     {
86         n = write(fileno(sockfp), buf, len);
87         if (n <= 0)
88             return -1;
89         len -= n;
90         wrlen += n;
91         buf += n;
92     }
93     return wrlen;
94 }
95
96 int SockGets(buf, len, sockfp)
97 char *buf;
98 int len;
99 FILE *sockfp;
100 {
101     int rdlen = 0;
102
103     while (--len)
104     {
105         if (read(fileno(sockfp), buf, 1) != 1)
106             return -1;
107         else
108             rdlen++;
109         if (*buf == '\n')
110             break;
111         if (*buf != '\r') /* remove all CRs */
112             buf++;
113     }
114     *buf = 0;
115     return rdlen;
116 }
117
118 #if defined(HAVE_STDARG_H)
119 int SockPrintf(FILE *sockfp, char* format, ...)
120 {
121 #else
122 int SockPrintf(sockfp,format,va_alist)
123 FILE *sockfp;
124 char *format;
125 va_dcl {
126 #endif
127
128     va_list ap;
129     char buf[8192];
130
131 #if defined(HAVE_STDARG_H)
132     va_start(ap, format) ;
133 #else
134     va_start(ap);
135 #endif
136     vsprintf(buf, format, ap);
137     va_end(ap);
138     return SockWrite(buf, strlen(buf), sockfp);
139
140 }
141
142 /* socket.c ends here */