PtokaX forum

Development Section => LUA & PtokaX-Scripting-Interface => Topic started by: plop on 13 October, 2005, 01:10:51

Title: Lua Extension: WsaSocket.lua - support script for PXwsa.dll
Post by: plop on 13 October, 2005, 01:10:51
stripped all the buggy stuff (i hope).
only whois and http acces in this but easy 2 implement in any script.

it contains 2 files.
1) the loader script.
2) the actual support script
both files and the pxwsa.dll should be inside the scripts/libs/ folder.

when openend you get a table called Sock with all the events/handlers/functions from the support script.

sock.lua--[[ WsaSocket loader for PXwsa.dll from bluebear.

usage:
add the folowing line to your script.
require("libs/sock.lua")
and save this file as sock.lua inside your scripts/libs/ folder.

by plop
]]--

Sock = require("libs/WsaSocket")
if Sock then
Sock.Init()
else
SendToAll("WsaSocket", "failed to load WSA sockets library. "..
"http://www.thewildplace.dk/site/download.php?list.11"
)
end
OnWsaConnected = Sock.OnWsaConnected
OnWsaSendComplete = Sock.OnWsaSendComplete
OnWsaDataArrival = Sock.OnWsaDataArrival

plop
Title:
Post by: plop on 13 October, 2005, 01:14:47
wsasocket.lua--[[ wsasocket.lua.
support script for pxwsa.dll from bluebear.
by plop.
]]--

local _Debug = false
local libinit = loadlib("libs/pxwsa.dll", "_libinit")
libinit()
local tSocket = {}

-- version of the library.
tSocket.Version = function()
return WSA.version()
end

tSocket.Debug = function(_ErrorCode, _ErrorStr)
local fFile = io.open("error/PXWsaLibray.log", "a+")
fFile:write(_ErrorCode.."\t".._ErrorStr.."\n")
fFile:close()
end

-- Common for both non-blocking/blocking sockets.
tSocket.Init = function()
local _ErrorCode, _ErrorStr = WSA.Init()
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
end
end

tSocket.NewSocket = function(sType)
if sType ~= 1 then
sType = 0
end
local _ErrorCode, _ErrorStr, sock = WSA.NewSocket(sType)
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
else
return nil, sock
end
end

tSocket.Bind = function(sock, sIP, iPort)
local _ErrorCode, _ErrorStr = WSA.Bind(sock, sIP, iPort)
if _ErrorCode then
return _ErrorStr
end
end

tSocket.Listen = function(sock)
local _ErrorCode, _ErrorStr = WSA.Listen(sock)
if _ErrorCode then
return _ErrorStr
end
end

tSocket.Dispose = function()
local _ErrorCode, _ErrorStr = WSA.Dispose()
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
end
end

-- DNS/IP.
tSocket.IPtoDEC = function(sIP)
return WSA.IPtoDEC(sIP)
end

tSocket.DECtoIP = function(sDec)
return WSA.DECtoIP(sDec)
end

tSocket.GetHostByName = function(sName)
if tSocket.IsDomain(sName) then
return nil, WSA.GetHostByName(sName)
else
return "No domain name given!"
end
end

tSocket.GetHostByAddr = function(sIP)
if tSocket.IsIP(sIP) then
return nil, WSA.GetHostByAddr(sIP)
else
return "No IP given!"
end
end

-- blocking sockets.
tSocket.Connect = function(sock, sHost, iPort)
local _ErrorCode, _ErrorStr = WSA.Connect(sock, sHost, iPort)
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
end
end

tSocket.Close = function(sock)
local _ErrorCode, _ErrorStr = WSA.Close(sock)
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
end
end

tSocket.Send = function(sock, sData)
local _ErrorCode, _ErrorStr, BytesSent = WSA.Send(sock, sData)
if _ErrorCode then
if _Debug then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
end
end

tSocket.Receive = function(sock)
local _ErrorCode, _ErrorStr, sData, iLength = WSA.Receive(sock)
if _ErrorCode then
if _Debug and (_ErrorCode ~= 0) then
tSocket.Debug(_ErrorCode, _ErrorStr)
end
return _ErrorStr
else
return nil, sData, iLength
end
end

-- helper functions blocking sockets
tSocket.NewConnection = function(sUrl, iPort)
local _ErrorStr, sock = tSocket.NewSocket()
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr = tSocket.Connect(sock, sUrl, iPort)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr, sData = tSocket.Receive(sock)
if _ErrorStr then
return _ErrorStr
end
return nil, sock, sData
end

tSocket.CloseLib = function(sock)
local _ErrorStr = tSocket.Close(sock)
if _ErrorStr then
return _ErrorStr
end
local  _ErrorStr = tSocket.Dispose()
if _ErrorStr then
return _ErrorStr
end
end

tSocket.ReceiveAll = function(sock)
local _ErrorStr, sData = nil, ""
while not _ErrorStr do
_ErrorStr, _sData = tSocket.Receive(sock)
if _ErrorStr then
if _ErrorStr == 0 then
return _ErrorStr
end
else
sData = sData.."\r\n".._sData
end
end
return nil, sData
end

