]> git.sesse.net Git - mlt/blob - src/valerie/valerie_socket.c
8a918328ec2efc6ddafcab2893cf03a13a3bbe8e
[mlt] / src / valerie / valerie_socket.c
1 /*
2  * valerie_socket.c -- Client Socket
3  * Copyright (C) 2002-2003 Ushodaya Enterprises Limited
4  * Author: Charles Yates <charles.yates@pandora.be>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 /* System header files */
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <unistd.h>
30 #include <netdb.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <fcntl.h>
34 #include <errno.h>
35 #include <netinet/in.h>
36 #include <sys/time.h>
37
38 /* Application header files */
39 #include "valerie_socket.h"
40
41 /** Initialise the socket.
42 */
43
44 valerie_socket valerie_socket_init( char *server, int port )
45 {
46         valerie_socket socket = malloc( sizeof( valerie_socket_t ) );
47         if ( socket != NULL )
48         {
49                 memset( socket, 0, sizeof( valerie_socket_t ) );
50                 socket->fd = -1;
51                 socket->server = strdup( server );
52                 socket->port = port;
53         }
54         return socket;
55 }
56
57 /** Connect to the server.
58 */
59
60 int valerie_socket_connect( valerie_socket connection )
61 {
62         int ret = 0;
63     struct hostent *host;
64     struct sockaddr_in sock;
65
66         if ( connection->server != NULL )
67         {               
68                 host = gethostbyname( connection->server );
69         
70                 memset( &sock, 0, sizeof( struct sockaddr_in ) );
71                 memcpy( &sock.sin_addr, host->h_addr, host->h_length );
72                 sock.sin_family = host->h_addrtype;
73                 sock.sin_port = htons( connection->port );
74         
75                 if ( ( connection->fd = socket( AF_INET, SOCK_STREAM, 0 ) ) != -1 )
76                         ret = connect( connection->fd, (const struct sockaddr *)&sock, sizeof( struct sockaddr_in ) );
77                 else
78                         ret = -1;
79         }
80         
81         return ret;     
82 }
83
84 /** Convenience constructor for a connected file descriptor.
85 */
86
87 valerie_socket valerie_socket_init_fd( int fd )
88 {
89         valerie_socket socket = malloc( sizeof( valerie_socket_t ) );
90         if ( socket != NULL )
91         {
92                 memset( socket, 0, sizeof( valerie_socket_t ) );
93                 socket->fd = fd;
94                 socket->no_close = 1;
95         }
96         return socket;
97 }
98
99 /** Read an arbitrarily formatted block of data from the server.
100 */
101
102 int valerie_socket_read_data( valerie_socket socket, char *data, int length )
103 {
104     struct timeval tv = { 1, 0 };
105     fd_set rfds;
106         int used = 0;
107
108         data[ 0 ] = '\0';
109
110     FD_ZERO( &rfds );
111     FD_SET( socket->fd, &rfds );
112
113         if ( select( socket->fd + 1, &rfds, NULL, NULL, &tv ) )
114         {
115                 used = read( socket->fd, data, length - 1 );
116                 if ( used > 0 )
117                         data[ used ] = '\0';
118                 else
119                         used = -1;
120         }
121
122         return used;
123 }       
124
125 /** Write an arbitrarily formatted block of data to the server.
126 */
127
128 int valerie_socket_write_data( valerie_socket socket, const char *data, int length )
129 {
130         int used = 0;
131         
132         while ( used >=0 && used < length )
133         {
134                 struct timeval tv = { 1, 0 };
135                 fd_set rfds;
136                 fd_set wfds;
137                 fd_set efds;
138         
139                 FD_ZERO( &rfds );
140                 FD_SET( socket->fd, &rfds );
141                 FD_ZERO( &wfds );
142                 FD_SET( socket->fd, &wfds );
143                 FD_ZERO( &efds );
144                 FD_SET( socket->fd, &efds );
145         
146                 errno = 0;
147
148                 if ( select( socket->fd + 1, &rfds, &wfds, &efds, &tv ) )
149                 {
150                         if ( errno != 0 || FD_ISSET( socket->fd, &efds ) || FD_ISSET( socket->fd, &rfds ) )
151                         {
152                                 used = -1;
153                         }
154                         else if ( FD_ISSET( socket->fd, &wfds ) )
155                         {
156                                 int inc = write( socket->fd, data + used, length - used );
157                                 if ( inc > 0 )
158                                         used += inc;
159                                 else
160                                         used = -1;
161                         }
162                 }
163         }
164
165         return used;
166 }
167
168 /** Close the socket.
169 */
170
171 void valerie_socket_close( valerie_socket socket )
172 {
173         if ( socket->fd > 0 && !socket->no_close )
174                 close( socket->fd );
175         free( socket->server );
176         free( socket );
177 }