Removed archive handlers, as they are on separate repos now.

This commit is contained in:
2022-10-02 12:44:14 +02:00
parent 01b4bf7a41
commit 44c9de2df9
4 changed files with 0 additions and 626 deletions

View File

@@ -1,122 +0,0 @@
diff -ur unadf-0.7.11a.orig/Demo/unadf.c unadf-0.7.11a/Demo/unadf.c
--- unadf-0.7.11a.orig/Demo/unadf.c 2013-05-12 17:59:51.214905177 +0200
+++ unadf-0.7.11a/Demo/unadf.c 2013-05-12 17:50:06.843420519 +0200
@@ -58,6 +58,7 @@
puts(" -r : lists directory tree contents");
puts(" -c : use dircache data (must be used with -l)");
puts(" -s : display entries logical block pointer (must be used with -l)");
+ puts(" -m : display file comments, if exists (must be used with -l)");
putchar('\n');
puts(" -v n : mount volume #n instead of default #0 volume");
putchar('\n');
@@ -65,7 +66,8 @@
puts(" -d dir : extract to 'dir' directory");
}
-void printEnt(struct Volume *vol, struct Entry* entry, char *path, BOOL sect)
+void printEnt(struct Volume *vol, struct Entry* entry, char *path, BOOL sect,
+ BOOL comment)
{
/* do not print the links entries, ADFlib do not support them yet properly */
if (entry->type==ST_LFILE || entry->type==ST_LDIR || entry->type==ST_LSOFT)
@@ -89,7 +91,7 @@
printf("%s/",entry->name);
else
printf("%s",entry->name);
- if (entry->comment!=NULL && strlen(entry->comment)>0)
+ if (comment && entry->comment!=NULL && strlen(entry->comment)>0)
printf(", %s",entry->comment);
putchar('\n');
@@ -199,13 +201,14 @@
}
-void printTree(struct Volume *vol, struct List* tree, char* path, BOOL sect)
+void printTree(struct Volume *vol, struct List* tree, char* path, BOOL sect,
+ BOOL comment)
{
char *buf;
struct Entry* entry;
while(tree) {
- printEnt(vol, tree->content, path, sect);
+ printEnt(vol, tree->content, path, sect, comment);
if (tree->subdir!=NULL) {
entry = (struct Entry*)tree->content;
if (strlen(path)>0) {
@@ -215,11 +218,11 @@
return;
}
sprintf(buf,"%s/%s", path, entry->name);
- printTree(vol, tree->subdir, buf, sect);
+ printTree(vol, tree->subdir, buf, sect, comment);
free(buf);
}
else
- printTree(vol, tree->subdir, entry->name, sect);
+ printTree(vol, tree->subdir, entry->name, sect, comment);
}
tree = tree->next;
}
@@ -370,12 +373,10 @@
int main(int argc, char* argv[])
{
int i, j;
- BOOL rflag, lflag, xflag, cflag, vflag, sflag, dflag, pflag, qflag;
+ BOOL rflag, lflag, xflag, cflag, vflag, sflag, dflag, pflag, qflag, mflag;
struct List* files, *rtfiles;
char *devname, *dirname;
- char strbuf[80];
unsigned char *extbuf;
- int vInd, dInd, fInd, aInd;
BOOL nextArg;
struct Device *dev;
@@ -389,8 +390,7 @@
exit(0);
}
- rflag = lflag = cflag = vflag = sflag = dflag = pflag = qflag = FALSE;
- vInd = dInd = fInd = aInd = -1;
+ rflag = lflag = cflag = vflag = sflag = dflag = pflag = qflag = mflag = FALSE;
xflag = TRUE;
dirname = NULL;
devname = NULL;
@@ -430,6 +430,9 @@
case 's':
sflag = TRUE;
break;
+ case 'm':
+ mflag = TRUE;
+ break;
case 'c':
cflag = TRUE;
break;
@@ -522,13 +525,13 @@
if (!rflag) {
cell = list = adfGetDirEnt(vol,vol->curDirPtr);
while(cell) {
- printEnt(vol,cell->content,"", sflag);
+ printEnt(vol,cell->content,"", sflag, mflag);
cell = cell->next;
}
adfFreeDirList(list);
} else {
cell = list = adfGetRDirEnt(vol,vol->curDirPtr,TRUE);
- printTree(vol,cell,"", sflag);
+ printTree(vol,cell,"", sflag, mflag);
adfFreeDirList(list);
}
}else if (xflag) {
diff -ur unadf-0.7.11a.orig/Demo/unadf.usage unadf-0.7.11a/Demo/unadf.usage
--- unadf-0.7.11a.orig/Demo/unadf.usage 2006-12-03 15:27:00.000000000 +0100
+++ unadf-0.7.11a/Demo/unadf.usage 2013-05-12 17:40:23.116966854 +0200
@@ -3,6 +3,7 @@
-r : lists directory tree contents
-c : use dircache data (must be used with -l)
-s : display entries logical block pointer (must be used with -l)
+ -m : display file comments, if exists (must be used with -l)
-v n : mount volume #n instead of default #0 volume

187
uadf
View File

@@ -1,187 +0,0 @@
#!/usr/bin/env python3
"""
UADF Virtual filesystem
This extfs provides quick and dirty read-only access to disk image files for
the Commodore Amiga adf or adz (gzipped adfs) and dms.
It requires the unadf utility, unfortunately there is no original sources,
since authors page doesn't exists anymore. Luckily, there is a copy of the
source (and useful patches) in Debian repository:
http://packages.debian.org/sid/unadf
There should be one change made to the source of unadf, though. While using
"-lr" switch it by default also displays comments, separated by the comma.
However there is no way to distinguish where filename ends and comment starts,
if comment or filename already contains any comma.
The patched sources are available from: https://github.com/lclevy/ADFlib
It also requires xdms utility, for optional dms support.
Changelog:
1.3 Switch to Python3
1.2 Added failsafe for filenames in archive with spaces and nodos message.
1.1 Moved common code into extfslib library
1.0 Initial release
Author: Roman 'gryf' Dobosz <gryf73@gmail.com>
Date: 2019-06-30
Version: 1.3
Licence: BSD
"""
import sys
import re
import os
import gzip
from subprocess import check_output, check_call, CalledProcessError
from tempfile import mkstemp, mkdtemp
import shutil
from extfslib import Archive, parse_args
class UAdf(Archive):
"""
Class for interact with c1541 program and MC
"""
LINE_PAT = re.compile(b'\s*(?P<size>\d+)?'
b'\s{2}(?P<date>\d{4}/\d{2}/\d{2})'
b'\s{2}\s?(?P<time>\d+:\d{2}:\d{2})'
b'\s{2}(?P<fpath>.*)')
ARCHIVER = b"unadf"
DMS = b"xdms"
CMDS = {"list": b"-lr",
"read": b"r",
"write": b"w",
"delete": b"d"}
DATETIME = b"%s-%s-%s %02d:%s"
def __init__(self, fname):
"""Prepare archive content for operations"""
self._clean = True
self._arch = fname
if fname.lower().endswith(".adz"):
self._ungzip()
if fname.lower().endswith(".dms"):
self._undms()
super(UAdf, self).__init__(self._arch)
def __del__(self):
"""Cleanup"""
if not self._clean:
try:
os.unlink(self._arch)
except OSError:
pass
def _parse_dt(self, date, time):
"""Return parsed datetime which fulfill extfs standards date."""
year, month, day = date.split(b"/")
hours, minutes, _unused = time.split(b":")
return self.DATETIME % (month, day, year, int(hours), minutes)
def _ungzip(self):
"""Create temporary file for ungzipped adf file since unadf does not
accept gzipped content in any way including reading from stdin."""
fdesc, tmp_fname = mkstemp(suffix=".adf")
os.close(fdesc)
with gzip.open(self._arch) as gobj:
with open(tmp_fname, "wb") as fobj:
fobj.write(gobj.read())
self._arch = tmp_fname
self._clean = False
def _undms(self):
"""Create temporary adf file extracted from dms."""
fdesc, tmp_fname = mkstemp(suffix=".adf")
os.close(fdesc)
try:
check_call([self.DMS, b'-q', b'u', self._arch, "+" + tmp_fname])
self._arch = tmp_fname
self._clean = False
except (CalledProcessError, OSError):
pass
def _get_dir(self):
"""Retrieve directory"""
contents = []
with open(os.devnull, "w") as fnull:
try:
out = check_output([self.ARCHIVER, self.CMDS['list'],
self._arch], stderr=fnull)
except CalledProcessError:
return contents
for line in out.split(b"\n"):
match = self.LINE_PAT.match(line)
if not match:
continue
match_entry = match.groupdict()
entry = {}
for key in match_entry:
entry[bytes(key, 'utf-8')] = match_entry[key]
del match_entry
entry[b'perms'] = b"-rw-r--r--"
if not entry[b'size']:
entry[b'perms'] = b"drwxr-xr-x"
entry[b'size'] = b"0"
entry[b'display_name'] = self._map_name(entry[b'fpath'])
entry[b'datetime'] = self._parse_dt(entry[b'date'], entry[b'time'])
entry[b'uid'] = bytes(str(self._uid), 'utf-8')
entry[b'gid'] = bytes(str(self._gid), 'utf-8')
contents.append(entry)
return contents
def list(self):
"""
Output list contents of adf image.
Convert filenames to be Unix filesystem friendly
Add suffix to show user what kind of file do he dealing with.
"""
if not self._contents:
sys.stderr.write("Nodos or archive error\n")
return 1
for entry in self._contents:
sys.stdout.buffer.write(self.ITEM % entry)
return 0
def copyout(self, src, dst):
"""Copy file form the adf image."""
real_src = self._get_real_name(src)
if not real_src:
raise IOError("No such file or directory")
if b" " in real_src:
sys.stderr.write("unadf is unable to operate on filepath with "
"space inside.\nUse affs to mount image and than"
" extract desired files.\n")
return 1
extract_dir = mkdtemp()
cmd = [self.ARCHIVER, self._arch, real_src, b"-d", extract_dir]
if check_call(cmd, stdout=open(os.devnull, 'wb'),
stderr=open(os.devnull, 'wb')) != 0:
shutil.rmtree(extract_dir)
sys.stderr.write("unadf returned with nonzero exit code\n")
return 1
shutil.move(os.path.join(bytes(extract_dir, "utf8"), real_src),
bytes(dst, "utf8"))
shutil.rmtree(extract_dir)
return 0
if __name__ == "__main__":
sys.exit(parse_args(UAdf))

182
ulha
View File

@@ -1,182 +0,0 @@
#!/usr/bin/env python3
"""
Lha Virtual filesystem executive for Midnight Commander.
Tested against python 3.6, lha[1] 1.14 and mc 4.8.22
[1] http://lha.sourceforge.jp
Changelog:
1.3 Switch to python3
1.2 Moved item pattern to extfslib module
1.1 Moved common code into extfslib library
1.0 Initial release
Author: Roman 'gryf' Dobosz <gryf73@gmail.com>
Date: 2019-06-30
Version: 1.3
Licence: BSD
"""
import os
import sys
import re
import shutil
from subprocess import call, check_call, CalledProcessError
from tempfile import mkdtemp, mkstemp
from extfslib import Archive, parse_args
class ULha(Archive):
"""Archive handle. Provides interface to MC's extfs subsystem"""
LINE_PAT = re.compile(b"^((?P<perms>[d-][rswx-]{9})|(\[generic\])|"
b"(\[unknown\]))"
b"((\s+\d+/\d+\s+)|(\s+))"
b"(?P<uid>)(?P<gid>)" # just for the record
b"(?P<size>\d+)"
b"\s+(\*{6}|\d+\.\d%)"
b"\s(?P<month>[JFMASOND][a-z]{2})\s+" # month
b"(?P<day>\d+)\s+" # day
b"(?P<yh>\d{4}|(\d{2}:\d{2}))" # year/hour
b"\s(?P<fpath>.*)")
ARCHIVER = b"lha"
CMDS = {"list": b"lq",
"read": b"pq",
"write": b"aq",
"delete": b"dq"}
DATETIME = b"%(month)s %(day)s %(yh)s"
def _get_dir(self):
"""Prepare archive file listing"""
contents = []
out = self._call_command("list")
if not out:
return
for line in out.split(b"\n"):
# -lhd- can store empty directories
perms = b"-rw-r--r--"
if line.endswith(bytes(os.path.sep, 'utf-8')):
line = line[:-1]
perms = b"drw-r--r--"
match = self.LINE_PAT.match(line)
if not match:
continue
match_entry = match.groupdict()
entry = {}
for key in match_entry:
entry[bytes(key, 'utf-8')] = match_entry[key]
del match_entry
# UID and GID sometimes can have strange values depending on
# the information that was written into archive. Most of the
# times I was dealing with Amiga lha archives, so that i don't
# really care about real user/group
entry[b'uid'] = bytes(str(self._uid), 'utf-8')
entry[b'gid'] = bytes(str(self._gid), 'utf-8')
entry[b'datetime'] = self.DATETIME % entry
if not entry[b'perms']:
entry[b'perms'] = perms
entry[b'display_name'] = self._map_name(entry[b'fpath'])
contents.append(entry)
return contents
def list(self):
"""Output contents of the archive to stdout"""
for entry in self._contents:
sys.stdout.buffer.write(self.ITEM % entry)
return 0
def rm(self, dst):
"""Remove file from archive"""
dst = self._get_real_name(dst)
# deleting with quiet option enabled will output nothing, so we get
# empty string here or None in case of error. Not smart.
if self._call_command('delete', dst=dst) is None:
return 1
return 0
def rmdir(self, dst):
"""Remove empty directory"""
dst = self._get_real_name(dst)
if not dst.endswith(bytes(os.path.sep, 'utf-8')):
dst += bytes(os.path.sep, 'utf-8')
if self._call_command('delete', dst=dst) is None:
return 1
return 0
def run(self, dst):
"""Execute file out of archive"""
fdesc, tmp_file = mkstemp()
os.close(fdesc)
result = 0
if self.copyout(dst, tmp_file) != 0:
result = 1
os.chmod(tmp_file, int("700", 8))
try:
result = call([tmp_file])
finally:
try:
os.unlink(tmp_file)
except OSError:
pass
return result
def mkdir(self, dst):
"""Create empty directory in archive"""
return self.copyin(dst)
def copyin(self, dst, src=None):
"""Copy file to the archive or create direcotry inside.
If src is empty, create empty directory with dst name."""
current_dir = os.path.abspath(os.curdir)
tmpdir = mkdtemp()
arch_abspath = os.path.realpath(self._arch)
os.chdir(tmpdir)
if src:
os.makedirs(os.path.dirname(dst))
shutil.copy2(src, dst)
else:
os.makedirs(dst)
try:
result = check_call([self.ARCHIVER.decode('utf-8'),
self.CMDS["write"].decode('utf-8'),
arch_abspath, dst])
except CalledProcessError:
return 1
finally:
os.chdir(current_dir)
shutil.rmtree(tmpdir)
return result
def copyout(self, src, dst):
"""Copy file out form archive."""
src = self._get_real_name(src)
fobj = open(dst, "wb")
try:
result = check_call([self.ARCHIVER, self.CMDS['read'], self._arch,
src], stdout=fobj)
except CalledProcessError:
return 1
finally:
fobj.close()
return result
if __name__ == "__main__":
sys.exit(parse_args(ULha))

135
ulzx
View File

@@ -1,135 +0,0 @@
#!/usr/bin/env python3
"""
Read only, Amiga LZX[1] archiver Virtual filesystem executive for Midnight
Commander.
Tested against python 3.6, unlzx[1] 1.1 and mc 4.8.22
[1] ftp://us.aminet.net/pub/aminet/misc/unix/unlzx.c.gz.readme
Changelog:
1.2 Use python3
1.1 Moved common code into extfslib library
1.0 Initial release
Author: Roman 'gryf' Dobosz <gryf73@gmail.com>
Date: 2019-06-30
Version: 1.2
Licence: BSD
"""
import os
import sys
import re
import shutil
from subprocess import call, CalledProcessError
from tempfile import mkdtemp, mkstemp
from extfslib import Archive, parse_args
class ULzx(Archive):
"""Archive handle. Provides interface to MC's extfs subsystem"""
LINE_PAT = re.compile(b"^\s+(?P<size>\d+)\s+"
b"((n/a)|\d+)\s"
b"(?P<time>\d{2}:\d{2}:\d{2})\s+"
b"(?P<date>\d+-[a-z]{3}-\d{4})\s"
b"(?P<perms>[h-][s-][p-][a-][r-][w-][e-][d-])\s"
b"\"(?P<fpath>.*)\"")
ARCHIVER = b"unlzx"
CMDS = {"list": b"-v",
"read": b"-x"}
DATETIME = b"%02d-%02d-%s %02d:%02d"
def _get_date(self, time, date):
"""Return MM-DD-YYYY hh:mm formatted date out of time and date
strings"""
month_list = [b"jan", b"feb", b"mar", b"apr", b"may", b"jun", b"jul",
b"aug", b"sep", b"oct", b"nov", b"dec"]
day, month, year = date.split(b"-")
month = month_list.index(month) + 1
hours, minutes, dummy = time.split(b":")
return self.DATETIME % (month, int(day), year, int(hours),
int(minutes))
def _get_dir(self):
"""Prepare archive file listing"""
contents = []
out = self._call_command("list")
if not out:
return
for line in out.split(b"\n"):
match = self.LINE_PAT.match(line)
if not match:
continue
match_entry = match.groupdict()
entry = {}
for key in match_entry:
entry[bytes(key, 'utf-8')] = match_entry[key]
del match_entry
entry[b'datetime'] = self._get_date(entry[b'time'], entry[b'date'])
entry[b'display_name'] = self._map_name(entry[b'fpath'])
entry[b'perms'] = b"-rw-r--r--" # lzx doesn't store empty dirs
entry[b'uid'] = bytes(str(self._uid), 'utf-8')
entry[b'gid'] = bytes(str(self._gid), 'utf-8')
contents.append(entry)
return contents
def list(self):
"""Output contents of the archive to stdout"""
for entry in self._contents:
sys.stdout.buffer.write(self.ITEM % entry)
return 0
def run(self, dst):
"""Execute file out of archive"""
fdesc, tmp_file = mkstemp()
os.close(fdesc)
result = 0
if self.copyout(dst, tmp_file) != 0:
result = 1
os.chmod(tmp_file, int("700", 8))
try:
result = call([tmp_file])
finally:
try:
os.unlink(tmp_file)
except OSError:
pass
return result
def copyout(self, src, dst):
"""Unfortunately, to copy one file out entire LZX archive have to be
extracted. For small archives is not a problem, but in relatively big
one it could be a performance issue."""
tmp_dir = mkdtemp()
src = self._get_real_name(src)
current_dir = os.path.abspath(os.curdir)
os.chdir(tmp_dir)
try:
with open(os.devnull, "w") as fnull:
result = call([self.ARCHIVER, self.CMDS['read'],
os.path.join(current_dir, self._arch)],
stdout=fnull, stderr=fnull)
if result == 0:
shutil.copy2(src, dst)
except CalledProcessError:
return 1
finally:
shutil.rmtree(tmp_dir)
os.chdir(current_dir)
return result
if __name__ == "__main__":
sys.exit(parse_args(ULzx))