-- blocking protocoll functions.
tSocket.WhoIs = function(sWhoIs)
local oUser = GetItemByName(sWhoIs)
if oUser then
sWhois = oUser.sIP
elseif tSocket.IsDomainIP(sWhoIs) then
return "No username/domain or IP given"
end
local _ErrorStr, sock = tSocket.NewConnection("whois.ripe.net", 43)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr = tSocket.Send(sock, sWhoIs.."\n")
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr, sData = tSocket.ReceiveAll(sock)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr = tSocket.CloseLib(sock)
if _ErrorStr then
return _ErrorStr
end
return sData
end

tSocket.HTTP = function(sUrl)
local _ErrorStr, sock = tSocket.NewConnection("www.plop.nl", 80)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr = tSocket.Send(sock, "GET [URL]http://[/URL]"..sUrl..
" HTTP/1.0\nConnection: Keep-Alive\nAccept: */*\nAccept-Language: en\n\n"
)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr, sData = tSocket.ReceiveAll(sock)
if _ErrorStr then
return _ErrorStr
end
local _ErrorStr = tSocket.CloseLib(sock)
if _ErrorStr then
return _ErrorStr
end
return sData
end


----------------------------------------------------------------
-- non blocking events/functions.
----------------------------------------------------------------

-- table 2 keep track of asyn sockets and there events.
tSocket.Connections = {
--[[-- example table with the commands/protocolls for the async handling.
sock = {
OnWsaConnected = function(_ErrorCode, _ErrorStr, sock)
-- do your code here
end,
OnWsaSendComplete = function(_ErrorCode, _ErrorStr, sock, iBytesSend)
-- do your code here,
OnWsaDataArrival = function(_ErrorCode, _ErrorStr, sock, sData, iLenght)
-- do your code here
end,
sName = username, -- username as a string
--iStep = stepnumber, -- an example that you can add key/vallue's if you like.
Status = nil, -- shows status of the socket.
iConnected = nil --  is 1 if connected, else nil
tArgs = {arg1, arg2, arg....}, -- arguments in a array.
you can send more arguments directly 2 the function which generates your
function table for the socket. sWhois is an example of that.
}
--]]--
}

-- building the event functions for async whois.
tSocket.AsyncWhoIs =  function(oUser, sWhoIs)
if sWhoIs then
local tTemp = {
OnWsaConnected = function(_ErrorCode, _ErrorStr, sock)
tSocket.DebugSend("Whois is connected")
tSocket.BeginReceive(sock)
tSocket.BeginSend(sock, sWhoIs.."\n")
end,
OnWsaSendComplete = function(_ErrorCode, _ErrorStr, sock, iBytesSend)
tSocket.DebugSend(iBytesSend.." bytes send.")
end,
OnWsaDataArrival = function(_ErrorCode, _ErrorStr, sock, sData, iLenght, oUser)
oUser:SendData("Socket_"..tostring(sock), sData)
end
}
local tArgs = {sWhoIs}
tSocket.DebugSend("Event function table generated")
tSocket.BeginConnect(oUser, "whois.ripe.net", 43, tTemp, tArgs)
tSocket.DebugSend("Started connecting")
else
return "Nothing to do check out!"
end
end

tSocket.AsyncHTTP =  function(oUser, sUrl)
if sUrl then
local _ErrorStr, sPage, sDomain, sUrl = tSocket.CleanUrl(sUrl)
if _ErrorStr then
return _ErrorStr
end
local tTemp = {
OnWsaConnected = function(_ErrorCode, _ErrorStr, sock)
tSocket.DebugSend("HTTP is connected")
tSocket.BeginReceive(sock)
tSocket.BeginSend(sock, "GET [URL]http://[/URL]"..sUrl..
" HTTP/1.0\nConnection: Keep-Alive\nAccept: */*\nAccept-Language: en\n\n"
)
end,
OnWsaSendComplete = function(_ErrorCode, _ErrorStr, sock, iBytesSend)
tSocket.DebugSend(iBytesSend.." bytes send.")
end,
OnWsaDataArrival = function(_ErrorCode, _ErrorStr, sock, sData, iLenght, oUser)
sData = tSocket.StripHTML(sData)
oUser:SendData("Socket_".."\r\n"..tostring(sock), sData)
end
}
local tArgs = {sUrl, sDomain}
tSocket.DebugSend("Event function table generated")
tSocket.BeginConnect(oUser, sDomain, 80, tTemp, tArgs)
tSocket.DebugSend("Started connecting")
else
return "No url given!"
end
end

-- non blocking sockets.
-- this generates the standard event vallue's possible 2 use in your events table.
tSocket.BeginConnect = function(oUser, sHost, iPort, tTasks, tArgs)
_ErrorStr, sock = tSocket.NewSocket()
if _ErrorStr then
return _ErrorStr
else
tSocket.Connections.sock = tTasks
if type(oUser) == "table" then
tSocket.Connections.sock.sName = oUser.sName
else
tSocket.Connections.sock.sName = oUser
end
tSocket.Connections.sock.Status = "connecting"
tSocket.Connections.sock.tArguments = tArgs
tSocket.Connections.sock.IsConnected = 1

