return posix.mkdtemp("/tmp/qwikboard-XXXXXX")
end
+function fs.getmd5(filename)
+ local md5_file_name = filename .. ".md5"
+ os.execute(qb.md5sum .. " " .. filename .. " > " .. md5_file_name)
+ local md5fh = assert(io.open(md5_file_name), "r")
+ local md5f_str = md5fh:read("*all")
+ md5fh:close()
+
+ return string.match(md5f_str, "^(%w+)%s")
+end
+
--- Message database parsing ---
function Message(msg)
-- and that the handler can execute it and read your
-- system's nncp.hjson file.
qb.nncp_file = "/usr/bin/nncp-file"
+
+-- Location of md5sum. If available, this is used to check
+-- for duplicate REP submissions.
+qb.md5sum = "/usr/bin/md5sum"
+
]])
cf:close()
qwk.import_rep(arg[1], arg[2])
end
-local function restore_nncp_usernames()
- nncp_usernames = {}
+local function restore_nncp_userdata()
+ nncp_userdata = {}
if fs.exists(qb.path .. "/nncp_users.lua") then
dofile(qb.path .. "/nncp_users.lua")
end
end
-local function store_nncp_usernames()
+local function store_nncp_userdata()
local fh = assert(io.open(qb.path .. "/nncp_users.lua", "w"))
- for k,v in pairs(nncp_usernames) do
- fh:write("nncp_usernames[" .. string.format("%q",k) .. "] = " ..
- string.format("%q", v) .. "\n")
+ for uid,tab in pairs(nncp_userdata) do
+ fh:write("nncp_userdata[" .. string.format("%q",uid) .. "] = {\n")
+ for k,v in pairs(tab) do
+ fh:write(k .. ": " string.format(%q, v) .. ",\n")
+ end
+ fh:write("}\n")
end
end
return false
end
- restore_nncp_usernames()
+ restore_nncp_userdata()
local input_string = io.stdin:read("*all")
if string.match(input_string, "^%s*get") then
- local user_name = string.match(input_string, "^%s*get%s+(%w+)%s*$")
- if user_name then
- nncp_usernames[node_id] = user_name
- store_nncp_usernames()
+ local handle = string.match(input_string, "^%s*get%s+(%w+)%s*$")
+ if handle then
+ nncp_userdata[node_id].handle = user_name
+ store_nncp_userdata()
else
- user_name = nncp_usernames[node_id]
+ handle = nncp_userdata.handle[node_id]
end
- if not user_name then
+ if not handle then
print("Error: no known handle for node " .. node_id .. ". Aborting.")
return false
end
- print("Building QWK packet for user '" .. user_name .. "'")
+ print("Building QWK packet for user '" .. handle .. "'")
-- Construct QWK packet
local out_file_name = os.tmpname()
fs.rmfile(out_file_name)
local out_file_name = out_file_name .. ".qwk"
- qwk.build_qwk(user_name, out_file_name)
+ qwk.build_qwk(handle, out_file_name)
os.execute(qb.nncp_file .. " " .. out_file_name .. " " ..
node_id .. ":" .. qb.bbsid .. ".QWK")
fs.rmfile(out_file_name)
else
- local user_name = nncp_usernames[node_id]
+ local handle = nncp_userdata[node_id].handle
- if not user_name then
+ if not handle then
print("Error: No user name for node " .. node_id .. " found. Aborting.")
return false
end
- print("Accepting REP packet from user '" .. user_name .. "'")
+ print("Accepting REP packet from user '" .. handle .. "'")
-- Accept REP packet
local rep_file_name = os.tmpname()
rf:write(input_string)
rf:close()
- qwk.import_rep(user_name, rep_file_name)
+ if qb.md5sum then
+ -- Check for duplicate REP submissions
+
+ local md5 = fs.getmd5(rep_file_name)
+ local stored_md5 = nncp_userdata[node_id].md5
+ if stored_md5 and (md5 ~= stored_md5) then
+ print("Error: Duplicate REP submission detected. Skipping.")
+ return false
+ end
+
+ nncp_userdata[node_id].md5 = md5
+ store_nncp_userdata()
+ end
+
+ qwk.import_rep(handle, rep_file_name)
fs.rmfile(rep_file_name)
end