1
0
mirror of https://github.com/gryf/uc1541.git synced 2026-01-14 14:24:11 +01:00

Working version of the script

This commit is contained in:
2012-09-24 21:04:56 +02:00
commit 5e273677f0

169
uc1541 Executable file
View File

@@ -0,0 +1,169 @@
#! /usr/bin/env python
"""
UC1541 Virtual filesystem
This extfs provides an access to disk image files for the Commodore
VIC20/C64/C128. It requires the utility c1541 that comes bundled with Vice,
the emulator for the VIC20, C64, C128 and other computers made by Commodore.
Author: Roman 'gryf' Dobosz <gryf73@gmail.com>
Date: 2012-08-07
Version: 1.0
Licence: BSD
"""
import sys
import re
import os
from subprocess import Popen, PIPE
from argparse import ArgumentParser
class Uc1541(object):
"""
Class for interact with c1541 program and MC
"""
PRG = re.compile(r'(\d+)\s+"([^"]*)".+?\s(del|prg)([\s<])')
def __init__(self, archname):
self.arch = archname
self.out = ''
self.err = ''
def list(self):
"""
List contents of D64 image.
Convert filenames to be unix filesystem friendly
Add suffix to show user what kind of file do he dealing with.
"""
if not self._call_command('list'):
return self._show_error()
for line in self.out.split("\n"):
if Uc1541.PRG.match(line):
blocks, fname, ext, rw = Uc1541.PRG.match(line).groups()
if '/' in fname:
fname = fname.replace('/', '\\')
rw = rw.strip() and "-" or "w"
#fname = ".".join([fname, ext])
sys.stdout.write("-r%s-r--r-- 1 %-8d %-8d %8d Jan 01 1980"
" %s\n" % (rw, os.getuid(), os.getgid(),
int(blocks) * 256, fname))
return 0
def rm(self, dst):
"""
Remove file from D64 image
"""
dst = self._correct_fname(dst)
if not self._call_command('delete', dst=dst):
return self._show_error()
# In case of error during removing, ERRORCODE is sent to stdout
# instead of stderr AND 'ERRORCODE 1' means: # 'everything fine'
if '\nERRORCODE 1\n' in self.out:
return 0
sys.exit(self.out)
def copyin(self, dst, src):
"""
Copy file to the D64 image. Destination filename has to be corrected.
"""
dst = self._correct_fname(dst)
if not self._call_command('write', src=src, dst=dst):
return self._show_error()
return 0
def copyout(self, src, dst):
"""
Copy file form the D64 image. Source filename has to be corrected,
since it's representaion differ from the real one inside D64 image.
"""
src = self._correct_fname(src)
if not self._call_command('read', src=src, dst=dst):
return self._show_error()
return 0
def _correct_fname(self, fname):
"""
Correct filenames containing backslashes (since in unices slash in
filenames is forbidden, and on PET ASCII there is no backslash, but
slash in filenames is accepted) and make it into slash. Also remove
.del/.prg suffix, since destination, correct file will always be prg.
"""
if "\\" in fname:
fname = fname.replace('\\', '/')
#if fname.lower().endswith('.prg') or fname.lower().endswith('.del'):
# fname = fname[:-4]
return fname
def _show_error(self):
"""
Pass out error output from c1541 execution
"""
sys.exit(self.err)
def _call_command(self, cmd, src=None, dst=None):
"""
Return status of the provided command, which can be one of:
write
read
delete
dir/list
"""
command = ['c1541', '-attach', self.arch, '-%s' % cmd]
if src and dst:
command.append(src)
command.append(dst)
elif src or dst:
command.append(src and src or dst)
self.out, self.err = Popen(command, stdout=PIPE,
stderr=PIPE).communicate()
return not self.err
if __name__ == "__main__":
parser = ArgumentParser()
subparsers = parser.add_subparsers(help='supported commands')
parser_list = subparsers.add_parser('list', help="List contents of D64 "
"image")
parser_copyin = subparsers.add_parser('copyin', help="Copy file into D64 "
"image")
parser_copyout = subparsers.add_parser('copyout', help="Copy file out of "
"D64 image")
parser_rm = subparsers.add_parser('rm', help="Delete file from D64 image")
parser_list.add_argument('ARCH', help="D64 Image filename")
parser_list.set_defaults(func=lambda a: Uc1541(a.ARCH).list())
parser_copyin.add_argument('ARCH', help="D64 Image filename")
parser_copyin.add_argument('SRC', help="Source filename")
parser_copyin.add_argument('DST', help="Destination filename (to be "
"written into D64 image)")
parser_copyin.set_defaults(func=lambda a: Uc1541(a.ARCH). \
copyin(a.SRC, a.DST))
parser_copyout.add_argument('ARCH', help="D64 Image filename")
parser_copyout.add_argument('SRC', help="Source filename (to be read from"
" D64 image")
parser_copyout.add_argument('DST', help="Destination filename")
parser_copyout.set_defaults(func=lambda a: Uc1541(a.ARCH). \
copyout(a.SRC, a.DST))
parser_rm.add_argument('ARCH', help="D64 Image filename")
parser_rm.add_argument('DST', help="File inside D64 image to be deleted")
parser_rm.set_defaults(func=lambda a: Uc1541(a.ARCH).rm(a.DST))
args = parser.parse_args()
args.func(args)