ia64/xen-unstable

view tools/xfrd/connection.c @ 2422:2274a0386cc9

bitkeeper revision 1.1159.69.5 (4138e882jA1YaR_OfTfNHe_uT4PDIg)

trivial
author iap10@labyrinth.cl.cam.ac.uk
date Fri Sep 03 21:56:18 2004 +0000 (2004-09-03)
parents bae23a1177c6
children 7f7c68433c4c
line source
1 #include <stdlib.h>
2 #include <errno.h>
3 #include <unistd.h>
4 #include <sys/socket.h>
5 #include <netinet/in.h>
6 #include <arpa/inet.h>
8 #include "connection.h"
9 #include "file_stream.h"
10 #include "lzi_stream.h"
11 #include "sxpr_parser.h"
13 #define dprintf(fmt, args...) fprintf(stdout, "[DEBUG] %s" fmt, __FUNCTION__, ##args)
14 #define wprintf(fmt, args...) fprintf(stderr, "[WARN] %s" fmt, __FUNCTION__, ##args)
15 #define iprintf(fmt, args...) fprintf(stdout, "[INFO] %s" fmt, __FUNCTION__, ##args)
16 #define eprintf(fmt, args...) fprintf(stderr, "[ERROR] %s" fmt, __FUNCTION__, ##args)
18 /** Compress magic header. */
19 char compress_magic[2] = { 0x1f, 0x8b };
21 /** Plain magic header. */
22 char plain_magic[2] = { 0x0, 0x0 };
24 int Conn_read_header(int sock, int *flags){
25 int err = 0;
26 char magic[2] = {};
27 int k, n = sizeof(magic);
28 k = read(sock, magic, n);
29 if(k != n){
30 err = -EINVAL;
31 goto exit;
32 }
33 dprintf("> magic={ 0x%x, 0x%x }\n", magic[0], magic[1]);
34 if(magic[0] == compress_magic[0] && magic[1] == compress_magic[1]){
35 *flags |= CONN_READ_COMPRESS;
36 dprintf("> Using compress read.\n");
37 } else {
38 dprintf("> Using plain read.\n");
39 }
40 exit:
41 return err;
42 }
44 int Conn_write_header(int sock, int flags){
45 int err = 0;
46 if(flags & CONN_WRITE_COMPRESS){
47 dprintf("> Using compress write.\n");
48 err = write(sock, compress_magic, 2);
49 } else {
50 dprintf("> Using plain write.\n");
51 err = write(sock, plain_magic, 2);
52 }
53 if(err == 2) err = 0;
54 return err;
55 }
57 /** Initialize a file stream from a file desciptor.
58 *
59 * @param fd file descriptor
60 * @param mode file mode
61 * @param flags control compression and buffering
62 * @param io return parameter for the stream
63 * @return 0 on success, error code otherwise
64 */
65 int stream_init(int fd, const char *mode, int flags, int compress, IOStream **io){
66 int err = 0;
67 dprintf(">mode=%s flags=%x compress=%d\n", mode, flags, compress);
68 if(compress){
69 *io = lzi_stream_fdopen(fd, mode);
70 } else {
71 *io = file_stream_fdopen(fd, mode);
72 }
73 if(!*io){
74 err = -errno;
75 perror("fdopen");
76 goto exit;
77 }
78 if(1 && (flags & CONN_NOBUFFER)){
79 // Make unbuffered.
80 dprintf("> unbuffer...\n");
81 err = file_stream_setvbuf((compress ? lzi_stream_io(*io) : *io), NULL, _IONBF, 0);
82 if(err){
83 err = -errno;
84 perror("setvbuf");
85 goto exit;
86 }
87 }
88 exit:
89 if(err && *io){
90 dprintf("> close err=%d\n", err);
91 IOStream_close(*io);
92 *io = NULL;
93 }
94 dprintf("< err=%d\n", err);
95 return err;
96 }
98 /** Initialize a connection.
99 *
100 * @param conn connection
101 * @param flags
102 * @param sock socket
103 * @param ipaddr ip address
104 * @return 0 on success, error code otherwise
105 */
106 int Conn_init(Conn *conn, int flags, int sock, struct sockaddr_in addr){
107 int err = 0;
108 dprintf("> flags=%x\n", flags);
109 conn->addr = addr;
110 conn->sock = sock;
111 dprintf("> write stream...\n");
112 err = stream_init(sock, "w", flags, (flags & CONN_WRITE_COMPRESS), &conn->out);
113 if(err) goto exit;
114 IOStream_flush(conn->out);
115 dprintf("> read stream...\n");
116 err = stream_init(sock, "r", flags, (flags & CONN_READ_COMPRESS) , &conn->in);
117 if(err) goto exit;
118 exit:
119 if(err) eprintf("< err=%d\n", err);
120 return err;
121 }
123 /** Open a connection.
124 *
125 * @param conn connection
126 * @param flags
127 * @param ipaddr ip address to connect to
128 * @param port port
129 * @return 0 on success, error code otherwise
130 */
131 int Conn_connect(Conn *conn, int flags, struct in_addr ipaddr, uint16_t port){
132 int err = 0;
133 int sock;
134 struct sockaddr_in addr_in;
135 struct sockaddr *addr = (struct sockaddr *)&addr_in;
136 socklen_t addr_n = sizeof(addr_in);
137 dprintf("> addr=%s:%d\n", inet_ntoa(ipaddr), ntohs(port));
138 sock = socket(AF_INET, SOCK_STREAM, 0);
139 if(sock < 0){
140 err = -errno;
141 goto exit;
142 }
143 addr_in.sin_family = AF_INET;
144 addr_in.sin_addr = ipaddr;
145 addr_in.sin_port = port;
146 err = connect(sock, addr, addr_n);
147 if(err) goto exit;
148 //err = Conn_write_header(sock, flags);
149 //if(err < 0) goto exit;
150 err = Conn_init(conn, flags, sock, addr_in);
151 exit:
152 if(err) eprintf("< err=%d\n", err);
153 return err;
154 }
156 /** Close a connection.
157 *
158 * @param conn connection
159 */
160 void Conn_close(Conn *conn){
161 if(conn->in) IOStream_close(conn->in);
162 if(conn->out) IOStream_close(conn->out);
163 shutdown(conn->sock, 2);
164 }
166 int Conn_sxpr(Conn *conn, Sxpr *sxpr){
167 int err = 0;
168 Sxpr val = ONONE;
169 int c = 0;
171 dprintf(">\n");
172 if(!conn->parser){
173 conn->parser = Parser_new();
174 set_error_stream(conn->parser, iostdout);
175 }
176 while(!err && c >= 0 && !Parser_ready(conn->parser)){
177 c = IOStream_getc(conn->in);
178 printf("%c", (char)c);
179 if(c < 0){
180 err = Parser_input_eof(conn->parser);
181 } else {
182 err = Parser_input_char(conn->parser, c);
183 }
184 }
185 if(Parser_ready(conn->parser)){
186 val = Parser_get_val(conn->parser);
187 }
188 if(err){
189 objfree(val);
190 val = ONONE;
191 }
192 *sxpr = val;
193 dprintf("< err=%d\n", err);
194 return err;
195 }