-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgen-disk.py
More file actions
150 lines (125 loc) · 3.96 KB
/
gen-disk.py
File metadata and controls
150 lines (125 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/usr/bin/python
#
# usage: gen-disk.py input output.img
#
# see comments in disk1.in for file format
import sys
import diskfmt as fs
import random as rnd
quiet = False
if sys.argv[1] == '-q':
quiet = True
sys.argv.pop(1)
chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
class file(object):
def __init__(self, fields):
inum,self.name,self.uid,self.gid,self.mode,self.ctime,self.mtime,size,blocks = fields
self.inum = int(inum)
self.size = int(size)
self.blocks = list(map(int, blocks.split(',')))
def inode(self):
i = fs.inode()
i.uid, i.gid, i.mode = self.uid, self.gid, self.mode
i.ctime, i.mtime, i.size = self.ctime, self.mtime, self.size
for j in range(len(self.blocks)):
i.ptrs[j] = self.blocks[j]
return bytearray(i)
def block(self,offset):
if not quiet:
print("block", self.name, offset)
# rnd.seed(hash(self.name) + offset)
rnd.seed(self.inum *1000 + offset)
val = ''
for i in range(4096):
n = rnd.randint(0,50)
val = val + chars[n]
return bytearray(val, 'ascii')
class dir(object):
def __init__(self, fields):
self.inum = 0
inum,self.name,self.uid,self.gid,self.mode,self.ctime,self.mtime,size,blocks = fields[0:9]
self.inum = int(inum)
self.size = int(size)
self.blocks = list(map(int, blocks.split(',')))
entries = fields[9:]
self.entries = []
for e in fields[9:]:
if e[0] == '-':
self.entries.append([False, e[1:], 0])
# print(e[1:], 0)
else:
name,inum = e.split(',')
self.entries.append([True, name, int(inum)])
# print(name, int(inum))
def inode(self):
i = fs.inode()
i.uid, i.gid, i.mode = self.uid, self.gid, self.mode
i.ctime, i.mtime, i.size = self.ctime, self.mtime, self.size
for j in range(len(self.blocks)):
i.ptrs[j] = self.blocks[j]
return bytearray(i)
# dirent is 32 bytes, 128 per block
def block(self,offset):
data = bytearray(4096)
de = fs.dirent()
j = 0
for i in range(offset*128, min(len(self.entries), (offset+1)*128)):
val,name,num = self.entries[i]
de.valid, de.inode, de.name = val, num, name.encode('ascii')
data[j:j+32] = bytearray(de)
j += 32
return data
syms = dict()
files = []
dirs = []
nblocks = 0
magic = 0x30303635
for line in open(sys.argv[1],'r'):
fields = line.split()
if line[0] == '#' or len(fields) == 0:
continue
if line[0] == '$':
syms[fields[0]] = int(fields[1],0)
continue
if fields[0] == 'size':
nblocks = int(fields[1])
continue
for i in range(len(fields)):
if fields[i][0] == '$':
fields[i] = syms[fields[i]]
if fields[0] == 'file':
files.append(file(fields[1:]))
if fields[0] == 'dir':
dirs.append(dir(fields[1:]))
blockmap = fs.bitmap()
blockmap.set(0,True) # superblock
blockmap.set(1,True) # bitmap
blocks = [None] * 400
for f in files + dirs:
blocks[f.inum] = [f]
blockmap.set(f.inum, True)
i = 0
for b in f.blocks:
if blockmap.get(b):
print('ERROR: double counted', b)
blockmap.set(b, True)
blocks[b] = [f,i]
i += 1
sb = fs.super()
sb.magic, sb.disk_sz = magic, nblocks
zeros = bytearray(4096)
fp = open(sys.argv[2], 'wb')
fp.write(bytearray(sb))
fp.write(bytearray(blockmap))
for i in range(2,nblocks):
if not blocks[i]:
fp.write(zeros)
elif len(blocks[i]) == 1:
filedir = blocks[i][0]
fp.write(filedir.inode())
else:
item,offset = blocks[i]
if not quiet:
print('item ', item.name, ' offset', offset)
fp.write(item.block(offset))
fp.close()