#! /usr/bin/python
#  -*- Python -*-

"""Kernel synchronization utility

This script allows synchronization between ALSA CVS repository and 
standard kernel sources stored in local BK repository.

This tool is intended mainly for internal use of Jaroslav Kysela.

Usage:
	%(PROGRAM)s [options] command

Where options is:

	-h
	--help
		Print this help

	-C <path>
	--cvsroot=<path>
		Set root of ALSA CVS repository

	-B <path>
	--bkroot=<path>
		Set root of Linux kernel BitKeeper repository

Where command is:

	diffall
		Diff between ALSA and Linux kernel repositories
	diffall -r
		Reverse diff between ALSA and Linux kernel repositories

"""

import os
import sys
import string
import time
import dircache
import getopt

# define for documentation
PROGRAM = sys.argv[0]

# define working directories
CVSROOT = '~/alsa'
BKROOT = '~/linux/official'
PATCH_UPDATE = '~/alsa/alsa-kernel/scripts/kchanges/update'

# exclude some files or directories
ALSA_EXCLUDE = ['/include/version.h']
ALSA_EXCLUDE_DIR = ['/scripts', '/oss']
KERNEL_EXCLUDE = ['/COPYING', '/CREDITS',
		  '/MAINTAINERS','/Makefile',
		  '/README','/REPORTING-BUGS',
		  '/include/sound/version.h']
KERNEL_EXCLUDE_DIR = ['/BitKeeper',
		      '/Documentation',
		      '/arch', '/drivers', '/crypto', '/fs',
		      '/include', '/init', '/ipc',
		      '/kernel', '/lib', '/mm', '/usr',
		      '/net', '/scripts', '/security',
		      '/sound/oss']
# force to process
ALSA_FORCE = []
ALSA_FORCE_DIR = ['/']
KERNEL_FORCE = []
KERNEL_FORCE_DIR = ['/Documentation/sound/alsa', '/include/sound']

# Directory mapping
ALSA_MAP = {'/':'/sound',
	    '/Documentation':'/Documentation/sound/alsa',
	    '/include':'/include/sound'}
KERNEL_MAP = {}		# Initialized from ALSA_MAP

# Global variables
LAST_CVS_TIME = 0
FATAL_LSYNC_ERROR = 0

# Translation tables for CVS user IDs
CVS_USER = {'perex':'Jaroslav Kysela <perex@suse.cz>',
	    'uid53661':'Jaroslav Kysela <perex@suse.cz>',	# seems SF CVS malfunction
	    'tiwai':'Takashi Iwai <tiwai@suse.de>',
	    'abramo':'Abramo Bagnara <abramo@alsa-project.org>'}

def usage(code, msg=''):
	print __doc__ % globals()
	if msg:
		print msg
	sys.exit(code)

def get_cvs_root():
	return os.path.expanduser(CVSROOT + '/alsa-kernel')

def get_bk_root():
	return os.path.expanduser(BKROOT)

def print_file(fp, lines):
	for line in lines:
		fp.write(line)

def print_file_comment(fp, lines, space=''):
	for line in lines:
		fp.write('# %s' % space)
		fp.write(line)

def modify_version_file():
	filename = get_cvs_root() + '/include/version.h'
	fp = open(filename)
	lines = fp.readlines()
	fp.close()
	fp = open(filename + '.new', 'w')
	for line in lines:
		str = '#define CONFIG_SND_DATE'
		if line[0:len(str)] == str:
			t = time.gmtime(LAST_CVS_TIME)
			ts = time.strftime('%a %b %d %H:%M:%S %Y', t)
			str = str + ' " (%s UTC)"\n' % ts
			fp.write(str)
		else:
			fp.write(line)
	fp.close()
	os.rename(filename + '.new', filename)

def update_cvs_file(file, destfile = '', params = ''):
	path, file = os.path.split(file)
	try:
		os.chdir(get_cvs_root() + '/' + path)
	except OSError, msg:
		os.mkdir(get_cvs_root() + '/' + path)
		pass
	if destfile == '':
		cmd = 'cvs -z3 update %s' % file
	else:
		cmd = 'cvs -z3 update -p %s %s' % (params, file)
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	if destfile == '':
		print_file(sys.stderr, lines)
	else:
		fp = open(destfile, 'w')
		print_file(fp, lines)
		fp.close()

