· 6 years ago · Oct 24, 2019, 03:50 PM
1local tArgs = {...}
2termX, termY = term.getSize()
3Peripheral = {
4 GetPeripheral = function(_type)
5 for i, p in ipairs(Peripheral.GetPeripherals()) do
6 if p.Type == _type then
7 return p
8 end
9 end
10 end,
11
12 Call = function(type, ...)
13 local tArgs = {...}
14 local p = GetPeripheral(type)
15 peripheral.call(p.Side, unpack(tArgs))
16 end,
17
18 GetPeripherals = function(filterType)
19 local peripherals = {}
20 for i, side in ipairs(peripheral.getNames()) do
21 local name = peripheral.getType(side):gsub("^%l", string.upper)
22 local code = string.upper(side:sub(1,1))
23 if side:find('_') then
24 code = side:sub(side:find('_')+1)
25 end
26
27 local dupe = false
28 for i, v in ipairs(peripherals) do
29 if v[1] == name .. ' ' .. code then
30 dupe = true
31 end
32 end
33
34 if not dupe then
35 local _type = peripheral.getType(side)
36 local isWireless = false
37 if _type == 'modem' then
38 if not pcall(function()isWireless = peripheral.call(sSide, 'isWireless') end) then
39 isWireless = true
40 end
41 if isWireless then
42 _type = 'wireless_modem'
43 name = 'W '..name
44 end
45 end
46 if not filterType or _type == filterType then
47 table.insert(peripherals, {Name = name:sub(1,8) .. ' '..code, Fullname = name .. ' ('..Capitalise(side)..')', Side = side, Type = _type, Wireless = isWireless})
48 end
49 end
50 end
51 return peripherals
52 end,
53
54 GetPeripheral = function(_type)
55 for i, p in ipairs(Peripheral.GetPeripherals()) do
56 if p.Type == _type then
57 return p
58 end
59 end
60 end,
61
62 PresentNamed = function(name)
63 return peripheral.isPresent(name)
64 end,
65
66 CallType = function(type, ...)
67 local tArgs = {...}
68 local p = Peripheral.GetPeripheral(type)
69 return peripheral.call(p.Side, unpack(tArgs))
70 end,
71
72 CallNamed = function(name, ...)
73 local tArgs = {...}
74 return peripheral.call(name, unpack(tArgs))
75 end
76}
77
78Capitalise = function(str)
79 return str:sub(1, 1):upper() .. str:sub(2, -1)
80end
81-- Modem Functions Called For Info On Modems, Or To Change Modem Status
82modem = {
83 channels = {
84 discover = 6019,
85 fileSend = 6021,
86 reply = 6023,
87 },
88 isOpen = function(channel) --Returns if the channel is open or not
89 Peripheral.CallType('wireless_modem', 'isOpen', channel)
90 end,
91
92 Open = function(channel) --Open a channel if not already open
93 if not modem.isOpen(channel) then
94 Peripheral.CallType('wireless_modem', 'open', channel)
95 end
96 end,
97
98 Close = function(channel) --Close channel specified
99 Peripheral.CallType('wireless_modem', 'close', channel)
100 end,
101
102 CloseAll = function() --Close all channels
103 Peripheral.CallType('wireless_modem', 'closeAll')
104 end,
105
106 Transmit = function(channel, replyChannel, message) --Transmit a message over the modem... The message is serialized first so it can hold data.... Use FormatMessage()
107 Peripheral.CallType('wireless_modem', 'transmit', channel, replyChannel, textutils.serialize(message))
108 end,
109
110 isPresent = function()
111 if Peripheral.GetPeripheral('wireless_modem') == nil then
112 return false
113 else
114 return true
115 end
116 end,
117
118 SendMessage = function(channel, message, reply, messageID, destinationID)
119 reply = reply or modem.channels.reply
120 modem.Open(channel)
121 modem.Open(reply)
122 local _message = modem.FormatMessage(message, messageID, destinationID)
123 modem.Transmit(channel, reply, _message)
124 return _message
125 end,
126
127
128 FormatMessage = function(message, messageID, destinationID)
129 return {
130 content = textutils.serialize(message),
131 senderID = os.getComputerID(),
132 senderName = os.getComputerLabel(),
133 channel = channel,
134 replyChannel = reply
135 }
136 end,
137
138 Initialise = function()
139 if modem.isPresent() then
140 for i, c in pairs(modem.channels) do
141 modem.Open(c)
142 LogFile.i(c.." Open", runningProgram)
143 end
144 end
145 end,
146
147 checkMessage = function(event, side, channel, reply, _message, distance)
148 message = textutils.unserialize(_message)
149 LogFile.i('message received: '..textutils.serialize(message), runningProgram)
150 if channel == modem.channels.discover then
151 if PCwaiting then
152 if message == "discoverClients" then
153 local message = {}
154 message["idno"] = os.getComputerID()
155 message["name"] = os.getComputerLabel()
156 LogFile.i('Sending Message: '..tostring(message), runningProgram)
157 rmessage = textutils.serialize(message)
158 LogFile.i('Compiled Message: '..tostring(rmessage), runningProgram)
159 modem.Transmit(modem.channels.reply, modem.channels.discover, message)
160 return
161 end
162 end
163 elseif channel == modem.channels.fileSend then
164 if PCwaiting then
165 if message['content'] == "downloadConfirm" and tonumber(message['dest']) == os.getComputerID() then
166 tableClear()
167 drawTitle()
168 printer.centered('Transfer Request', 6)
169 term.setTextColor(colors.gray)
170 printer.centered('Computer '..message['name']..' ('..message['idno']..')', 8)
171 printer.centered('Wants to send you a file ('..message['fileName']..')', 9)
172 printer.centered('Do you accept or deny the request?', 11)
173 deny = btnInit("Deny", nil, nil, 2, 18, 1, colors.blue, colors.black, 1, function()
174 local senderID = message['idno']
175 local message = {}
176 message['content'] = "DENY"
177 message['idno'] = os.getComputerID()
178 message['name'] = os.getComputerLabel()
179 message['dest'] = senderID
180 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
181 mainMenu()
182 end, false)
183 accept = btnInit("Accept", nil, nil, termX-4-#"Accept", 18, 1, colors.blue, colors.black, 1, function()
184 senderID = message['idno']
185 local message = {}
186 message['content'] = "ACCEPT"
187 message['idno'] = os.getComputerID()
188 message['name'] = os.getComputerLabel()
189 message['dest'] = senderID
190 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
191 tableClear()
192 drawTitle()
193 printer.centered('Waiting For Download', 6)
194 term.setTextColor(colors.gray)
195 printer.centered('You have accepted the download', 10)
196 printer.centered('we are just waiting for the sender', 11)
197 printer.centered('to transfer the file', 12)
198 while true do
199 local e, p1, p2, p3, p4, p5 = os.pullEvent()
200 if e == "mouse_click" then
201 doClick(e, p1, p2, p3)
202 elseif e == "modem_message" then
203 message = textutils.unserialize(p4)
204 if message['proto'] == "fileTransfer" then
205 if tonumber(message['dest']) == os.getComputerID() then
206 message['fileName'] = fileConflict(message['fileName'])
207 tableClear()
208 drawTitle()
209 printer.centered('Downloading File', 10)
210 local text = stripText(message['fileName'])
211 printer.centered(text, 11)
212 printer.centered("", 12)
213 sleep(0.6)
214 local f = fs.open(message['fileName'], 'w')
215 f.write(message['content'])
216 f.close()
217 drawTitle()
218 printer.centered('Download Complete', 6)
219 local _message = {}
220 _message['dest'] = senderID
221 _message['idno'] = os.getComputerID()
222 _message['name'] = os.getComputerLabel() or 'FTP Client'
223 _message['content'] = 'downloadComplete'
224 modem.Transmit(modem.channels.fileSend, modem.channels.reply, _message)
225 term.setTextColor(colors.gray)
226 printer.centered('File has been saved to; ', 8)
227 printer.centered(message['fileName'], 9)
228 term.setTextColor(colors.black)
229 printer.centered('Click anywhere to continue', 19)
230 os.pullEvent('mouse_click')
231 mainMenu()
232 end
233 elseif message['proto'] == 'dirTransfer' and message['dest'] == os.getComputerID() then
234 drawTitle()
235 tableClear()
236 printer.centered('Downloading Directories', 6)
237 term.setTextColor(colors.gray)
238 printer.centered('The file being sent is a folder containing multiple', 8)
239 printer.centered('files, we are downloading them now', 9)
240 while true do
241 local e, p1, p2, p3, p4, p5 = os.pullEvent()
242 if e == 'mouse_click' then
243 doClick(e, p1, p2, p3)
244 elseif e == "modem_message" then
245 p4 = textutils.unserialize(p4)
246 if tonumber(p4['dest']) == os.getComputerID() then
247 if p4['proto'] == 'dirTransfer' or p4['proto'] == 'dirTransferFinal' then
248 drawTitle()
249 p4['fileName'] = fileConflict(p4['fileName'])
250 drawTitle()
251 printer.centered('Downloading', 10)
252 local text = stripText(p4['fileName'])
253 printer.centered(p4['fileName'], 11)
254 local h = fs.open(p4['fileName'], 'w')
255 h.write(p4['content'])
256 h.close()
257 local _message = {}
258 _message['dest'] = p4['idno']
259 _message['content'] = 'downloadComplete'
260 modem.Transmit(modem.channels.fileSend, modem.channels.reply, _message)
261 if p4['proto'] == 'dirTransferFinal' then
262 drawTitle()
263 printer.centered('Download Complete', 6)
264 local _message = {}
265 _message['dest'] = senderID
266 _message['idno'] = os.getComputerID()
267 _message['name'] = os.getComputerLabel() or 'FTP Client'
268 _message['content'] = 'downloadComplete'
269 modem.Transmit(modem.channels.fileSend, modem.channels.reply, _message)
270 term.setTextColor(colors.gray)
271 printer.centered('The download is finished!', 8)
272 printer.centered('Click anywhere to continue', 19)
273 os.pullEvent('mouse_click')
274 mainMenu()
275 end
276 else error'Incorrect protocol' end
277 else error('Incorrect ID: '..os.getComputerID()..":<>:"..p4['dest']..":EntireMessage:"..textutils.serialize(p4)) end
278 end
279 end
280 end
281 end
282 end
283 end, false)
284 elseif message['content'] == 'downloadExpired' and message['dest'] == os.getComputerID() then
285 tableClear()
286 drawTitle()
287 printer.centered('Download Revoked', 6)
288 printer.centered('Click anywhere to return', 19)
289 term.setTextColor(colors.gray)
290 printer.centered('The sender revoked the download', 10)
291 os.pullEvent('mouse_click')
292 mainMenu()
293 end
294 elseif PCsending then
295 if message['content'] == 'ACCEPT' and message['dest'] == os.getComputerID() then
296 os.queueEvent('accept')
297 elseif message['content'] == 'DENY' and message['dest'] == os.getComputerID() then
298 os.queueEvent('deny')
299 elseif message['content'] == "downloadComplete" and message['dest'] == os.getComputerID() then
300 drawTitle()
301 tableClear()
302 printer.centered('Transfer Complete', 6)
303 term.setTextColor(colors.gray)
304 printer.centered('Client '..message['idno']..' has completed the download', 8)
305 term.setTextColor(colors.black)
306 printer.centered('Click anywhere to continue', 19)
307 os.pullEvent('mouse_click')
308 mainMenu()
309 end
310 end
311 end
312 end,
313}
314
315function stripText(text)
316 if #text > 20 then
317 local s1 = string.sub(text, 1, 10)
318 local s2 = string.sub(text, -10)
319 LogFile.i('Stripping text: '..text.."::Part One: "..s1.."Part Two: "..s2, runningProgram)
320 local text = (s1.."..."..s2)
321 return text
322 end
323 return text
324end
325
326local blackList = {
327 "\\"
328}
329
330function fileConflict(file)
331 LogFile.i('Checking File conflict: '..file, runningProgram)
332 tableClear()
333 if fs.exists(file) then
334 LogFile.i('CONFLICT: '..file, runningProgram)
335 drawTitle()
336 printer.centered('File Conflict', 6)
337 printer.centered(file, 19)
338 term.setTextColor(colors.gray)
339 printer.centered('A file already exists with the same name', 8)
340 printer.centered('as the file you are trying to download', 9)
341 printer.centered('Do you want to overwrite the file or save', 11)
342 printer.centered('elsewhere', 12)
343 saveelse = btnInit("Save Elsewhere", nil, nil, termX-4-#"Save Elsewhere", 18, 1, colors.blue, colors.black, 1, function() os.queueEvent('saveelse') end, false)
344 overwrite = btnInit("Overwrite", nil, nil, saveelse.x-4-#"Overwrite", 18, 1, colors.blue, colors.black, 1, function() os.queueEvent('overwrite') end, false)
345 while true do
346 local e, p1, p2, p3, p4, p5 = os.pullEvent()
347 if e == "mouse_click" then
348 doClick(e, p1, p2, p3)
349 elseif e == "overwrite" then
350 fs.delete(file)
351 return file
352 elseif e == "saveelse" then
353 drawTitle()
354 tableClear()
355 printer.centered('Rename File', 6)
356 term.setTextColor(colors.gray)
357 printer.centered('Enter the new path for the download', 8)
358 local text = "New Path: "
359 term.setCursorPos(termX/2-#text, 12)
360 write(text)
361 local input = uInput.restrictedKeyRead(termX*10, nil, elements, blackList)
362 if input ~= "" then
363 return input
364 end
365 end
366 end
367 end
368 return file
369end
370
371local required = {
372 'LogFile',
373 'element',
374 'printer',
375 'titleBar',
376 'uInput'
377}
378
379Events = {}
380elements = {}
381computers = {}
382
383function downloadFile(getUrl, toPath)
384 for i = 1, 3 do
385 local response = http.get(getUrl)
386 if response then
387 data = response.readAll()
388 if fs.exists(toPath) then
389 fs.delete(toPath)
390 end
391 if toPath then
392 if fs.exists(toPath) then fs.delete(toPath) end
393 local file = fs.open(toPath, "w")
394 file.write(data)
395 file.close()
396 print(getUrl)
397 print(toPath)
398 sleep(0)
399 return true
400 else
401 return false
402 end
403 else
404 return false
405 end
406 end
407 return false
408end
409if not fs.exists('api') then fs.makeDir('api') end
410if not fs.exists('systemFiles') then fs.makeDir('systemFiles') end
411for i, v in pairs(required) do
412 print(v)
413 if not fs.exists('/api/'..v) then
414 if not downloadFile("https://raw.githubusercontent.com/hbomb79/securitySystemPro/master/api/"..v, "/api/"..v) then error('Failed to download: '..v) end
415 end
416 if not os.loadAPI('/api/'..v) then error('Failed to load API: '..v) end
417end
418
419LogFile.Initialise()
420
421function btnInit(btnText, btnWidth, btnHeight, btnX, btnY, btnTC, btnBG, oTC, oBG, onClick, toggle, secBG, secTC, secText, parent) --Function to create button
422 local btn = element.create(btnText, btnWidth, btnHeight, btnX, btnY, btnTC, btnBG, oTC, oBG, onClick, toggle, secBG, secTC, secText, parent) --Calls API to generate button
423 table.insert(elements, btn) --Inserts into table so it can be scanned later
424 element.opacity(btn, true) --Sets visibility to true
425 return btn
426end
427
428function doClick(event, btn, x, y)
429 functionToRun = element.tryClick(elements, x, y)
430 if functionToRun then --Check click location
431 functionToRun()
432 end
433end
434
435function eventRegister(event, functionToRun)
436 LogFile.i('Registered Event: '..event, runningProgram)
437 if not Events[event] then
438 Events[event] = {}
439 end
440 table.insert(Events[event], functionToRun)
441end
442
443function eventLoop()
444 while true do
445 local event, arg1, arg2, arg3, arg4, arg5, arg6 = os.pullEventRaw()
446 if Events[event] then
447 for i, e in ipairs(Events[event]) do
448 e(event, arg1, arg2, arg3, arg4, arg5, arg6)
449 end
450 end
451 end
452end
453
454function drawTitle()
455 titleBar.draw('FTP', 'Wireless Transfer', colors.white, 1, colors.blue, colors.white, colors.black)
456end
457
458displayButtons = {}
459
460function tableClear(optional)
461 term.setCursorBlink(false)
462 if optional then tablesToRemove = {displayButtons, elements, computers} else tablesToRemove = {displayButtons, elements} end
463 for i, v in ipairs (tablesToRemove) do
464 local k = next(v)
465 while k do
466 v[k] = nil
467 k = next(v)
468 end
469 end
470end
471
472local blackList = {
473 "\\"
474}
475
476function pingDiscover()
477 pcMsg = {}
478 timeout = os.startTimer(3)
479 while true do
480 local e, p1, p2, p3, p4, p5 = os.pullEvent()
481 if e == "modem_message" then
482 timeout = os.startTimer(1)
483 table.insert(pcMsg, p4)
484 elseif e == "timer" then
485 if p1 == timeout then
486 addComputers()
487 break
488 end
489 end
490 end
491end
492
493function addComputers()
494 tableClear(true)
495 for i, v in ipairs(pcMsg) do
496 _message = textutils.unserialize(v)
497 local DUPE = false
498 for _, pc in ipairs(computers) do
499 if tonumber(_message['idno']) == pc then DUPE = true end
500 end
501
502 if not DUPE then
503 table.insert(computers, _message)
504 LogFile.i("Inserted "..tostring(_message['idno']).." Into Table", runningProgram)
505 if _message['name'] then
506 LogFile.i(_message['name'], runningProgram)
507 end
508 end
509 end
510end
511
512function listClients()
513 term.setCursorBlink(false)
514 tableClear()
515 drawTitle()
516 printer.centered("Please Wait While We Search For Clients", 6)
517 term.setTextColor(colors.gray)
518 printer.centered("Run this program on other computers and", 8)
519 printer.centered("They will appear here", 9)
520 modem.Transmit(modem.channels.discover, modem.channels.reply, "discoverClients")
521 pingDiscover()
522 if #computers < 1 then
523 tableClear()
524 drawTitle()
525 printer.centered("We Couldn't Find Any Clients", 6)
526 term.setTextColor(colors.gray)
527 printer.centered("In order to find some you must have", 8)
528 printer.centered("other computers running this program in", 9)
529 printer.centered("WAIT mode", 10)
530 term.setTextColor(colors.black)
531 printer.centered("Click Anywhere To Return", 19)
532 os.pullEvent('mouse_click')
533 return 'NOCLIENTS'
534 else
535 tableClear()
536 drawTitle()
537 printer.centered('Clients Found: '..#computers, 6)
538 printer.centered('Please wait while we render the menu', 8)
539 local function clientList()
540 local title = "Choose the device to send your file to"
541 local tArgs = computers
542 local pages = {[1]={}}
543 for i = 1, #tArgs, 1 do
544 if #pages[ #pages ] == 6 then
545 pages[ #pages + 1 ] = {}
546 end
547 pages[ #pages ][ #pages[#pages] + 1 ] = tArgs[ i ]
548 end
549 local maxx, maxy = term.getSize()
550 local page = 1
551 local selected = 1
552 local function render()
553 local tbl = pages[ page ]
554 tableClear()
555 drawTitle()
556 printer.centered(title, 4)
557 local xValue = 2
558 local Count = 1
559 local yValue = 8
560 LogFile.i("Length Of PreRender: "..tostring(#tbl), runningProgram)
561 if pages[page-1] then prevBtn = btnInit("Previous Page", nil, nil, 2, 18, 1, colors.cyan, colors.black, 1, function() os.queueEvent("PreviousPage") end, false, nil, nil, nil, nil) end
562 if pages[page+1] then nxtBtn = btnInit("Next Page", nil, nil, termX - 2 - #"Next Page", 18, 1, colors.cyan, colors.black, 1, function() os.queueEvent("NextPage") end, false, nil, nil, nil, nil) end
563 backBtn = btnInit("Return", nil, nil, termX/2-#"Return"/2, 18, 1, colors.red, colors.black, 1, function() os.queueEvent("back") end, false, nil, nil, nil, nil)
564 LogFile.i(tostring(textutils.serialize(tbl)), runningProgram)
565 LogFile.i(tostring(textutils.serialize(computers)), runningProgram)
566 for i = 1, #tbl do
567 local lastName = tbl[i]['name'] or "FTP Client"
568 LogFile.i("Iteration "..i.." Name: "..tostring(lastName).." ID: "..tostring(tbl[i]['idno']), runningProgram)
569 if Count == 1 then x = 2 y = 8
570 elseif Count == 2 then y = 8 x = termX-6-#lastName-#tostring(tbl[i]['idno'])
571 elseif Count == 3 then y = 11 x = 2
572 elseif Count == 4 then y = 11 x = termX-6-#lastName-#tostring(tbl[i]['idno'])
573 elseif Count == 5 then y = 14 x = 2
574 elseif Count == 6 then y = 14 x = termX-6-#lastName-#tostring(tbl[i]['idno']) Count = 1
575 end
576 displayButtons[tbl[i]] = btnInit(tostring(lastName)..' ('..tostring(tbl[i]['idno'])..')', nil, nil, x, y, 1, colors.blue, colors.black, 1, function() clientToSend = tbl[i]['idno'] os.queueEvent('Done') end, false, nil, nil, nil, nil)
577 Count = Count + 1
578 end
579 if pages[ page - 1 ] then
580 element.opacity(prevBtn, true)
581 end
582 if pages[ page + 1 ] then
583 element.opacity(nxtBtn, true)
584 end
585 term.setTextColor(colors.gray)
586 local str = "(" .. page .. "/" .. #pages .. ")"
587 printer.centered( str , 19)
588 term.setTextColor(colors.black)
589 end
590 while true do
591 render()
592 local event, param1, p2, p3 = os.pullEvent()
593 if event == "mouse_click" then
594 doClick(event, param1, p2, p3)
595 elseif event == "PreviousPage" then
596 if pages[page-1] then
597 printer.centered("Loading, Please Wait...", 4) sleep(0)
598 page = page -1
599 element.opacity(prevBtn, false)
600 element.opacity(nxtBtn, false)
601 tableClear()
602 drawTitle()
603 else
604 prevBtn.visible = false
605 LogFile.w("Previous Button Fired When On First Page!", runningProgram)
606 end
607 elseif event == "NextPage" then
608 if pages[page+1] then
609 printer.centered("Loading, Please Wait...", 4) sleep(0.2)
610 page = page + 1
611 element.opacity(prevBtn, false)
612 element.opacity(nxtBtn, false)
613 tableClear()
614 drawTitle()
615 else
616 nxtBtn.visible = false
617 LogFile.w("Next Button Fired When On Last Page!", runningProgram)
618 end
619 elseif event == "Done" then
620 return clientToSend
621 elseif event == "back" then
622 tableClear()
623 drawTitle()
624 mainMenu()
625 end
626 end
627 end
628 client = clientList()
629 return client
630 end
631end
632
633
634function directoryFound(dir, protocol)
635 if protocol == false then
636 term.setTextColor(colors.black)
637 printer.centered('Found directory!', 6)
638 term.setTextColor(colors.gray)
639 printer.centered("We found this directory", 8)
640 printer.centered(stripText(dir), 9)
641 printer.centered('Do you want to transmit files in here too?', 11)
642 back = btnInit("Yes", nil, nil, termX-2-#"Yes", 18, 1, colors.green, colors.black, 1, function() os.queueEvent('yes') end, false)
643 back = btnInit("Nope", nil, nil, 2, 18, 1, colors.red, colors.black, 1, function() os.queueEvent('no') end, false)
644 while true do
645 local e, p1, p2, p3 = os.pullEvent()
646 if e == 'mouse_click' then doClick(e, p1, p2, p3)
647 elseif e == 'yes' then return true elseif e == 'no' then return false end
648 end
649 else return true end
650end
651
652
653function transferDir(mainDir, clientToSend, transferAll)
654 local dirs, fileToSend = {}, {}
655 local tablesToRemove = {fileToSend, dirs}
656 for i, v in ipairs (tablesToRemove) do
657 local k = next(v)
658 while k do
659 v[k] = nil
660 k = next(v)
661 end
662 end
663 tableClear()
664 drawTitle()
665 printer.centered('Searching '..mainDir, 6)
666 term.setTextColor(colors.gray)
667 printer.centered('We are searching the main directory', 8)
668 printer.centered('for files and folders to send', 9)
669 for i, v in ipairs(fs.list(mainDir)) do
670 sleep()
671 v = mainDir..'/'..v
672 LogFile.i('List File: '..v, runningProgram)
673 if fs.isDir(v) then
674 if directoryFound(v, transferAll) then
675 table.insert(dirs, v)
676 LogFile.i('Added directory: '..v, runningProgram)
677 end
678 else
679 LogFile.i('Adding file: '..v, runningProgram)
680 table.insert(fileToSend, v)
681 end
682 end
683 LogFile.i('Secondary Check', runningProgram)
684 for i, v in ipairs(dirs) do
685 for _, k in ipairs(fs.list(v)) do
686 sleep()
687 k = v..'/'..k
688 LogFile.i('Scanning File: '..k, runningProgram)
689 if fs.isDir(k) and directoryFound(k, transferAll) then
690 LogFile.i('DIRECTORY Found: '..k, runningProgram)
691 table.insert(dirs, k)
692 else
693 LogFile.i('File Found: '..k, runningProgram)
694 table.insert(fileToSend, k)
695 end
696 end
697 end
698 LogFile.i('File Found: '..textutils.serialize(fileToSend)..' Dirs: '..textutils.serialize(dirs), runningProgram)
699 if #fileToSend < 1 and #dirs < 1 then
700 tableClear()
701 drawTitle()
702 printer.centered('Nothing To Send', 6)
703 printer.centered('Click Anywhere To Return', 19)
704 term.setTextColor(colors.gray)
705 printer.centered('We cannot find any files or folders', 8)
706 printer.centered('inside of '..mainDir, 9)
707 else
708 tableClear()
709 drawTitle()
710 local messageProbe = {}
711 messageProbe['idno'] = os.getComputerID()
712 messageProbe['dest'] = clientToSend
713 messageProbe['proto'] = 'dirTransfer'
714 modem.Transmit(modem.channels.fileSend, modem.channels.reply, messageProbe)
715 printer.centered('Transfering Files', 6)
716 term.setTextColor(colors.gray)
717 printer.centered('Any files in directories you requested', 6)
718 printer.centered('to be sent will be transfered as well', 7)
719 for i, v in ipairs(fileToSend) do
720 term.setTextColor(colors.black)
721 printer.centered('Sending '..stripText(v), 10)
722 printer.centered('', 11)
723 term.setTextColor(colors.gray)
724 local message = {}
725 message['dest'] = clientToSend
726 message['idno'] = os.getComputerID()
727 message['name'] = os.getComputerLabel()
728 if i < #fileToSend then message['proto'] = 'dirTransfer' elseif i == #fileToSend then LogFile.i('Last Message', runningProgram) message['proto'] = 'dirTransferFinal' end
729 message['fileName'] = v
730 local f = fs.open(message['fileName'], 'r')
731 message['content'] = f.readAll()
732 f.close()
733 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
734 LogFile.i('Sent File: '..textutils.serialize(message), runningProgram)
735 while true do
736 printer.centered('Waiting For Client', 11)
737 LogFile.i('Awaiting Client Confirmation', runningProgram)
738 local e, p1, p2, p3, p4, p5 = os.pullEvent()
739 if e == 'modem_message' then
740 p4 = textutils.unserialize(p4)
741 if p4['dest'] == os.getComputerID() and p4['content'] == 'downloadComplete' then
742 LogFile.i('Client Confirmed', runningProgram)
743 break
744 end
745 end
746 end
747 if i == #fileToSend then
748 drawTitle()
749 printer.centered('Download Finished!', 6)
750 printer.centered('Click Anywhere To Continue', 19)
751 term.setTextColor(colors.gray)
752 printer.centered('The client has downloaded all the files', 8)
753 printer.centered('you sent', 9)
754 os.pullEvent('mouse_click')
755 end
756 end
757 mainMenu()
758 end
759end
760
761function transferFile(file, clientToSend)
762 tableClear()
763 drawTitle()
764 printer.centered('Starting Download', 6)
765 term.setTextColor(colors.gray)
766 printer.centered('The client accepted your download request', 8)
767 printer.centered('please wait while transfer your file', 9)
768 term.setTextColor(colors.black)
769 printer.centered('Gathering Information', 6)
770 local message = {}
771 message['dest'] = clientToSend
772 message['idno'] = os.getComputerID()
773 message['name'] = os.getComputerLabel() or "FTP Client"
774 message['proto'] = 'fileTransfer'
775 message['fileName'] = file
776 printer.centered('Extracting File', 6)
777 if not fs.exists(file) then error'File no longer exists!' end
778 local f = fs.open(file, 'r')
779 local fileToSend = f.readAll()
780 f.close()
781 message['content'] = fileToSend
782 printer.centered('Transfering...', 6)
783 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
784end
785
786function sendFile(args)
787 while true do
788 if not args then
789 tableClear()
790 drawTitle()
791 submit = btnInit("Choose Cient", nil, nil, termX/2-#"Choose Client"/2, 18, 1, colors.blue, colors.black, 1, function() os.queueEvent("submit_Result") end, false)
792 back = btnInit("Back", nil, nil, 2, 18, 1, colors.red, colors.black, 1, function() os.queueEvent('submit_Result') mainMenu() end, false)
793 printer.centered("File Send", 6)
794 term.setTextColor(colors.gray)
795 printer.centered("To send a file or directory, enter its path", 8)
796 printer.centered("and click \"Choose Client\" to continue", 9)
797 printer.centered("NOTE: You can use backward dirs (..)", 19)
798 local text = "File Path: "
799 term.setCursorPos(termX/2-#text, 11)
800 write(text)
801 input = uInput.restrictedEventRead(termX*10, nil, elements, blackList)
802 else input = tostring(args) end
803 if input ~= "" then
804 fileToSend = input
805 if fs.isDir(input) then
806 drawTitle()
807 tableClear()
808 printer.centered('Transfer Directory', 6)
809 term.setTextColor(colors.gray)
810 printer.centered('The path you entered is a directory', 8)
811 printer.centered('If you continue then we will send the contents', 9)
812 printer.centered('If you did this on accident then click back', 10)
813 goBtn = btnInit("Go Ahead!", nil, nil, termX-2-#"Go Ahead!", 18, 1, colors.blue, colors.black, 1,function() os.queueEvent('continue') end, false)
814 backBtn = btnInit("No Thanks", nil, nil, goBtn.x-4-#"No Thanks", 18, 1, colors.blue, colors.black, 1, function() os.queueEvent('back') end, false)
815 while true do
816 local e, p1, p2, p3 = os.pullEvent()
817 LogFile.i(e, runningProgram)
818 if e == "mouse_click" then
819 doClick(e, p1, p2, p3)
820 elseif e == 'back' then
821 tableClear()
822 drawTitle()
823 mainMenu()
824 elseif e == 'continue' then
825 break
826 end
827 end
828 end
829 if fs.exists(input) then
830 clientToSend = listClients()
831 if clientToSend == "NOCLIENTS" then break end
832 local message = {}
833 message['dest'] = clientToSend
834 message['idno'] = os.getComputerID()
835 message['name'] = os.getComputerLabel() or "FTP Client"
836 message['fileName'] = fileToSend or "ERROR, DONT DOWNLOAD"
837 message['content'] = "downloadConfirm"
838 PCsending = true
839 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
840 tableClear()
841 drawTitle()
842 printer.centered('Waiting For Consent', 6)
843 term.setTextColor(colors.gray)
844 printer.centered("Client "..tostring(clientToSend).." needs to accept your request", 8)
845 printer.centered("When the client accepts, the download will begin", 10)
846 back = btnInit("Cancel", nil, nil, termX/2-#"Cancel"/2, 18, 1, colors.red, colors.black, 1, function() os.queueEvent('cancel') end, false)
847 while true do
848 local e, p1, p2, p3, p4, p5 = os.pullEvent()
849 if e == "accept" then
850 --Transfer file.
851 if fs.isDir(input) then
852 drawTitle()
853 tableClear()
854 printer.centered('More Directories', 6)
855 term.setTextColor(colors.gray)
856 printer.centered('When we check this directory we may find', 8)
857 printer.centered('more directories, If you like you can tell us now', 9)
858 printer.centered('to send any and all directories we find inside of', 10)
859 printer.centered(input, 11)
860 goBtn = btnInit("Transfer All", nil, nil, termX-2-#"Transfer All", 18, 1, colors.blue, colors.black, 1,function() os.queueEvent('all') end, false)
861 backBtn = btnInit("Let Me Choose", nil, nil, goBtn.x-4-#"Let Me Choose", 18, 1, colors.blue, colors.black, 1, function() os.queueEvent('pick') end, false)
862 while true do
863 local e, p1, p2, p3 = os.pullEvent()
864 LogFile.i(e, runningProgram)
865 if e == "mouse_click" then
866 doClick(e, p1, p2, p3)
867 elseif e == 'pick' then
868 transferDir(input, clientToSend, false)
869 elseif e == 'all' then
870 transferDir(input, clientToSend, true)
871 end
872 end
873 else
874 transferFile(input, clientToSend)
875 end
876 elseif e == "deny" then
877 tableClear()
878 drawTitle()
879 printer.centered("Download Denied", 6)
880 term.setTextColor(colors.gray)
881 printer.centered("The client denied your download request", 10)
882 printer.centered("Click Anywhere To Continue", 19)
883 os.pullEvent('mouse_click')
884 drawTitle()
885 tableClear()
886 mainMenu()
887 elseif e == "cancel" then
888 local message = {}
889 message['dest'] = clientToSend
890 message['idno'] = os.getComputerID()
891 message['name'] = os.getComputerLabel() or "FTP Client"
892 message['content'] = "downloadExpired"
893 modem.Transmit(modem.channels.fileSend, modem.channels.reply, message)
894 tableClear()
895 drawTitle()
896 mainMenu()
897 elseif e == "mouse_click" then
898 doClick(e, p1, p2, p3)
899 elseif e == "modem_message" then
900 modem.checkMessage(e, p1, p2, p3, p4, p5)
901 end
902 end
903 else
904 printer.centered("File Doesn't Exist!", 19) sleep(0.5)
905 if args then mainMenu() end
906 end
907 else
908 printer.centered("You Must Enter A File Path", 19) sleep(0.5)
909 end
910 end
911 mainMenu()
912end
913
914function mainMenu()
915 PCwaiting = false
916 PCsending = false
917 tableClear()
918 drawTitle()
919 printer.centered("Welcome To FTP", 6)
920 term.setTextColor(colors.gray)
921 printer.centered("This program allows you to easily transfer", 10)
922 printer.centered("files from PC to PC", 11)
923 printer.centered("If you wish to transfer then click send", 13)
924 printer.centered("otherwise click wait if you are expecting a file", 14)
925 sendBtn = btnInit("Send", nil, nil, termX-2-#"Send", 18, 1, colors.blue, colors.black, 1, sendFile, false)
926 waitBtn = btnInit("Wait", nil, nil, sendBtn.x-4-#"Wait", 18, 1, colors.blue, colors.black, 1, waitFile, false)
927 exitBtn = btnInit("Exit", nil, nil, 2, 18, 1, colors.red, colors.black, 1, function() term.setBackgroundColor(colors.black) term.setTextColor(1) term.clear() term.setCursorPos(1, 1) shell.run("shell") end)
928 if waitON then waitON = false waitFile() end
929 eventLoop()
930end
931
932function waitFile()
933 tableClear()
934 drawTitle()
935 back = btnInit("Back", nil, nil, 2, 18, 1, colors.red, colors.black, 1, function() mainMenu() end, false)
936 printer.centered("Waiting For File...", 6)
937 term.setTextColor(colors.gray)
938 printer.centered("To send a file simply select the send option", 8)
939 printer.centered("on the computer that has the file you want to send", 9)
940 printer.centered("When we receive the file well let you know", 11)
941 PCwaiting = true
942end
943
944function Initialise()
945 printer.centered("Please Wait...", 6)
946 printer.centered("Registering Events", 6)
947 eventRegister("terminate", function() error'You Have Terminated This Program' end)
948 eventRegister("mouse_click", doClick)
949 eventRegister("modem_message", modem.checkMessage)
950 drawTitle()
951 while not modem.isPresent() do
952 printer.centered("Please attach a wireless modem to continue", 6)
953 printer.centered("This program uses rednet to transfer files", 8)
954 printer.centered("between computers", 9)
955 os.pullEvent()
956 end
957 modem.Initialise()
958 --Shell args
959 if #tArgs == 1 then
960 if fs.exists(tArgs[1]) then
961 sendFile(tArgs[1])
962 elseif tArgs[1] == "-w" then
963 waitON = true
964 else
965 printer.centered("Shell Arg Error", 6)
966 printer.centered("Click Anywhere To Continue", 19)
967 printer.centered(tArgs[1].." Doesn't Exist", 11)
968 term.setTextColor(colors.gray)
969 printer.centered("The file you are trying to send", 8)
970 printer.centered("via the shell doesn't exist", 9)
971 os.pullEvent('mouse_click') mainMenu()
972 end
973 elseif #tArgs > 1 then
974 printer.centered("Program Arguments Detected", 6)
975 printer.centered('Click Anywhere To Continue', 19)
976 printer.centered(shell.getRunningProgram().." <FileToSend>", 11)
977 printer.centered(shell.getRunningProgram().." -w (To Wait For Files)", 13)
978 term.setTextColor(colors.gray)
979 printer.centered("This program accepts only one shell arg.", 8)
980 printer.centered("Use the following syntax;", 9)
981 printer.centered("Or", 12)
982 os.pullEvent('mouse_click')
983 end
984 mainMenu()
985end
986if pocket then
987 error'This program doesnt support pocket computers yet, sorry'
988elseif not term.isColor() then
989 error'The device must be advanced to use this program'
990else
991 Initialise()
992end
993error'Apologies, The program has left the loop, Please report this with steps to reproduce'