Browse Source

Version 0.8.5rc1

philemon 9 years ago
parent
commit
7affd8ebea
11 changed files with 65 additions and 82 deletions
  1. 1 1
      mmgen/addr.py
  2. 1 1
      mmgen/filename.py
  3. 14 18
      mmgen/globalvars.py
  4. 2 2
      mmgen/obj.py
  5. 2 2
      mmgen/seed.py
  6. 2 9
      mmgen/term.py
  7. 3 3
      mmgen/tool.py
  8. 2 2
      mmgen/tw.py
  9. 2 16
      mmgen/util.py
  10. 1 1
      setup.py
  11. 35 27
      test/test.py

+ 1 - 1
mmgen/addr.py

@@ -89,7 +89,7 @@ class AddrList(MMGenObject): # Address info for a single seed ID
 # A text label of {n} characters or less may be added to the right of each
 # A text label of {n} characters or less may be added to the right of each
 # address, and it will be appended to the bitcoind wallet label upon import.
 # address, and it will be appended to the bitcoind wallet label upon import.
 # The label may contain any printable ASCII symbol.
 # The label may contain any printable ASCII symbol.
-""".strip().format(n=g.max_addr_label_len,pnm=pnm),
+""".strip().format(n=MMGenAddrLabel.max_len,pnm=pnm),
 	'record_chksum': """
 	'record_chksum': """
 Record this checksum: it will be used to verify the address file in the future
 Record this checksum: it will be used to verify the address file in the future
 """.strip(),
 """.strip(),

+ 1 - 1
mmgen/filename.py

@@ -51,7 +51,7 @@ class Filename(MMGenObject):
 		import stat
 		import stat
 		if stat.S_ISBLK(os.stat(fn).st_mode):
 		if stat.S_ISBLK(os.stat(fn).st_mode):
 			mode = (os.O_RDONLY,os.O_RDWR)[bool(write)]
 			mode = (os.O_RDONLY,os.O_RDWR)[bool(write)]
-			if sys.platform[:3] == 'win': mode |= os.O_BINARY
+			if g.platform == 'win': mode |= os.O_BINARY
 			try:
 			try:
 				fd = os.open(fn, mode)
 				fd = os.open(fn, mode)
 			except OSError as e:
 			except OSError as e:

+ 14 - 18
mmgen/globalvars.py

@@ -20,7 +20,7 @@
 globalvars.py:  Constants and configuration options for the MMGen suite
 globalvars.py:  Constants and configuration options for the MMGen suite
 """
 """
 
 
-import sys, os
+import sys,os
 
 
 # Variables - these might be altered at runtime:
 # Variables - these might be altered at runtime:
 
 
@@ -29,13 +29,6 @@ hash_preset    = '3'
 usr_randchars  = 30
 usr_randchars  = 30
 use_urandchars = False
 use_urandchars = False
 
 
-# returns None if env var unset
-debug                = os.getenv('MMGEN_DEBUG')
-no_license           = os.getenv('MMGEN_NOLICENSE')
-bogus_wallet_data    = os.getenv('MMGEN_BOGUS_WALLET_DATA')
-disable_hold_protect = os.getenv('MMGEN_DISABLE_HOLD_PROTECT')
-color = (False,True)[sys.stdout.isatty() and not os.getenv('MMGEN_DISABLE_COLOR')]
-
 from mmgen.obj import BTCAmt
 from mmgen.obj import BTCAmt
 tx_fee        = BTCAmt('0.0003')
 tx_fee        = BTCAmt('0.0003')
 tx_fee_adj    = 1.0
 tx_fee_adj    = 1.0
@@ -46,12 +39,19 @@ http_timeout = 60
 
 
 # Constants - these don't change at runtime
 # Constants - these don't change at runtime
 
 