def update_bk_file(file):
	path, file = os.path.split(file)
	if os.path.isdir(path):
		os.chdir(path)
	else:
		xpath, xfile = os.path.split(path)
		os.chdir(xpath)
		cmd = 'bk mkdir %s' % xfile
		print cmd
		fp = os.popen(cmd)
		lines = fp.readlines()
		fp.close()
		print_file(sys.stderr, lines)
		os.chdir(path)
	cmd = 'bk get %s' % file
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	print_file(sys.stderr, lines)

def change_diff_line(line, file):
	if line[:4] == '--- ':
		file = file + '.old'
	if line[:4] == '--- ' or line[:4] == '+++ ':
		idx = string.find(line[4:], '\t')
		nline = line[:4] + file + line[4+idx:]
		return nline
	return line

def change_diff_lines(lines, file):
	if len(lines) > 1:
		lines[0] = change_diff_line(lines[0], file)
		lines[1] = change_diff_line(lines[1], file)
	return lines

def update_last_cvs_time(stime):
	global LAST_CVS_TIME
	# mktime returns local time, and we need to convert
	# the result to GMT (UTC) time, so substract the difference
	# in seconds between local time and GMT (time.timezone)	
	gm_time = time.mktime(time.strptime(stime)) - time.timezone
	if (LAST_CVS_TIME < gm_time):
		LAST_CVS_TIME = gm_time

def get_cvs_files(base, dir):
	dlist = []
	flist = []

	# Read all entries
	fp = open(base + dir + 'CVS/Entries')
	entries = fp.readlines()
	fp.close()

	# Process files entries
	for e in entries:
		try:
			flags, name, rev, time, unk1, unk2 = string.split(e, '/')
			if string.count(flags, 'D') <= 0:
				update_last_cvs_time(time)
				flist.append(dir + name);
		except ValueError, msg:
			pass

	# Process directory entries
	for e in entries:
		try:
			flags, name, rev, time, unk1, unk2 = string.split(e, '/')
			if string.count(flags, 'D') > 0 and not ALSA_EXCLUDE_DIR.count(dir + name):
				dlist1, flist1 = get_cvs_files(base, dir + name + '/');
				dlist.append(dir + name);
				dlist = dlist + dlist1
				flist = flist + flist1
		except ValueError, msg:
			pass

	return dlist, flist

def get_bk_files(base, dir):
	dlist = []
	flist = []

	# merge files
	sccs_dir = base + dir + 'SCCS/'
	l = dircache.listdir(sccs_dir)
	for f in l:
		if f == 's.ChangeSet':
			dummy = 1
		elif f[0:2] == 's.':
			if not os.path.isdir(sccs_dir + f):
				flist.append(dir + f[2:])
	del l

	# merge directories
	l = dircache.listdir(base + dir)
	for f in l:
		if f == 'SCCS':
			dummy = 1	# Nothing
		elif os.path.isdir(base + dir + f):
			if os.path.isdir(base + dir + f + '/SCCS/') and not KERNEL_EXCLUDE_DIR.count(dir + f):
				dlist1, flist1 = get_bk_files(base, dir + f + '/')
				dlist.append(dir + f)
				dlist = dlist + dlist1
				flist = flist + flist1
			else:
				if not KERNEL_EXCLUDE_DIR.count(dir + f):
					print 'Ignoring BK directory %s' % base + dir + f
	del l

	return dlist, flist

def remap_engine(dir, dict):
	comp = string.split(dir, '/')
	add = ''
	while len(comp) > 0:
		tmp = string.join(comp, '/');
		if tmp == '':
			tmp = '/'
		if dict.has_key(tmp):
			if add != '' and dict[tmp] != '/':
				add = '/' + add
			return dict[tmp] + add;
		if add == '':
			add = comp.pop();
		else:
			add = comp.pop() + '/' + add;
	return dir

def remap_alsa(dir):
	return remap_engine(dir, ALSA_MAP);

def remap_kernel(dir):
	return remap_engine(dir, KERNEL_MAP);

def remap_alsa_file(file):
	comp = string.split(file, '/')
	path = string.join(comp[:len(comp)-1],'/')
	if path == '':
		path = '/'
	path = remap_alsa(path)
	if path[-1] != '/':
		path = path + '/'
	return path + comp[-1]

