bafeea9b5bef56578c1e0105764f50586037dfdd
[citadel.git] / webcit / tcp_sockets.c
1 /*
2  * tcp_sockets.c
3  * 
4  * TCP socket module for WebCit
5  *
6  * $Id$
7  */
8
9 #include <stdlib.h>
10 #ifdef HAVE_UNISTD_H
11 #include <unistd.h>
12 #endif
13 #include <stdio.h>
14 #include <signal.h>
15 #include <sys/types.h>
16 #include <sys/socket.h>
17 #include <netinet/in.h>
18 #include <arpa/inet.h>
19 #include <netdb.h>
20 #include <string.h>
21 #include <stdarg.h>
22 #include "webcit.h"
23
24 char server_is_local = 0;
25
26 #ifndef INADDR_NONE
27 #define INADDR_NONE 0xffffffff
28 #endif
29
30 extern int errno;
31
32 int serv_sock;
33
34
35 RETSIGTYPE timeout(int signum)
36 {
37         fprintf(stderr, "Connection timed out.\n");
38         exit(3);
39 }
40
41 int connectsock(char *host, char *service, char *protocol)
42 {
43         struct hostent *phe;
44         struct servent *pse;
45         struct protoent *ppe;
46         struct sockaddr_in sin;
47         int s, type;
48
49         bzero((char *) &sin, sizeof(sin));
50         sin.sin_family = AF_INET;
51
52         pse = getservbyname(service, protocol);
53         if (pse) {
54                 sin.sin_port = pse->s_port;
55         } else if ((sin.sin_port = htons((u_short) atoi(service))) == 0) {
56                 fprintf(stderr, "Can't get %s service entry\n", service);
57                 return (-1);
58         }
59         phe = gethostbyname(host);
60         if (phe) {
61                 bcopy(phe->h_addr, (char *) &sin.sin_addr, phe->h_length);
62         } else if ((sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE) {
63                 fprintf(stderr, "Can't get %s host entry: %s\n",
64                         host, strerror(errno));
65                 return (-1);
66         }
67         if ((ppe = getprotobyname(protocol)) == 0) {
68                 fprintf(stderr, "Can't get %s protocol entry: %s\n",
69                         protocol, strerror(errno));
70                 return (-1);
71         }
72         if (!strcmp(protocol, "udp"))
73                 type = SOCK_DGRAM;
74         else
75                 type = SOCK_STREAM;
76
77         s = socket(PF_INET, type, ppe->p_proto);
78         if (s < 0) {
79                 fprintf(stderr, "Can't create socket: %s\n", strerror(errno));
80                 return (-1);
81         }
82         signal(SIGALRM, timeout);
83         alarm(30);
84
85         if (connect(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
86                 fprintf(stderr, "can't connect to %s.%s: %s\n",
87                         host, service, strerror(errno));
88                 return (-1);
89         }
90         alarm(0);
91         signal(SIGALRM, SIG_IGN);
92
93         return (s);
94 }
95
96
97
98
99 /*
100  * Input binary data from socket
101  */
102 void serv_read(char *buf, int bytes)
103 {
104         int len, rlen;
105
106         len = 0;
107         while (len < bytes) {
108                 rlen = read(serv_sock, &buf[len], bytes - len);
109                 if (rlen < 1) {
110                         fprintf(stderr, "Server connection broken: %s\n",
111                                 strerror(errno));
112                         connected = 0;
113                         logged_in = 0;
114                         return;
115                 }
116                 len = len + rlen;
117         }
118 }
119
120
121 /*
122  * input string from pipe
123  */
124 void serv_gets(char *strbuf)
125 {
126         int ch, len;
127         char buf[2];
128
129         len = 0;
130         strcpy(strbuf, "");
131         do {
132                 serv_read(&buf[0], 1);
133                 ch = buf[0];
134                 strbuf[len++] = ch;
135         } while ((ch != 10) && (ch != 13) && (ch != 0) && (len < 255));
136         strbuf[len - 1] = 0;
137         /* fprintf(stderr, ">%s\n", strbuf); */
138 }
139
140
141
142 /*
143  * send binary to server
144  */
145 void serv_write(char *buf, int nbytes)
146 {
147         int bytes_written = 0;
148         int retval;
149         while (bytes_written < nbytes) {
150                 retval = write(serv_sock, &buf[bytes_written],
151                                nbytes - bytes_written);
152                 if (retval < 1) {
153                         fprintf(stderr, "Server connection broken: %s\n",
154                                 strerror(errno));
155                         connected = 0;
156                         logged_in = 0;
157                         return;
158                 }
159                 bytes_written = bytes_written + retval;
160         }
161 }
162
163
164 /*
165  * send line to server
166  */
167 void serv_puts(char *string)
168 {
169         char buf[256];
170
171         sprintf(buf, "%s\n", string);
172         serv_write(buf, strlen(buf));
173 }
174
175
176 /*
177  * convenience function to send stuff to the server
178  */
179 void serv_printf(const char *format,...)
180 {
181         va_list arg_ptr;
182         char buf[256];
183
184         va_start(arg_ptr, format);
185         vsprintf(buf, format, arg_ptr);
186         va_end(arg_ptr);
187
188         strcat(buf, "\n");
189         serv_write(buf, strlen(buf));
190         /* fprintf(stderr, "<%s", buf); */
191 }