-
Notifications
You must be signed in to change notification settings - Fork 0
/
uici1.c
153 lines (139 loc) · 4 KB
/
uici1.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/* uici.c sockets implementation */
/*#include <stdio.h>*/
#include <unistd.h>
/*#include <string.h>*/
/*#include <netdb.h>*/
#include <signal.h>
/*#include <ctype.h>*/
/*#include <sys/types.h>*/
#include <sys/socket.h>
/*#include <netinet/in.h>*/
/*#include <netinet/tcp.h>*/
/*#include <arpa/inet.h>*/
#include <errno.h>
#include "uiciname.h"
#include "uici.h"
#define MAXBACKLOG 50
/* return 1 if error, 0 if OK */
static int u_ignore_sigpipe()
{
struct sigaction act;
if (sigaction(SIGPIPE, (struct sigaction *)NULL, &act) < 0)
return 1;
if (act.sa_handler == SIG_DFL) {
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, (struct sigaction *)NULL) < 0)
return 1;
}
return 0;
}
/*
* u_open
* Return a file descriptor which is bound to the given port.
*
* parameter:
* s = number of port to bind to
* returns: file descriptor if successful
* -1 on error and sets errno
*/
int u_open(u_port_t port)
{
struct sockaddr_in server;
int sock;
int true = 1;
int error;
if ( (u_ignore_sigpipe() != 0) ||
((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) )
return -1;
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&true,
sizeof(true)) < 0) {
error = errno;
close(sock);
errno = error;
return -1;
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons((short)port);
if ( (bind(sock, (struct sockaddr *)&server, sizeof(server)) < 0) ||
(listen(sock, MAXBACKLOG) < 0) ) {
error = errno;
close(sock);
errno = error;
return -1;
}
return sock;
}
/*
* u_accept
* Wait for a from a host on a specified port.
*
* parameters:
* fd = file descriptor previously bound to listening port
* hostn = name of host to listen for
* hostnsize = size of hostn buffer
* returns: communication file descriptor or -1 on error
*
* comments: This function is used by the server to wait for a
* communication. It blocks until a remote request is received
* from the port bound to the given file descriptor.
* hostn is filled with an ASCII string containing the remote
* host name. It must point to a buffer of size at least hostnsize.
* If the name does not fit, as much of the name as is possible is put
* into the buffer.
* If hostn is NULL or hostnsize <= 0, no hostname is copied.
*/
int u_accept(int fd, char *hostn, int hostnsize)
{
int len = sizeof(struct sockaddr);
struct sockaddr_in net_client;
int retval;
while ( ((retval =
accept(fd, (struct sockaddr *)(&net_client), &len)) == -1) &&
(errno == EINTR) )
;
if ( (retval == -1) || (hostn == NULL) || (hostnsize <= 0) )
return retval;
addr_to_name(net_client.sin_addr,hostn,hostnsize);
return retval;
}
/*
* u_connect
* Initiate communication with a remote server.
*
* parameters:
* port = well-known port on remote server
* hostn = character string giving the Internet name of the
* remote machine
* returns: the file descriptor used for communication if successful
* -1 on error on system error that sets errno
* U_EHOST if hostn cannot be resolved
* U_ECONNECTION if connection fails
*/
int u_connect(u_port_t port, char *hostn)
{
int retval;
struct sockaddr_in server;
int sock;
int error;
if (name_to_addr(hostn,&(server.sin_addr.s_addr)) < 0) {
errno = EINVAL;
return -1;
}
server.sin_port = htons((short)port);
server.sin_family = AF_INET;
if ( (u_ignore_sigpipe() != 0) ||
((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) )
return -1;
while ( ((retval =
connect(sock, (struct sockaddr *)&server, sizeof(server))) == -1)
&& (errno == EINTR) )
;
if (retval == -1) {
error = errno;
close(sock);
errno = error;
return -1;
}
return sock;
}