def remap_kernel_file(file):
	comp = string.split(file, '/')
	path = string.join(comp[:len(comp)-1],'/')
	if path == '':
		path = '/'
	path = remap_kernel(path)
	if path[-1] != '/':
		path = path + '/'
	return path + comp[-1]

def get_cvs_date_param(from_cvs_time, to_cvs_time):
	if from_cvs_time:
		xtime1 = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(from_cvs_time))
	if to_cvs_time:
		xtime2 = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(to_cvs_time))
	if from_cvs_time and not to_cvs_time:
		return "-d'%s<'" % xtime1
	elif not from_cvs_time and to_cvs_time:
		return "-d'%s>'" % xtime2
	else:
		return "-d'%s<%s'" % (xtime1, xtime2)

def get_cvs_date_param1(to_cvs_time):
	if to_cvs_time:
		xtime1 = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(to_cvs_time))
		return "-D'%s'" % xtime1
	else:
		return ''

def collect_cvs_logs(file, from_cvs_time, to_cvs_time):
	path, file = os.path.split(file)
	os.chdir(get_cvs_root() + '/' + path)
	cmd = "cvs -z3 log %s %s" % (get_cvs_date_param(from_cvs_time, to_cvs_time), file)
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	i = 0
	fdead = 1
	dead = 0
	next_is_comment = 0
	result = ''
	while i < len(lines):
		if lines[i][0:11] == 'revision ':
			revision = line[i][11:]
			i = i + 1
		elif lines[i][0:6] == 'date: ':
			date, author, state, xlines = string.split(lines[i], ';')
			date = date[6:]
			author = string.lstrip(author)[8:]
			state = string.lstrip(state)[7:]
			if state == 'dead' and fdead:
				dead = 1
			i = i + 1
			next_is_comment = 1
			fdead = 0
		elif next_is_comment:
			next_is_comment = 0
			comment = ''
			while i < len(lines) and lines[i][0:6] != '------' and lines[i][0:6] != '======':
				if lines[i][0:9] == 'branches:' or lines[i][0:11] == '*BK_IGNORE*':
					while i < len(lines) and lines[i][0:6] != '------' and lines[i][0:6] != '======':
						i = i + 1
				else:
					comment = comment + '  ' + lines[i]
					i = i + 1
			result = result + '%s, %s :\n' % (CVS_USER[author], date) + comment
		else:
			i = i + 1
	return result, dead

def write_to_patch_update_file(lines):
	global PATCH_UPDATE
	fp = open(os.path.expanduser(PATCH_UPDATE), 'a+')
	print_file(fp, lines)
	fp.close()

def do_alsa_kernel_diff(alsa, kernel, from_cvs_time, to_cvs_time):
	global FATAL_LSYNC_ERROR
	ncvsflag = 0
	nbkflag = 0
	lsyncflag = 0
	if from_cvs_time or to_cvs_time:
		lsyncflag = 1
#		ncvsflag = 1
#		afile = '/tmp/ksync_kernel_diff'
#		params = get_cvs_date_param1(to_cvs_time)
#		update_cvs_file(alsa, afile, params)
#	else:
	afile = get_cvs_root() + alsa;
	if not os.path.exists(afile):
		update_cvs_file(alsa)
		if not os.path.exists(afile):
			ncvsflag = 1
			os.system('touch %s' % afile)
	kfile = get_bk_root() + kernel;
	if not os.path.exists(kfile):
		update_bk_file(kfile)
		if not os.path.exists(kfile):
			nbkflag = 1
			os.system('touch %s' % kfile)
	if lsyncflag > 0:
		cmd = 'diff -uN %s %s' % (afile, kfile)
	else:
		cmd = 'diff -uN %s %s' % (kfile, afile)
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	lines = change_diff_lines(lines, "linux" + kernel)
	if len(lines) > 1:
		if lsyncflag > 0:
			collected_logs, dead = collect_cvs_logs(alsa, from_cvs_time, to_cvs_time)
			os.chdir(get_bk_root())
			print 'Updating file %s' % kfile
			if not nbkflag and not dead:
				if os.system('bk edit %s' % kfile):
					sys.exit(1)
			if nbkflag:
				if os.system('cp -avf %s %s' % (afile, kfile)):
					sys.exit(1)
				if os.system('bk new %s' % kfile):
					sys.exit(1)
				nbkflag = 0
			elif dead:
				if os.system('bk rm %s' % kfile):
					sys.exit(1)
			else:
				if os.system('cp -avf %s %s' % (afile, kfile)):
					sys.exit(1)
				if os.system('bk ci -y"ksync" %s' % kfile):
					sys.exit(1)
			tmpfile = '/tmp/ksyncABCD1234'
			fp = open(tmpfile, 'w+')
			if alsa == '/include/version.h':
				collected_logs = 'Updated date/time/version from the ALSA CVS tree'
			fp.write(collected_logs)
			fp.close()
			if os.system('bk comments -Y%s %s' % (tmpfile, kfile)):
				write_to_patch_update_file(lines)
				FATAL_LSYNC_ERROR = 1
			os.remove(tmpfile)
		else:
			print_file(sys.stdout, lines)
	if ncvsflag:
		os.remove(afile)
	if nbkflag:
		os.remove(kfile)

