Stary2001

FTP! Yay!

Jan 7th, 2013
47
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.56 KB | None | 0 0
  1. function read( _sReplaceChar, _tHistory )
  2. term.setCursorBlink( true )
  3.  
  4. local sLine = ""
  5. local nHistoryPos = nil
  6. local nPos = 0
  7. if _sReplaceChar then
  8. _sReplaceChar = string.sub( _sReplaceChar, 1, 1 )
  9. end
  10.  
  11. local w, h = term.getSize()
  12. local sx, sy = term.getCursorPos()
  13.  
  14. local function redraw( _sCustomReplaceChar )
  15. local nScroll = 0
  16. if sx + nPos >= w then
  17. nScroll = (sx + nPos) - w
  18. end
  19.  
  20. local tx,ty = term.getCursorPos()
  21. if ty ~= sy and nPos == 0 then sy = ty + (ty - sy) end
  22.  
  23. term.setCursorPos( sx, sy )
  24. local sReplace = _sCustomReplaceChar or _sReplaceChar
  25. if sReplace then
  26. term.write( string.rep(sReplace, string.len(sLine) - nScroll) )
  27. else
  28. term.write( string.sub( sLine, nScroll + 1 ) )
  29. end
  30. term.setCursorPos( sx + nPos - nScroll, sy )
  31. end
  32.  
  33. while true do
  34. local sEvent, param = os.pullEvent()
  35. if sEvent == "char" then
  36. sLine = string.sub( sLine, 1, nPos ) .. param .. string.sub( sLine, nPos + 1 )
  37. nPos = nPos + 1
  38. redraw()
  39.  
  40. elseif sEvent == "key" then
  41. if param == keys.enter then
  42. -- Enter
  43. break
  44.  
  45. elseif param == keys.left then
  46. -- Left
  47. if nPos > 0 then
  48. nPos = nPos - 1
  49. redraw()
  50. end
  51.  
  52. elseif param == keys.right then
  53. -- Right
  54. if nPos < string.len(sLine) then
  55. nPos = nPos + 1
  56. redraw()
  57. end
  58.  
  59. elseif param == keys.up or param == keys.down then
  60. -- Up or down
  61. if _tHistory then
  62. redraw(" ");
  63. if param == keys.up then
  64. -- Up
  65. if nHistoryPos == nil then
  66. if #_tHistory > 0 then
  67. nHistoryPos = #_tHistory
  68. end
  69. elseif nHistoryPos > 1 then
  70. nHistoryPos = nHistoryPos - 1
  71. end
  72. else
  73. -- Down
  74. if nHistoryPos == #_tHistory then
  75. nHistoryPos = nil
  76. elseif nHistoryPos ~= nil then
  77. nHistoryPos = nHistoryPos + 1
  78. end
  79. end
  80.  
  81. if nHistoryPos then
  82. sLine = _tHistory[nHistoryPos]
  83. nPos = string.len( sLine )
  84. else
  85. sLine = ""
  86. nPos = 0
  87. end
  88. redraw()
  89. end
  90. elseif param == keys.backspace then
  91. -- Backspace
  92. if nPos > 0 then
  93. redraw(" ");
  94. sLine = string.sub( sLine, 1, nPos - 1 ) .. string.sub( sLine, nPos + 1 )
  95. nPos = nPos - 1
  96. redraw()
  97. end
  98. elseif param == keys.home then
  99. -- Home
  100. nPos = 0
  101. redraw()
  102. elseif param == keys.delete then
  103. if nPos < string.len(sLine) then
  104. redraw(" ");
  105. sLine = string.sub( sLine, 1, nPos ) .. string.sub( sLine, nPos + 2 )
  106. redraw()
  107. end
  108. elseif param == keys["end"] then
  109. -- End
  110. nPos = string.len(sLine)
  111. redraw()
  112. end
  113. end
  114. end
  115.  
  116. term.setCursorBlink( false )
  117. term.setCursorPos( w + 1, sy )
  118. print()
  119.  
  120. return sLine
  121. end
  122.  
  123. local args={...}
  124.  
  125. local function log(s)
  126. local f = fs.open("ftp_log","a")
  127. f.writeLine(s)
  128. f.close()
  129. print(s)
  130. end
  131.  
  132. for k,v in pairs(rs.getSides()) do
  133. if peripheral.getType(v) == "modem" then
  134. rednetSide = v
  135. break
  136. end
  137. end
  138.  
  139. if not rednetSide then print("Rednet is needed!") return end
  140.  
  141. rednet.open(rednetSide)
  142.  
  143. local clients = {}
  144.  
  145. function auth(id,data)
  146. local u , pass = string.gmatch(data,"^(.-):(.+)$")()
  147.  
  148. if pass == users[u] then
  149. log(u .. " connected with id ".. id)
  150. clients[id] = {user=u}
  151. return true
  152. else
  153. log("Attempt to log into " .. u .. " by id " .. id .. " failed!")
  154. return false
  155. end
  156. end
  157.  
  158. function getDir(file)
  159. return string.gsub(file,fs.getName(file).."/","")
  160. end
  161.  
  162. function getPerms(file)
  163. if string.find(file,"/") == nil then
  164. if perms[file] then
  165. return perms[fix(file)]
  166. else
  167. return {write="all",read="all"}
  168. end
  169. end
  170.  
  171. if perms[fix(getDir(file))] then
  172. if perms[fix(file)] then
  173. return perms[fix(file)]
  174. else
  175. return perms[fix(getDir(file))]
  176. end
  177. else
  178. return {write="all",read="all"}
  179. end
  180. end
  181.  
  182. function hasRead(file, user)
  183. local perms = getPerms(file).read
  184. if perms == "all" then
  185. return true
  186. elseif perms == "logged_in" then
  187. return user~=nil
  188. elseif type(perms) == "table" then
  189. for k,v in pairs(perms) do
  190. if user == v then return true end
  191. end
  192. return false
  193. end
  194. end
  195.  
  196. function hasWrite(file, user)
  197. local perms = getPerms(file).write
  198. if perms == "all" then
  199. return true
  200. elseif perms == "logged_in" then
  201. return user~=nil
  202. elseif type(perms) == "table" then
  203. for k,v in pairs(perms) do
  204. if user == v then return true end
  205. end
  206. return false
  207. end
  208. end
  209.  
  210. function put(id,data)
  211. local filename ,contents = string.gmatch(data,"^(.-):(.+)$")()
  212.  
  213. local user
  214. if clients[id] then
  215. user=clients[id].user
  216. end
  217. if not hasWrite(filename,user) then
  218. local first = "User "
  219. if not user then
  220. user = "An anonymous user"
  221. first = ""
  222. end
  223.  
  224. log(first .. user .. " tried to write forbidden file " ..filename)
  225. return false
  226. else
  227. local f = fs.open(filename,"w")
  228. f.write(contents)
  229. f.close()
  230. return true
  231. end
  232. end
  233.  
  234. function get(id,data)
  235. local filename = data
  236.  
  237. local user
  238. if clients[id] then
  239. user=clients[id].user
  240. end
  241.  
  242. if not hasRead(filename,user) then
  243. local first = "User "
  244. if not user then
  245. user = "An anonymous user"
  246. first = ""
  247. end
  248. log(first .. user .. " tried to read forbidden file ".. filename)
  249. else
  250. local f = fs.open(filename,"r")
  251. rednet.send(id,"DATA " .. filename .. ":" .. f.readAll())
  252. f.close()
  253. end
  254. end
  255.  
  256. function list(id,data)
  257. local dir = data
  258. local s = ""
  259.  
  260. if not hasRead(dir,user) then
  261. local first = "User "
  262. if not user then
  263. user = "An anonymous user"
  264. first = ""
  265. end
  266. log(first .. user .. " tried to list forbidden dir ".. dir)
  267. else
  268. for k,v in pairs(fs.list(data)) do
  269. s = s .. v .. " "
  270. end
  271. rednet.send(id,"LIST " .. s)
  272. end
  273. end
  274.  
  275. function host()
  276. while true do
  277. local clientID,msg = rednet.receive()
  278. print(clientID," ",msg)
  279. if msg:sub(1,7) == "CONNECT" then
  280. if auth(clientID,msg:sub(9)) then
  281. rednet.send(clientID,"ACCEPT")
  282. else
  283. rednet.send(clientID,"DENY")
  284. end
  285. elseif msg:sub(1,3) == "GET" then
  286. get(clientID,msg:sub(5))
  287. elseif msg:sub(1,3) == "PUT" then
  288. put(clientID,msg:sub(5))
  289. elseif msg:sub(1,4) == "QUIT" then
  290. clients[clientID] = nil
  291. elseif msg:sub(1,4) == "LIST" then
  292. list(clientID,msg:sub(5))
  293. elseif msg:sub(1,2) == "CD" then
  294. if fs.exists(msg:sub(4)) or msg:sub(4) == "/" or msg:sub(4) == "" then
  295. rednet.send(clientID,"DIR " .. msg:sub(4))
  296. end
  297. end
  298. end
  299. end
  300.  
  301. function client()
  302. while true do
  303. local serverID,msg = rednet.receive()
  304.  
  305. if msg == "ACCEPT" then
  306. print("Connection accepted.")
  307. elseif msg == "DENY" then
  308. print("Permission denied.")
  309. elseif msg:sub(1,4) == "DATA" then
  310. local filename,content = string.gmatch(msg:sub(6),"^(.-):(.+)$")()
  311. local f = fs.open(filename,"w")
  312. f.write(content)
  313. f.close()
  314. print("Wrote " .. filename)
  315. elseif msg:sub(1,3) == "DIR" then
  316. curDir = msg:sub(5)
  317. elseif msg:sub(1,4) == "LIST" then
  318. print(msg:sub(6))
  319. end
  320. end
  321. end
  322.  
  323. function readFile(name)
  324. local f = fs.open(name,"r")
  325. local r = f.readAll()
  326. f.close()
  327. return r
  328. end
  329.  
  330. local curDir = ""
  331.  
  332. function toCmd(line)
  333. if string.lower(line:sub(1,3)) == "get" then
  334. return "GET " .. line:sub(5)
  335. elseif string.lower(line:sub(1,3)) == "put" then
  336. return "PUT " .. line:sub(5) .. ":" .. readFile(line:sub(5))
  337. elseif string.lower(line:sub(1,4)) == "list" then
  338. return "LIST " .. curDir
  339. elseif string.lower(line:sub(1,2)) == "cd" then
  340. curDir = line:sub(4)
  341. end
  342. end
  343.  
  344. function input()
  345. while true do
  346. local line = read()
  347. local cmd=toCmd(line)
  348. if cmd then
  349. rednet.send(server,cmd)
  350. end
  351. end
  352. end
  353.  
  354.  
  355. if #args >= 1 then
  356.  
  357. if args[1] == "host" then
  358. local f= fs.open("users","r")
  359. users = textutils.unserialize(f.readAll())
  360. f.close()
  361.  
  362. f = fs.open("perms","r")
  363. perms = textutils.unserialize(f.readAll())
  364. f.close()
  365.  
  366. host()
  367. else
  368. local id = tonumber(args[1])
  369.  
  370. io.write("Username: ")
  371. local user = read()
  372. io.write("Password: ")
  373. local pass = read("*")
  374. rednet.send(id,"CONNECT "..user..":"..pass)
  375.  
  376. parallel.waitForAny(client,input)
  377. end
  378. else
  379. print("Usage: ftp host|<id>")
  380. end
  381.  
  382. rednet.close(rednetSide)
Advertisement
Add Comment
Please, Sign In to add comment