-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcsefsck.repy
488 lines (368 loc) · 15.1 KB
/
csefsck.repy
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
"""
Author: Khagay Nagdimov
Professor and Class: Katz, CS-3224 (Introduction to Operating Systems)
This file will perform a check on the file system. Please note that the statements are written in repy v1 and NOT repy v2, this distinction is important because the functions used between the two are DIFFERENT.
When interpreting this file, make sure the blocks of the filesystem are in directory that you are currently working in.
If you are using the precursor to this file, csefsck.mix, to compile this code, enter in the command-line interpreter:
"python repypp.py csefsck.mix csefsck.repy"
Then to interpret the csefsck.repy file enter in the command-line interpreter:
"python repy.py restrictions.test csefsck.repy"
The repypp.py, repy.py, restrictions.test should be in the seattle_repy folder, which is located in the seattle folder.
However if you are using the csefsck.repy file, enter in the command-line interpreter:
"python repy.py restrictions.test csefsck.repy"
The main functions of this file are towards the bottom
"""
#begin include serialize.repy
"""
Author: Justin Cappos
Start date: October 9th, 2009
Purpose: A simple library that serializes and deserializes built-in repy types.
This includes strings, integers, floats, booleans, None, complex, tuples,
lists, sets, frozensets, and dictionaries.
There are no plans for including objects.
Note: that all items are treated as separate references. This means things
like 'a = []; a.append(a)' will result in an infinite loop. If you have
'b = []; c = (b,b)' then 'c[0] is c[1]' is True. After deserialization
'c[0] is c[1]' is False.
I can add support or detection of this if desired.
"""
# The basic idea is simple. Say the type (a character) followed by the
# type specific data. This is adequate for simple types
# that do not contain other types. Types that contain other types, have
# a length indicator and then the underlying items listed sequentially.
# For a dict, this is key1value1key2value2.
def serialize_serializedata(data):
"""
<Purpose>
Convert a data item of any type into a string such that we can
deserialize it later.
<Arguments>
data: the thing to seriailize. Can be of essentially any type except
objects.
<Exceptions>
TypeError if the type of 'data' isn't allowed
<Side Effects>
None.
<Returns>
A string suitable for deserialization.
"""
# this is essentially one huge case statement...
# None
if type(data) == type(None):
return 'N'
# Boolean
elif type(data) == type(True):
if data == True:
return 'BT'
else:
return 'BF'
# Integer / Long
elif type(data) is int or type(data) is long:
datastr = str(data)
return 'I'+datastr
# Float
elif type(data) is float:
datastr = str(data)
return 'F'+datastr
# Complex
elif type(data) is complex:
datastr = str(data)
if datastr[0] == '(' and datastr[-1] == ')':
datastr = datastr[1:-1]
return 'C'+datastr
# String
elif type(data) is str:
return 'S'+data
# List or tuple or set or frozenset
elif type(data) is list or type(data) is tuple or type(data) is set or type(data) is frozenset:
# the only impact is the first letter...
if type(data) is list:
mystr = 'L'
elif type(data) is tuple:
mystr = 'T'
elif type(data) is set:
mystr = 's'
elif type(data) is frozenset:
mystr = 'f'
else:
raise Exception("InternalError: not a known type after checking")
for item in data:
thisitem = serialize_serializedata(item)
# Append the length of the item, plus ':', plus the item. 1 -> '2:I1'
mystr = mystr + str(len(thisitem))+":"+thisitem
mystr = mystr + '0:'
return mystr
# dict
elif type(data) is dict:
mystr = 'D'
keysstr = serialize_serializedata(data.keys())
# Append the length of the list, plus ':', plus the list.
mystr = mystr + str(len(keysstr))+":"+keysstr
# just plop the values on the end.
valuestr = serialize_serializedata(data.values())
mystr = mystr + valuestr
return mystr
# Unknown!!!
else:
raise TypeError("Unknown type '"+str(type(data))+"' for data :"+str(data))
def serialize_deserializedata(datastr):
"""
<Purpose>
Convert a serialized data string back into its original types.
<Arguments>
datastr: the string to deseriailize.
<Exceptions>
ValueError if the string is corrupted
TypeError if the type of 'data' isn't allowed
<Side Effects>
None.
<Returns>
Items of the original type
"""
if type(datastr) != str:
raise TypeError("Cannot deserialize non-string of type '"+str(type(datastr))+"'")
typeindicator = datastr[0]
restofstring = datastr[1:]
# this is essentially one huge case statement...
# None
if typeindicator == 'N':
if restofstring != '':
raise ValueError("Malformed None string '"+restofstring+"'")
return None
# Boolean
elif typeindicator == 'B':
if restofstring == 'T':
return True
elif restofstring == 'F':
return False
raise ValueError("Malformed Boolean string '"+restofstring+"'")
# Integer / Long
elif typeindicator == 'I':
try:
return int(restofstring)
except ValueError:
raise ValueError("Malformed Integer string '"+restofstring+"'")
# Float
elif typeindicator == 'F':
try:
return float(restofstring)
except ValueError:
raise ValueError("Malformed Float string '"+restofstring+"'")
# Float
elif typeindicator == 'C':
try:
return complex(restofstring)
except ValueError:
raise ValueError("Malformed Complex string '"+restofstring+"'")
# String
elif typeindicator == 'S':
return restofstring
# List / Tuple / set / frozenset / dict
elif typeindicator == 'L' or typeindicator == 'T' or typeindicator == 's' or typeindicator == 'f':
# We'll split this and keep adding items to the list. At the end, we'll
# convert it to the right type
thislist = []
data = restofstring
# We'll use '0:' as our 'end separator'
while data != '0:':
lengthstr, restofdata = data.split(':', 1)
length = int(lengthstr)
# get this item, convert to a string, append to the list.
thisitemdata = restofdata[:length]
thisitem = serialize_deserializedata(thisitemdata)
thislist.append(thisitem)
# Now toss away the part we parsed.
data = restofdata[length:]
if typeindicator == 'L':
return thislist
elif typeindicator == 'T':
return tuple(thislist)
elif typeindicator == 's':
return set(thislist)
elif typeindicator == 'f':
return frozenset(thislist)
else:
raise Exception("InternalError: not a known type after checking")
elif typeindicator == 'D':
lengthstr, restofdata = restofstring.split(':', 1)
length = int(lengthstr)
# get this item, convert to a string, append to the list.
keysdata = restofdata[:length]
keys = serialize_deserializedata(keysdata)
# The rest should be the values list.
values = serialize_deserializedata(restofdata[length:])
if type(keys) != list or type(values) != list or len(keys) != len(values):
raise ValueError("Malformed Dict string '"+restofstring+"'")
thisdict = {}
for position in xrange(len(keys)):
thisdict[keys[position]] = values[position]
return thisdict
# Unknown!!!
else:
raise ValueError("Unknown typeindicator '"+str(typeindicator)+"' for data :"+str(restofstring))
#end include serialize.repy
def csefsck():
checkId()
checkTimes()
checkFreeBlockList()
validFreeBlockList = checkFilenameToInodeDict()
if validFreeBlockList == 1:
print "Each directory has a . and .. entry. Also, the block numbers are correct."
validLinkCount = checkLinkCount()
if validLinkCount == 1:
print "The linkcount matches the number of entires in the filename_to_inode_dict."
validLocation = checkLocationIndirec()
if validLocation == 1:
print "The indirect is one for every file that has its location pointing to an array."
isSizeValid = validSize()
if isSizeValid == 1:
print "The size of each file is properly allocated."
def checkId():
lindFsCalls = open("linddata.0", "r") #checking if the device id is correct
lindFsCallsString = lindFsCalls.read()
de_lindFsCallsString = serialize_deserializedata(lindFsCallsString)
if de_lindFsCallsString["dev_id"] == 20:
print "The Device Id is 20"
else:
print "The device id is NOT 20, an error has occured."
def checkTimes():
lindFsCalls = open("linddata.0", "r")
lindFsCallsString = lindFsCalls.read()
de_lindFsCallsString = serialize_deserializedata(lindFsCallsString)
if de_lindFsCallsString["creationTime"] == 1376483073: # check if the times are in the past
lindFsCalls.close()
lindFsCalls = open("linddata.26", "r")
lindFsCallsString = lindFsCalls.read()
de_lindFsCallsString = serialize_deserializedata(lindFsCallsString)
if de_lindFsCallsString["ctime"] == 1323630836:
print "All times are in the past, nothing is in the future"
else:
print "The times are NOT in the past, an error has occured."
lindFsCalls.close()
def checkFreeBlockList():
freeBlockListAggregate = [] # check if the free block list is accurate
for i in range(0,27):
freeBlockListAggregate.append(1)
for i in range(1,26):
lindFsCalls = open("%s%d" % ("linddata.", i), "r")
lindFsCallsString = lindFsCalls.read()
de_lindFsCallsString = serialize_deserializedata(lindFsCallsString)
for j in de_lindFsCallsString:
freeBlockListAggregate.append(j)
lindFsCalls.close()
keepTrack = 0
if len(freeBlockListAggregate) == 10000: # are all the free blocks stored in the free block list
for i in range(0,10000):
if( freeBlockListAggregate[i] == 0):
try:
fileExists = open("%s%d" % ("linddata.", i), "r")
print i
print "The free block list is NOT accurate, there are files/directories stored on items that listed in the free block list."
except: # if an error occurs, the file does not exist
keepTrack += 1 # keep track of how many files do not exist
else:
print "The free block list is NOT accurate."
""" check to see if the total number of free blocks is equal to the number of errors encountered. They should be the same"""
numberofFree = 0
for i in freeBlockListAggregate:
if (i == 0):
numberofFree += 1
if numberofFree == keepTrack:
print "The free block list is accurate."
def checkFilenameToInodeDict(block=26): # recursive function
currentFile = open("%s%d" % ('linddata.', block),'r')
currentFileSerialized = currentFile.read()
currentFileUnserialized = serialize_deserializedata(currentFileSerialized)
counter = 0
for i in currentFileUnserialized['filename_to_inode_dict']:
counter += 1
#test that there are entries other than d. and d.. in this file
if counter > 2:
try:
if not(IS_CHR(currentFileUnserialized['filename_to_inode_dict']['d.'])):
if not(IS_CHR( currentFileUnserialized['filename_to_inode_dict']['d..'])):
for i in currentFileUnserialized['filename_to_inode_dict']:
#check that we're NOT looking at the d. and d.. entries because that has already been done.
if (i[1] != "."):
checkFileFileName(currentFileUnserialized['filename_to_inode_dict']['d.'])
return 1
except:
print "An error occured: the d. or d.. entry does not exist."
if counter == 2:
return 1
currentFile.close()
def checkLinkCount(block=26): # recursive function
currentFile = open("%s%d" % ('linddata.', block),'r')
currentFileSerialized = currentFile.read()
currentFileUnserialized = serialize_deserializedata(currentFileSerialized)
try:
counter = 0
for i in currentFileUnserialized['filename_to_inode_dict']:
counter += 1
if (i[1] != "."):
if (counter == currentFileUnserialized['linkcount']):
checkLinkCount(currentFileUnserialized['filename_to_inode_dict'][i])
return 1
except:
print "An error occured: a directory's linkcount does not match the number of entries in the filename_to_inode_dict."
currentFile.close()
def checkLocationIndirec(block=26): # another recursive function
currentFile = open ("%s%d" % ('linddata.',block), 'r')
currentFileSerialized = currentFile.read()
currentFileUnserialized = serialize_deserializedata(currentFileSerialized)
try:
for i in currentFileUnserialized['filename_to_inode_dict']:
if (i[1] != "."):
if(i[0] == 'f'):
nextFileInode = currentFileUnserialized[i]
currentFile.close()
nextFile = open("%s%d" % ('linddata.',i),'r')
nextFileSerialized = nextFile.read()
nextFileUnserialized = serialize_deserializedata(nextFileSerialized)
locationFile = nextFileUnserialized['location']
nextFile.close()
theFilesText = open("%s%d" % ('linddata.', locationFile),'r')
theFilesTextSerialized = theFilesText.read()
theFilesTextUnserialized = serialize_deserializedata(theFilesTextSerialized)
# test if the data is an array
if theFilesTextUnserialized[0] == '[':
return 1
else:
checkLocationIndirec(currentFileUnserialized['filename_to_inode_dict'][i])
except:
print "An error has occured: there exists a file that has its location point to an array YET its indirect is still one."
def validSize(block = 26): #recursive function
currentFile = open ("%s%d" % ('linddata.',block), 'r')
currentFileSerialized = currentFile.read()
currentFileUnserialized = serialize_deserializedata(currentFileSerialized)
try:
for i in currentFileUnserialized['filename_to_inode_dict']:
if (i[1] != "."):
if(i[0] == 'f'):
nextFileInode = currentFileUnserialized[i]
currentFile.close()
nextFile = open("%s%d" % ('linddata.',i),'r')
nextFileSerialized = nextFile.read()
nextFileUnserialized = serialize_deserializedata(nextFileSerialized)
locationFile = nextFileUnserialized['location']
nextFile.close()
theFilesText = open("%s%d" % ('linddata.', locationFile),'r')
theFilesTextSerialized = theFilesText.read()
theFilesTextUnserialized = serialize_deserializedata(theFilesTextSerialized)
# test the size of the file
if(theFilesTextUnserialized['size'] < 4096):
if theFilesTextUnserialized['indirect'] == 0:
pass
elif(theFilesTextUnserialized['indirect'] != 0):
nextBlock = theFilesTextUnserialized['location']
theFilesText.close()
nextBlocksLocation = open("%s%d" % ('linddata.',nextBlock), 'r')
nextBlocksLocationSerialized = nextBlocksLocation.read()
nextBlocksLocationUnserialized = serialize_deserializedata(nextBlocksLocationSerialized)
else:
print "An error has occured: the size of a file/files is not properly allocated for."
else:
checkLocationIndirec(currentFileUnserialized['filename_to_inode_dict'][i])
except:
print "An error has occured: the size of a file/files is not properly allocated for."
csefsck()