def do_kernel_alsa_diff(kernel, alsa):
	afile = get_cvs_root() + alsa;
	kfile = get_bk_root() + kernel;
	if not os.path.exists(afile):
		update_cvs_file(alsa)
	if not os.path.exists(kfile):
		update_bk_file(kfile)
	cmd = 'diff -uN %s %s' % (afile, kfile)
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	lines = change_diff_lines(lines, alsa)
	print_file(sys.stdout, lines)

def show_last_changeset():
	os.chdir(get_bk_root())
	cmd = 'bk prs -r+ ChangeSet'
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
        print '# This is an automatically generated patch'
        print '# Project: Advanced Linux Sound Architecture (ALSA)'
        print '# Tool: ksync (path in CVS repository: alsa-kernel/scripts/ksync)'
        print '# Generated: %s' % time.strftime("%a, %d %b %Y %H:%M:%S +0000", time.gmtime(time.time()))
        print '# Source: ALSA CVS (cvs.alsa-project.org:/cvsroot/alsa)'
        print '# Kernel ChangeSet:'
	print_file_comment(sys.stdout, lines, '  ')
	print '#'

def diffall(reverse, from_cvs_time = 0, to_cvs_time = 0):
	lsyncflag = 0
	if from_cvs_time or to_cvs_time:
		lsyncflag = 1
	cdirs, cfiles = get_cvs_files(get_cvs_root(), '/')
	bdirs, bfiles = get_bk_files(get_bk_root(), '/')
	print 'BKROOT = %s' % BKROOT
	show_last_changeset()
	for d in ALSA_FORCE_DIR:
		if len(d) == 0:
			continue
		if cdirs.count(d) == 0:
			cdirs.append(d)
			if d[-1] != '/':
				d = d + '/'
			if d != '/':
				cdirs1, cfiles1 = get_cvs_files(get_cvs_root(), d)
				cdirs = cdirs + cdirs1
				cfiles = cfiles + cfiles1
	for d in KERNEL_FORCE_DIR:
		if len(d) == 0:
			continue
		if bdirs.count(d) == 0:
			bdirs.append(d)
			if d[-1] != '/':
				d = d + '/'
			if d != '/':
				bdirs1, bfiles1 = get_bk_files(get_bk_root(), d)
				bdirs = bdirs + bdirs1
				bfiles = bfiles + bfiles1
	cfiles = cfiles + ALSA_FORCE
	bfiles = bfiles + KERNEL_FORCE
	for f in ALSA_EXCLUDE:
		cfiles.remove(f)
	for f in KERNEL_EXCLUDE:
		bfiles.remove(f)
	first = 1
	for d in cdirs:
		dm = d
		d = remap_alsa(dm)
		if not bdirs.count(d):
			if first:
				print '# Added directories to Kernel Tree:'
				first = 0
			print '#   %s (%s)' % (dm, d)
	first = 1
	for d in bdirs:
		dm = d
		d = remap_kernel(dm)
		if not cdirs.count(d):
			if first:
				print '# Removed directories from Kernel Tree:'
				first = 0
			print '#   %s (%s)' % (dm, d)
	first = 1
	for f in cfiles:
		df = f
		f = remap_alsa_file(df)
		if not bfiles.count(f):
			if first:
				print '# Added files to Kernel Tree:'
				first = 0
			print '#   %s (%s)' % (df, f)
	first = 1
	for f in bfiles:
		df = f
		f = remap_kernel_file(df)
		if not cfiles.count(f):
			if first:
				print '# Removed files from Kernel Tree:'
				first = 0
			print '#   %s (%s)' % (df, f)
	print '\n'
	for f in cfiles:
		df = f
		f = remap_alsa_file(df)
		if not reverse:
			do_alsa_kernel_diff(df, f, from_cvs_time, to_cvs_time)
		else:
			do_kernel_alsa_diff(f, df)
		if bfiles.count(f):
			bfiles.remove(f)
	for f in bfiles:
		df = f
		f = remap_kernel_file(df)
		if not reverse:
			do_alsa_kernel_diff(f, df, from_cvs_time, to_cvs_time)
		else:
			do_kernel_alsa_diff(df, f)
		if cfiles.count(f):
			cfiles.remove(f)
	update_cvs_file('include/version.h')
	modify_version_file()
	if not reverse:
		do_alsa_kernel_diff('/include/version.h', '/include/sound/version.h', from_cvs_time, to_cvs_time)
	else:
		do_kernel_alsa_diff('/include/sound/version.h', '/include/version.h')
	os.remove(get_cvs_root() + '/include/version.h')
	update_cvs_file('include/version.h')

