Advertisement
Guest User

d

a guest
Sep 24th, 2016
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.32 KB | None | 0 0
  1. local chans = {
  2.   atm = 1,
  3.   db = 2,
  4. }
  5.  
  6. local common = dofile("/disk/common")
  7. local blake = dofile("/disk/blake")
  8.  
  9. local database = {}
  10. local dbpath = "/bank.db"
  11. local logpath = "/bank.log"
  12. local maintenance_pass = "test"
  13. local modem = peripheral.find("modem")
  14.  
  15. local oldpull = os.pullEvent
  16. os.pullEvent = os.pullEventRaw
  17.  
  18. local function loadDB(path)
  19.   local ret = {}
  20.   if fs.exists(path) then
  21.     local f = fs.open(path, "r")
  22.     local c = f.readAll()
  23.     ret = textutils.unserialise(c)
  24.     if not ret then return false end
  25.   end
  26.   return ret
  27. end
  28. local function saveDB(path, db)
  29.   local f = fs.open(path, "w")
  30.   local s = textutils.serialise(db)
  31.   f.write(s)
  32.   f.close()
  33.   return true
  34. end
  35. local function printHeader(str, ny)
  36.   local w, h = term.getSize()
  37.   local x, y = term.getCursorPos()
  38.   term.setCursorPos(math.ceil(w/2) - math.floor(#str/2), ny or 1)
  39.   term.clearLine()
  40.   term.write(str)
  41.   term.setCursorPos(x, y)
  42. end
  43. local logfile = fs.open(logpath, "a")
  44. local function log(top, str, nosave)
  45.   local form = (top and ("["..top.."] ") or "")..(str)
  46.   print(form)
  47.   printHeader("Database running with "..dbpath)
  48.   if not nosave then
  49.     logfile.writeLine(form)
  50.     logfile.flush()
  51.   end
  52. end
  53.  
  54. database = loadDB(dbpath)
  55. saveDB(dbpath, database)
  56.  
  57. modem.open(chans.db)
  58. term.clear()
  59. term.setCursorPos(1,2)
  60. logfile.writeLine()
  61. log("Init", "Database started")
  62.  
  63. while true do
  64.   local event, side, chan, reply, msg = os.pullEvent()
  65.   if event == "modem_message" and chan == chans.db and reply == chans.atm and type(msg) == "table" then
  66.  
  67.     if msg[1] == "auth" then
  68.       local user = msg[2]:lower()
  69.       local userdata = database[user]
  70.       if userdata then
  71.         modem.transmit(reply, chans.db, {true, userdata.salt})
  72.         local resp = common.waitForMsg(reply, 2)
  73.         if resp and resp[1] then
  74.           local ok = resp[2] == userdata.passwd
  75.           modem.transmit(reply, chans.db, {ok, not ok and "Wrong password" or nil})
  76.           log("Auth", (ok and "Valid" or "Invalid").." auth: "..user)
  77.         else log("Auth", user.." timed out")
  78.         end
  79.       else
  80.         log("Auth", "User not found: "..user)
  81.         modem.transmit(reply, chans.db, {false, "User not found"})
  82.       end
  83.  
  84.     elseif msg[1] == "register" then
  85.       local user = msg[2]:lower()
  86.       local ok = true
  87.       if user:find("%s") then ok = false log("Register", "Tried registering with a space: "..user) modem.transmit(reply, chans.db, {false, "Username cannot contain spaces"}) end
  88.       if database[user] then ok = false log("Register", "User already exists: "..user) modem.transmit(reply, chans.db, {false, "User already exists"}) end
  89.       if ok then
  90.         local salt = common.genSalt(16)
  91.         modem.transmit(reply, chans.db, {true, salt})
  92.         local r = common.waitForMsg(reply, 2)
  93.         if r and r[1] and type(r[2]) == "string" and #r[2] == 64 then
  94.           database[user] = {}
  95.           database[user].balance = 0
  96.           database[user].passwd = r[2]
  97.           database[user].salt = salt
  98.           saveDB(dbpath, database)
  99.           log("Register", user.." created")
  100.           modem.transmit(reply, chans.db, {true})
  101.         else
  102.           log("Register", user.." timed out")
  103.         end
  104.       end
  105.  
  106.     elseif msg[1] == "balance" then
  107.       local user = msg[2]:lower()
  108.       local userdata = database[user]
  109.       if msg[3] == userdata.passwd then
  110.         modem.transmit(reply, chans.db, {true, userdata.balance})
  111.         log("Balance", "Sent balance: "..user)
  112.       else
  113.         modem.transmit(reply, chans.db, {false, "Invalid hash"})
  114.         log("Balance", "Invalid hash from: "..user)
  115.       end
  116.      
  117.     elseif msg[1] == "transfer" then
  118.       local user = msg[2]:lower()
  119.       local recip = msg[4]:lower()
  120.       local hash = msg[3]
  121.       local amt = tonumber(msg[5]) or math.huge
  122.       amt = math.abs(amt)
  123.       local userdat = database[user]
  124.       local recipdat = database[recip]
  125.       local ok = true
  126.      
  127.       if not recipdat then ok = false log("Transfer", user.." tried to send to invalid: "..recip) modem.transmit(reply, chans.db, {false, "Recipient doesn't exist"}) end
  128.       if userdat.passwd ~= hash then ok = false log("Transfer", "Invalid hash from: "..user) modem.transmit(reply, chans.db, {false, "Invalid hash"}) end
  129.       if userdat.balance < amt then ok = false log("Transfer", user.." tied to send "..amt.." but has "..userdat.balance.." to "..recip) modem.transmit(reply, chans.db, {false, "Insufficent funds"}) end
  130.       if ok then
  131.         database[user].balance = userdat.balance - amt
  132.         database[recip].balance = recipdat.balance + amt
  133.         saveDB(dbpath, database)
  134.         modem.transmit(reply, chans.db, {true, userdat.balance})
  135.         log("Transfer", user.." transfered "..amt.." to "..recip)
  136.       end
  137.     end
  138.  
  139.   elseif event == "key" and side == keys.enter then
  140.     log("Admin", "Enter password")
  141.     write("> ")
  142.     local pswd = read("*")
  143.     if pswd == maintenance_pass then
  144.       log("Admin", "Entering maintenance mode")
  145.       while true do
  146.         write("> ")
  147.         local cmd = read()
  148.         cmd = common.split(cmd, "%s")
  149.         if cmd[1] == "set" then
  150.           local user = cmd[2]:lower()
  151.           local amt = tonumber(cmd[3]) or 0
  152.           if database[user] then
  153.             database[user].balance = amt
  154.             saveDB(dbpath, database)
  155.             log("Admin", "Set "..user.." balance to "..amt)
  156.           else
  157.             log("Admin", "Cannot set balance of "..user)
  158.           end
  159.    
  160.         elseif cmd[1] == "add" then
  161.           local user = cmd[2]:lower()
  162.           local amt = tonumber(cmd[3]) or 0
  163.           if database[user] then
  164.             database[user].balance = database[user].balance + amt
  165.             saveDB(dbpath, database)
  166.             log("Admin", (amt >= 0 and "Added " or "Removed ")..amt.." to "..user.."'s balance")
  167.           else
  168.             log("Admin", "Cannot add to balance of "..user)
  169.           end
  170.    
  171.         elseif cmd[1] == "delete" then
  172.           local user = cmd[2]:lower()
  173.           if database[user] then
  174.             database[user] = nil
  175.             saveDB(dbpath, database)
  176.             log("Admin", user.." deleted from database")
  177.           else
  178.             log("Admin", "Tried to delete invalid user: "..user)
  179.           end
  180.    
  181.         elseif cmd[1] == "list" then
  182.           local users = {}
  183.           for user, userdat in pairs(database) do
  184.             log(nil, user..": "..userdat.balance, true)
  185.           end
  186.         elseif cmd[1] == "help" then
  187.           log(nil, "set <user> <balance> -- Sets a users balance", true)
  188.           log(nil, "add <user> <+/- amount> -- Add or remove from user balance", true)
  189.           log(nil, "delete <user> -- Removes an account from the database", true)
  190.           log(nil, "list -- Lists accounts", true)
  191.           log(nil, "quit -- Quits maintenance mode", true)
  192.           log(nil, "stop -- Stops the database", true)
  193.  
  194.         elseif cmd[1] == "quit" then break
  195.         elseif cmd[1] == "stop" then return
  196.    
  197.         else log("Command", "Invalid command: "..(cmd[1] or ""), true)
  198.         end
  199.         repeat event, side = os.pullEvent("key") until side == keys.enter
  200.       end
  201.       log("Admin", "Exiting maintenance")
  202.     else
  203.       log("Admin", "Wrong password")
  204.     end
  205.   end
  206. end
  207. log("Admin", "Database shutting down")
  208. os.pullEvent = oldpull
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement