Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / int / net / ip / sock.c
1 #include "sock.h"
2
3
4 #ifndef FD_SET
5 #define BITS_PER_INT 32
6 #define FD_SET(f,fds) (fds)->fds_bits[(f)/BITS_PER_INT]|=(1<<((f)%BITS_PER_INT))
7 #define FD_ZERO(fds) { (fds)->fds_bits[0]=0; (fds)->fds_bits[1]=0; }
8 #endif
9
10
11
12 #ifdef BZERO
13 void bzero( buf, size ) char *buf; int size; {
14    while( --size >= 0 )
15       buf[size]='\0';
16 }
17 void bcopy( from, to, size ) char *from,*to; int size; {
18    while( --size >= 0 )
19       to[size]=from[size];
20 }
21 #endif
22
23
24
25 #ifndef INADDR_NONE
26 #define INADDR_NONE 0xffffffffUL
27 #endif
28
29
30 int sock_open( socket_type, protocol, host, service, port, as_server )
31    char *host;
32    char *service;
33    char *protocol;
34    int socket_type,port;
35    int as_server;
36 {
37    int fd;
38    unsigned long inaddr;
39    struct sockaddr_in my_addr,it_addr,*srv_addr;
40    struct servent *sp;
41    struct hostent *hp;
42    struct protoent *pp;
43
44    bzero((char *)&my_addr,sizeof(my_addr));
45    bzero((char *)&it_addr,sizeof(it_addr));
46
47    my_addr.sin_family=AF_INET;
48    it_addr.sin_family=AF_INET;
49
50    my_addr.sin_port=htons(0);
51    it_addr.sin_port=htons(0);
52
53    my_addr.sin_addr.s_addr=htonl(INADDR_ANY);
54    it_addr.sin_addr.s_addr=htonl(INADDR_ANY);
55
56    if( as_server )
57       srv_addr = &my_addr;
58    else
59       srv_addr = &it_addr;
60
61    if( (pp=getprotobyname(protocol)) == NULL ){
62       fprintf(stderr,"protocol %s unknown\n",protocol);
63       return -1;
64    }
65
66    if( service != NULL ){
67       if( (sp=getservbyname(service,protocol)) == NULL ){
68          fprintf(stderr,"port_open:unknown service %s/%s\n",service,protocol);
69          return -1;
70       }
71       srv_addr->sin_port = sp->s_port;
72    }
73
74    if( port>0 )
75       srv_addr->sin_port = htons( port );
76
77    if( host!=NULL )
78       if( (inaddr = inet_addr(host)) != INADDR_NONE ){
79          /* it is dotted-decimal address */
80          bcopy((char *)&inaddr,(char *)&(srv_addr->sin_addr),sizeof(inaddr));
81       } else {
82          if( (hp = gethostbyname(host)) == NULL ){
83             fprintf(stderr,"port_open:host name error %s\n",host);
84             return -1;
85          }
86          bcopy(hp->h_addr,(char *)&(srv_addr->sin_addr),hp->h_length);
87       }
88
89    if( (fd = socket(AF_INET,socket_type,pp->p_proto)) < 0 ){
90       perror("port_open:can't create socket");
91       errno=0;
92       return -1;
93    }
94
95    if( bind( fd, (struct sockaddr *)&my_addr, sizeof(my_addr) ) < 0 ){
96       perror("port_open:bind error");
97       errno=0;
98       return -1;
99    }
100
101    if( !as_server )
102       if( connect( fd, (struct sockaddr *)&it_addr, sizeof(it_addr) ) < 0 ){
103          perror("port_open:connect error");
104          errno=0;
105          return -1;
106       }
107
108    return fd;
109 }
110
111
112 int sock_cli_send( sock, m, size ) int sock,size; void *m; {
113    if( send(sock, m, size, 0) < 0) {
114       perror("cli:send failed");
115       errno=0;
116       return -1;
117    }
118    return 0;
119 }
120
121
122
123 int sock_poll( sock, ms )  int sock,ms; {
124    struct timeval timeout;
125    fd_set rd_fds;
126    int nfds;
127    FD_ZERO(&rd_fds);
128    timeout.tv_sec  = ms/1000;
129    timeout.tv_usec = (ms%1000)*1000;
130    if( sock>=0 )   /* sock==-1 means we only sleep */
131       FD_SET(sock,&rd_fds);
132    nfds = select(sock+1,&rd_fds,NULL,NULL,&timeout);
133    errno=0;
134    return ( nfds == 1 );
135 }
136
137
138 static int cli_recv_timeout = 2000 /* miliseconds */;
139
140 void set_cli_recv_timeout( ms )  int ms; {  /* set timeout to miliseconds */
141    cli_recv_timeout = ms;
142 }
143
144 int  sock_cli_recv( sock, m, size ) int sock,size; void *m; {
145    int recv_size;
146    int nfds;
147    nfds = sock_poll(sock,cli_recv_timeout);
148    if( nfds==0 ){  errno=0;  return 0;  }   /* timeout */
149    if( nfds<0 ){
150       perror("cli:select failed");
151       errno=0;
152       return -1;
153    }
154    if( (recv_size=recv(sock, m, size, 0)) < 0) {
155       perror("cli:recv failed");
156       errno=0;
157       return -1;
158    }
159    return recv_size;
160 }
161
162
163 static int srv_send_wait_time = 1;
164
165 void set_srv_send_delay( ms )  int ms; {  /* set delay to miliseconds */
166    srv_send_wait_time = ms;
167 }
168
169 int sock_srv_send( sock, m, size, addr, namelen )
170    int sock,size,namelen;
171    void *m;
172    struct sockaddr_in *addr;
173 {
174    sock_poll(-1,srv_send_wait_time);
175    if( sendto(sock,m,size,0,addr,namelen) <= 0) {
176       perror("srv:send failed");
177       errno=0;
178       return -1;
179    }
180    return 0;
181 }
182
183 int  sock_srv_recv( sock, m, size, addr, namelen )
184    int sock,size,*namelen;
185    void *m;
186    struct sockaddr_in *addr;
187 {
188    int recv_size;
189    if( (recv_size=recvfrom(sock, m, size, 0, addr, namelen )) < 0) {
190       perror("srv:recvfrom");
191       errno=0;
192       return -1;
193    }
194    return recv_size;
195 }
196
197