net.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:12k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * net.c: Network related functions
  3.  *****************************************************************************
  4.  * Copyright (C) 2007-2008 the VideoLAN team
  5.  * $Id: dcf21664632fdbbff14972e38c7e3ac98681409a $
  6.  *
  7.  * Authors: Antoine Cellerier <dionoea at videolan tod org>
  8.  *
  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.
  13.  *
  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.
  18.  *
  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.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifndef  _GNU_SOURCE
  27. #   define  _GNU_SOURCE
  28. #endif
  29. #ifdef HAVE_CONFIG_H
  30. # include "config.h"
  31. #endif
  32. #include <vlc_common.h>
  33. #include <vlc_network.h>
  34. #include <vlc_url.h>
  35. #include <lua.h>        /* Low level lua C API */
  36. #include <lauxlib.h>    /* Higher level C API */
  37. #include "../vlc.h"
  38. #include "../libs.h"
  39. /*****************************************************************************
  40.  *
  41.  *****************************************************************************/
  42. static int vlclua_url_parse( lua_State *L )
  43. {
  44.     const char *psz_url = luaL_checkstring( L, 1 );
  45.     const char *psz_option = luaL_optstring( L, 2, NULL );
  46.     vlc_url_t url;
  47.     vlc_UrlParse( &url, psz_url, psz_option?*psz_option:0 );
  48.     lua_newtable( L );
  49.     lua_pushstring( L, url.psz_protocol );
  50.     lua_setfield( L, -2, "protocol" );
  51.     lua_pushstring( L, url.psz_username );
  52.     lua_setfield( L, -2, "username" );
  53.     lua_pushstring( L, url.psz_password );
  54.     lua_setfield( L, -2, "password" );
  55.     lua_pushstring( L, url.psz_host );
  56.     lua_setfield( L, -2, "host" );
  57.     lua_pushinteger( L, url.i_port );
  58.     lua_setfield( L, -2, "port" );
  59.     lua_pushstring( L, url.psz_path );
  60.     lua_setfield( L, -2, "path" );
  61.     lua_pushstring( L, url.psz_option );
  62.     lua_setfield( L, -2, "option" );
  63.     vlc_UrlClean( &url );
  64.     return 1;
  65. }
  66. /*****************************************************************************
  67.  * Net listen
  68.  *****************************************************************************/
  69. static int vlclua_net_listen_close( lua_State * );
  70. static int vlclua_net_accept( lua_State * );
  71. static const luaL_Reg vlclua_net_listen_reg[] = {
  72.     { "accept", vlclua_net_accept },
  73.     { NULL, NULL }
  74. };
  75. static int vlclua_net_listen_tcp( lua_State *L )
  76. {
  77.     vlc_object_t *p_this = vlclua_get_this( L );
  78.     const char *psz_host = luaL_checkstring( L, 1 );
  79.     int i_port = luaL_checkint( L, 2 );
  80.     int *pi_fd = net_ListenTCP( p_this, psz_host, i_port );
  81.     if( pi_fd == NULL )
  82.         return luaL_error( L, "Cannot listen on %s:%d", psz_host, i_port );
  83.     int **ppi_fd = lua_newuserdata( L, sizeof( int * ) );
  84.     *ppi_fd = pi_fd;
  85.     if( luaL_newmetatable( L, "net_listen" ) )
  86.     {
  87.         lua_newtable( L );
  88.         luaL_register( L, NULL, vlclua_net_listen_reg );
  89.         lua_setfield( L, -2, "__index" );
  90.         lua_pushcfunction( L, vlclua_net_listen_close );
  91.         lua_setfield( L, -2, "__gc" );
  92.     }
  93.     lua_setmetatable( L, -2 );
  94.     return 1;
  95. }
  96. static int vlclua_net_listen_close( lua_State *L )
  97. {
  98.     int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
  99.     net_ListenClose( *ppi_fd );
  100.     return 0;
  101. }
  102. static int vlclua_net_accept( lua_State *L )
  103. {
  104.     vlc_object_t *p_this = vlclua_get_this( L );
  105.     int **ppi_fd = (int**)luaL_checkudata( L, 1, "net_listen" );
  106.     mtime_t i_wait = luaL_optint( L, 2, -1 ); /* default to block */
  107.     int i_fd = net_Accept( p_this, *ppi_fd, i_wait );
  108.     lua_pushinteger( L, i_fd );
  109.     return 1;
  110. }
  111. /*****************************************************************************
  112.  *
  113.  *****************************************************************************/
  114. static int vlclua_net_close( lua_State *L )
  115. {
  116.     int i_fd = luaL_checkint( L, 1 );
  117.     net_Close( i_fd );
  118.     return 0;
  119. }
  120. static int vlclua_net_send( lua_State *L )
  121. {
  122.     int i_fd = luaL_checkint( L, 1 );
  123.     size_t i_len;
  124.     const char *psz_buffer = luaL_checklstring( L, 2, &i_len );
  125.     i_len = luaL_optint( L, 3, i_len );
  126.     i_len = send( i_fd, psz_buffer, i_len, 0 );
  127.     lua_pushinteger( L, i_len );
  128.     return 1;
  129. }
  130. static int vlclua_net_recv( lua_State *L )
  131. {
  132.     int i_fd = luaL_checkint( L, 1 );
  133.     size_t i_len = luaL_optint( L, 2, 1 );
  134.     char psz_buffer[i_len];
  135.     i_len = recv( i_fd, psz_buffer, i_len, 0 );
  136.     lua_pushlstring( L, psz_buffer, i_len );
  137.     return 1;
  138. }
  139. /*****************************************************************************
  140.  *
  141.  *****************************************************************************/
  142. static int vlclua_net_select( lua_State *L )
  143. {
  144.     int i_ret;
  145.     size_t i_nfds = luaL_checkint( L, 1 );
  146.     fd_set *fds_read = (fd_set*)luaL_checkudata( L, 2, "fd_set" );
  147.     fd_set *fds_write = (fd_set*)luaL_checkudata( L, 3, "fd_set" );
  148.     double f_timeout = luaL_checknumber( L, 4 );
  149.     struct timeval timeout;
  150. #ifndef WIN32
  151.     if( i_nfds > FD_SETSIZE )
  152.         i_nfds = FD_SETSIZE;
  153. #endif
  154.     timeout.tv_sec = (int)f_timeout;
  155.     timeout.tv_usec = (int)(1e6*(f_timeout-(double)((int)f_timeout)));
  156.     i_ret = select( i_nfds, fds_read, fds_write, 0, &timeout );
  157.     lua_pushinteger( L, i_ret );
  158.     lua_pushinteger( L, (double)timeout.tv_sec+((double)timeout.tv_usec)/1e-6 );
  159.     return 2;
  160. }
  161. /*****************************************************************************
  162.  *
  163.  *****************************************************************************/
  164. static int vlclua_fd_clr( lua_State * );
  165. static int vlclua_fd_isset( lua_State * );
  166. static int vlclua_fd_set( lua_State * );
  167. static int vlclua_fd_zero( lua_State * );
  168. static const luaL_Reg vlclua_fd_set_reg[] = {
  169.     { "clr", vlclua_fd_clr },
  170.     { "isset", vlclua_fd_isset },
  171.     { "set", vlclua_fd_set },
  172.     { "zero", vlclua_fd_zero },
  173.     { NULL, NULL }
  174. };
  175. static int vlclua_fd_set_new( lua_State *L )
  176. {
  177.     fd_set *fds = (fd_set*)lua_newuserdata( L, sizeof( fd_set ) );
  178.     FD_ZERO( fds );
  179.     if( luaL_newmetatable( L, "fd_set" ) )
  180.     {
  181.         lua_newtable( L );
  182.         luaL_register( L, NULL, vlclua_fd_set_reg );
  183.         lua_setfield( L, -2, "__index" );
  184.     }
  185.     lua_setmetatable( L, -2 );
  186.     return 1;
  187. }
  188. static int vlclua_fd_clr( lua_State *L )
  189. {
  190.     fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
  191.     int i_fd = luaL_checkint( L, 2 );
  192.     FD_CLR( i_fd, fds );
  193.     return 0;
  194. }
  195. static int vlclua_fd_isset( lua_State *L )
  196. {
  197.     fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
  198.     int i_fd = luaL_checkint( L, 2 );
  199.     lua_pushboolean( L, FD_ISSET( i_fd, fds ) );
  200.     return 1;
  201. }
  202. static int vlclua_fd_set( lua_State *L )
  203. {
  204.     fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
  205.     size_t i_fd = luaL_checkint( L, 2 );
  206.     /* FIXME: we should really use poll() instead here, but that breaks the
  207.      * VLC/LUA API. On Windows, overflow protection is built-in FD_SET, not
  208.      * on POSIX. In both cases, run-time behavior will however be wrong. */
  209. #ifndef WIN32
  210.     if( i_fd < FD_SETSIZE )
  211. #endif
  212.         FD_SET( i_fd, fds );
  213.     return 0;
  214. }
  215. static int vlclua_fd_zero( lua_State *L )
  216. {
  217.     fd_set *fds = (fd_set*)luaL_checkudata( L, 1, "fd_set" );
  218.     FD_ZERO( fds );
  219.     return 0;
  220. }
  221. /*****************************************************************************
  222.  *
  223.  *****************************************************************************/
  224. /*
  225. static int vlclua_fd_open( lua_State *L )
  226. {
  227. }
  228. */
  229. static int vlclua_fd_write( lua_State *L )
  230. {
  231.     int i_fd = luaL_checkint( L, 1 );
  232.     size_t i_len;
  233.     ssize_t i_ret;
  234.     const char *psz_buffer = luaL_checklstring( L, 2, &i_len );
  235.     i_len = luaL_optint( L, 3, i_len );
  236.     i_ret = write( i_fd, psz_buffer, i_len );
  237.     lua_pushinteger( L, i_ret );
  238.     return 1;
  239. }
  240. static int vlclua_fd_read( lua_State *L )
  241. {
  242.     int i_fd = luaL_checkint( L, 1 );
  243.     size_t i_len = luaL_optint( L, 2, 1 );
  244.     char psz_buffer[i_len];
  245.     i_len = read( i_fd, psz_buffer, i_len );
  246.     lua_pushlstring( L, psz_buffer, i_len );
  247.     return 1;
  248. }
  249. /*****************************************************************************
  250.  *
  251.  *****************************************************************************/
  252. static int vlclua_stat( lua_State *L )
  253. {
  254. #ifdef HAVE_SYS_STAT_H
  255.     const char *psz_path = luaL_checkstring( L, 1 );
  256.     struct stat s;
  257.     if( utf8_stat( psz_path, &s ) )
  258.         return 0;
  259.         //return luaL_error( L, "Couldn't stat %s.", psz_path );
  260.     lua_newtable( L );
  261.     if( S_ISREG( s.st_mode ) )
  262.         lua_pushstring( L, "file" );
  263.     else if( S_ISDIR( s.st_mode ) )
  264.         lua_pushstring( L, "dir" );
  265. #ifdef S_ISCHR
  266.     else if( S_ISCHR( s.st_mode ) )
  267.         lua_pushstring( L, "character device" );
  268. #endif
  269. #ifdef S_ISBLK
  270.     else if( S_ISBLK( s.st_mode ) )
  271.         lua_pushstring( L, "block device" );
  272. #endif
  273. #ifdef S_ISFIFO
  274.     else if( S_ISFIFO( s.st_mode ) )
  275.         lua_pushstring( L, "fifo" );
  276. #endif
  277. #ifdef S_ISLNK
  278.     else if( S_ISLNK( s.st_mode ) )
  279.         lua_pushstring( L, "symbolic link" );
  280. #endif
  281. #ifdef S_ISSOCK
  282.     else if( S_ISSOCK( s.st_mode ) )
  283.         lua_pushstring( L, "socket" );
  284. #endif
  285.     else
  286.         lua_pushstring( L, "unknown" );
  287.     lua_setfield( L, -2, "type" );
  288.     lua_pushinteger( L, s.st_mode );
  289.     lua_setfield( L, -2, "mode" );
  290.     lua_pushinteger( L, s.st_uid );
  291.     lua_setfield( L, -2, "uid" );
  292.     lua_pushinteger( L, s.st_gid );
  293.     lua_setfield( L, -2, "gid" );
  294.     lua_pushinteger( L, s.st_size );
  295.     lua_setfield( L, -2, "size" );
  296.     lua_pushinteger( L, s.st_atime );
  297.     lua_setfield( L, -2, "access_time" );
  298.     lua_pushinteger( L, s.st_mtime );
  299.     lua_setfield( L, -2, "modification_time" );
  300.     lua_pushinteger( L, s.st_ctime );
  301.     lua_setfield( L, -2, "creation_time" );
  302.     return 1;
  303. #else
  304. #   warning "Woops, looks like we don't have stat on your platform"
  305.     return luaL_error( L, "System is missing <sys/stat.h>" );
  306. #endif
  307. }
  308. static int vlclua_opendir( lua_State *L )
  309. {
  310.     const char *psz_dir = luaL_checkstring( L, 1 );
  311.     DIR *p_dir;
  312.     int i = 0;
  313.     if( ( p_dir = utf8_opendir( psz_dir ) ) == NULL )
  314.         return luaL_error( L, "cannot open directory `%s'.", psz_dir );
  315.     lua_newtable( L );
  316.     for( ;; )
  317.     {
  318.         char *psz_filename = utf8_readdir( p_dir );
  319.         if( !psz_filename ) break;
  320.         i++;
  321.         lua_pushstring( L, psz_filename );
  322.         lua_rawseti( L, -2, i );
  323.         free( psz_filename );
  324.     }
  325.     closedir( p_dir );
  326.     return 1;
  327. }
  328. /*****************************************************************************
  329.  *
  330.  *****************************************************************************/
  331. static const luaL_Reg vlclua_net_reg[] = {
  332.     { "url_parse", vlclua_url_parse },
  333.     { "listen_tcp", vlclua_net_listen_tcp },
  334.     { "close", vlclua_net_close },
  335.     { "send", vlclua_net_send },
  336.     { "recv", vlclua_net_recv },
  337.     { "select", vlclua_net_select },
  338.     { "fd_set_new", vlclua_fd_set_new },
  339.     { "read", vlclua_fd_read },
  340.     { "write", vlclua_fd_write },
  341.     { "stat", vlclua_stat }, /* Not really "net" */
  342.     { "opendir", vlclua_opendir }, /* Not really "net" */
  343.     { NULL, NULL }
  344. };
  345. void luaopen_net( lua_State *L )
  346. {
  347.     lua_newtable( L );
  348.     luaL_register( L, NULL, vlclua_net_reg );
  349.     lua_setfield( L, -2, "net" );
  350. }