def get_last_lsync_time():
	os.chdir(get_bk_root())
	os.system('bk get -q include/sound/version.h')
	fp = open('include/sound/version.h', 'r')
	lines = fp.readlines()
	fp.close()
	if lines[2][0:24] != '#define CONFIG_SND_DATE ':
		print 'Error, unexpected include/sound/version.h in BK directory'
		print lines[2]
		sys.exit(1)
	str = lines[2][27:-7]
	t = time.mktime(time.strptime(str, '%a %b %d %H:%M:%S %Y'))
	return t + time.timezone

def get_last_changeset():
	os.chdir(get_bk_root())
	os.system('bk get -q Makefile')
	fp = open('Makefile', 'r')
	lines = fp.readlines()
	fp.close()
	kernel1 = '?'
	kernel2 = '?'
	kernel3 = '?'
	kernel4 = ''
	for line in lines:
		if line[0:10] == 'VERSION = ':
			kernel1 = line[10:-1]
		elif line[0:13] == 'PATCHLEVEL = ':
			kernel2 = line[13:-1]
		elif line[0:11] == 'SUBLEVEL = ':
			kernel3 = line[11:-1]
		elif line[0:15] == 'EXTRAVERSION = ':
			kernel4 = line[15:-1]
	kernel = kernel1 + '.' + kernel2 + '.' + kernel3 + kernel4
	cmd = 'bk prs -r+ ChangeSet'
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	cs = '0.0'
	for line in lines:
		line = line[:-1]
		words = string.split(line, ' ')
		if words[0] == 'D':
			cs = words[1]
		elif words[0] == 'S':
			kernel = words[1][1:]
	return cs, kernel

def filename(ver = 1):
	cs, kernel = get_last_changeset()
        print 'alsa-%s-%s-linux-%s-cs%s.patch' % (time.strftime("%Y-%m-%d", time.gmtime(time.time())), ver, kernel, cs)	

def kdiffs(cs = '1.403.57.48'):
	os.chdir(get_bk_root())
	cmd = 'sh -c \'bk rset -hr%s.. | grep -E "^(sound/|include/sound/)" | grep -E -v "^sound/oss/" | bk gnupatch -du\'' % cs
	fp = os.popen(cmd)
	lines = fp.readlines()
	fp.close()
	print_file(sys.stdout, lines)

def parse_time(str):
	args = string.split(str, '/')
	if len(args) < 3:
		args.insert(0, time.strftime("%Y", time.gmtime(time.time())))
	if len(args) != 3:
		print 'Bad date syntax'
		sys.exit(0)
	str = args[0] + ' ' + args[1] + ' ' + args[2]
	t = time.mktime(time.strptime(str, '%Y %m %d'))
	return t - time.timezone

