From 5d97a75efbba287f345d82e1d364fd410519aa68 Mon Sep 17 00:00:00 2001 From: "T. Joseph Carter" Date: Fri, 7 Jul 2017 07:33:26 -0700 Subject: [PATCH] Move argument parsing out of legacy.py The point is to separate the CLI interface to cppo from the inner logic so that we can begin replacing the legacy code with proper implementations thereof. This isn't 100% complete in that regard--we still need to pass args to the legacy main function--but the part of cppo that will survive this whole process is now functionally isolated from the part that's likely to get replaced to a large degree. --- blocksfree/legacy.py | 61 ++----------------------- cppo | 104 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 58 deletions(-) create mode 100755 cppo diff --git a/blocksfree/legacy.py b/blocksfree/legacy.py index 803fad4..dc3c7a1 100755 --- a/blocksfree/legacy.py +++ b/blocksfree/legacy.py @@ -776,10 +776,6 @@ def quit_now(exitcode=0): shutil.rmtree('/tmp' + "/" + file) sys.exit(exitcode) -def usage(exitcode=1): - print(sys.modules[__name__].__doc__) - quit_now(exitcode) - def to_sys_name(name): if os.name == 'nt': if name[-1] == '.': @@ -1033,59 +1029,6 @@ def hexdump( def run_cppo(args: list): - while True: # breaks when there are no more arguments starting with dash - if len(args) == 1: - usage() - - elif args[1][0] != '-': - break - - elif args[1] == '-s': - g.afpsync_msg = False - args = args[1:] - - elif args[1] == '-n': - g.extract_in_place = True - args = args[1:] - - elif args[1] == '-uc': - g.casefold_upper = True - args = args[1:] - - elif args[1] == '-ad': - g.use_appledouble = True - g.prodos_names = True - args = args[1:] - - elif args[1] == '-shk': - g.src_shk = True - args = args[1:] - - elif args[1] == '-pro': - g.prodos_names = True - args = args[1:] - - elif args[1] == '-e': - g.use_extended = True - g.prodos_names = True - args = args[1:] - - elif args[1] == '-cat': - g.catalog_only = True - args = args[1:] - - else: - usage() - - if g.use_appledouble and g.use_extended: - usage() - if g.catalog_only: - if len(args) != 2: - usage() - else: - if len(args) not in (3, 4): - usage() - try: disk = Disk(args[1]) except IOError as e: @@ -1279,7 +1222,9 @@ def run_cppo(args: list): # enforce leading slash if ProDOS if (not g.src_shk and not g.dos33 and g.extract_file and (args[2][0] not in ('/', ':'))): - usage() + log.critical("Cannot extract {} from {}: " + "ProDOS volume name required".format(args[2], args[1])) + quit_now(2) if g.dos33: disk_name = (disk.diskname diff --git a/cppo b/cppo new file mode 100755 index 0000000..8ab1b93 --- /dev/null +++ b/cppo @@ -0,0 +1,104 @@ +#!/usr/bin/env python3 +# vim: set tabstop=4 shiftwidth=4 noexpandtab filetype=python: + +# Copyright (C) 2013-2016 Ivan Drucker +# Copyright (C) 2017 T. Joseph Carter +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# +# If interested, please see the file HISTORY.md for information about both the +# technical and licensing decisions that have gone into the rewriting of cppo. + +"""cppo: Copy/catalog files from a ProDOS/DOS 3.3/ShrinkIt image/archive. + +copy all files: cppo [options] imagefile target_directory +copy one file : cppo [options] imagefile /extract/path target_path +catalog image : cppo -cat [options] imagefile + +options: +-shk: ShrinkIt archive as source (also auto-enabled by filename). +-ad : Netatalk-compatible AppleDouble metadata files and resource forks. +-e : Nulib2-compatible filenames with type/auxtype and resource forks. +-uc : Copy GS/OS mixed case filenames as uppercase. +-pro: Adapt DOS 3.3 names to ProDOS and remove addr/len from file data. + +/extract/path examples: + /FULL/PRODOS/PATH (ProDOS image source) + "MY FILENAME" (DOS 3.3 image source) + Dir:SubDir:FileName (ShrinkIt archive source) + ++ after a file name indicates a GS/OS or Mac OS extended (forked) file. +Wildcard matching (*) is not supported and images are not validated. +ShrinkIt support requires Nulib2. cppo requires Python 2.6+ or 3.0+.""" + +import sys + +from blocksfree.legacy import g +import blocksfree.legacy + +def usage(exitcode=1): + print(sys.modules[__name__].__doc__) + sys.exit(exitcode) + +def cppo(args: list): + while True: # breaks when there are no more arguments starting with dash + if len(args) == 1: + usage() + + elif args[1][0] != '-': + break + + elif args[1] == '-s': + g.afpsync_msg = False + args = args[1:] + + elif args[1] == '-n': + g.extract_in_place = True + args = args[1:] + + elif args[1] == '-uc': + g.casefold_upper = True + args = args[1:] + + elif args[1] == '-ad': + g.use_appledouble = True + g.prodos_names = True + args = args[1:] + + elif args[1] == '-shk': + g.src_shk = True + args = args[1:] + + elif args[1] == '-pro': + g.prodos_names = True + args = args[1:] + + elif args[1] == '-e': + g.use_extended = True + g.prodos_names = True + args = args[1:] + + elif args[1] == '-cat': + g.catalog_only = True + args = args[1:] + + else: + usage() + + blocksfree.legacy.run_cppo(args) + +if __name__ == '__main__': + cppo(sys.argv)