Added upstream from http://ftp.icm.edu.pl/pub/loglan/
[loglan.git] / sources / new-s5r4 / sock.c
1      /* Loglan82 Compiler&Interpreter
2      Copyright (C) 1981-1993 Institute of Informatics, University of Warsaw
3      Copyright (C)  1993, 1994 LITA, Pau
4      
5      This program is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published by
7      the Free Software Foundation; either version 2 of the License, or
8      (at your option) any later version.
9      
10      This program is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13      GNU General Public License for more details.
14      
15              You should have received a copy of the GNU General Public License
16              along with this program; if not, write to the Free Software
17              Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19  contacts:  Andrzej.Salwicki@univ-pau.fr
20
21 or             Andrzej Salwicki
22                 LITA   Departement d'Informatique
23                 Universite de Pau
24                 Avenue de l'Universite
25                 64000 Pau   FRANCE
26                  tel.  ++33 59923154    fax. ++33 59841696
27
28 =======================================================================
29 */
30
31 #include <assert.h>
32
33 #include "depend.h"
34 #include "genint.h"
35 #include "int.h"
36 #include "process.h"
37 #include "intproto.h"
38 #include "soct.h"
39 #include "sock.h"
40 #include "tcpip.h"
41
42
43 #ifndef FD_SET
44 #define BITS_PER_INT 32
45 #define FD_SET(f,fds) (fds)->fds_bits[(f)/BITS_PER_INT]|=(1<<((f)%BITS_PER_INT))
46 #define FD_ZERO(fds) { (fds)->fds_bits[0]=0; (fds)->fds_bits[1]=0; }
47 #endif
48
49
50
51 #ifdef BZERO
52 void bzero( buf, size ) char *buf; int size; {
53    while( --size >= 0 )
54       buf[size]='\0';
55 }
56 void bcopy( from, to, size ) char *from,*to; int size; {
57    while( --size >= 0 )
58       to[size]=from[size];
59 }
60 #endif
61
62
63
64 #ifndef INADDR_NONE
65 #define INADDR_NONE 0xffffffffUL
66 #endif
67
68 /* Zerowanie adresu O.S.*/
69 #define init_addr(addr)                       \
70    bzero((char *)&(addr),sizeof(addr));       \
71    (addr).sin_family=AF_INET;                 \
72    (addr).sin_port=htons(0);                  \
73    (addr).sin_addr.s_addr=htonl(INADDR_ANY);
74
75
76
77 int host_addr( host, buf )  char *host; struct sockaddr_in *buf; {
78
79    long inaddr;
80    int port;
81    struct hostent *hp;
82    char *addr;
83
84    init_addr( *buf );
85
86    addr = strchr( host, ':' );
87    if( addr == NULL )
88       port = PORT;
89    else
90    {
91       *addr = '\0';
92       addr++;
93       if( *addr!='\0' )
94          if( sscanf( addr, "%d", &port ) != 1 )  usage();
95          else;
96       else
97          port = PORT;
98    }
99
100    buf->sin_port = htons( port );
101
102                                           /* try dotted-decimal address */
103    if( (inaddr = inet_addr(host)) == INADDR_NONE ){
104       if( (hp = gethostbyname(host)) == NULL )
105          return -1;
106       assert( hp->h_length == sizeof( inaddr ) );
107       bcopy( (char *)( hp->h_addr ), (char *)&( buf->sin_addr ), sizeof( inaddr ) );
108    }
109
110    return 0;
111 }
112
113
114 /* zwraca otwarte gniazdko */
115
116 int sock_open( socket_type, protocol, service, port )
117    char *service;
118    char *protocol;
119    int socket_type,port;
120 {
121    int fd;
122    struct sockaddr_in my_addr;
123    struct servent *sp;
124    struct protoent *pp;
125
126    init_addr( my_addr );
127
128    if( (pp=getprotobyname(protocol)) == NULL )
129       return -1;
130
131    if( service != NULL ){
132       if( (sp=getservbyname(service,protocol)) == NULL )
133          return -1;
134       my_addr.sin_port = sp->s_port;
135    }
136
137    if( port>0 )
138       my_addr.sin_port = htons( port );
139
140    if( (fd = socket(AF_INET,socket_type,pp->p_proto)) < 0 )
141       return -1;
142
143    if( bind( fd, (struct sockaddr *)&my_addr, sizeof(my_addr) ) < 0 )
144       return -1;
145
146    return fd;
147 }
148
149
150
151 int sock_poll( sock, ms )  int sock,ms; {
152    struct timeval timeout;
153    fd_set rd_fds;
154    int nfds;
155    FD_ZERO(&rd_fds);
156    timeout.tv_sec  = ms/1000;
157    timeout.tv_usec = (ms%1000)*1000;
158    if( sock>=0 )   /* sock==-1 means we only sleep */
159       FD_SET(sock,&rd_fds);
160    if( ms >= 0 )
161       nfds = select(sock+1,&rd_fds,NULL,NULL,&timeout);
162    else
163       nfds = select(sock+1,&rd_fds,NULL,NULL,NULL);
164    errno=0;
165    return ( nfds == 1 );
166 }
167
168
169
170 static int send_wait_time = 0;
171
172 void set_send_delay( ms )  int ms; {  /* set delay to miliseconds */
173    send_wait_time = ms;
174 }
175
176 int sock_send( sock, buf, size, addr )
177    int sock,size;
178    void *buf;
179    struct sockaddr_in *addr;
180 {
181    struct sockaddr *adr;
182
183    int namelen = sizeof( *addr );
184    if( send_wait_time > 0 )
185       sock_poll( -1, send_wait_time );
186    if( sendto( sock, (char *)buf, size, 0, addr, namelen ) <= 0 ){
187       fprintf(
188               stderr,
189               "socket send to %s:%d\n",
190               inet_ntoa( addr->sin_addr ),
191               (int)ntohs( addr->sin_port )
192              );
193       perror("send error");
194       abend("send error");
195    }
196    return 0;
197 }
198
199 int  sock_recv( sock, buf, size, addr )
200    int sock,size;
201    void *buf;
202    struct sockaddr_in *addr;
203 {
204    int recv_size;
205    int namelen = sizeof( struct sockaddr_in );
206    if( ( recv_size = recvfrom( sock, buf, size, 0, addr, &namelen ) ) < 0 ){
207       perror("recv");
208       return -1;
209    }
210    if( namelen != sizeof( struct sockaddr_in ) ){
211       printf("str sockaddr_in %d namelen %d\n",sizeof(struct sockaddr_in),namelen);
212       printf("addr %s\n",inet_ntoa(addr->sin_addr));
213       abend("strenge message");
214    }
215    return recv_size;
216 }
217
218
219