+# os.getenv() returns None if environmental var is unset
+debug                = os.getenv('MMGEN_DEBUG')
+no_license           = os.getenv('MMGEN_NOLICENSE')
+bogus_wallet_data    = os.getenv('MMGEN_BOGUS_WALLET_DATA')
+disable_hold_protect = os.getenv('MMGEN_DISABLE_HOLD_PROTECT')
+color = (False,True)[sys.stdout.isatty() and not os.getenv('MMGEN_DISABLE_COLOR')]
+
 proj_name = 'MMGen'
 proj_name = 'MMGen'
 prog_name = os.path.basename(sys.argv[0])
 prog_name = os.path.basename(sys.argv[0])
 author    = 'Philemon'
 author    = 'Philemon'
 email     = '<mmgen-py@yandex.com>'
 email     = '<mmgen-py@yandex.com>'
 Cdates    = '2013-2016'
 Cdates    = '2013-2016'
-version   = '0.8.4'
+version   = '0.8.5rc1'
 
 
 required_opts = [
 required_opts = [
 	'quiet','verbose','debug','outdir','echo_passphrase','passwd_file',
 	'quiet','verbose','debug','outdir','echo_passphrase','passwd_file',
@@ -100,12 +100,8 @@ hash_presets = {
 	'7': [18, 8, 24],
 	'7': [18, 8, 24],
 }
 }
 
 
-mmgen_idx_max_digits = 7
-
-printable_nonl = [chr(i+32) for i in range(95)]
-printable = printable_nonl + ['\n','\t']
-addr_label_symbols = wallet_label_symbols = printable_nonl
-
-max_addr_label_len   = 32
-max_wallet_label_len = 48
-max_tx_comment_len   = 72 # Comment is b58 encoded, so can permit UTF-8
+for k in ('win','linux'):
+	if sys.platform[:len(k)] == k: platform = k; break
+else:
+	sys.stderr.write("'%s': platform not supported by %s\n" % (sys.platform,proj_name))
+	sys.exit(1)

+ 2 - 2
mmgen/obj.py

@@ -39,8 +39,8 @@ class MMGenObject(object):
 		def conv(v,col_w):
 		def conv(v,col_w):
 			vret = ''
 			vret = ''
 			if type(v) in (str,unicode):
 			if type(v) in (str,unicode):
-				import mmgen.globalvars as g
-				if not (set(list(v)) <= set(list(g.printable))):
+				from string import printable
+				if not (set(list(v)) <= set(list(printable))):
 					vret = repr(v)
 					vret = repr(v)
 				else:
 				else:
 					vret = fix_linebreaks(v,fixed_indent=0)
 					vret = fix_linebreaks(v,fixed_indent=0)

+ 2 - 2
mmgen/seed.py

@@ -955,7 +955,7 @@ harder to find, you're advised to choose a much larger file size than this.
 		d.target_data_len = self._get_incog_data_len(opt.seed_len)
 		d.target_data_len = self._get_incog_data_len(opt.seed_len)
 		self._check_valid_offset(self.infile,'read')
 		self._check_valid_offset(self.infile,'read')
 
 
-		flgs = os.O_RDONLY|os.O_BINARY if sys.platform[:3] == 'win' else os.O_RDONLY
+		flgs = os.O_RDONLY|os.O_BINARY if g.platform == 'win' else os.O_RDONLY
 		fh = os.open(self.infile.name,flgs)
 		fh = os.open(self.infile.name,flgs)
 		os.lseek(fh,int(d.hincog_offset),os.SEEK_SET)
 		os.lseek(fh,int(d.hincog_offset),os.SEEK_SET)
 		self.fmt_data = os.read(fh,d.target_data_len)
 		self.fmt_data = os.read(fh,d.target_data_len)
@@ -1005,7 +1005,7 @@ harder to find, you're advised to choose a much larger file size than this.
 			self._check_valid_offset(f,'write')
 			self._check_valid_offset(f,'write')
 			if not opt.quiet: confirm_or_exit('',"alter file '%s'" % f.name)
 			if not opt.quiet: confirm_or_exit('',"alter file '%s'" % f.name)
 
 
-		flgs = os.O_RDWR|os.O_BINARY if sys.platform[:3] == 'win' else os.O_RDWR
+		flgs = os.O_RDWR|os.O_BINARY if g.platform == 'win' else os.O_RDWR
 		fh = os.open(f.name,flgs)
 		fh = os.open(f.name,flgs)
 		os.lseek(fh, int(d.hincog_offset), os.SEEK_SET)
 		os.lseek(fh, int(d.hincog_offset), os.SEEK_SET)
 		os.write(fh, self.fmt_data)
 		os.write(fh, self.fmt_data)

+ 2 - 9
mmgen/term.py

@@ -21,7 +21,6 @@ term.py:  Terminal-handling routines for the MMGen suite
 """
 """
 
 
 import os,struct
 import os,struct
-
 from mmgen.common import *
 from mmgen.common import *
 
 
 def _kb_hold_protect_unix():
 def _kb_hold_protect_unix():
@@ -201,15 +200,9 @@ except:
 		get_terminal_size = _get_terminal_size_mswin
 		get_terminal_size = _get_terminal_size_mswin
 		myflush = mswin_dummy_flush
 		myflush = mswin_dummy_flush
 	except:
 	except:
-		if not sys.platform.startswith('linux') \
-				and not sys.platform.startswith('win'):
-			msg('Unsupported platform: %s' % sys.platform)
-			msg('This program currently runs only on Linux and Windows')
-		else:
-			msg('Unable to set terminal mode')
+		msg('Unable to set terminal mode')
 		sys.exit(2)
 		sys.exit(2)
 
 
-
 def do_pager(text):
 def do_pager(text):
 
 
 	pagers = ['less','more']
 	pagers = ['less','more']
@@ -224,7 +217,7 @@ def do_pager(text):
 # 'print' instead of the pager.
 # 'print' instead of the pager.
 # We risk assuming that 'more' will always be available on a stock
 # We risk assuming that 'more' will always be available on a stock
 # Windows installation.
 # Windows installation.
-	if sys.platform.startswith('win'):
+	if g.platform == 'win':
 		if 'HOME' not in environ: # native Windows terminal
 		if 'HOME' not in environ: # native Windows terminal
 			shell = True
 			shell = True
 			pagers = ['more']
 			pagers = ['more']

+ 3 - 3
mmgen/tool.py

@@ -252,7 +252,7 @@ def hexdump(infile, cols=8, line_nums=True):
 				cols=cols,line_nums=line_nums))
 				cols=cols,line_nums=line_nums))
 
 
 def unhexdump(infile):
 def unhexdump(infile):