WSA.BeginConnect(sock, sHost, iPort)
tSocket.DebugSend("Connecting to: "..sHost..":"..iPort.." for: "..tSocket.Connections.sock.sName)
end
end

tSocket.OnWsaConnected = function(_ErrorCode, _ErrorStr, sock)
if _ErrorCode then
tSocket.DebugSend("Failed to connect: "..tostring(sock))
tSocket.BeginClose(sock)
return _ErrorStr
else
tSocket.Connections.sock.Status = "connected"
tSocket.DebugSend("Connected: "..tostring(sock))
tSocket.Connections.sock.IsConnected = 1
if tSocket.Connections.sock then
tSocket.Connections.sock.OnWsaConnected(_ErrorCode, _ErrorStr, sock)
end
end
end

tSocket.BeginSend = function(sock, sData)
WSA.BeginSend(sock, sData)
tSocket.DebugSend("Sending: "..sData)
tSocket.Connections.sock.Status = "sending"
end

tSocket.OnWsaSendComplete = function (_ErrorCode, _ErrorStr, sock, sBytesSent)
tSocket.DebugSend("Send completed: "..sBytesSent)
if tSocket.Connections.sock then
tSocket.Connections.sock.OnWsaSendComplete(_ErrorCode, _ErrorStr, sock, sBytesSent)
end
end

tSocket.BeginReceive = function(sock)
tSocket.DebugSend("Receiving data started")
WSA.BeginReceive(sock)
tSocket.Connections.sock.Status = "receiving"
end

tSocket.OnWsaDataArrival = function(_ErrorCode, _ErrorStr, sock, sData, iLength)
tSocket.DebugSend("Data arriving on:"..tostring(sock))
local oUser = GetItemByName(tSocket.Connections.sock.sName)
if oUser then
if _ErrorCode then
if _ErrorCode == 0 then
tSocket.DebugSend(_ErrorCode.." ".._ErrorStr)
tSocket.BeginClose(sock)
return 0, _ErrorStr
else
tSocket.DebugSend("Error while reading data from socket. "..tostring(sock))
return 0, "Error while reading data from socket."
end
else
tSocket.DebugSend(sData)
if tSocket.Connections.sock then
tSocket.Connections.sock.OnWsaDataArrival(_ErrorCode, _ErrorStr, sock, sData, iLength, oUser)
return 1, sock, sData, iLength
end
end
else
tSocket.DebugSend("Closing connection "..tostring(sock)..", user left the hub.")
tSocket.BeginClose(sock)
end
return 1, sock, sData, iLength
end

tSocket.BeginClose = function(sock)
tSocket.DebugSend("Closing the connection: "..tostring(sock))
if tSocket.Connections.sock then
tSocket.Connections.sock = nil
end
WSA.Close(sock)
end

-- helper functions.
tSocket.IsDomain = function(sDomain)
if string.find(sDomain, "^(%w+%.%w+)$") then
return 1
end
end

tSocket.IsIP = function(sIP)
if string.find(sIP, "^(%d+%.%d+%.%d+%.%d+)$") then
return 1
end
end

tSocket.IsUser = function(sUser)
local oUser = GetItemByName(sUser)
if oUser then
return oUser
end
end

tSocket.IsDomainIP = function(sArg)
-- !! returns nil if 1 is true !!!!
if tSocket.IsDomain(sArg) or tSocket.IsIP(sArg) then
return
end
return 1
end

tSocket.IsUserDomainIP = function(sArg)
-- !! returns nil if 1 is true !!!!
if tSocket.IsUSer(SArg) or tSocket.IsDomain(sArg) or tSocket.IsIP(sArg) then
return
end
return 1
end

tSocket.IsConnected = function(sock)
return tSocket.Connections.sock.IsConnected
end

tSocket.CleanUrl = function(sUrl)
tSocket.DebugSend("CleanUrl: "..sUrl)
if string.find(sUrl, "^http") then
sUrl = string.sub(sUrl, 8, (string.len(sUrl)))
tSocket.DebugSend("CleanUrl: removed [URL]http://[/URL] "..sUrl)
end
local s,e,sDomain, sPage = string.find(sUrl, "([^/]+)/*(.*)")
tSocket.DebugSend("CleanUrl: domain "..(sDomain or "nil"))
tSocket.DebugSend("CleanUrl: page "..(sPage or "nil"))
if sPage and sDomain and sUrl then
return nil, sPage, sDomain, sUrl
else
return "Failed to decode the given url!"
end
end

tSocket.StripHTML = function(sData)
--local s,e,sData = string.find(sData, "Content%-Type:%s+%S+(.+)$")
if sData then
return string.gsub(sData, "(%b<>)", "")
else
return "Failed stripping the data!"
end
end

tSocket.DebugSend = function(sMsg)
if _Debug then
SendToAll("WsaSocket", sMsg)
end
end

return tSocket

plop