def main():
	global CVSROOT, BKROOT, PATCH_UPDATE, ALSA_MAP, KERNEL_MAP
	try:
		opts, args = getopt.getopt(sys.argv[1:], 'hB:C:',
					   ['cvsroot=', 'bkroot=', 'help']);
	except getopt.error, msg:
		usage(1, msg)

	cwd = os.getcwd()

	# parse the options
	for opt, arg in opts:
		if opt in ('-h', '--help'):
			usage(0)
		elif opt == '--cvsroot':
			CVSROOT = arg
		elif opt == '--bkroot':
			BKROOT = arg

	for k in ALSA_MAP.keys():
		KERNEL_MAP[ALSA_MAP[k]] = k

	if not args:
		print 'Command not specified'
		sys.exit(1)
	if args[0] == 'diffall' or args[0] == 'linux-sound' or args[0] == 'work':
		reverse=0
		if args[0] == 'linux-sound':
			BKROOT = '~/bk/linux-sound/linux-sound'
		elif args[0] == 'work':
			BKROOT = '~/bk/linux-sound/work'
		if len(args) > 1:
			if args[1] == '-r':
				reverse=1
			else:
				print 'Ignoring extra arguments %s' % args[1:]
		diffall(reverse)
	elif args[0] == 'lsync':
		to_cvs_time = 0
		patch = ''
		if len(args) > 1:
			if args[1] == "last":
				BKROOT = '~/bk/linux-sound/linux-sound'
				xtime = get_last_lsync_time()
				print time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(xtime))
				return
			to_cvs_time = parse_time(args[1])
		if len(args) > 2:
			patch = os.path.abspath(os.path.expanduser(args[2]))
		else:
			npatch = os.path.abspath('kchanges/%s' % time.strftime("%Y-%m-%d", time.gmtime(to_cvs_time)))
			if os.path.exists(npatch):
				print 'Using kernel patch %s' % npatch
				patch = npatch

		if to_cvs_time > 0:
			CVSROOT = '~/alsa.local'
			os.chdir(os.path.expanduser('~/'))
			os.system('rm -rf alsa.local')
			os.system('mkdir alsa.local')
			os.chdir(os.path.expanduser('~/alsa.local'))
			os.system('cvs -d/home/src/alsa co -P %s alsa-driver alsa-kernel' % get_cvs_date_param1(to_cvs_time))
			if os.path.exists(patch):
				os.chdir(os.path.expanduser('~/alsa.local/alsa-kernel'))
				os.system('patch -p2 < %s' % patch)
				print 'Is this ok? Press Ctrl-C to abort...'
				sys.stdin.readline()

		BKROOT = '~/bk/linux-sound/work'
		os.chdir(os.path.expanduser('~/bk/linux-sound'))
		os.system('rm -rf work')
		os.system('bk clone -l linux-sound work')

		if os.path.exists(os.path.expanduser(PATCH_UPDATE)):
			os.remove(os.path.expanduser(PATCH_UPDATE))

		from_cvs_time = get_last_lsync_time()
		if to_cvs_time > 0 and to_cvs_time <= from_cvs_time:
			print 'Time < last_lsync_time (%s)' % time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(from_cvs_time))
			sys.exit(1)
		diffall(0, from_cvs_time, to_cvs_time)
		if FATAL_LSYNC_ERROR > 0:
			print 'Error during merge, see %s file...' % PATCH_UPDATE
	elif args[0] == 'cvslocal':
		if len(args) <= 1:
			print 'Specify time, please'
			sys.exit(1)
		to_cvs_time = parse_time(args[1])
		CVSROOT = '~/alsa.local'
		os.chdir(os.path.expanduser('~/'))
		os.system('rm -rf alsa.local')
		os.system('mkdir alsa.local')
		os.chdir(os.path.expanduser('~/alsa.local'))
		os.system('cvs -d/home/src/alsa co -P %s alsa-driver alsa-kernel' % get_cvs_date_param1(to_cvs_time))
	elif args[0] == 'filename':
		ver = 1
		if len(args) > 1:
			ver = args[1]
		filename(ver)
	elif args[0] == 'kdiffs':
		if len(args) > 1:
			kdiffs(args[1])
		else:
			kdiffs()
	else:
		print 'Unknown command %s' % args[0]
		sys.exit(1)

if __name__ == '__main__':
	main()
	sys.exit(0)
