static void totimespec(lua_State *L, int index, struct timespec *ts) { luaL_checktype(L, index, LUA_TTABLE); ts->tv_sec = optintfield(L, index, "tv_sec", 0); ts->tv_nsec = optintfield(L, index, "tv_nsec", 0); checkfieldnames(L, index, Stimespec_fields); }
static void totm(lua_State *L, int index, struct tm *t) { luaL_checktype(L, index, LUA_TTABLE); t->tm_sec = optintfield(L, index, "tm_sec", 0); t->tm_min = optintfield(L, index, "tm_min", 0); t->tm_hour = optintfield(L, index, "tm_hour", 0); t->tm_mday = optintfield(L, index, "tm_mday", 0); t->tm_mon = optintfield(L, index, "tm_mon", 0); t->tm_year = optintfield(L, index, "tm_year", 0); t->tm_wday = optintfield(L, index, "tm_wday", 0); t->tm_yday = optintfield(L, index, "tm_yday", 0); t->tm_isdst = optintfield(L, index, "tm_isdst", 0); checkfieldnames(L, index, Stm_fields); }
/*** Network address and service translation. @function getaddrinfo @string host name of a host @string service name of service @tparam[opt] PosixAddrInfo hints table @treturn[1] list of @{sockaddr} tables @return[2] nil @treturn[2] string error message @treturn[2] int errnum @see getaddrinfo(2) @usage local res, errmsg, errcode = posix.getaddrinfo ("www.lua.org", "http", { family = P.IF_INET, socktype = P.SOCK_STREAM } ) */ static int Pgetaddrinfo(lua_State *L) { int n = 1; const char *host = optstring(L, 1, NULL); const char *service = NULL; struct addrinfo *res, hints; hints.ai_family = PF_UNSPEC; checknargs(L, 3); switch (lua_type(L, 2)) { case LUA_TNONE: case LUA_TNIL: if (host == NULL) argtypeerror(L, 2, "string or int"); break; case LUA_TNUMBER: case LUA_TSTRING: service = lua_tostring(L, 2); break; default: argtypeerror(L, 2, "string, int or nil"); break; } switch (lua_type(L, 3)) { case LUA_TNONE: case LUA_TNIL: break; case LUA_TTABLE: checkfieldnames (L, 3, Sai_fields); hints.ai_family = optintfield(L, 3, "family", PF_UNSPEC); hints.ai_socktype = optintfield(L, 3, "socktype", 0); hints.ai_protocol = optintfield(L, 3, "protocol", 0); hints.ai_flags = optintfield(L, 3, "flags", 0); break; default: argtypeerror(L, 3, "table or nil"); break; } { int r; if ((r = getaddrinfo(host, service, &hints, &res)) != 0) { lua_pushnil(L); lua_pushstring(L, gai_strerror(r)); lua_pushinteger(L, r); return 3; } } /* Copy getaddrinfo() result into Lua table */ { struct addrinfo *p; lua_newtable(L); for (p = res; p != NULL; p = p->ai_next) { lua_pushnumber(L, n++); pushsockaddrinfo(L, p->ai_family, p->ai_addr); pushnumberfield("socktype", p->ai_socktype); pushstringfield("canonname", p->ai_canonname); pushnumberfield("protocol", p->ai_protocol); lua_settable(L, -3); } } freeaddrinfo(res); return 1; }
/* Populate a sockaddr_storage with the info from the given lua table */ static int sockaddr_from_lua(lua_State *L, int index, struct sockaddr_storage *sa, socklen_t *addrlen) { int family, r = -1; luaL_checktype(L, index, LUA_TTABLE); family = checkintfield(L, index, "family"); memset(sa, 0, sizeof *sa); switch (family) { case AF_INET: { struct sockaddr_in *sa4 = (struct sockaddr_in *)sa; int port = checkintfield(L, index, "port"); const char *addr = checkstringfield(L, index, "addr"); checkfieldnames (L, index, Safinet_fields); if (inet_pton(AF_INET, addr, &sa4->sin_addr) == 1) { sa4->sin_family = family; sa4->sin_port = htons(port); *addrlen = sizeof(*sa4); r = 0; } break; } case AF_INET6: { struct sockaddr_in6 *sa6= (struct sockaddr_in6 *)sa; int port = checkintfield(L, index, "port"); const char *addr = checkstringfield(L, index, "addr"); checkfieldnames (L, index, Safinet_fields); if (inet_pton(AF_INET6, addr, &sa6->sin6_addr) == 1) { sa6->sin6_family= family; sa6->sin6_port = htons(port); *addrlen = sizeof(*sa6); r = 0; } break; } case AF_UNIX: { struct sockaddr_un *sau = (struct sockaddr_un *)sa; const char *path = checkstringfield(L, index, "path"); checkfieldnames (L, index, Safunix_fields); sau->sun_family = family; strlcpy(sau->sun_path, path, sizeof(sau->sun_path)); sau->sun_path[sizeof(sau->sun_path) - 1]= '\0'; *addrlen = sizeof(*sau); r = 0; break; } #if HAVE_LINUX_NETLINK_H case AF_NETLINK: { struct sockaddr_nl *san = (struct sockaddr_nl *)sa; san->nl_family = family; san->nl_pid = checkintfield(L, index, "pid"); san->nl_groups = checkintfield(L, index, "groups"); *addrlen = sizeof(*san); checkfieldnames (L, index, Safnetlink_fields); r = 0; break; } #endif default: lua_pushfstring(L, "unsupported family type %d", family); luaL_argcheck(L, 0, index, lua_tostring (L, -1)); lua_pop (L, 1); break; } return r; }