Advertisement
magik6000

Untitled

Nov 24th, 2013
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.00 KB | None | 0 0
  1. --CCPT - ComputerCraft Packaging Tool
  2.  
  3. ------
  4.  
  5. if not http then
  6. error("HTTP API MUST be enabled to use this program")
  7. end
  8.  
  9. --Pseudo enums
  10.  
  11. local validator = {ok = 0, installed = 1, file_conflict = 2}
  12.  
  13. ---Pre-definitions
  14.  
  15. local install = nil
  16. local remove = nil
  17.  
  18. ---UTILITIES
  19.  
  20. List = {}
  21. function List.new ()
  22. return {first = 0, last = -1}
  23. end
  24.  
  25. function List.pushleft (list, value)
  26. local first = list.first - 1
  27. list.first = first
  28. list[first] = value
  29. end
  30.  
  31. function List.pushright (list, value)
  32. local last = list.last + 1
  33. list.last = last
  34. list[last] = value
  35. end
  36.  
  37. function List.popleft (list)
  38. local first = list.first
  39. if first > list.last then return nil end
  40. local value = list[first]
  41. list[first] = nil
  42. list.first = first + 1
  43. return value
  44. end
  45.  
  46. function List.popright (list)
  47. local last = list.last
  48. if list.first > last then return nil end
  49. local value = list[last]
  50. list[last] = nil
  51. list.last = last - 1
  52. return value
  53. end
  54.  
  55. local function CGetS(file,name)
  56. local _cfg = fs.open(file,"r")
  57.  
  58. if not _cfg then
  59. error("Could not open configuration file: "..file)
  60. end
  61.  
  62. local x = true;
  63.  
  64. while x do
  65. local line = _cfg.readLine()
  66. if line == nil then
  67. x = false;
  68. else
  69.  
  70. local side = false
  71. local prop = ""
  72. local val = ""
  73. for a=1,#line do
  74. if line:sub(a,a) == '=' then
  75. side = true
  76. elseif side then
  77. val = val .. line:sub(a,a)
  78. else
  79. prop = prop .. line:sub(a,a)
  80. end
  81. end
  82.  
  83. if prop == name then
  84. _cfg.close()
  85. return val
  86. end
  87. end
  88. end
  89. _cfg.close()
  90. end
  91.  
  92. local function CGetN(file,name)
  93. return tonumber(CGetS(file,name))
  94. end
  95.  
  96. local function download(file, url)
  97. local res = http.get(url)
  98. if res then
  99. if file ~= nil then
  100. fs.delete(file)
  101. fs.makeDir(file)
  102. fs.delete(file)
  103. local fhnd = fs.open(file, "w");
  104. if fhnd then
  105. fhnd.write(res.readAll())
  106. fhnd.close()
  107. return res.readAll()
  108. else
  109. res.close()
  110. error("Could not open "..file.." for writing")
  111. end
  112. else
  113. return res.readAll()
  114. end
  115. else
  116. print("WARNING:Download failed for: "..url)
  117. end
  118. res.close()
  119. end
  120.  
  121. function split(text,splitter)
  122. local rt = {}
  123. local act = ""
  124. for x=1,#text do
  125. if text:sub(x,x+#splitter-1) == splitter then
  126. rt[#rt+1]=act
  127. act=""
  128. else
  129. act = act .. text:sub(x,x)
  130. end
  131. end
  132. if act ~= "" then
  133. rt[#rt+1] = act
  134. end
  135. return rt;
  136. end
  137.  
  138. ---Intarnal functions
  139.  
  140. local function update_list()
  141. --local sync = CGetS("/etc/ccpt/config","master")
  142. --if sync then
  143. --download("/etc/ccpt/list",sync)
  144. local run = true
  145. local exec = List.new()
  146. local num = 0
  147.  
  148. local sources = fs.open("/etc/ccpt/sources","r")
  149.  
  150. if not sources then
  151. error("Could not open base file: /etc/ccpt/list")
  152. end
  153.  
  154. local x = true;
  155. while x do
  156. local line = sources.readLine()
  157. if line == nil then
  158. x = false;
  159. else
  160. print("List:"..line)
  161. List.pushright(exec,download(nil,line))
  162. end
  163. end
  164.  
  165.  
  166. fs.delete("/etc/ccpt/list")
  167. fs.makeDir("/etc/ccpt/list")
  168. fs.delete("/etc/ccpt/list")
  169. local fhnd = fs.open("/etc/ccpt/list", "w");
  170. if fhnd then
  171. while run do
  172. local proc = List.popright(exec)
  173. if proc then
  174. local tline = split(proc,"\n")
  175. for k,val in pairs(tline) do
  176. local row = split(val,";")
  177. if row[1] == "p" then
  178. fhnd.writeLine(val)
  179. num = num + 1
  180. elseif row[1] == "s" then
  181. print("List:"..row[2])
  182. local dl = download(nil,row[2])
  183. if dl then
  184. List.pushright(exec,dl)
  185. end
  186. end
  187. end
  188. else
  189. run = false
  190. end
  191. end
  192. fhnd.close()
  193. else
  194. error("Could not open "..file.." for writing")
  195. end
  196. print("Packages defined: "..tostring(num))
  197. end
  198.  
  199. local function register(name,version,header)
  200.  
  201. local reg = nil
  202.  
  203. if fs.exists("/etc/ccpt/installed") then
  204. reg = fs.open("/etc/ccpt/installed","a")
  205. else
  206. reg = fs.open("/etc/ccpt/installed","w")
  207. end
  208.  
  209. if reg then
  210. reg.writeLine(name..";"..tostring(version))
  211. reg.close()
  212. else
  213. error("Critical:Could not register installation")
  214. end
  215.  
  216. local freg = nil
  217.  
  218. if fs.exists("/etc/ccpt/files") then
  219. freg = fs.open("/etc/ccpt/files","a")
  220. else
  221. freg = fs.open("/etc/ccpt/files","w")
  222. end
  223.  
  224. if freg then+
  225. local lhead = split(header,"\n")
  226. local x = 1
  227. for x = 1, #lhead do
  228. if split(lhead[x],";")[1] == "f" then
  229. freg.writeLine(name..";"..split(lhead[x],";")[2])
  230. elseif split(lhead[x],";")[1] == "u" then
  231. freg.writeLine(name..";"..split(lhead[x],";")[2])
  232. end
  233. end
  234. freg.close()
  235. else
  236. error("Error:Could not register files")
  237. end
  238.  
  239. end
  240.  
  241. local function base_find(name)
  242. local base = fs.open("/etc/ccpt/list","r")
  243.  
  244. if not base then
  245. error("Could not open base file: /etc/ccpt/list")
  246. end
  247.  
  248. local x = true;
  249. while x do
  250. local line = base.readLine()
  251. if line == nil then
  252. x = false;
  253. else
  254. local entry = split(line,";")
  255. if entry[1] == "p" then
  256. if entry[2] == name then
  257. local ret = {name=entry[2],url=entry[4],version=tonumber(entry[3])}
  258. return ret
  259. end
  260. end
  261. end
  262. end
  263. end
  264.  
  265. local function validate(pname,header)
  266. local instbase = fs.open("/etc/ccpt/installed","r")
  267. if instbase then
  268. local x = true
  269. while x do
  270. local tline = instbase.readLine()
  271. if tline == nil then
  272. x = false
  273. else
  274. if pname == split(tline,";")[1] then
  275. return validator.installed
  276. end
  277. end
  278. end
  279. instbase.close()
  280. end
  281. --local filebase = fs.open("/etc/ccpt/files","r")
  282. if header then
  283. lhead = split(header,"\n")
  284. local x = 1
  285. for x = 1, #lhead do
  286. if split(lhead[x],";")[1] == "f" then
  287. if fs.exists(split(lhead[x],";")[2]) then
  288. print("[info]Conflict: "..split(lhead[x],";")[2])
  289. return validator.file_conflict
  290. end
  291. end
  292. end
  293. end
  294.  
  295. return validator.ok
  296. end
  297.  
  298. local function download_files(url,header)
  299. local lhead = split(header,"\n")
  300. local x = 1
  301. for x = 1, #lhead do
  302. if split(lhead[x],";")[1] == "f" then
  303. download(split(lhead[x],";")[2],url..split(lhead[x],";")[2])
  304. end
  305. if split(lhead[x],";")[1] == "u" then
  306. download(split(lhead[x],";")[2],split(lhead[x],";")[3])
  307. end
  308. end
  309. end
  310.  
  311. local function run_scripts(url,header)
  312. local lhead = split(header,"\n")
  313. local x = 1
  314. for x = 1, #lhead do
  315. if split(lhead[x],";")[1] == "s" then
  316. download("/tmp/ccptpirs",url..split(lhead[x],";")[2])
  317. shell.run("/tmp/ccptpirs")
  318. fs.delete("/tmp/ccptpirs")
  319. end
  320. end
  321. end
  322.  
  323. local function dep_register(what,onwhat)
  324. local reg = nil
  325.  
  326. if fs.exists("/etc/ccpt/dtree") then
  327. reg = fs.open("/etc/ccpt/dtree","a")
  328. else
  329. reg = fs.open("/etc/ccpt/dtree","w")
  330. end
  331.  
  332. if reg then
  333. reg.writeLine(what..";"..onwhat)
  334. reg.close()
  335. else
  336. error("Critical:Could not register dependencies")
  337. end
  338. end
  339.  
  340. local function dependencies(header,package)
  341. local lhead = split(header,"\n")
  342. local x = 1
  343. for x = 1, #lhead do
  344. if split(lhead[x],";")[1] == "d" then
  345. install(split(lhead[x],";")[2])
  346. dep_register(package,split(lhead[x],";")[2])
  347. end
  348. end
  349. end
  350.  
  351. local function filelist(package)
  352. local freg = fs.open("/etc/ccpt/files","r")
  353. if freg then
  354. local ret = {}
  355. local x = true
  356. while x do
  357. local tline = freg.readLine()
  358. if tline == nil then
  359. x = false
  360. else
  361. row = split(tline,";")
  362. if row[1] == package then
  363. ret[#ret+1] = row[2]
  364. end
  365. end
  366. end
  367. freg.close()
  368. return ret
  369. end
  370. end
  371.  
  372. local function get_deps(package)
  373. local reg = fs.open("/etc/ccpt/dtree","r")
  374. if reg then
  375. local ret = {}
  376. local x = true
  377. while x do
  378. local tline = reg.readLine()
  379. if tline == nil then
  380. x = false
  381. else
  382. local row = split(tline,";")
  383. if row[1] == package then
  384. ret[#ret+1] = row[2]
  385. end
  386. end
  387. end
  388. reg.close()
  389. return ret
  390. end
  391. end
  392.  
  393. local function get_refcount(package)
  394. local reg = fs.open("/etc/ccpt/dtree","r")
  395. local ret = 0
  396. if reg then
  397. local x = true
  398. while x do
  399. local tline = reg.readLine()
  400. if tline == nil then
  401. x = false
  402. else
  403. local row = split(tline,";")
  404. if row[2] == package then
  405. ret = ret + 1
  406. end
  407. end
  408. end
  409. reg.close()
  410. end
  411. return ret
  412. end
  413.  
  414. local function get_unused(list)
  415. local x = 1
  416. local ret = {}
  417. if list then
  418. for x = 1, #list do
  419. if get_refcount(list[x]) == 0 then
  420. ret[#ret + 1] = list[x]
  421. end
  422. end
  423. end
  424. return ret
  425. end
  426.  
  427. local function unregister(package)
  428. local reg = fs.open("/etc/ccpt/installed","r")
  429. local newbase = {}
  430. if reg then
  431. local x = true
  432. while x do
  433. local tline = reg.readLine()
  434. if tline == nil then
  435. x = false
  436. else
  437. local row = split(tline,";")
  438. if row[1] ~= package then
  439. newbase[#newbase+1] = tline
  440. end
  441. end
  442. end
  443. reg.close()
  444. end
  445. fs.delete("/etc/ccpt/installed")
  446. reg = fs.open("/etc/ccpt/installed","w")
  447. if reg then
  448. local x = 1
  449. for x = 1, #newbase do
  450. reg.writeLine(newbase[x])
  451. end
  452. reg.close()
  453. else
  454. error("CRITICAL: Could not open database for writing")
  455. end
  456. reg = fs.open("/etc/ccpt/files","r")
  457. newbase = {}
  458. if reg then
  459. local x = true
  460. while x do
  461. local tline = reg.readLine()
  462. if tline == nil then
  463. x = false
  464. else
  465. local row = split(tline,";")
  466. if row[1] ~= package then
  467. newbase[#newbase+1] = tline
  468. end
  469. end
  470. end
  471. reg.close()
  472. end
  473. fs.delete("/etc/ccpt/files")
  474. reg = fs.open("/etc/ccpt/files","w")
  475. if reg then
  476. local x = 1
  477. for x = 1, #newbase do
  478. reg.writeLine(newbase[x])
  479. end
  480. reg.close()
  481. else
  482. error("CRITICAL: Could not open file base for writing")
  483. end
  484. end
  485.  
  486. local function deptree_unregister(package)
  487. local reg = fs.open("/etc/ccpt/dtree","r")
  488. local newbase = {}
  489. if reg then
  490. local x = true
  491. while x do
  492. local tline = reg.readLine()
  493. if tline == nil then
  494. x = false
  495. else
  496. local row = split(tline,";")
  497. if row[1] ~= package then
  498. newbase[#newbase+1] = tline
  499. end
  500. end
  501. end
  502. reg.close()
  503. end
  504. fs.delete("/etc/ccpt/dtree")
  505. reg = fs.open("/etc/ccpt/dtree","w")
  506. if reg then
  507. local x = 1
  508. for x = 1, #newbase do
  509. reg.writeLine(newbase[x])
  510. end
  511. reg.close()
  512. else
  513. error("CRITICAL: Could not dtree database for writing")
  514. end
  515. end
  516.  
  517. local function get_installed()
  518. local reg = fs.open("/etc/ccpt/installed","r")
  519. local ret = {}
  520. if reg then
  521. local x = true
  522. while x do
  523. local tline = reg.readLine()
  524. if tline == nil then
  525. x = false
  526. else
  527. local row = split(tline,";")
  528. ret[#ret + 1] = {name = row[1], version = tonumber(row[2])}
  529. end
  530. end
  531. reg.close()
  532. end
  533. return ret
  534. end
  535.  
  536. local function list_upgardable()
  537. local installed = get_installed()
  538. local ret = {}
  539. for k,val in pairs(installed) do
  540. if val.version ~= base_find(val.name).version then
  541. ret[#ret + 1] = val.name
  542. end
  543. end
  544. return ret
  545. end
  546.  
  547. install = function (package)
  548.  
  549. print("["..package.."]Reading Database")
  550. local entry = base_find(package)
  551. if entry then
  552. print("["..package.."]Downloading package header")
  553. local header = download(nil, entry.url..entry.name.."/index")
  554. print("["..package.."]Checking for conflicts")
  555. local vres = validate(entry.name,header)
  556. if vres == validator.ok then
  557. print("["..package.."]Checking dependencies")
  558. dependencies(header,package)
  559. print("["..package.."]Downloading files")
  560. download_files(entry.url..entry.name,header)
  561. print("["..package.."]Registering")
  562. register(package,entry.version,header)
  563. print("["..package.."]Running post-init scripts")
  564. run_scripts(entry.url..entry.name,header)
  565. elseif vres == validator.installed then
  566. print("["..package.."]Package already installed")
  567. else
  568. error("["..package.."]File conflict detected!")
  569. end
  570. else
  571. print("["..package.."]Package not found!")
  572. end
  573. end
  574.  
  575. remove = function (package)
  576. print("["..package.."]Reading database")
  577. if validate(package,nil) == validator.installed then
  578. print("["..package.."]Removing files")
  579. local list = filelist(package)
  580. local removed = 0
  581. if list then
  582. local x = 1
  583. for x = 1, #list do
  584. fs.delete(list[x])
  585. removed = removed + 1
  586. end
  587. end
  588. print("["..package.."]"..tostring(removed).." files removed")
  589. print("["..package.."]Removing from database")
  590. unregister(package)
  591. print("["..package.."]Removing unused dependencies")
  592. local deps = get_deps(package)
  593. deptree_unregister(package)
  594. local remlist = get_unused(deps)
  595. for k,val in pairs(remlist) do
  596. remove(val)
  597. end
  598. else
  599. print("["..package.."]Package not installed")
  600. end
  601. end
  602.  
  603. local function upgrade()
  604. print("Updating package list")
  605. update_list()
  606. print("Upgrading packages")
  607. local todo = list_upgardable()
  608. for k,val in pairs(todo) do
  609. remove(val)
  610. install(val)
  611. end
  612. print(tostring(#todo).." Packages upgraded")
  613. end
  614.  
  615. ---MAIN CODE
  616.  
  617. local argv = {...}
  618. if argv[1] == "init" then
  619. if fs.exists("/etc/ccpt") then
  620. print("ComuterCraftPackagingTool already initated")
  621. else
  622. print("Installing directories")
  623. fs.makeDir("/etc/")
  624. fs.makeDir("/etc/ccpt")
  625. fs.makeDir("/bin/")
  626. fs.makeDir("/usr/")
  627. fs.makeDir("/tmp/")
  628. fs.makeDir("/var/")
  629. fs.makeDir("/var/log")
  630. fs.makeDir("/opt/")
  631. fs.makeDir("/usr/bin")
  632. fs.makeDir("/usr/lib")
  633. fs.makeDir("/usr/share")
  634. print("Downloading default configuration")
  635. download("/etc/ccpt/sources","http://cc.nativehttp.org/fresh/sources")
  636. download("/etc/ccpt/installed","http://cc.nativehttp.org/fresh/installed")
  637. download("/etc/ccpt/files","http://cc.nativehttp.org/fresh/files")
  638. print("Checking for upgrades")
  639. upgrade()
  640. end
  641. elseif argv[1] == "update" then
  642. print("Updating package list")
  643. update_list()
  644. elseif argv[1] == "install" then
  645. if argv[2] == nil then
  646. print("Usage: ccpk install [name]")
  647. else
  648. install(argv[2])
  649. end
  650. elseif argv[1] == "remove" then
  651. if argv[2] == nil then
  652. print("Usage: ccpk remove [name]")
  653. else
  654. remove(argv[2])
  655. end
  656. elseif argv[1] == "upgrade" then
  657. upgrade()
  658. else
  659. print("Usage:")
  660. print("ccpt init")
  661. print("ccpt install [name]")
  662. print("ccpt remove [name]")
  663. print("ccpt update")
  664. print("ccpt upgrade")
  665.  
  666. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement