diff options
author | wkj <devnull@localhost> | 2004-06-17 01:47:21 +0000 |
---|---|---|
committer | wkj <devnull@localhost> | 2004-06-17 01:47:21 +0000 |
commit | 7285a491c1ce1e630a0751b1011fd33e6b17234b (patch) | |
tree | b2b2e24e333fa4660325a35f6c0f1d333e50e797 /src/cmd/9660/ichar.c | |
parent | e1dddc053287874e82e2b67f95ccee7d7bc63e22 (diff) | |
download | plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.tar.gz plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.tar.bz2 plan9port-7285a491c1ce1e630a0751b1011fd33e6b17234b.zip |
Dump9660 (and mk9660). Until we either do something
intelligent with symlinks or put in a switch for things
like dump9660, this is of rather limited utility under Unix.
Diffstat (limited to 'src/cmd/9660/ichar.c')
-rw-r--r-- | src/cmd/9660/ichar.c | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/src/cmd/9660/ichar.c b/src/cmd/9660/ichar.c new file mode 100644 index 00000000..35b0c056 --- /dev/null +++ b/src/cmd/9660/ichar.c @@ -0,0 +1,206 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <libsec.h> +#include <ctype.h> + +#include "iso9660.h" + +/* + * ISO 9660 file names must be uppercase, digits, or underscore. + * We use lowercase, digits, and underscore, translating lower to upper + * in mkisostring, and upper to lower in isostring. + * Files with uppercase letters in their names are thus nonconforming. + * Conforming files also must have a basename + * at most 8 letters and at most one suffix of at most 3 letters. + */ +char* +isostring(uchar *buf, int len) +{ + char *p, *q; + + p = emalloc(len+1); + memmove(p, buf, len); + p[len] = '\0'; + while(len > 0 && p[len-1] == ' ') + p[--len] = '\0'; + for(q=p; *q; q++) + *q = tolower(*q); + + q = atom(p); + free(p); + return q; +} + +int +isisofrog(char c) +{ + if(c >= '0' && c <= '9') + return 0; + if(c >= 'a' && c <= 'z') + return 0; + if(c == '_') + return 0; + + return 1; +} + +int +isbadiso9660(char *s) +{ + char *p, *q; + int i; + + if((p = strchr(s, '.')) != nil) { + if(p-s > 8) + return 1; + for(q=s; q<p; q++) + if(isisofrog(*q)) + return 1; + if(strlen(p+1) > 3) + return 1; + for(q=p+1; *q; q++) + if(isisofrog(*q)) + return 1; + } else { + if(strlen(s) > 8) + return 1; + for(q=s; *q; q++) + if(isisofrog(*q)) + return 1; + + /* + * we rename files of the form [FD]dddddd + * so they don't interfere with us. + */ + if(strlen(s) == 7 && (s[0] == 'D' || s[0] == 'F')) { + for(i=1; i<7; i++) + if(s[i] < '0' || s[i] > '9') + break; + if(i == 7) + return 1; + } + } + return 0; +} + +/* + * ISO9660 name comparison + * + * The standard algorithm is as follows: + * Take the filenames without extensions, pad the shorter with 0x20s (spaces), + * and do strcmp. If they are equal, go on. + * Take the extensions, pad the shorter with 0x20s (spaces), + * and do strcmp. If they are equal, go on. + * Compare the version numbers. + * + * Since Plan 9 names are not allowed to contain characters 0x00-0x1F, + * the padded comparisons are equivalent to using strcmp directly. + * We still need to handle the base and extension differently, + * so that .foo sorts before !foo.foo. + */ +int +isocmp(const void *va, const void *vb) +{ + int i; + char s1[32], s2[32], *b1, *b2, *e1, *e2; + const Direc *a, *b; + + a = va; + b = vb; + + strecpy(s1, s1+sizeof s1, a->confname); + b1 = s1; + strecpy(s2, s2+sizeof s2, b->confname); + b2 = s2; + if((e1 = strchr(b1, '.')) != nil) + *e1++ = '\0'; + else + e1 = ""; + if((e2 = strchr(b2, '.')) != nil) + *e2++ = '\0'; + else + e2 = ""; + + if((i = strcmp(b1, b2)) != 0) + return i; + + return strcmp(e1, e2); +} + +static char* +mkisostring(char *isobuf, int n, char *s) +{ + char *p, *q, *eq; + + eq = isobuf+n; + for(p=s, q=isobuf; *p && q < eq; p++) + if('a' <= *p && *p <= 'z') + *q++ = *p+'A'-'a'; + else + *q++ = *p; + + while(q < eq) + *q++ = ' '; + + return isobuf; +} + +void +Cputisopvd(Cdimg *cd, Cdinfo info) +{ + char buf[130]; + + Cputc(cd, 1); /* primary volume descriptor */ + Cputs(cd, "CD001", 5); /* standard identifier */ + Cputc(cd, 1); /* volume descriptor version */ + Cputc(cd, 0); /* unused */ + + assert(~info.flags & (CDplan9|CDrockridge)); + + /* system identifier */ + strcpy(buf, ""); + if(info.flags & CDplan9) + strcat(buf, "plan 9 "); + if(info.flags & CDrockridge) + strcat(buf, "rrip "); + if(info.flags & CDbootable) + strcat(buf, "boot "); + if(info.flags & CDconform) + strcat(buf, "iso9660"); + else + strcat(buf, "utf8"); + + struprcpy(buf, buf); + Cputs(cd, buf, 32); + + Cputs(cd, mkisostring(buf, 32, info.volumename), 32); /* volume identifier */ + + Crepeat(cd, 0, 8); /* unused */ + Cputn(cd, 0, 4); /* volume space size */ + Crepeat(cd, 0, 32); /* unused */ + Cputn(cd, 1, 2); /* volume set size */ + Cputn(cd, 1, 2); /* volume sequence number */ + Cputn(cd, Blocksize, 2); /* logical block size */ + Cputn(cd, 0, 4); /* path table size */ + Cputnl(cd, 0, 4); /* location of Lpath */ + Cputnl(cd, 0, 4); /* location of optional Lpath */ + Cputnm(cd, 0, 4); /* location of Mpath */ + Cputnm(cd, 0, 4); /* location of optional Mpath */ + Cputisodir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */ + + Cputs(cd, mkisostring(buf, 128, info.volumeset), 128); /* volume set identifier */ + Cputs(cd, mkisostring(buf, 128, info.publisher), 128); /* publisher identifier */ + Cputs(cd, mkisostring(buf, 128, info.preparer), 128); /* data preparer identifier */ + Cputs(cd, mkisostring(buf, 128, info.application), 128); /* application identifier */ + + Cputs(cd, "", 37); /* copyright notice */ + Cputs(cd, "", 37); /* abstract */ + Cputs(cd, "", 37); /* bibliographic file */ + Cputdate1(cd, now); /* volume creation date */ + Cputdate1(cd, now); /* volume modification date */ + Cputdate1(cd, 0); /* volume expiration date */ + Cputdate1(cd, 0); /* volume effective date */ + Cputc(cd, 1); /* file structure version */ + Cpadblock(cd); +} |