Advertisement
magik6000

Untitled

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