Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local args={...}
- for k,v in pairs(rs.getSides()) do
- if peripheral.getType(v) == "modem" then
- rednetSide = v
- break
- end
- end
- if not rednetSide then print("Rednet is needed!") return end
- rednet.open(rednetSide)
- local clients = {}
- function getDir(file)
- return string.gsub(file,fs.getName(file)+"%/","")
- end
- function fix(file)
- if file:sub(1,1) == "/" then
- file = file:sub(2)
- end
- return file
- end
- function getPerms(file)
- if perms[fix(getDir(file))] then
- if perms[fix(file)] then
- return perms[fix(file)]
- else
- return perms[fix(getDir(file))]
- end
- else
- return {write="all",read="all"}
- end
- end
- function hasRead(file, user)
- local perms = getPerms(file).read
- if perms == "anon" then
- return true
- elseif perms == "logged_in" then
- return user~=nil
- elseif type(perms) == "table" then
- for k,v in pairs(perms) do
- if user == v then return true end
- end
- return false
- end
- end
- function hasWrite(file, user)
- local perms = getPerms(file).write
- if perms == "anon" then
- return true
- elseif perms == "logged_in" then
- return user~=nil
- elseif type(perms) == "table" then
- for k,v in pairs(perms) do
- if user == v then return true end
- end
- return false
- end
- end
- function put(id,data)
- local filename ,contents = string.gmatch(data,"^(.-):(.+)$")()
- if not hasWrite(clients[id].user) then
- print("User " .. clients[id].user .. " tried to write forbidden file " ..filename)
- return false
- else
- local f = fs.open(filename,"w")
- f.write(contents)
- f.close()
- return true
- end
- end
- function get(id,data)
- local filename = data
- if not hasRead(clients[id].user) then
- print("User " .. clients[id].user .. " tried to read forbidden file ".. filename)
- else
- local f = fs.open(filename,"r")
- rednet.send(id,"DATA " .. f.readAll())
- f.close()
- end
- end
- function auth(id,data)
- local u , pass = string.gmatch(data,"^(.-):(.+)$")()
- if pass == users[u] then
- print(u .. " connected with id ".. id)
- clients[id] = {user=u}
- return true
- else
- print("Attempt to log into " .. u .. " failed!")
- return false
- end
- end
- function host()
- while true do
- local clientID,msg = rednet.receive()
- print(clientID," ",msg)
- if msg:sub(1,7) == "CONNECT" then
- if auth(clientID,msg:sub(9)) then
- rednet.send(clientID,"ACCEPT")
- else
- rednet.send(clientID,"DENY")
- end
- elseif msg:sub(1,3) == "GET" then
- get(clientID,msg:sub(5))
- elseif msg:sub(1,3) == "PUT" then
- put(clientID,msg:sub(5))
- elseif msg:sub(1,4) == "QUIT" then
- clients[clientID] = nil
- end
- end
- end
- function client()
- while true do
- local serverID,msg = rednet.receive()
- if msg == "ACCEPT" then
- print("Connection accepted.")
- elseif msg == "DENY" then
- print("Permission denied.")
- elseif msg:sub(1,4) == "DATA" then
- print(msg:sub(5))
- end
- end
- end
- function readFile(name)
- local f = fs.open(name,"r")
- local r = f.readAll()
- f.close()
- return r
- end
- function toCmd(line)
- if string.lower(line:sub(1,3)) == "get" then
- return "GET " .. line:sub(5)
- elseif string.lower(line:sub(1,3)) == "put" then
- return "PUT " .. line:sub(5) .. readFile(line:sub(5))
- end
- end
- function input()
- while true do
- local line = io.read()
- rednet.send(server,toCmd(line))
- end
- end
- if #args >= 1 then
- if args[1] == "host" then
- local f= fs.open("users","r")
- users = textutils.unserialize(f.readAll())
- f.close()
- f = fs.open("perms","r")
- perms = textutils.unserialize(f.readAll())
- f.close()
- host()
- else
- local id = tonumber(args[1])
- io.write("Username: ")
- local user = read()
- io.write("Password: ")
- local pass = read("*")
- rednet.send(id,"CONNECT "..user..":"..pass)
- parallel.waitForAny(client,input)
- end
- else
- print("Usage: ftp host|<id>")
- end
- rednet.close(rednetSide)
Advertisement
Add Comment
Please, Sign In to add comment