-	if sys.platform[:3] == 'win':
+	if g.platform == 'win':
 		import msvcrt
 		import msvcrt
 		msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
 		msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
 	sys.stdout.write(decode_pretty_hexdump(
 	sys.stdout.write(decode_pretty_hexdump(
@@ -425,7 +425,7 @@ def listaddresses(addrs='',minconf=1,showempty=False,pager=False,showbtcaddrs=Fa
 	)
 	)
 
 
 	def s_mmgen(key): # TODO
 	def s_mmgen(key): # TODO
-		return '{}:{:>0{w}}'.format(w=g.mmgen_idx_max_digits, *key.split('_'))
+		return '{}:{:>0{w}}'.format(w=AddrIdx.max_digits, *key.split('_'))
 
 
 	out = []
 	out = []
 	for k in sorted(addrs,key=s_mmgen):
 	for k in sorted(addrs,key=s_mmgen):
@@ -572,7 +572,7 @@ def decrypt(infile,outfile='',hash_preset=''):
 def find_incog_data(filename,iv_id,keep_searching=False):
 def find_incog_data(filename,iv_id,keep_searching=False):
 	ivsize,bsize,mod = g.aesctr_iv_len,4096,4096*8
 	ivsize,bsize,mod = g.aesctr_iv_len,4096,4096*8
 	n,carry = 0,' '*ivsize
 	n,carry = 0,' '*ivsize
-	flgs = os.O_RDONLY|os.O_BINARY if sys.platform[:3] == 'win' else os.O_RDONLY
+	flgs = os.O_RDONLY|os.O_BINARY if g.platform == 'win' else os.O_RDONLY
 	f = os.open(filename,flgs)
 	f = os.open(filename,flgs)
 	for ch in iv_id:
 	for ch in iv_id:
 		if ch not in '0123456789ABCDEF':
 		if ch not in '0123456789ABCDEF':

+ 2 - 2
mmgen/tw.py

@@ -84,7 +84,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
 	def s_mmid(self,i):
 	def s_mmid(self,i):
 		if i.mmid:
 		if i.mmid:
 			return '{}:{:>0{w}}'.format(
 			return '{}:{:>0{w}}'.format(
-				*i.mmid.split(':'), w=g.mmgen_idx_max_digits)
+				*i.mmid.split(':'), w=AddrIdx.max_digits)
 		else: return 'G' + (i.label or '')
 		else: return 'G' + (i.label or '')
 
 
 	def do_sort(self,key,reverse=None):
 	def do_sort(self,key,reverse=None):
@@ -97,7 +97,7 @@ watch-only wallet using '{}-addrimport' and then re-run this program.
 
 
 	def sort_info(self,include_group=True):
 	def sort_info(self,include_group=True):
 		ret = ([],['Reverse'])[self.reverse]
 		ret = ([],['Reverse'])[self.reverse]
-		ret.append(self.sort.capitalize().replace('Mmid','MMGenId'))
+		ret.append(self.sort.capitalize().replace('Mmid','MMGenID'))
 		if include_group and self.group and (self.sort in ('addr','txid','mmid')):
 		if include_group and self.group and (self.sort in ('addr','txid','mmid')):
 			ret.append('Grouped')
 			ret.append('Grouped')
 		return ret
 		return ret

+ 2 - 16
mmgen/util.py

@@ -57,7 +57,7 @@ def magenta(s): return _mag+s+_reset
 def nocolor(s): return s
 def nocolor(s): return s
 
 
 def start_mscolor():
 def start_mscolor():
-	if sys.platform[:3] == 'win':
+	if g.platform == 'win':
 		global red,green,yellow,cyan,nocolor
 		global red,green,yellow,cyan,nocolor
 		import os
 		import os
 		if 'MMGEN_NOMSCOLOR' in os.environ:
 		if 'MMGEN_NOMSCOLOR' in os.environ:
@@ -101,20 +101,6 @@ def pp_msg(d):
 	import pprint
 	import pprint
 	msg(pprint.PrettyPrinter(indent=4).pformat(d))
 	msg(pprint.PrettyPrinter(indent=4).pformat(d))
 
 
-def is_mmgen_wallet_label(s):
-	if len(s) > g.max_wallet_label_len:
-		msg('ERROR: wallet label length (%s chars) > maximum allowed (%s chars)' % (len(s),g.max_wallet_label_len))
-		return False
-
-	try: s = s.decode('utf8')
-	except: pass
-
-	for ch in s:
-		if ch not in g.wallet_label_symbols:
-			msg('ERROR: wallet label contains illegal symbol (%s)' % ch)
-			return False
-	return True
-
 # From 'man dd':
 # From 'man dd':
 # c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024,
 # c=1, w=2, b=512, kB=1000, K=1024, MB=1000*1000, M=1024*1024,
 # GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y.
 # GB=1000*1000*1000, G=1024*1024*1024, and so on for T, P, E, Z, Y.
@@ -503,7 +489,7 @@ def write_data_to_file(
 			else:
 			else:
 				msg('Redirecting output to file')
 				msg('Redirecting output to file')
 
 
-		if binary and sys.platform[:3] == 'win':
+		if binary and g.platform == 'win':
 			import msvcrt
 			import msvcrt
 			msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
 			msvcrt.setmode(sys.stdout.fileno(),os.O_BINARY)
 
 

+ 1 - 1
setup.py

@@ -21,7 +21,7 @@ from distutils.core import setup
 setup(
 setup(
 		name         = 'mmgen',
 		name         = 'mmgen',
 		description  = 'A complete Bitcoin cold-storage solution for the command line',
 		description  = 'A complete Bitcoin cold-storage solution for the command line',
-		version      = '0.8.4',
+		version      = '0.8.5rc1',
 		author       = 'Philemon',
 		author       = 'Philemon',
 		author_email = 'mmgen-py@yandex.com',
 		author_email = 'mmgen-py@yandex.com',
 		url          = 'https://github.com/mmgen/mmgen',
 		url          = 'https://github.com/mmgen/mmgen',

+ 35 - 27
test/test.py

@@ -482,6 +482,7 @@ opts_data = {
 -s, --system        Test scripts and modules installed on system rather
 -s, --system        Test scripts and modules installed on system rather
                     than those in the repo root.
                     than those in the repo root.
 -S, --skip-deps     Skip dependency checking for command
 -S, --skip-deps     Skip dependency checking for command
+-u, --usr-random    Get random data interactively from user
 -t, --traceback     Run the command inside the '{tb_cmd}' script.
 -t, --traceback     Run the command inside the '{tb_cmd}' script.
 -v, --verbose       Produce more verbose output.
 -v, --verbose       Produce more verbose output.
 """.format(tb_cmd=tb_cmd,lf=log_file),
 """.format(tb_cmd=tb_cmd,lf=log_file),
@@ -498,6 +499,9 @@ if opt.log:
 	log_fd = open(log_file,'a')
 	log_fd = open(log_file,'a')
 	log_fd.write('\nLog started: %s\n' % make_timestr())
 	log_fd.write('\nLog started: %s\n' % make_timestr())
 
 
+usr_rand_chars = (5,30)[bool(opt.usr_random)]
+usr_rand_arg = '-r%s' % usr_rand_chars
+
 if opt.system: sys.path.pop(0)
 if opt.system: sys.path.pop(0)
 ni = bool(opt.non_interactive)
 ni = bool(opt.non_interactive)
 
 
@@ -530,7 +534,7 @@ stderr_save = sys.stderr
 
 
 def silence():
 def silence():
 	if not (opt.verbose or opt.exact_output):
 	if not (opt.verbose or opt.exact_output):
-		f = ('/dev/null','stderr.out')[sys.platform[:3]=='win']
+		f = ('/dev/null','stderr.out')[g.platform=='win']
 		sys.stderr = open(f,'a')
 		sys.stderr = open(f,'a')
 
 
 def end_silence():
 def end_silence():
@@ -708,17 +712,21 @@ class MMGenExpect(object):
 		my_expect(self.p,'Generating encryption key from OS random data plus ' + m)
 		my_expect(self.p,'Generating encryption key from OS random data plus ' + m)
 
 
 	def usr_rand(self,num_chars):
 	def usr_rand(self,num_chars):
-		rand_chars = list(getrandstr(num_chars,no_space=True))
-		my_expect(self.p,'symbols left: ','x')
-		try:
-			vmsg_r('SEND ')
-			while self.p.expect('left: ',0.1) == 0:
-				ch = rand_chars.pop(0)
-				msg_r(yellow(ch)+' ' if opt.verbose else '+')
-				self.p.send(ch)
-		except:
-			vmsg('EOT')
-		my_expect(self.p,'ENTER to continue: ','\n')
+		if opt.usr_random:
+			self.interactive()
+			my_send(self.p,'\n')
+		else:
+			rand_chars = list(getrandstr(num_chars,no_space=True))
+			my_expect(self.p,'symbols left: ','x')
+			try:
+				vmsg_r('SEND ')
+				while self.p.expect('left: ',0.1) == 0:
+					ch = rand_chars.pop(0)
+					msg_r(yellow(ch)+' ' if opt.verbose else '+')
+					self.p.send(ch)
+			except:
+				vmsg('EOT')
+			my_expect(self.p,'ENTER to continue: ','\n')
 
 
 	def passphrase_new(self,desc,passphrase):
 	def passphrase_new(self,desc,passphrase):
 		my_expect(self.p,('Enter passphrase for %s: ' % desc), passphrase+'\n')
 		my_expect(self.p,('Enter passphrase for %s: ' % desc), passphrase+'\n')
@@ -807,7 +815,7 @@ labels = [
 	"Healthcare",
 	"Healthcare",
 	"Freelancing 1",
 	"Freelancing 1",
 	"Freelancing 2",
 	"Freelancing 2",
-	"Alice's assets",
+	"Alice's allowance",
 	"Bob's bequest",
 	"Bob's bequest",
 	"House purchase",
 	"House purchase",
 	"Real estate fund",
 	"Real estate fund",
@@ -1043,14 +1051,14 @@ class MMGenTestSuite(object):
 
 
 	def walletgen(self,name,seed_len=None):
 	def walletgen(self,name,seed_len=None):
 		write_to_tmpfile(cfg,pwfile,cfg['wpasswd']+'\n')
 		write_to_tmpfile(cfg,pwfile,cfg['wpasswd']+'\n')
-		add_args = (['-r5'],
+		add_args = ([usr_rand_arg],
 			['-q','-r0','-L','NI Wallet','-P',get_tmpfile_fn(cfg,pwfile)])[bool(ni)]
 			['-q','-r0','-L','NI Wallet','-P',get_tmpfile_fn(cfg,pwfile)])[bool(ni)]
 		args = ['-d',cfg['tmpdir'],'-p1']
 		args = ['-d',cfg['tmpdir'],'-p1']
 		if seed_len: args += ['-l',str(seed_len)]
 		if seed_len: args += ['-l',str(seed_len)]
 		t = MMGenExpect(name,'mmgen-walletgen', args + add_args)
 		t = MMGenExpect(name,'mmgen-walletgen', args + add_args)
 		if ni: return
 		if ni: return
 		t.license()
 		t.license()
-		t.usr_rand(10)
+		t.usr_rand(usr_rand_chars)
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
 		t.label()
 		t.label()
 		t.written_to_file('MMGen wallet')
 		t.written_to_file('MMGen wallet')
@@ -1069,13 +1077,13 @@ class MMGenTestSuite(object):
 			add_args = ['-r0', '-q', '-P%s' % get_tmpfile_fn(cfg,pwfile),
 			add_args = ['-r0', '-q', '-P%s' % get_tmpfile_fn(cfg,pwfile),
 							get_tmpfile_fn(cfg,bf)]
 							get_tmpfile_fn(cfg,bf)]
 		else:
 		else:
-			add_args = ['-r5']
+			add_args = [usr_rand_arg]
 		t = MMGenExpect(name,'mmgen-walletconv', args + add_args)
 		t = MMGenExpect(name,'mmgen-walletconv', args + add_args)
 		if ni: return
 		if ni: return
 		t.license()
 		t.license()
 		t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n')
 		t.expect('Enter brainwallet: ', ref_wallet_brainpass+'\n')
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
-		t.usr_rand(10)
+		t.usr_rand(usr_rand_chars)
 		sid = t.written_to_file('MMGen wallet').split('-')[0].split('/')[-1]
 		sid = t.written_to_file('MMGen wallet').split('-')[0].split('/')[-1]
 		refcheck('Seed ID',sid,cfg['seed_id'])
 		refcheck('Seed ID',sid,cfg['seed_id'])
 
 
@@ -1086,7 +1094,7 @@ class MMGenTestSuite(object):
 		silence()
 		silence()
 		write_to_tmpfile(cfg,pwfile,get_data_from_file(pf))
 		write_to_tmpfile(cfg,pwfile,get_data_from_file(pf))
 		end_silence()
 		end_silence()
-		add_args = (['-r16'],['-q','-r0','-P',pf])[bool(ni)]
+		add_args = ([usr_rand_arg],['-q','-r0','-P',pf])[bool(ni)]
 		t = MMGenExpect(name,'mmgen-passchg', add_args +
 		t = MMGenExpect(name,'mmgen-passchg', add_args +
 				['-d',cfg['tmpdir'],'-p','2','-L','New Label',wf])
 				['-d',cfg['tmpdir'],'-p','2','-L','New Label',wf])
 		if ni: return
 		if ni: return
@@ -1095,7 +1103,7 @@ class MMGenTestSuite(object):
 		t.expect_getend('Hash preset changed to ')
 		t.expect_getend('Hash preset changed to ')
 		t.passphrase('MMGen wallet',cfg['wpasswd'],pwtype='new')
 		t.passphrase('MMGen wallet',cfg['wpasswd'],pwtype='new')
 		t.expect('Repeat passphrase: ',cfg['wpasswd']+'\n')
 		t.expect('Repeat passphrase: ',cfg['wpasswd']+'\n')
-		t.usr_rand(16)
+		t.usr_rand(usr_rand_chars)
 		t.expect_getend('Label changed to ')
 		t.expect_getend('Label changed to ')
 #		t.expect_getend('Key ID changed: ')
 #		t.expect_getend('Key ID changed: ')
 		t.written_to_file('MMGen wallet')
 		t.written_to_file('MMGen wallet')
@@ -1295,7 +1303,7 @@ class MMGenTestSuite(object):
 		t.passphrase('MMGen wallet',cfg['wpasswd'])
 		t.passphrase('MMGen wallet',cfg['wpasswd'])
 		if pw:
 		if pw:
 			t.passphrase_new('new '+desc,cfg['wpasswd'])
 			t.passphrase_new('new '+desc,cfg['wpasswd'])
-			t.usr_rand(10)
+			t.usr_rand(usr_rand_chars)
 		if ' '.join(desc.split()[-2:]) == 'incognito data':
 		if ' '.join(desc.split()[-2:]) == 'incognito data':
 			t.expect('Generating encryption key from OS random data ')
 			t.expect('Generating encryption key from OS random data ')
 			t.expect('Generating encryption key from OS random data ')
 			t.expect('Generating encryption key from OS random data ')
@@ -1323,7 +1331,7 @@ class MMGenTestSuite(object):
 		self.export_seed(name,wf,desc='mnemonic data',out_fmt='words')
 		self.export_seed(name,wf,desc='mnemonic data',out_fmt='words')
 
 
 	def export_incog(self,name,wf,desc='incognito data',out_fmt='i',add_args=[]):
 	def export_incog(self,name,wf,desc='incognito data',out_fmt='i',add_args=[]):
-		uargs = ['-p1','-r5'] + add_args
+		uargs = ['-p1',usr_rand_arg] + add_args
 		self.walletconv_export(name,wf,desc=desc,out_fmt=out_fmt,uargs=uargs,pw=True)
 		self.walletconv_export(name,wf,desc=desc,out_fmt=out_fmt,uargs=uargs,pw=True)
 		ok()
 		ok()
 
 
@@ -1453,11 +1461,11 @@ class MMGenTestSuite(object):
 		bwf = os.path.join(cfg['tmpdir'],cfg['bw_filename'])
 		bwf = os.path.join(cfg['tmpdir'],cfg['bw_filename'])
 		make_brainwallet_file(bwf)
 		make_brainwallet_file(bwf)
 		seed_len = str(cfg['seed_len'])
 		seed_len = str(cfg['seed_len'])
-		args = ['-d',cfg['tmpdir'],'-p1','-r5','-l'+seed_len,'-ib']
+		args = ['-d',cfg['tmpdir'],'-p1',usr_rand_arg,'-l'+seed_len,'-ib']
 		t = MMGenExpect(name,'mmgen-walletconv', args + [bwf])
 		t = MMGenExpect(name,'mmgen-walletconv', args + [bwf])
 		t.license()
 		t.license()
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
 		t.passphrase_new('new MMGen wallet',cfg['wpasswd'])
-		t.usr_rand(10)
+		t.usr_rand(usr_rand_chars)
 		t.label()
 		t.label()
 		t.written_to_file('MMGen wallet')
 		t.written_to_file('MMGen wallet')
 		ok()
 		ok()
@@ -1734,7 +1742,7 @@ class MMGenTestSuite(object):
 
 
 	# wallet conversion tests
 	# wallet conversion tests
 	def walletconv_in(self,name,infile,desc,uopts=[],pw=False,oo=False):
 	def walletconv_in(self,name,infile,desc,uopts=[],pw=False,oo=False):
-		opts = ['-d',cfg['tmpdir'],'-o','words','-r5']
+		opts = ['-d',cfg['tmpdir'],'-o','words',usr_rand_arg]
 		if_arg = [infile] if infile else []
 		if_arg = [infile] if infile else []
 		d = '(convert)'
 		d = '(convert)'
 		if ni:
 		if ni:
@@ -1788,7 +1796,7 @@ class MMGenTestSuite(object):
 				rd = os.urandom(ref_wallet_incog_offset+128)
 				rd = os.urandom(ref_wallet_incog_offset+128)
 				write_to_tmpfile(cfg,hincog_fn,rd)
 				write_to_tmpfile(cfg,hincog_fn,rd)
 		else:
 		else:
-			aa = ['-r5']
+			aa = [usr_rand_arg]
 		infile = os.path.join(ref_dir,cfg['seed_id']+'.mmwords')
 		infile = os.path.join(ref_dir,cfg['seed_id']+'.mmwords')
 		t = MMGenExpect(name,'mmgen-walletconv',aa+opts+[infile],extra_desc='(convert)')
 		t = MMGenExpect(name,'mmgen-walletconv',aa+opts+[infile],extra_desc='(convert)')
 
 
@@ -1807,7 +1815,7 @@ class MMGenTestSuite(object):
 			t.license()
 			t.license()
 			if pw:
 			if pw:
 				t.passphrase_new('new '+desc,cfg['wpasswd'])
 				t.passphrase_new('new '+desc,cfg['wpasswd'])
-				t.usr_rand(10)
+				t.usr_rand(usr_rand_chars)
 			if ' '.join(desc.split()[-2:]) == 'incognito data':
 			if ' '.join(desc.split()[-2:]) == 'incognito data':
 				for i in (1,2,3):
 				for i in (1,2,3):
 					t.expect('Generating encryption key from OS random data ')
 					t.expect('Generating encryption key from OS random data ')
@@ -1876,7 +1884,7 @@ ts = MMGenTestSuite()
 # Laggy flash media cause pexpect to crash, so read and write all temporary
 # Laggy flash media cause pexpect to crash, so read and write all temporary
 # files to volatile memory in '/dev/shm'
 # files to volatile memory in '/dev/shm'
 if not opt.skip_deps:
 if not opt.skip_deps:
-	if sys.platform[:3] == 'win':
+	if g.platform == 'win':
 		for cfg in sorted(cfgs): mk_tmpdir(cfgs[cfg])
 		for cfg in sorted(cfgs): mk_tmpdir(cfgs[cfg])
 	else:
 	else:
 		d,pfx = '/dev/shm','mmgen-test-'
 		d,pfx = '/dev/shm','mmgen-test-'