diff -urN cdrtools-1.11/mkisofs/Makefile cdrtools-1.11-hacked/mkisofs/Makefile --- cdrtools-1.11/mkisofs/Makefile Sun Jul 21 15:17:15 2002 +++ cdrtools-1.11-hacked/mkisofs/Makefile Sat Jul 27 15:59:48 2002 @@ -38,6 +38,7 @@ scsi.c \ scsi_cdr.c cd_misc.c \ modes.c \ + archimedes.c \ apple.c volume.c desktop.c mac_label.c \ ifo_read.c dvd_file.c dvd_reader.c HFILES= apple.h bootinfo.h config.h defaults.h diskmbr.h exclude.h \ diff -urN cdrtools-1.11/mkisofs/archimedes.c cdrtools-1.11-hacked/mkisofs/archimedes.c --- cdrtools-1.11/mkisofs/archimedes.c Thu Jan 1 01:00:00 1970 +++ cdrtools-1.11-hacked/mkisofs/archimedes.c Sat Jul 27 15:59:05 2002 @@ -0,0 +1,143 @@ +/* + * File archimedes.c - generate ARCHIMEDES records for iso9660 filesystems. + + Ben Harris, 2002. + Loosely based on rock.c, which was written by Eric Youngdale (1993). + + Copyright 1993 Yggdrasil Computing, Incorporated + + 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, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#include +#include "mkisofs.h" +#include +#include + +/* + * I've never seen any real documentation of the ARCHIMEDES extension, but + * Stephen Borrill has provided the following: + * + * Directory record has 32 byte system use area + * + * 0-9 "ARCHIMEDES" + * 13121110 + * 10-13 Load address &FFFtttdd + * 17161514 + * 14-17 Execution address &dddddddd + * 21201918 + * 18-21 Attributes &ffffffaa + * 22-31 Reserved 0 + * + * ttt = filetype + * dd = date stamp (ignored - use directory record date) + * ffffff = filesystem specific attributes (bit 0 of offset 19 is + * set if initial underscore should be replaced by !) + * aa = RISCOS access permissions (ignore - read access is forced) + */ + +/* + * Buffer to build ARCHIMEDES attributes + */ +static int currlen = 0; + +static void +archimedes_date(result, crtime) + long *result; + time_t crtime; +{ + unsigned long baselow, basehigh, low, high, offlow, offhigh; + + /* + * RISC OS date stamps are five-byte integers counting + * centi-seconds since 1900-01-01 00:00:00Z. We only + * bother with the whole seconds, since there's no portable + * way to get sub-second resolution from stat() and it's not + * worth the hassle. To avoid using 64-bit integers, we build + * the result in two parts. + */ + + /* RISC OS representation of the Unix epoch (1970-01-01 00:00:00Z) */ + baselow = 0x6e996a00; + basehigh = 0x33; + + /* Short multiplication, using 16-bit digits */ + offlow = (((unsigned long)crtime & 0xffff) * 100); + offhigh = (((unsigned long)crtime >> 16) * 100) + (offlow >> 16); + offlow = (offlow & 0xffff) + ((offhigh & 0xffff) << 16); + offhigh >>= 16; + + low = baselow + offlow; + high = basehigh + offhigh + (low < baselow); + result[0] = low; + result[1] = high; +} + +int +generate_archimedes_attributes(whole_name, name, + s_entry, + statbuf, + lstatbuf, + deep_opt) + char *whole_name; + char *name; + struct directory_entry *s_entry; + struct stat *statbuf, + *lstatbuf; + int deep_opt; + +{ + unsigned char *p; + unsigned char arcext[32]; + unsigned long arcdate[2]; + int filetype; + unsigned long loadaddr = 0xffffff49; + unsigned long execaddr = 0x8a2169c1; + unsigned long attribs = 0x00000033; + + /* no need to fill in the ARCHIMEDES stuff if we won't see the file */ + if (s_entry->de_flags & INHIBIT_ISO9660_ENTRY) + return 0; + + /* Decide if this file needs the extension */ + p = strrchr(name, ','); + if ((p != NULL && + isxdigit(p[1]) && isxdigit(p[2]) && isxdigit(p[3]) && + p[4] == '\0') || name[0] == '!') { + archimedes_date(arcdate, lstatbuf->st_mtime); + if (p != NULL) + filetype = strtoul(p + 1, NULL, 16); + else + filetype = 0xffd; /* "Data" */ + + loadaddr = 0xfff00000 | (filetype << 8) | arcdate[1]; + execaddr = arcdate[0]; + attribs = 0x11; /* read-only for everyone */ + if (name[0] == '!') + attribs |= 0x100; + + memset(arcext, 0, 32); + memcpy(arcext, "ARCHIMEDES", 10); + + set_731(arcext + 10, loadaddr); + set_731(arcext + 14, execaddr); + set_731(arcext + 18, attribs); + + s_entry->archimedes_attributes = + (unsigned char *) e_malloc(32); + memcpy(s_entry->archimedes_attributes, arcext, 32); + return 32; + } + return 0; +} diff -urN cdrtools-1.11/mkisofs/mkisofs.8 cdrtools-1.11-hacked/mkisofs/mkisofs.8 --- cdrtools-1.11/mkisofs/mkisofs.8 Sun Jul 21 15:36:23 2002 +++ cdrtools-1.11-hacked/mkisofs/mkisofs.8 Sat Jul 27 15:59:05 2002 @@ -44,6 +44,11 @@ as longer filenames, uid/gid, posix permissions, symbolic links, block and character devices. .PP +.B mkisofs +is also capable of generating the +.B ARCHIMEDES +extension, used by RISC OS systems to store file type information. +.PP If Joliet or HFS hybrid command line options are specified, .B mkisofs will create additional filesystem meta data for Joliet or HFS. @@ -201,6 +206,16 @@ .br This violates the ISO9660 standard, but it happens to work on many systems. Use with caution. +.TP +.B \-archimedes +Generate ARCHIMEDES records for files and directories whose names +begin with an exclamation mark or end with a comma and three +hexadecimal digits. In the latter case, the hex digits will be used +to form the RISC OS type of the file. Note that the same file cannot +have both ARCHIMEDES and Rock Ridge records, and +.B mkisofs +will generate ARCHIMEDES records in preference. Also note that a CD +with both kinds of record violates the Rock Ridge specification. .TP .BI \-biblio " FILE Specifies the bibliographic file name. diff -urN cdrtools-1.11/mkisofs/mkisofs.c cdrtools-1.11-hacked/mkisofs/mkisofs.c --- cdrtools-1.11/mkisofs/mkisofs.c Sun Jul 21 12:59:35 2002 +++ cdrtools-1.11-hacked/mkisofs/mkisofs.c Sat Jul 27 16:04:15 2002 @@ -94,6 +94,7 @@ int use_genboot = 0; int use_RockRidge = 0; int use_Joliet = 0; +int use_ARCHIMEDES = 0; int verbose = 1; int debug = 0; int gui = 0; @@ -339,6 +340,8 @@ #define OPTION_CHECK_SESSION 1060 #define OPTION_FORCE_RR 1061 +#define OPTION_USE_ARCHIMEDES 1063 + #define OPTION_DEBUG 1062 #ifdef UDF @@ -410,6 +413,8 @@ '\0', "FILE", "Set Abstract filename", ONE_DASH}, {{"appid", required_argument, NULL, 'A'}, 'A', "ID", "Set Application ID", ONE_DASH}, + {{"archimedes", no_argument, NULL, OPTION_USE_ARCHIMEDES}, + '\0', NULL, "Generate ARCHIMEDES records", ONE_DASH}, {{"biblio", required_argument, NULL, OPTION_BIBLIO}, '\0', "FILE", "Set Bibliographic filename", ONE_DASH}, {{"cache-inodes", no_argument, NULL, OPTION_CACHE_INODES}, @@ -1864,6 +1869,9 @@ boot_info_table++; get_boot_entry(); current_boot_entry->boot_info_table = 1; + break; + case OPTION_USE_ARCHIMEDES: + use_ARCHIMEDES++; break; #ifdef APPLE_HYB case OPTION_HFS_TYPE: diff -urN cdrtools-1.11/mkisofs/mkisofs.h cdrtools-1.11-hacked/mkisofs/mkisofs.h --- cdrtools-1.11/mkisofs/mkisofs.h Sun Jul 21 15:00:29 2002 +++ cdrtools-1.11-hacked/mkisofs/mkisofs.h Sat Jul 27 15:59:06 2002 @@ -109,6 +109,7 @@ unsigned int rr_attr_size; unsigned int total_rr_attr_size; unsigned int got_rr_name; + unsigned char *archimedes_attributes; #ifdef APPLE_HYB struct directory_entry *assoc; /* entry has a resource fork */ hfsdirent *hfs_ent; /* HFS parameters */ @@ -311,6 +312,7 @@ extern int boot_info_table; extern int use_RockRidge; extern int use_Joliet; +extern int use_ARCHIMEDES; extern int rationalize; extern int rationalize_uid; extern int rationalize_gid; @@ -534,6 +536,11 @@ extern char *generate_rr_extension_record __PR((char *id, char *descriptor, char *source, int *size)); + +extern int generate_archimedes_attributes __PR((char *, char *, + struct directory_entry *, + struct stat *, struct stat *, + int deep_flag)); extern int check_prev_session __PR((struct directory_entry **, int len, struct directory_entry *, diff -urN cdrtools-1.11/mkisofs/name.c cdrtools-1.11-hacked/mkisofs/name.c --- cdrtools-1.11/mkisofs/name.c Thu May 2 23:17:53 2002 +++ cdrtools-1.11-hacked/mkisofs/name.c Sat Jul 27 15:59:06 2002 @@ -117,6 +117,7 @@ int extra = 0; int ignore = 0; char *last_dot; + char *archimedes_comma; const char *pnt; int priority = 32767; char *result; @@ -154,6 +155,23 @@ */ pnt = name; + archimedes_comma = NULL; + if (use_ARCHIMEDES) { + char *p; + + /* + * If the filename ends in comma followed by three hex + * digits, those specify the RISC OS file type. Trim + * them off, since we don't want to see them in + * RISC OS. + */ + p = strrchr(pnt, ','); + if (p != NULL && + isxdigit(p[1]) && isxdigit(p[2]) && isxdigit(p[3]) && + p[4] == '\0') + archimedes_comma = p; + } + /* * Find the '.' that we intend to use for the extension. * Usually this is the last dot, but if we have . followed by nothing @@ -292,6 +310,12 @@ } extra++; pnt++; + continue; + } + + if (pnt == archimedes_comma) { + /* Skip the file type */ + ignore++; continue; } diff -urN cdrtools-1.11/mkisofs/rock.c cdrtools-1.11-hacked/mkisofs/rock.c --- cdrtools-1.11/mkisofs/rock.c Sun Jul 21 12:21:03 2002 +++ cdrtools-1.11-hacked/mkisofs/rock.c Sat Jul 27 15:59:06 2002 @@ -167,6 +167,13 @@ return 0; /* + * Rock Ridge and ARCHIMEDES attributes can't + * co-exist on a file. + */ + if (s_entry->archimedes_attributes != NULL) + return 0; + + /* * Obtain the amount of space that is currently used for the directory * record. Assume max for name, since name conflicts may cause us to * rename the file later on diff -urN cdrtools-1.11/mkisofs/tree.c cdrtools-1.11-hacked/mkisofs/tree.c --- cdrtools-1.11/mkisofs/tree.c Sun Jul 21 12:54:56 2002 +++ cdrtools-1.11-hacked/mkisofs/tree.c Sat Jul 27 15:59:06 2002 @@ -448,6 +448,11 @@ new_reclen++; /* Pad to an even byte */ new_reclen += s_entry->rr_attr_size; } + if (s_entry->archimedes_attributes != NULL) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += 32; + } if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ s_entry->isorec.length[0] = new_reclen; @@ -486,6 +491,11 @@ new_reclen++; /* Pad to an even byte */ new_reclen += s_entry1->rr_attr_size; } + if (s_entry1->archimedes_attributes != NULL) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += 32; + } if (new_reclen & 1) new_reclen++; /* Pad to an even byte */ s_entry1->isorec.length[0] = new_reclen; @@ -617,6 +627,11 @@ new_reclen += s_entry->rr_attr_size; + if (s_entry->archimedes_attributes != NULL) { + if (new_reclen & 1) + new_reclen++; /* Pad to an even byte */ + new_reclen += 32; + } if (new_reclen & 1) new_reclen++; @@ -2039,6 +2054,11 @@ } /* Now figure out how much room this file will take in the directory */ + if (use_ARCHIMEDES) { + generate_archimedes_attributes(whole_path, + short_name, s_entry, + &statbuf, &lstatbuf, deep_flag); + } #ifdef APPLE_HYB /* if the file is HFS excluded, then we don't have an hfs_ent */ if (apple_both && !have_rsrc && s_entry->hfs_ent) { diff -urN cdrtools-1.11/mkisofs/write.c cdrtools-1.11-hacked/mkisofs/write.c --- cdrtools-1.11/mkisofs/write.c Sun Jul 21 15:00:29 2002 +++ cdrtools-1.11-hacked/mkisofs/write.c Sat Jul 27 15:59:06 2002 @@ -1372,6 +1372,13 @@ s_entry->rr_attributes, s_entry->rr_attr_size); dir_index += s_entry->rr_attr_size; + } else if (s_entry->archimedes_attributes != NULL) { + if (dir_index & 1) { + directory_buffer[dir_index++] = 0; + } + memcpy(directory_buffer + dir_index, + s_entry->archimedes_attributes, 32); + dir_index += 32; } if (dir_index & 1) { directory_buffer[dir_index++] = 0; @@ -1386,6 +1393,10 @@ if (s_entry_d->rr_attributes) { free(s_entry_d->rr_attributes); s_entry_d->rr_attributes = NULL; + } + if (s_entry_d->archimedes_attributes) { + free(s_entry_d->archimedes_attributes); + s_entry_d->archimedes_attributes = NULL; } }