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