]> arthur.barton.de Git - bup.git/blob - lib/bup/cmd/damage.py
chmod -x lib/bup/cmd/*.py
[bup.git] / lib / bup / cmd / damage.py
1
2 from __future__ import absolute_import
3 import os, random
4
5 from bup import options
6 from bup.compat import argv_bytes, bytes_from_uint
7 from bup.helpers import log
8 from bup.io import path_msg
9
10
11 def randblock(n):
12     return b''.join(bytes_from_uint(random.randrange(0,256)) for i in range(n))
13
14
15 optspec = """
16 bup damage [-n count] [-s maxsize] [-S seed] <filenames...>
17 --
18    WARNING: THIS COMMAND IS EXTREMELY DANGEROUS
19 n,num=   number of blocks to damage
20 s,size=  maximum size of each damaged block
21 percent= maximum size of each damaged block (as a percent of entire file)
22 equal    spread damage evenly throughout the file
23 S,seed=  random number seed (for repeatable tests)
24 """
25
26 def main(argv):
27     o = options.Options(optspec)
28     opt, flags, extra = o.parse_bytes(argv[1:])
29
30     if not extra:
31         o.fatal('filenames expected')
32
33     if opt.seed != None:
34         random.seed(opt.seed)
35
36     for name in extra:
37         name = argv_bytes(name)
38         log('Damaging "%s"...\n' % path_msg(name))
39         with open(name, 'r+b') as f:
40             st = os.fstat(f.fileno())
41             size = st.st_size
42             if opt.percent or opt.size:
43                 ms1 = int(float(opt.percent or 0)/100.0*size) or size
44                 ms2 = opt.size or size
45                 maxsize = min(ms1, ms2)
46             else:
47                 maxsize = 1
48             chunks = opt.num or 10
49             chunksize = size // chunks
50             for r in range(chunks):
51                 sz = random.randrange(1, maxsize+1)
52                 if sz > size:
53                     sz = size
54                 if opt.equal:
55                     ofs = r*chunksize
56                 else:
57                     ofs = random.randrange(0, size - sz + 1)
58                 log('  %6d bytes at %d\n' % (sz, ofs))
59                 f.seek(ofs)
60                 f.write(randblock(sz))