1 /*****************************************************************************
2 * net.c: Network related functions
3 *****************************************************************************
4 * Copyright (C) 2007 the VideoLAN team
7 * Authors: Antoine Cellerier <dionoea at videolan tod org>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
36 #include <vlc_network.h>
39 #include <lua.h> /* Low level lua C API */
40 #include <lauxlib.h> /* Higher level C API */
41 #include <lualib.h> /* Lua libs */
45 /*****************************************************************************
47 *****************************************************************************/
48 int vlclua_url_parse( lua_State
*L
)
50 const char *psz_url
= luaL_checkstring( L
, 1 );
51 const char *psz_option
= luaL_optstring( L
, 2, NULL
);
54 vlc_UrlParse( &url
, psz_url
, psz_option
?*psz_option
:0 );
57 lua_pushstring( L
, url
.psz_protocol
);
58 lua_setfield( L
, -2, "protocol" );
59 lua_pushstring( L
, url
.psz_username
);
60 lua_setfield( L
, -2, "username" );
61 lua_pushstring( L
, url
.psz_password
);
62 lua_setfield( L
, -2, "password" );
63 lua_pushstring( L
, url
.psz_host
);
64 lua_setfield( L
, -2, "host" );
65 lua_pushinteger( L
, url
.i_port
);
66 lua_setfield( L
, -2, "port" );
67 lua_pushstring( L
, url
.psz_path
);
68 lua_setfield( L
, -2, "path" );
69 lua_pushstring( L
, url
.psz_option
);
70 lua_setfield( L
, -2, "option" );
77 int vlclua_net_listen_tcp( lua_State
*L
)
79 vlc_object_t
*p_this
= vlclua_get_this( L
);
80 const char *psz_host
= luaL_checkstring( L
, 1 );
81 int i_port
= luaL_checkint( L
, 2 );
82 int *pi_fd
= net_ListenTCP( p_this
, psz_host
, i_port
);
84 return luaL_error( L
, "Cannot listen on %s:%d", psz_host
, i_port
);
85 lua_pushlightuserdata( L
, pi_fd
);
89 int vlclua_net_listen_close( lua_State
*L
)
91 int *pi_fd
= (int*)luaL_checklightuserdata( L
, 1 );
92 net_ListenClose( pi_fd
);
96 int vlclua_net_accept( lua_State
*L
)
98 vlc_object_t
*p_this
= vlclua_get_this( L
);
99 int *pi_fd
= (int*)luaL_checklightuserdata( L
, 1 );
100 mtime_t i_wait
= luaL_optint( L
, 2, -1 ); /* default to block */
101 int i_fd
= net_Accept( p_this
, pi_fd
, i_wait
);
102 lua_pushinteger( L
, i_fd
);
106 int vlclua_net_close( lua_State
*L
)
108 int i_fd
= luaL_checkint( L
, 1 );
113 int vlclua_net_send( lua_State
*L
)
115 int i_fd
= luaL_checkint( L
, 1 );
117 const char *psz_buffer
= luaL_checklstring( L
, 2, &i_len
);
118 i_len
= luaL_optint( L
, 3, i_len
);
119 i_len
= send( i_fd
, psz_buffer
, i_len
, 0 );
120 lua_pushinteger( L
, i_len
);
124 int vlclua_net_recv( lua_State
*L
)
126 int i_fd
= luaL_checkint( L
, 1 );
127 size_t i_len
= luaL_optint( L
, 2, 1 );
128 char psz_buffer
[i_len
];
129 i_len
= recv( i_fd
, psz_buffer
, i_len
, 0 );
130 lua_pushlstring( L
, psz_buffer
, i_len
);
134 int vlclua_net_select( lua_State
*L
)
137 size_t i_nfds
= luaL_checkint( L
, 1 );
138 fd_set
*fds_read
= (fd_set
*)luaL_checkuserdata( L
, 2, sizeof( fd_set
) );
139 fd_set
*fds_write
= (fd_set
*)luaL_checkuserdata( L
, 3, sizeof( fd_set
) );
140 double f_timeout
= luaL_checknumber( L
, 4 );
141 struct timeval timeout
;
144 if( i_nfds
> FD_SETSIZE
)
147 timeout
.tv_sec
= (int)f_timeout
;
148 timeout
.tv_usec
= (int)(1e6
*(f_timeout
-(double)((int)f_timeout
)));
149 i_ret
= select( i_nfds
, fds_read
, fds_write
, 0, &timeout
);
150 lua_pushinteger( L
, i_ret
);
151 lua_pushinteger( L
, (double)timeout
.tv_sec
+((double)timeout
.tv_usec
)/1e-6 );
155 int vlclua_fd_set_new( lua_State
*L
)
157 fd_set
*fds
= (fd_set
*)lua_newuserdata( L
, sizeof( fd_set
) );
162 int vlclua_fd_clr( lua_State
*L
)
164 fd_set
*fds
= (fd_set
*)luaL_checkuserdata( L
, 1, sizeof( fd_set
) );
165 int i_fd
= luaL_checkint( L
, 2 );
169 int vlclua_fd_isset( lua_State
*L
)
171 fd_set
*fds
= (fd_set
*)luaL_checkuserdata( L
, 1, sizeof( fd_set
) );
172 int i_fd
= luaL_checkint( L
, 2 );
173 lua_pushboolean( L
, FD_ISSET( i_fd
, fds
) );
176 int vlclua_fd_set( lua_State
*L
)
178 fd_set
*fds
= (fd_set
*)luaL_checkuserdata( L
, 1, sizeof( fd_set
) );
179 size_t i_fd
= luaL_checkint( L
, 2 );
180 /* FIXME: we should really use poll() instead here, but that breaks the
181 * VLC/LUA API. On Windows, overflow protection is built-in FD_SET, not
182 * on POSIX. In both cases, run-time behavior will however be wrong. */
184 if( i_fd
< FD_SETSIZE
)
189 int vlclua_fd_zero( lua_State
*L
)
191 fd_set
*fds
= (fd_set
*)luaL_checkuserdata( L
, 1, sizeof( fd_set
) );
197 int vlclua_fd_open( lua_State *L )
202 int vlclua_fd_write( lua_State
*L
)
204 int i_fd
= luaL_checkint( L
, 1 );
207 const char *psz_buffer
= luaL_checklstring( L
, 2, &i_len
);
208 i_len
= luaL_optint( L
, 3, i_len
);
209 i_ret
= write( i_fd
, psz_buffer
, i_len
);
210 lua_pushinteger( L
, i_ret
);
214 int vlclua_fd_read( lua_State
*L
)
216 int i_fd
= luaL_checkint( L
, 1 );
217 size_t i_len
= luaL_optint( L
, 2, 1 );
218 char psz_buffer
[i_len
];
219 i_len
= read( i_fd
, psz_buffer
, i_len
);
220 lua_pushlstring( L
, psz_buffer
, i_len
);
224 int vlclua_stat( lua_State
*L
)
226 #ifdef HAVE_SYS_STAT_H
227 const char *psz_path
= luaL_checkstring( L
, 1 );
229 if( utf8_stat( psz_path
, &s
) )
231 //return luaL_error( L, "Couldn't stat %s.", psz_path );
233 if( S_ISREG( s
.st_mode
) )
234 lua_pushstring( L
, "file" );
235 else if( S_ISDIR( s
.st_mode
) )
236 lua_pushstring( L
, "dir" );
238 else if( S_ISCHR( s
.st_mode
) )
239 lua_pushstring( L
, "character device" );
242 else if( S_ISBLK( s
.st_mode
) )
243 lua_pushstring( L
, "block device" );
246 else if( S_ISFIFO( s
.st_mode
) )
247 lua_pushstring( L
, "fifo" );
250 else if( S_ISLNK( s
.st_mode
) )
251 lua_pushstring( L
, "symbolic link" );
254 else if( S_ISSOCK( s
.st_mode
) )
255 lua_pushstring( L
, "socket" );
258 lua_pushstring( L
, "unknown" );
259 lua_setfield( L
, -2, "type" );
260 lua_pushinteger( L
, s
.st_mode
);
261 lua_setfield( L
, -2, "mode" );
262 lua_pushinteger( L
, s
.st_uid
);
263 lua_setfield( L
, -2, "uid" );
264 lua_pushinteger( L
, s
.st_gid
);
265 lua_setfield( L
, -2, "gid" );
266 lua_pushinteger( L
, s
.st_size
);
267 lua_setfield( L
, -2, "size" );
268 lua_pushinteger( L
, s
.st_atime
);
269 lua_setfield( L
, -2, "access_time" );
270 lua_pushinteger( L
, s
.st_mtime
);
271 lua_setfield( L
, -2, "modification_time" );
272 lua_pushinteger( L
, s
.st_ctime
);
273 lua_setfield( L
, -2, "creation_time" );
276 # warning "Woops, looks like we don't have stat on your platform"
277 return luaL_error( L
, "System is missing <sys/stat.h>" );
281 int vlclua_opendir( lua_State
*L
)
283 const char *psz_dir
= luaL_checkstring( L
, 1 );
286 #ifdef HAVE_SYS_STAT_H
288 if( utf8_stat( psz_dir
, &s
) == -1 )
289 return luaL_error( L
, "Error while trying to stat `%s'.", psz_dir
);
290 if( !S_ISDIR( s
.st_mode
) )
291 return luaL_error( L
, "`%s' is not a directory.", psz_dir
);
293 if( ( p_dir
= utf8_opendir( psz_dir
) ) == NULL
)
294 return luaL_error( L
, "cannot open directory `%s'.", psz_dir
);
299 char *psz_filename
= utf8_readdir( p_dir
);
300 if( !psz_filename
) break;
302 lua_pushstring( L
, psz_filename
);
303 lua_rawseti( L
, -2, i
);
304 free( psz_filename
);