Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local chans = {
- atm = 1,
- db = 2,
- }
- local common = dofile("/disk/common")
- local blake = dofile("/disk/blake")
- local database = {}
- local dbpath = "/bank.db"
- local logpath = "/bank.log"
- local maintenance_pass = "test"
- local modem = peripheral.find("modem")
- local oldpull = os.pullEvent
- os.pullEvent = os.pullEventRaw
- local function loadDB(path)
- local ret = {}
- if fs.exists(path) then
- local f = fs.open(path, "r")
- local c = f.readAll()
- ret = textutils.unserialise(c)
- if not ret then return false end
- end
- return ret
- end
- local function saveDB(path, db)
- local f = fs.open(path, "w")
- local s = textutils.serialise(db)
- f.write(s)
- f.close()
- return true
- end
- local function printHeader(str, ny)
- local w, h = term.getSize()
- local x, y = term.getCursorPos()
- term.setCursorPos(math.ceil(w/2) - math.floor(#str/2), ny or 1)
- term.clearLine()
- term.write(str)
- term.setCursorPos(x, y)
- end
- local logfile = fs.open(logpath, "a")
- local function log(top, str, nosave)
- local form = (top and ("["..top.."] ") or "")..(str)
- print(form)
- printHeader("Database running with "..dbpath)
- if not nosave then
- logfile.writeLine(form)
- logfile.flush()
- end
- end
- database = loadDB(dbpath)
- saveDB(dbpath, database)
- modem.open(chans.db)
- term.clear()
- term.setCursorPos(1,2)
- logfile.writeLine()
- log("Init", "Database started")
- while true do
- local event, side, chan, reply, msg = os.pullEvent()
- if event == "modem_message" and chan == chans.db and reply == chans.atm and type(msg) == "table" then
- if msg[1] == "auth" then
- local user = msg[2]:lower()
- local userdata = database[user]
- if userdata then
- modem.transmit(reply, chans.db, {true, userdata.salt})
- local resp = common.waitForMsg(reply, 2)
- if resp and resp[1] then
- local ok = resp[2] == userdata.passwd
- modem.transmit(reply, chans.db, {ok, not ok and "Wrong password" or nil})
- log("Auth", (ok and "Valid" or "Invalid").." auth: "..user)
- else log("Auth", user.." timed out")
- end
- else
- log("Auth", "User not found: "..user)
- modem.transmit(reply, chans.db, {false, "User not found"})
- end
- elseif msg[1] == "register" then
- local user = msg[2]:lower()
- local ok = true
- 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
- if database[user] then ok = false log("Register", "User already exists: "..user) modem.transmit(reply, chans.db, {false, "User already exists"}) end
- if ok then
- local salt = common.genSalt(16)
- modem.transmit(reply, chans.db, {true, salt})
- local r = common.waitForMsg(reply, 2)
- if r and r[1] and type(r[2]) == "string" and #r[2] == 64 then
- database[user] = {}
- database[user].balance = 0
- database[user].passwd = r[2]
- database[user].salt = salt
- saveDB(dbpath, database)
- log("Register", user.." created")
- modem.transmit(reply, chans.db, {true})
- else
- log("Register", user.." timed out")
- end
- end
- elseif msg[1] == "balance" then
- local user = msg[2]:lower()
- local userdata = database[user]
- if msg[3] == userdata.passwd then
- modem.transmit(reply, chans.db, {true, userdata.balance})
- log("Balance", "Sent balance: "..user)
- else
- modem.transmit(reply, chans.db, {false, "Invalid hash"})
- log("Balance", "Invalid hash from: "..user)
- end
- elseif msg[1] == "transfer" then
- local user = msg[2]:lower()
- local recip = msg[4]:lower()
- local hash = msg[3]
- local amt = tonumber(msg[5]) or math.huge
- amt = math.abs(amt)
- local userdat = database[user]
- local recipdat = database[recip]
- local ok = true
- 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
- if userdat.passwd ~= hash then ok = false log("Transfer", "Invalid hash from: "..user) modem.transmit(reply, chans.db, {false, "Invalid hash"}) end
- 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
- if ok then
- database[user].balance = userdat.balance - amt
- database[recip].balance = recipdat.balance + amt
- saveDB(dbpath, database)
- modem.transmit(reply, chans.db, {true, userdat.balance})
- log("Transfer", user.." transfered "..amt.." to "..recip)
- end
- end
- elseif event == "key" and side == keys.enter then
- log("Admin", "Enter password")
- write("> ")
- local pswd = read("*")
- if pswd == maintenance_pass then
- log("Admin", "Entering maintenance mode")
- while true do
- write("> ")
- local cmd = read()
- cmd = common.split(cmd, "%s")
- if cmd[1] == "set" then
- local user = cmd[2]:lower()
- local amt = tonumber(cmd[3]) or 0
- if database[user] then
- database[user].balance = amt
- saveDB(dbpath, database)
- log("Admin", "Set "..user.." balance to "..amt)
- else
- log("Admin", "Cannot set balance of "..user)
- end
- elseif cmd[1] == "add" then
- local user = cmd[2]:lower()
- local amt = tonumber(cmd[3]) or 0
- if database[user] then
- database[user].balance = database[user].balance + amt
- saveDB(dbpath, database)
- log("Admin", (amt >= 0 and "Added " or "Removed ")..amt.." to "..user.."'s balance")
- else
- log("Admin", "Cannot add to balance of "..user)
- end
- elseif cmd[1] == "delete" then
- local user = cmd[2]:lower()
- if database[user] then
- database[user] = nil
- saveDB(dbpath, database)
- log("Admin", user.." deleted from database")
- else
- log("Admin", "Tried to delete invalid user: "..user)
- end
- elseif cmd[1] == "list" then
- local users = {}
- for user, userdat in pairs(database) do
- log(nil, user..": "..userdat.balance, true)
- end
- elseif cmd[1] == "help" then
- log(nil, "set <user> <balance> -- Sets a users balance", true)
- log(nil, "add <user> <+/- amount> -- Add or remove from user balance", true)
- log(nil, "delete <user> -- Removes an account from the database", true)
- log(nil, "list -- Lists accounts", true)
- log(nil, "quit -- Quits maintenance mode", true)
- log(nil, "stop -- Stops the database", true)
- elseif cmd[1] == "quit" then break
- elseif cmd[1] == "stop" then return
- else log("Command", "Invalid command: "..(cmd[1] or ""), true)
- end
- repeat event, side = os.pullEvent("key") until side == keys.enter
- end
- log("Admin", "Exiting maintenance")
- else
- log("Admin", "Wrong password")
- end
- end
- end
- log("Admin", "Database shutting down")
- os.pullEvent = oldpull
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement