017e1ea73e70b0e5c85e36f4a84e2aa7e602a6cd
[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         fprintf(stderr, "Connection timed out.\n");
37         exit(3);
38         }
39
40 int connectsock(char *host, char *service, char *protocol)
41 {
42         struct hostent *phe;
43         struct servent *pse;
44         struct protoent *ppe;
45         struct sockaddr_in sin;
46         int s,type;
47
48         bzero((char *)&sin,sizeof(sin));
49         sin.sin_family = AF_INET;
50
51         pse=getservbyname(service,protocol);
52         if (pse) {
53                 sin.sin_port = pse->s_port;
54                 }
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         
60         phe=gethostbyname(host);
61         if (phe) {
62                 bcopy(phe->h_addr,(char *)&sin.sin_addr,phe->h_length);
63                 }
64         else if ((sin.sin_addr.s_addr = inet_addr(host))==INADDR_NONE) {
65                 fprintf(stderr, "Can't get %s host entry: %s\n",
66                         host,strerror(errno));
67                 return(-1);
68                 }
69
70         if ((ppe=getprotobyname(protocol))==0) {
71                 fprintf(stderr, "Can't get %s protocol entry: %s\n",
72                         protocol,strerror(errno));
73                 return(-1);
74                 }
75
76         if (!strcmp(protocol,"udp"))
77                 type = SOCK_DGRAM;
78         else
79                 type = SOCK_STREAM;
80
81         s = socket(PF_INET,type,ppe->p_proto);
82         if (s<0) {
83                 fprintf(stderr, "Can't create socket: %s\n", strerror(errno));
84                 return(-1);
85                 }
86
87
88         signal(SIGALRM,timeout);
89         alarm(30);
90
91         if (connect(s,(struct sockaddr *)&sin,sizeof(sin))<0) {
92                 fprintf(stderr,"can't connect to %s.%s: %s\n",
93                         host,service,strerror(errno));
94                 return(-1);
95                 }
96
97         alarm(0);
98         signal(SIGALRM,SIG_IGN);
99
100         return(s);
101         }
102
103
104
105
106 /*
107  * Input binary data from socket
108  */
109 void serv_read(char *buf, int bytes)
110 {
111         int len,rlen;
112
113         len = 0;
114         while(len<bytes) {
115                 rlen = read(serv_sock,&buf[len],bytes-len);
116                 if (rlen<1) {
117                         fprintf(stderr, "Server connection broken: %s\n",
118                                 strerror(errno));
119                         connected = 0;
120                         logged_in = 0;
121                         return;
122                         }
123                 len = len + rlen;
124                 }
125         }
126
127
128 /*
129  * input string from pipe
130  */
131 void serv_gets(char *strbuf)
132 {
133         int ch,len;
134         char buf[2];
135
136         len = 0;
137         strcpy(strbuf,"");
138         do {
139                 serv_read(&buf[0], 1);
140                 ch = buf[0];
141                 strbuf[len++] = ch;
142                 } while((ch!=10)&&(ch!=13)&&(ch!=0)&&(len<255));
143         strbuf[len-1] = 0;
144         /* fprintf(stderr, ">%s\n", strbuf); */
145         }
146
147
148
149 /*
150  * send binary to server
151  */
152 void serv_write(char *buf, int nbytes)
153 {
154         int bytes_written = 0;
155         int retval;
156         while (bytes_written < nbytes) {
157                 retval = write(serv_sock, &buf[bytes_written],
158                         nbytes - bytes_written);
159                 if (retval < 1) {
160                         fprintf(stderr, "Server connection broken: %s\n",
161                                 strerror(errno));
162                         connected = 0;
163                         logged_in = 0;
164                         return;
165                         }
166                 bytes_written = bytes_written + retval;
167                 }
168         }
169
170
171 /*
172  * send line to server
173  */
174 void serv_puts(char *string)
175 {
176         char buf[256];
177
178         sprintf(buf,"%s\n", string);
179         serv_write(buf, strlen(buf));
180         }
181
182
183 /*
184  * convenience function to send stuff to the server
185  */
186 void serv_printf(const char *format, ...) {   
187         va_list arg_ptr;   
188         char buf[256];
189
190         va_start(arg_ptr, format);   
191         vsprintf(buf, format, arg_ptr);   
192         va_end(arg_ptr);   
193
194         strcat(buf, "\n");
195         serv_write(buf, strlen(buf));
196         /* fprintf(stderr, "<%s", buf); */
197         }
198
199