View difference between Paste ID: BLXBxMDY and 4LSRnmJ8
SHOW: | | - or go back to the newest paste.
1-
--MPT - Minecraft packaging tool
1+
2-
--Made By magik6k
2+
3-
--do whatever you want, there is only one rule(stolen from zlib license):
3+
4
5-
--1. The origin of this software must not be misrepresented; you must not
5+
6-
--claim that you wrote the original software. If you use this software
6+
7-
--in a product, an acknowledgment in the product documentation would be
7+
8-
--appreciated but is not required.
8+
9-
------
9+
10-
--Of course you can modify the program, then, if you want, you can add your
10+
11-
--name to Credits section below
11+
12-
------
12+
13-
--Credits:
13+
14
			act=""
15
		else
16
			act = act .. text:sub(x,x)
17
			x = x + 1
18
		end
19
	end
20
	if act ~= "" then
21
		rt[#rt+1] = act
22
	end
23
	return rt;
24
end
25
]]--
26
27
function split(text,splitter)
28
	local rt = {}
29
	local act = ""
30
	local x = 1
31
	while x  <= #text do
32
		if text:sub(x,x+#splitter-1) == splitter then
33
			if act ~= "" then
34
        		rt[#rt+1] = act
35
        	end
36
			x = x + #splitter
37
			act=""
38
		else
39
			act = act .. text:sub(x,x)
40
			x = x + 1
41
		end
42
	end
43
	if act ~= "" then
44
		rt[#rt+1] = act
45
	end
46
	return rt;
47
end
48
49
local opencomputers = os.getenv
50
51
local internet = {}
52
local fs = fs
53
local term = term or require("term")
54
local write = term and term.write
55
56
local http = http
57
local shell = shell
58
local root = "/"
59
local verbose = false
60
61
if opencomputers then
62
    root = os.getenv("APTROOT")
63
    if not root then
64
        print("NO APTROOT SET!")
65
        return
66
    end
67
68
    internet = require("internet")
69
    shell = require("shell")
70
    local lfs = require("filesystem")
71
    fs = {}
72
    
73
    for k,v in pairs(lfs) do fs[k]=v end
74
    
75
    fs.delete = lfs.remove
76
    
77
    fs.open = function(...)
78
        --print("fopen:",...)
79
        
80
        local data = ""
81
        local dp = 1
82
        
83
        local args = {...}
84
        if args[2] == "r" then
85
            local th = lfs.open(args[1],"r")
86
            if th then
87
                local left = lfs.size(args[1])
88
                while left > 0 do
89
                    data = data .. th:read(left)
90
                    left = left - (left > 2048 and 2048 or left)
91
                end
92
                th:close()
93
            end
94
        end
95
96
        local h = lfs.open(...)
97
        if not h then return nil end
98
        local hnd = setmetatable({},{
99
                __index = function(t,k)
100
                    return function(...)return h[k](h,...)end
101
                end
102
            })
103
        hnd.writeLine = function(s)
104
            h:write(s.."\n")
105
        end
106
        hnd.readLine = function()
107
            local sbuf= ""
108
            while true do
109
                local c = data:sub(dp,dp)
110
                dp = dp + 1
111
                if #c == 0 then c = nil end
112
                if c == nil then
113
                    if #sbuf < 1 then
114
                        return nil
115
                    end
116
                    return sbuf
117
                end
118
                if c == "\n" then
119
                    return sbuf
120
                end
121
                sbuf = sbuf .. c
122
            end
123
        end
124
        
125
        return hnd
126
    end
127
    
128
    term = require("term")
129
    term.setCursorPos = term.setCursor
130
    term.getCursorPos = term.getCursor
131
    
132
    fs.makeDir = function(f)
133
        local tree = split(f,"/")
134
        local check = "/"
135
        for k,val in pairs(tree) do
136
            check = check .. val
137
            if not fs.exists(check) then
138
                fs.makeDirectory(check)
139
            end
140
            check = check .. "/"
141
        end
142
    end
143
    fs.isDir = fs.isDirectory
144
    
145
    http = {}
146
    http.get = function(url)
147
       
148
        local res = {}
149
        res.data = ""
150
        if url ~= "" then
151
            for line in internet.request(url)do if #res.data < 1 then res.data = line else res.data = res.data .. "\n" .. line end end
152
        else
153
            res.data = nil
154
        end
155
        res.readAll = function()
156
            return res.data
157
        end
158
        res.close = function()end
159
        return res
160
    end
161
end
162
163
local dir = root .. "etc/ccpt/"
164
165
if not http then
166
    if not internet then
167
        error("HTTP API MUST be enabled or internet modem attached to use this program")
168
    end
169
end
170
171
local argv = {...}
172
173
--Pseudo enums
174
175
local validator = {ok = 0, installed = 1, file_conflict = 2}
176
177
---Pre-definitions
178
179
local install = nil
180
local remove = nil
181
local ppa_host = "http://cc.nativehttp.org/ppa/vlist/"
182
183
---UTILITIES
184
185
local downloaded = 0
186
local proc = ""
187
local cp = 0
188
189
local function dstart()
190
    term.clearLine()
191
    print("\n")
192
    term.clearLine()
193
    print("\n")
194
    term.clearLine()
195
    local x,y = term.getCursorPos()
196
    cp = y - 2
197
    
198
    
199
end
200
201
local function dend()
202
    term.setCursorPos(1,cp+3)
203
end
204
205
local function stateP(s)--print(s)
206
    if not verbose then
207
        term.setCursorPos(1,cp)
208
        term.clearLine()
209
        term.write(s)
210
    else    
211
        print(s)
212
    end
213
    
214
end
215
216
local function det1P(s)--print(s)
217
    if not verbose then
218
        term.setCursorPos(1,cp + 1)
219
        term.clearLine()
220
        term.write(s)
221
    else    
222
        print(s)
223
    end
224
   
225
end
226
227
local function det2P(s)
228
    if not verbose then
229
        term.setCursorPos(1,cp + 2)
230
        term.clearLine()
231
        term.write(s)
232
    else    
233
        print(s)
234
    end
235
    
236
end
237
238
local function rState()
239
    stateP("DL:"..tostring(downloaded)..", PR:"..proc)
240
end
241
242
local List = {}
243
function List.new ()
244
	return {first = 0, last = -1}
245
end
246
247
function List.pushleft (list, value)
248
	local first = list.first - 1
249
	list.first = first
250
	list[first] = value
251
end
252
253
function List.pushright (list, value)
254
	local last = list.last + 1
255
	list.last = last
256
	list[last] = value
257
end
258
259
function List.popleft (list)
260
	local first = list.first
261
	if first > list.last then return nil end
262
	local value = list[first]
263
	list[first] = nil
264
	list.first = first + 1
265
	return value
266
end
267
268
function List.popright (list)
269
	local last = list.last
270
	if list.first > last then return nil end
271
	local value = list[last]
272
	list[last] = nil 
273
	list.last = last - 1
274
	return value
275
end
276
277
local function CGetS(file,name)
278
	local _cfg = fs.open(file,"r")
279
	
280
	if not _cfg then
281
		error("Could not open configuration file: "..file)
282
	end
283
	
284
	local x = true;
285
	 
286
	while x do
287
		local line = _cfg.readLine()
288
		if line == nil then
289
			x = false;
290
		else
291
		 
292
			local side = false
293
			local prop = ""
294
			local val = ""
295
			for a=1,#line do
296
				if line:sub(a,a) == '=' then
297
					side = true
298
				elseif side then
299
					val =  val .. line:sub(a,a)
300
				else
301
					prop = prop .. line:sub(a,a)
302
				end
303
			end
304
			
305
			if prop == name then
306
				_cfg.close()
307
				return val
308
			end			
309
		end	 
310
	end
311
	_cfg.close()	
312
end
313
 
314
local function CGetN(file,name)
315
	return tonumber(CGetS(file,name))
316
end
317
318
local function download(file, url)
319
    if file then det2P("get:"..file) else det2P("get:"..url) end
320
	local res = http.get(url)
321
	if res then
322
		if file ~= nil then
323
			fs.delete(file)
324
			fs.makeDir(file)
325
			fs.delete(file)
326
			local fhnd = fs.open(file, "w");
327
			if fhnd then
328
				fhnd.write(res.readAll())
329
				fhnd.close()
330
				downloaded = downloaded + 1
331
				rState()
332
				return res.readAll()
333
			else
334
				res.close()
335
				error("Could not open "..file.." for writing")
336
			end
337
	    else
338
	        rState()
339
	        downloaded = downloaded + 1
340
			return res.readAll()
341
		end
342
		res.close()
343
	else
344
		local rr = 7
345
	    if r then if rr == 1 then return nil end rr = r end
346
		det1P("WARNING:Download failed,  Retry in 5sec")
347
		print("\n",url)
348
		os.sleep(5)
349
		
350
		return download(file,url,rr-1)
351
	end
352
end
353
354
local function downloadfile(file, url)
355
    if file then det2P("ocget:"..file) else det2P("ocget:"..url) end
356
    if not opencomputers then
357
    	local res = http.get(url)
358
    	if res then
359
    		if file ~= nil then
360
    			fs.delete(file)
361
    			fs.makeDir(file)
362
    			fs.delete(file)
363
    			local fhnd = fs.open(file, "w");
364
    			if fhnd then
365
    				fhnd.write(res.readAll())
366
    				fhnd.close()
367
    				downloaded = downloaded + 1
368
    				rState()
369
    				return res.readAll()
370
    			else
371
    				res.close()
372
    				error("Could not open "..file.." for writing")
373
    			end
374
    	    else
375
    	        rState()
376
    	        downloaded = downloaded + 1
377
    			return res.readAll()
378
    		end
379
    		res.close()
380
    	else
381
    		local rr = 7
382
    	    if r then if rr == 1 then return nil end rr = r end
383
    		det1P("WARNING:Download failed,  Retry in 5sec")
384
    		print("\n",url)
385
    		os.sleep(5)
386
    		
387
    		return download(file,url,rr-1)
388
    	end
389
    else
390
        if file ~= nil then
391
			fs.delete(file)
392
			fs.makeDir(file)
393
			fs.delete(file)
394
        end
395
        shell.execute("wget -q -f  "..url.." "..file)--fuck it
396
    end
397
398
end
399
400
local function downloadln(file, url, r)
401
    if file then det2P("get:"..file) else det2P("get:"..url) end
402
	local res = http.get(url)
403
	if res then
404
		if file ~= nil then
405
			fs.delete(file)
406
			fs.makeDir(file)
407
			fs.delete(file)
408
			local fhnd = fs.open(file, "w");
409
			if fhnd then
410
				if opencomputers then fhnd.write(res.readAll())else  end
411
				fhnd.close()
412
				return res.readAll()
413
			else
414
				res.close()
415
				error("Could not open "..file.." for writing")
416
			end
417
		else
418
			return res.readAll()
419
		end
420
		res.close()
421
	else
422
	    local rr = 7
423
	    if r then if rr == 1 then return nil end rr = r end
424
		det1P("WARNING:Download failed,  Retry in 5sec")
425
		print("\n",url)
426
		os.sleep(5)
427
		
428
		return downloadln(file,url,rr-1)
429
	end
430
end
431
432
-----------------------------------------------------------------
433
-----------------------------------------------------------------
434
-----------------------------------------------------------------
435
---Intarnal functions
436
437
local function update_list()
438
	--local sync = CGetS("/etc/ccpt/config","master")
439
	--if sync then 
440
		--download("/etc/ccpt/list",sync)
441
	proc = "Update"
442
	rState()
443
	
444
	local run = true
445
	local exec = List.new()
446
	local num = 0
447
	
448
	if fs.exists(dir.."ppa") then
449
		local sources = fs.open(dir.."ppa","r")	
450
		if not sources then
451
			error("Could not open base file: "..dir.."ppa")
452
		end	
453
		local x = true
454
		while x do 
455
			local line = sources.readLine()
456
			if line == nil then
457
				x = false
458
			else
459
				det1P("PPA:"..line)
460
				List.pushright(exec,{prot = "ccpt", data = download(nil,ppa_host..line)})
461
			end
462
		end
463
		sources.close()
464
	end	
465
	
466
	if fs.exists(dir.."ac") then
467
        local sources = fs.open(dir.."ac","r")	
468
        if not sources then
469
			error("Could not open base file: "..dir.."ac")
470
		end	
471
        local x = true
472
        while x do
473
            local line = sources.readLine()
474
			if line == nil then
475
				x = false
476
			else
477
				det1P("AC:"..line)
478
				List.pushright(exec,{prot = "ac", data = download(nil,line .. "/packages.list"), repo = line})
479
			end
480
        end
481
        
482
        sources.close()
483
	end
484
	
485
	local sources = fs.open(dir.."sources","r")	
486
	if not sources then
487
		error("Could not open base file: "..dir.."sources")
488
	end	
489
	local x = true
490
	while x do 
491
		local line = sources.readLine()
492
		if line == nil or line == "" then
493
			x = false
494
		else
495
			print("List:"..line)
496
			List.pushleft(exec,{prot = "ccpt", data = download(nil,line)})
497
		end
498
	end
499
	sources.close()
500
	
501
	fs.delete(dir.."list")
502
	local fhnd = fs.open(dir.."list", "w");
503
	if fhnd then
504
		while run do
505
			local proc = List.popright(exec)
506
			
507
			if proc then
508
			    if proc.prot == "ccpt" then
509
    				local tline = split(proc.data,"\n")
510
    				for k,val in pairs(tline) do
511
    					local row = split(val,";")
512
    					if row[1] == "p" then
513
    						fhnd.writeLine(val)
514
    						num = num + 1
515
    					elseif row[1] == "s" then
516
    						det1P("List:"..row[2])
517
    						local dl = download(nil,row[2])
518
    						if dl then
519
    						List.pushright(exec,{prot = "ccpt", data = dl})
520
    						end
521
    					end
522
                    end
523
			    elseif proc.prot == "ac" then
524
			        local tline = split(proc.data,"\n")
525
			        for k,val in pairs(tline) do
526
                        local row = split(val,"::")
527
                        fhnd.writeLine("a;" .. row[1] .. ";" .. row[2] .. ";" .. proc.repo .. "/" .. row[1])
528
    					num = num + 1
529
		            end
530
			    end
531
			else
532
				run = false
533
			end
534
		end
535
		fhnd.close()
536
	else
537
		error("Could not open "..file.." for writing")
538
	end		
539
	det2P("Packages defined: "..tostring(num))
540
end
541
542
local function register(name,version,header)
543
	
544
	local reg = nil
545
	
546
	if fs.exists(dir.."installed") then
547
		reg = fs.open(dir.."installed","a")
548
	else
549
		reg = fs.open(dir.."installed","w")
550
	end
551
	
552
	if reg then
553
		reg.writeLine(name..";"..tostring(version))
554
		reg.close()
555
	else
556
		error("Critical:Could not register installation")
557
	end
558
	
559
	local freg = nil
560
	
561
	if fs.exists(dir.."files") then
562
		freg = fs.open(dir.."files","a")
563
	else
564
		freg = fs.open(dir.."files","w")
565
	end
566
	
567
	if freg then
568
		local lhead = split(header,"\n")
569
		local x = 1
570
		for x = 1, #lhead do
571
			if split(lhead[x],";")[1] == "f" then
572
				freg.writeLine(name..";"..split(lhead[x],";")[2])
573
			elseif split(lhead[x],";")[1] == "u" then
574
				freg.writeLine(name..";"..split(lhead[x],";")[2])
575
			end
576
		end
577
		freg.close()		
578
	else
579
		error("Error:Could not register files")
580
	end
581
	
582
end
583
584
local database = nil
585
586
local function load_database()
587
    if not database then
588
        database = {}
589
        local base = fs.open(dir.."list","r")
590
    	
591
    	if not base then
592
    		error("Could not open base file: "..dir.."list")
593
    	end
594
        
595
    	local x = true;
596
    	while x do 
597
            local line = base.readLine()
598
    		if line == nil then
599
    			x = false;
600
    		else
601
		        database[#database+1] = line
602
		    end
603
        end
604
        base.close()
605
    end
606
end
607
608
local function base_find(name)
609
    load_database()
610
611
	for k,line in ipairs(database) do
612
		local entry = split(line,";")
613
		if entry[1] == "p" then
614
			if entry[2] == name then
615
				local ret = {type="ccpt",name=entry[2],url=entry[4],version=tonumber(entry[3])}
616
				return ret
617
			end
618
        elseif entry[1] == "a" then
619
            if entry[2] == name then
620
                local ret = {type="ac",name=entry[2],url=entry[4],version=tonumber(entry[3])}
621
				return ret
622
            end
623
	    end
624
	end
625
626
end
627
628
local function validate(pname,header)
629
	local instbase = fs.open(dir.."installed","r")
630
	if instbase then
631
		local x = true
632
		while x do
633
			local tline = instbase.readLine()
634
			if tline == nil then
635
				x = false
636
			else
637
				if pname == split(tline,";")[1] then
638
					instbase.close()
639
					return validator.installed
640
				end
641
			end
642
		end
643
		instbase.close()
644
	end
645
	--local filebase = fs.open("/etc/ccpt/files","r")
646
	if header then
647
		lhead = split(header,"\n")
648
		local x = 1
649
		for x = 1, #lhead do
650
			if split(lhead[x],";")[1] == "f" then
651
				if fs.exists(root .. split(lhead[x],";")[2]) then
652
					stateP("[info]Conflict: "..split(lhead[x],";")[2])
653
                    if not opencomuters then
654
                        return validator.file_conflict
655
					end
656
				end
657
			end
658
		end
659
	end
660
	
661
	return validator.ok
662
end
663
664
local function download_files(url,header)
665
	local lhead = split(header,"\n")
666
	local x = 1
667
	for x = 1, #lhead do
668
		if split(lhead[x],";")[1] == "f" then
669
		    if opencomputers then
670
                downloadfile(root:sub(1,#root-1)..split(lhead[x],";")[2],url..split(lhead[x],";")[2])
671
            else
672
			    download(split(lhead[x],";")[2],url..split(lhead[x],";")[2])
673
			end
674
		end
675
		if split(lhead[x],";")[1] == "u" then
676
		    if opencomputers then
677
                downloadfile(root:sub(1,#root-1)..split(lhead[x],";")[2],split(lhead[x],";")[3])
678
            else
679
			    download(split(lhead[x],";")[2],split(lhead[x],";")[3])
680
		    end
681
		end
682
	end
683
end
684
685
local function run_scripts(url,header)
686
	local lhead = split(header,"\n")
687
	local x = 1
688
	for x = 1, #lhead do
689
		if split(lhead[x],";")[1] == "s" then
690
			download("/tmp/ccptpirs",url..split(lhead[x],";")[2])
691
			shell.run("/tmp/ccptpirs")
692
			fs.delete("/tmp/ccptpirs")
693
		end
694
	end
695
end
696
697
local function dep_register(what,onwhat)
698
	local reg = nil
699
	
700
	if fs.exists(dir.."dtree") then
701
		reg = fs.open(dir.."dtree","a")
702
	else
703
		reg = fs.open(dir.."dtree","w")
704
	end
705
	
706
	if reg then
707
		reg.writeLine(what..";"..onwhat)
708
		reg.close()
709
	else
710
		error("Critical:Could not register dependencies")
711
	end
712
end
713
714
local function dependencies(header,package)
715
	local lhead = split(header,"\n")
716
	local x = 1
717
	for x = 1, #lhead do
718
		if split(lhead[x],";")[1] == "d" then
719
			install(split(lhead[x],";")[2])
720
			dep_register(package,split(lhead[x],";")[2])
721
		end
722
	end
723
end
724
725
local function filelist(package)
726
	local freg = fs.open(dir.."files","r")
727
	if freg then
728
		local ret = {}
729
		local x = true
730
		while x do
731
			local tline = freg.readLine()
732
			if tline == nil then
733
				x = false
734
			else
735
				row = split(tline,";")
736
				if row[1] == package then
737
					ret[#ret+1] = row[2]
738
				end
739
			end
740
		end
741
		freg.close()
742
		return ret
743
	end
744
end
745
746
local function get_deps(package)
747
	local reg = fs.open(dir.."dtree","r")
748
	if reg then
749
		local ret = {}
750
		local x = true
751
		while x do
752
			local tline = reg.readLine()
753
			if tline == nil then
754
				x = false
755
			else
756
				local row = split(tline,";")
757
				if row[1] == package then
758
					ret[#ret+1] = row[2]
759
				end
760
			end
761
		end
762
		reg.close()
763
		return ret
764
	end
765
end
766
767
local function get_refcount(package)
768
	local reg = fs.open(dir.."dtree","r")
769
	local ret = 0
770
	if reg then
771
		local x = true
772
		while x do
773
			local tline = reg.readLine()
774
			if tline == nil then
775
				x = false
776
			else
777
				local row = split(tline,";")
778
				if row[2] == package then
779
					ret = ret + 1
780
				end
781
			end
782
		end
783
		reg.close()
784
	end
785
	return ret
786
end
787
788
local function get_unused(list)
789
	local x = 1
790
	local ret = {}
791
	if list then
792
		for x = 1, #list do
793
			if get_refcount(list[x]) == 0 then
794
				ret[#ret + 1] = list[x]
795
			end
796
		end
797
	end
798
	return ret
799
end
800
801
local function unregister(package)
802
	local reg = fs.open(dir.."installed","r")
803
	local newbase = {}
804
	if reg then
805
		local x = true
806
		while x do
807
			local tline = reg.readLine()
808
			if tline == nil then
809
				x = false
810
			else
811
				local row = split(tline,";")
812
				if row[1] ~= package then
813
					newbase[#newbase+1] = tline
814
				end
815
			end
816
		end
817
		reg.close()
818
	end
819
	if fs.exists(dir.."installed") then fs.delete(dir.."installed")end
820
	reg = fs.open(dir.."installed","w")
821
	if reg then
822
		local x = 1
823
		for x = 1, #newbase do
824
			reg.writeLine(newbase[x])
825
		end
826
		reg.close()
827
	else
828
		error("CRITICAL: Could not open database for writing")
829
	end
830
	reg = fs.open(dir.."files","r")
831
	newbase = {}
832
	if reg then
833
		local x = true
834
		while x do
835
			local tline = reg.readLine()
836
			if tline == nil then
837
				x = false
838
			else
839
				local row = split(tline,";")
840
				if row[1] ~= package then
841
					newbase[#newbase+1] = tline
842
				end
843
			end
844
		end
845
		reg.close()
846
	end
847
	fs.delete(dir.."files")
848
	reg = fs.open(dir.."files","w")
849
	if reg then
850
		local x = 1
851
		for x = 1, #newbase do
852
			reg.writeLine(newbase[x])
853
		end
854
		reg.close()
855
	else
856
		error("CRITICAL: Could not open file base for writing")
857
	end
858
end
859
860
local function deptree_unregister(package)
861
	local reg = fs.open(dir.."dtree","r")
862
	local newbase = {}
863
	if reg then
864
		local x = true
865
		while x do
866
			local tline = reg.readLine()
867
			if tline == nil then
868
				x = false
869
			else
870
				local row = split(tline,";")
871
				if row[1] ~= package then
872
					newbase[#newbase+1] = tline
873
				end
874
			end
875
		end
876
		reg.close()
877
	end
878
	fs.delete(dir.."dtree")
879
	reg = fs.open(dir.."dtree","w")
880
	if reg then
881
		local x = 1
882
		for x = 1, #newbase do
883
			reg.writeLine(newbase[x])
884
		end
885
		reg.close()
886
	else
887
		error("CRITICAL: Could not open dtree database for writing")
888
	end
889
end
890
891
local function get_installed()
892
	local reg = fs.open(dir.."installed","r")
893
	local ret = {}
894
	if reg then
895
		local x = true
896
		while x do
897
			local tline = reg.readLine()
898
			if tline == nil then
899
				x = false
900
			else
901
				local row = split(tline,";")
902
				ret[#ret + 1] = {name = row[1], version = tonumber(row[2])}
903
			end
904
		end
905
		reg.close()
906
	end
907
	return ret
908
end
909
910
local function list_upgardable()
911
	local installed = get_installed()
912
	local ret = {}
913
	for k,val in pairs(installed) do
914
	    det1P("Searching package "..val.name)
915
		local bpk = base_find(val.name)
916
		if bpk then
917
			if val.version ~= bpk.version then
918
				ret[#ret + 1] = val.name
919
			end
920
		else
921
			det1P("[Warning]Package "..val.name.." not found in database")
922
			os.sleep(0.5)
923
		end
924
	end
925
	return ret
926
end
927
928
local function ac_conv_header(head,url)
929
    local ret = ""
930
    local tline = split(head,"\n")
931
    for k,val in pairs(tline) do
932
        local pt = val:find(":")
933
        if pt ~= nil then
934
            local t = val:sub(1,pt-1)
935
            if t == "Executable" then
936
                local r = val:sub(pt+2,#val)
937
                local fr = val:find(" => ")
938
                if fr ~= nil then
939
                    local rfn = val:sub(pt+2,fr-1)
940
                    local lfn = val:sub(fr + 4, #val)
941
                    if lfn:sub(#lfn,#lfn) ~= "/" then
942
                        ret = ret .. "\nu;/bin/"..lfn..";"..url.."/bin/"..rfn..".lua"
943
                    end
944
                else
945
                    local fn = r
946
                    if fn:sub(#fn,#fn) ~= "/" then
947
                        ret = ret .. "\nu;/bin/" .. fn .. ";" .. url .. "/bin/" .. fn .. ".lua"
948
                    end
949
                end
950
            elseif t == "Library" then
951
                local r = val:sub(pt+2,#val)
952
                local fr = val:find(" => ")
953
                if fr ~= nil then
954
                    local rfn = val:sub(pt+2,fr-1)
955
                    local lfn = val:sub(fr + 4, #val)
956
                    if lfn:sub(#lfn,#lfn) ~= "/" then
957
                        ret = ret .. "\nu;/lib/"..lfn..";"..url.."/lib/"..rfn..".lua"
958
                    end
959
                else
960
                    local fn = r
961
                    if fn:sub(#fn,#fn) ~= "/" then
962
                        ret = ret .. "\nu;/lib/" .. fn .. ";" .. url .. "/lib/" .. fn .. ".lua"
963
                    end
964
                end
965
            elseif t == "Startup" then
966
                local r = val:sub(pt+2,#val)
967
                local fr = val:find(" => ")
968
                if fr ~= nil then
969
                    local rfn = val:sub(pt+2,fr-1)
970
                    local lfn = val:sub(fr + 4, #val)
971
                    if lfn:sub(#lfn,#lfn) ~= "/" then
972
                        ret = ret .. "\nu;/etc/ac.boot/"..lfn..";"..url.."/startup/"..rfn..".lua"
973
                    end
974
                else
975
                    local fn = r
976
                    if fn:sub(#fn,#fn) ~= "/" then
977
                        ret = ret .. "\nu;/etc/ac.boot/" .. fn .. ";" .. url .. "/startup/" .. fn .. ".lua"
978
                    end
979
                end
980
            elseif t == "Dependency" then
981
                local r = val:sub(pt+2,#val)
982
                ret = ret .. "\nd;" .. r
983
            end
984
            
985
        end
986
    end
987
    return ret
988
end
989
990
991
local function ppaadd(name)
992
    proc = "ppa "..name
993
    rState()
994
	local list = {}
995
	local fh={}
996
	if fs.exists(dir.."ppa") then
997
		local reg = fs.open(dir.."ppa","r")
998
		if reg then
999
			local x = true
1000
			while x do
1001
    			local ln = reg.readLine()
1002
    			if ln == nil then
1003
    				x = false
1004
    			else
1005
    				if ln == name then
1006
    					print("PPA added")
1007
    					reg.close()
1008
    					return
1009
    				end
1010
    				list[#list + 1] = ln
1011
    			end
1012
			end
1013
			reg.close()
1014
		end
1015
	end
1016
	list[#list + 1] = name
1017
	local reg = fs.open(dir.."ppa","w")
1018
	if reg then
1019
		for k,v in pairs(list) do
1020
			reg.writeLine(v)
1021
		end
1022
    reg.close()
1023
    end
1024
	update_list()
1025
	det1P("PPA added!")
1026
end
1027
1028
local function pparm(name)
1029
    proc = "rm ppa "..name
1030
    rState()
1031
    local list = {}
1032
    if fs.exists(dir.."ppa") then
1033
        local reg = fs.open(dir.."ppa","r")
1034
		if reg then
1035
            local x = true
1036
			while x do
1037
                local ln = reg.readLine()
1038
                if ln == nil then
1039
                    x = false
1040
                else
1041
                    if ln ~= name then
1042
                        list[#list + 1] = ln
1043
                    end
1044
                end
1045
			end
1046
            reg.close()
1047
	    end
1048
    end
1049
    local reg = fs.open(dir.."ppa","w")
1050
	if reg then
1051
		for k,v in pairs(list) do
1052
			reg.writeLine(v)
1053
		end
1054
    reg.close()
1055
    end
1056
    update_list()
1057
	det1P("PPA removed")
1058
end
1059
1060
local function acadd(url)
1061
    proc = "ac "..url
1062
    rState()
1063
	local list = {}
1064
	local fh={}
1065
	if fs.exists(dir.."ac") then
1066
		local reg = fs.open(dir.."ac","r")
1067
		if reg then
1068
			local x = true
1069
			while x do
1070
			local ln = reg.readLine()
1071
			if ln == nil then
1072
				x = false
1073
			else
1074
				if ln == url then
1075
					print("ac-get repo added")
1076
					reg.close()
1077
					return
1078
				end
1079
				list[#list + 1] = ln
1080
			end
1081
			end
1082
			reg.close()
1083
		end
1084
	end
1085
	list[#list + 1] = url
1086
	local reg = fs.open(dir.."ac","w")
1087
	if reg then
1088
		for k,v in pairs(list) do
1089
			reg.writeLine(v)
1090
		end
1091
	end
1092
	reg.close()
1093
	update_list()
1094
	det1P("ac-get repo added")
1095
end
1096
1097
local function acrm(name)
1098
    proc = "rm ac "..name
1099
    rState()
1100
    local list = {}
1101
    if fs.exists(dir.."ac") then
1102
        local reg = fs.open(dir.."ac","r")
1103
		if reg then
1104
            local x = true
1105
			while x do
1106
                local ln = reg.readLine()
1107
                if ln == nil then
1108
                    x = false
1109
                else
1110
                    if ln ~= name then
1111
                        list[#list + 1] = ln
1112
                    end
1113
                end
1114
			end
1115
            reg.close()
1116
	    end
1117
    end
1118
    local reg = fs.open(dir.."ac","w")
1119
	if reg then
1120
		for k,v in pairs(list) do
1121
			reg.writeLine(v)
1122
		end
1123
    reg.close()
1124
    end
1125
    update_list()
1126
	det1P("ac-get repo removed")
1127
end
1128
1129
install = function (package)
1130
    proc = "ins "..package
1131
    rState()
1132
	--det1P("Reading Database")
1133
	local entry = base_find(package)
1134
	if entry then
1135
	    if entry.type == "ccpt" then
1136
    		det1P("Downloading package header")
1137
    		local header = download(nil, entry.url..entry.name.."/index")
1138
    		det1P("Processing")
1139
    		local vres = validate(entry.name,header)
1140
    		if vres == validator.ok then
1141
    			--det1P("Checking dependencies")
1142
    			dependencies(header,package)
1143
    			det1P("Downloading files")
1144
    			download_files(entry.url..entry.name,header)
1145
    			det1P("Setting up")
1146
    			register(package,entry.version,header)
1147
    			run_scripts(entry.url..entry.name,header)
1148
    		elseif vres == validator.installed then
1149
    			det1P("Package already installed")
1150
    		else
1151
    			det1P("File conflict detected!")
1152
    		end
1153
        elseif entry.type == "ac" then
1154
            det1P("Downloading package header")
1155
            local header = download(nil, entry.url.."/details.pkg")
1156
            det1P("Processing")
1157
            local chead = ac_conv_header(header,entry.url)
1158
            
1159
            local vres = validate(entry.name,chead)
1160
    		if vres == validator.ok then
1161
    			--det1P("Checking dependencies")
1162
    			dependencies(chead,package)
1163
    			det1P("Downloading files")
1164
    			download_files(entry.url,chead)
1165
    			det1P("Setting up")
1166
    			register(package,entry.version,chead)
1167
    			--run_scripts(entry.url,chead)
1168
    		elseif vres == validator.installed then
1169
    			det1P("Package already installed")
1170
    		else
1171
    			det1P("File conflict detected!")
1172
    		end
1173
    		
1174
		end
1175
	else
1176
		det1P("Package not found!")
1177
	end
1178
end
1179
1180
remove = function (package,nrdeps)
1181
    proc = "rm "..package
1182
    rState()
1183
	--det1P("Reading database")
1184
	if validate(package,nil) == validator.installed then
1185
		det1P("Removing files")
1186
		local list = filelist(package)
1187
		local removed = 0
1188
		if list then
1189
			local x = 1
1190
			for x = 1, #list do
1191
				fs.delete(root..list[x])
1192
				det2P("Remove "..list[x])
1193
				removed = removed + 1
1194
			end
1195
		end
1196
		det1P(tostring(removed).." files removed")
1197
		--det1P("Removing from database")
1198
		unregister(package)
1199
		--det1P("Removing unused dependencies")
1200
		if not nrdeps then
1201
    		local deps = get_deps(package)
1202
    		deptree_unregister(package)
1203
    		local remlist = get_unused(deps)
1204
    		for k,val in pairs(remlist) do
1205
    			remove(val)
1206
    		end
1207
		end
1208
	else
1209
		det1P("Package not installed")
1210
	end
1211
end
1212
1213
local function upgrade()
1214
    dstart()rState()
1215
    
1216
    proc = "Upgrade"
1217
    rState()
1218
	det1P("Updating package list")
1219
	update_list()
1220
	det1P("Upgrading packages")
1221
	local todo = list_upgardable()
1222
	det1P("Upgrading "..tostring(#todo).." packages")
1223
	for k,val in pairs(todo) do
1224
		remove(val,true)
1225
		install(val)
1226
	end
1227
	det1P(tostring(#todo).." Packages upgraded")
1228
	dend()
1229
	print("Upgraded: ")
1230
	for k,v in pairs(todo) do
1231
        write(v.." ")
1232
    end
1233
    --print("\n")
1234
    --term.clearLine()
1235
    --local uu,cy=term.getCursorPos()
1236
    --term.setCursorPos(1,cy)
1237
end
1238
1239
local function ppa()
1240
	if argv[3] == nil  then
1241
		print("Usage:")
1242
		print("ccpt ppa add [name]")
1243
		print("ccpt ppa remove [name]")
1244
	else
1245
		if argv[2] == "add" then
1246
			ppaadd(argv[3])
1247
        elseif argv[2] == "remove" then
1248
            pparm(argv[3])
1249
		else
1250
		    print("Usage:")
1251
    		print("ccpt ppa add [name]")
1252
    		print("ccpt ppa remove [name]")
1253
		end
1254
	end
1255
end
1256
1257
local function ac()
1258
    if argv[3] == nil  then
1259
		print("Usage:")
1260
		print("ccpt ac add [name]")
1261
		print("ccpt ac remove [name]")
1262
	else
1263
		if argv[2] == "add" then
1264
			acadd(argv[3])
1265
		elseif argv[2] == "remove" then
1266
            acrm(argv[3])
1267
		else
1268
		    print("Usage:")
1269
    		print("ccpt ac add [name]")
1270
    		print("ccpt ac remove [name]")
1271
		end
1272
	end
1273
end
1274
1275
local function upck()
1276
    if goroutine then
1277
        rStat = function()end
1278
        stateP = function()end
1279
        det1P = function()end
1280
        det2P = function()end
1281
        
1282
        goroutine.spawnBackground("ccptUck",function()
1283
                update_list()
1284
                os.queueEvent("cptupg")
1285
            end)
1286
        local t1 = os.startTimer(1)
1287
        local t2 = os.startTimer(4)
1288
        while true do
1289
            e = {os.pullEvent()}
1290
            if e[1] == "cptupg" then
1291
                local x,y = term.getCursorPos()
1292
                term.clearLine()
1293
                term.setCursorPos(1,y)
1294
                print("[*]MPT: "..tostring(#list_upgardable()).." Upgradable packages")
1295
                return
1296
            elseif e[1] == "timer" then
1297
                if e[2] == t1 then
1298
                    write("[*]MPT: Checking for upgrades")
1299
                elseif e[2] == t2 then
1300
                    local x,y = term.getCursorPos()
1301
                    term.clearLine()
1302
                    term.setCursorPos(1,y)
1303
                    print("[*]MPT: Timed out")
1304
                    goroutine.kill("ccptUck")
1305
                    return
1306
                end
1307
            end
1308
        end
1309
    end
1310
end
1311
1312
---MAIN CODE
1313
1314
1315
1316
1317
if     argv[1] == "init"   then
1318
	if fs.exists(dir) then
1319
		print("ComuterCraftPackagingTool already initated")
1320
	else
1321
		print("Installing directories")
1322
		fs.makeDir("/etc/")
1323
		fs.makeDir(dir)
1324
1325
		print("Downloading default configuration")
1326
		downloadln(dir.."sources","http://cc.nativehttp.org/fresh/sources")
1327
		downloadln(dir.."installed","http://cc.nativehttp.org/fresh/installed")
1328
		downloadln(dir.."files","http://cc.nativehttp.org/fresh/files")
1329
		print("Checking for upgrades")
1330
		upgrade()
1331
	end
1332
elseif argv[1] == "update" then
1333
    dstart()rState()
1334
	print("Updating package list")
1335
	update_list()
1336
	dend()
1337
	print("\n")
1338
elseif argv[1] == "install" then
1339
    dstart()rState()
1340
	if argv[2] == nil then
1341
		print("Usage: ccpt install [name]")
1342
		dend()
1343
		print("\n")
1344
	else
1345
		install(argv[2])
1346
        dend()
1347
        print("\n")
1348
	end
1349
elseif argv[1] == "remove" then
1350
    dstart()rState()
1351
	if argv[2] == nil then
1352
		print("Usage: ccpt remove [name]")
1353
		dend()
1354
		print("\n")
1355
	else
1356
		remove(argv[2])
1357
		dend()
1358
		print("\n")
1359
	end
1360
elseif argv[1] == "upgrade" then
1361
	upgrade()
1362
	print("\n")
1363
elseif argv[1] == "ppa" then
1364
    dstart()rState()
1365
	ppa()
1366
	dend()
1367
	print("\n")
1368
elseif argv[1] == "ac" then
1369
    dstart()rState()
1370
	ac()
1371
	dend()
1372
	print("\n")
1373
elseif argv[1] == "upck" then --update check on startup
1374
    upck()
1375
    print("\n")
1376
elseif argv[1] == "api" then
1377
    
1378
else
1379
	print("Usage:")
1380
	print("apt init")
1381
	print("apt install [name]")
1382
	print("apt remove [name]")
1383
	print("apt update")
1384
	print("apt upgrade")
1385
	print("apt ppa")
1386
	print("apt ac")
1387
end
1388
1389
1390
--API
1391
1392
if _G.ccpt then
1393
	_G.ccpt = nil
1394
end
1395
_G.ccpt = {}
1396
1397
_G.ccpt.update = update_list
1398
_G.ccpt.upgrade = upgrade
1399
_G.ccpt.install = install
1400
_G.ccpt.remove = remove
1401
1402
_G.ccpt.ppa = {}
1403
_G.ccpt.ppa.add = ppaadd
1404
_G.ccpt.ppa.remove = pparm
1405
1406
_G.ccpt.ac = {}
1407
_G.ccpt.ac.add = acadd
1408
_G.ccpt.ac.remove = acrm
1409
1410
1411
_G.mpt = _G.ccpt