Acorn CDs

Matthew Wilcox (willy@odie.barnet.ac.uk)
Tue, 31 Mar 1998 10:46:34 +0100 (BST)


This patch against version 2.1.89 extends the Linux iso9660 filing system
to recognise Acorn extensions to CDROMs. It replaces `_' with `!' where
appropriate and appends `,xxx' to files which gives you filetypes when
viewed over NFS. It adds a new map type option to the driver; I felt
this was more appropriate than the `noacorn' option which I originally
implemented. I can't imagine anyone wanting to use all-caps-with-.;1
_and_ Acorn extensions since it rather misses the point. I've also
changed the driver to default to acorn mappings by default. Since it
implements a superset of the map=normal functionality (by calling the same
function!) and will appear to be identical for non-acorn CDs, it seemed
reasonable.

If any other vendor has something similar that should be supported,
I've thought of a better way, but it would be slower and I don't think
it's worth it until I see a CD-ROM with other extensions.

diff -ur linux/Documentation/filesystems/isofs.txt linuxn/Documentation/filesystems/isofs.txt
--- linux/Documentation/filesystems/isofs.txt Mon Mar 16 19:25:34 1998
+++ linuxn/Documentation/filesystems/isofs.txt Tue Mar 17 01:22:52 1998
@@ -21,7 +21,8 @@
check=strict Matches only filenames with the exact same case
cruft Try to handle badly formatted CDs.
map=off Do not map non-rockridge filenames to lowercase
- map=normal Map rockridge filenames to lowercase
+ map=normal Map non-rockridge filenames to lowercase
+ map=acorn As map=normal but also apply Acorn extensions if present
mode=xxx Sets the permissions on files to xxx
nojoliet Ignore Joliet extensions if they are present.
norock Ignore rockridge extensions if they are present.
diff -ur linux/fs/isofs/dir.c linuxn/fs/isofs/dir.c
--- linux/fs/isofs/dir.c Mon Mar 16 19:26:36 1998
+++ linuxn/fs/isofs/dir.c Tue Mar 17 01:27:09 1998
@@ -91,6 +91,32 @@
return i;
}

+/* Acorn extensions written by Matthew Wilcox <willy@bofh.ai> 1998 */
+int get_acorn_filename(struct iso_directory_record * de,
+ char * retname, struct inode * inode)
+{
+ int std;
+ unsigned char * chr;
+ int retnamlen = isofs_name_translate(de->name,
+ de->name_len[0], retname);
+ if (retnamlen == 0) return 0;
+ std = sizeof(struct iso_directory_record) + de->name_len[0];
+ if (std & 1) std++;
+ if ((*((unsigned char *) de) - std) != 32) return retnamlen;
+ chr = ((unsigned char *) de) + std;
+ if (strncmp(chr, "ARCHIMEDES", 10)) return retnamlen;
+ if ((*retname == '_') && ((chr[19] & 1) == 1)) *retname = '!';
+ if (((de->flags[0] & 2) == 0) && (chr[13] == 0xff)
+ && ((chr[12] & 0xf0) == 0xf0))
+ {
+ retname[retnamlen] = ',';
+ sprintf(retname+retnamlen+1, "%3.3x",
+ ((chr[12] & 0xf) << 8) | chr[11]);
+ retnamlen += 4;
+ }
+ return retnamlen;
+}
+
/*
* This should _really_ be cleaned up some day..
*/
@@ -230,15 +256,17 @@
p = tmpname;
} else
#endif
- {
- if (inode->i_sb->u.isofs_sb.s_mapping == 'n') {
- len = isofs_name_translate(de->name, de->name_len[0],
- tmpname);
- p = tmpname;
- } else {
- p = de->name;
- len = de->name_len[0];
- }
+ if (inode->i_sb->u.isofs_sb.s_mapping == 'a') {
+ len = get_acorn_filename(de, tmpname, inode);
+ p = tmpname;
+ } else
+ if (inode->i_sb->u.isofs_sb.s_mapping == 'n') {
+ len = isofs_name_translate(de->name,
+ de->name_len[0], tmpname);
+ p = tmpname;
+ } else {
+ p = de->name;
+ len = de->name_len[0];
}
}
if (len > 0) {
diff -ur linux/fs/isofs/inode.c linuxn/fs/isofs/inode.c
--- linux/fs/isofs/inode.c Mon Mar 16 19:26:36 1998
+++ linuxn/fs/isofs/inode.c Tue Mar 17 01:40:25 1998
@@ -92,7 +92,7 @@
{
char *this_char,*value;

- popt->map = 'n';
+ popt->map = 'a';
popt->rock = 'y';
popt->joliet = 'y';
popt->cruft = 'n';
@@ -151,10 +151,11 @@
} else
#endif
if (!strcmp(this_char,"map") && value) {
- if (value[0] && !value[1] && strchr("on",*value))
+ if (value[0] && !value[1] && strchr("ano",*value))
popt->map = *value;
else if (!strcmp(value,"off")) popt->map = 'o';
else if (!strcmp(value,"normal")) popt->map = 'n';
+ else if (!strcmp(value,"acorn")) popt->map = 'a';
else return 0;
}
else if (!strcmp(this_char,"check") && value) {
diff -ur linux/fs/isofs/namei.c linuxn/fs/isofs/namei.c
--- linux/fs/isofs/namei.c Wed Dec 3 12:24:29 1997
+++ linuxn/fs/isofs/namei.c Tue Mar 17 01:35:33 1998
@@ -178,6 +178,9 @@
dlen = get_joliet_filename(de, dir, page);
dpnt = page;
#endif
+ } else if (dir->i_sb->u.isofs_sb.s_mapping == 'a') {
+ dlen = get_acorn_filename(de, page, dir);
+ dpnt = page;
} else if (dir->i_sb->u.isofs_sb.s_mapping == 'n') {
for (i = 0; i < dlen; i++) {
c = dpnt[i];
diff -ur linux/include/linux/iso_fs.h linuxn/include/linux/iso_fs.h
--- linux/include/linux/iso_fs.h Mon Mar 16 19:25:49 1998
+++ linuxn/include/linux/iso_fs.h Mon Mar 16 21:05:09 1998
@@ -182,6 +182,7 @@
extern int find_rock_ridge_relocation(struct iso_directory_record *, struct inode *);

int get_joliet_filename(struct iso_directory_record *, struct inode *, unsigned char *);
+int get_acorn_filename(struct iso_directory_record *, char *, struct inode *);

/* The stuff that follows may be totally unneeded. I have not checked to see
which prototypes we are still using. */
@@ -227,6 +228,3 @@
#endif /* __KERNEL__ */

#endif
-
-
-
diff -ur linux/include/linux/iso_fs_sb.h linuxn/include/linux/iso_fs_sb.h
--- linux/include/linux/iso_fs_sb.h Mon Mar 16 19:25:49 1998
+++ linuxn/include/linux/iso_fs_sb.h Tue Mar 17 01:43:54 1998
@@ -30,10 +30,3 @@
};

#endif
-
-
-
-
-
-
-

-- 
Set Alias$Case Set Alias$[ |||| |MSet Alias$Otherwise Set Alias$[ \ Matthew
"" |MSet Alias$When If %0=%%0 Then Set Alias$[ "" ||MIf %0=%%0    \ Wilcox
Then Set Alias$Otherwise Set Alias$[ |||||||||||||||| ||MIf       \
%0=%%0 Then Set Alias$When Set Alias$[ ||||||||||||||||

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu