aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/9660/jchar.c
diff options
context:
space:
mode:
authorwkj <devnull@localhost>2004-06-17 01:47:21 +0000
committerwkj <devnull@localhost>2004-06-17 01:47:21 +0000
commit7285a491c1ce1e630a0751b1011fd33e6b17234b (patch)
treeb2b2e24e333fa4660325a35f6c0f1d333e50e797 /src/cmd/9660/jchar.c
parente1dddc053287874e82e2b67f95ccee7d7bc63e22 (diff)
downloadplan9port-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/jchar.c')
-rw-r--r--src/cmd/9660/jchar.c138
1 files changed, 138 insertions, 0 deletions
diff --git a/src/cmd/9660/jchar.c b/src/cmd/9660/jchar.c
new file mode 100644
index 00000000..c49da635
--- /dev/null
+++ b/src/cmd/9660/jchar.c
@@ -0,0 +1,138 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <libsec.h>
+
+#include "iso9660.h"
+
+char*
+jolietstring(uchar *buf, int len)
+{
+ char *p, *q;
+ int i;
+ Rune *rp;
+
+ rp = emalloc(sizeof(Rune)*(len/2+1));
+ p = emalloc(UTFmax*(len/2+1));
+
+ for(i=0; i<len/2; i++)
+ rp[i] = (buf[2*i]<<8) | buf[2*i+1];
+ rp[i] = (Rune)'\0';
+
+ snprint(p, UTFmax*(len/2+1), "%S", rp);
+ q = atom(p);
+ free(p);
+ return q;
+}
+
+/*
+ * Joliet name validity check
+ *
+ * Joliet names have length at most 128 bytes (64 runes),
+ * and cannot contain '*', '/', ':', ';', '?', or '\'.
+ */
+int
+isjolietfrog(Rune r)
+{
+ return r==L'*' || r==L'/' || r==L':'
+ || r==';' || r=='?' || r=='\\';
+}
+
+int
+isbadjoliet(char *s)
+{
+ Rune r[256], *p;
+
+ if(utflen(s) > 64)
+ return 1;
+ strtorune(r, s);
+ for(p=r; *p; p++)
+ if(isjolietfrog(*p))
+ return 1;
+ return 0;
+}
+
+/*
+ * Joliet name comparison
+ *
+ * The standard algorithm is the ISO9660 algorithm but
+ * on the encoded Runes. Runes are encoded in big endian
+ * format, so we can just use runecmp.
+ *
+ * Padding is with zeros, but that still doesn't affect us.
+ */
+
+static Rune emptystring[] = { (Rune)0 };
+int
+jolietcmp(const void *va, const void *vb)
+{
+ int i;
+ Rune s1[256], s2[256], *b1, *b2, *e1, *e2; /*BUG*/
+ const Direc *a, *b;
+
+ a = va;
+ b = vb;
+
+ b1 = strtorune(s1, a->confname);
+ b2 = strtorune(s2, b->confname);
+ if((e1 = runechr(b1, (Rune)'.')) != nil)
+ *e1++ = '\0';
+ else
+ e1 = emptystring;
+
+ if((e2 = runechr(b2, (Rune)'.')) != nil)
+ *e2++ = '\0';
+ else
+ e2 = emptystring;
+
+ if((i = runecmp(b1, b2)) != 0)
+ return i;
+
+ return runecmp(e1, e2);
+}
+
+/*
+ * Write a Joliet secondary volume descriptor.
+ */
+void
+Cputjolietsvd(Cdimg *cd, Cdinfo info)
+{
+ Cputc(cd, 2); /* secondary volume descriptor */
+ Cputs(cd, "CD001", 5); /* standard identifier */
+ Cputc(cd, 1); /* volume descriptor version */
+ Cputc(cd, 0); /* unused */
+
+ Cputrscvt(cd, "Joliet Plan 9", 32); /* system identifier */
+ Cputrscvt(cd, info.volumename, 32); /* volume identifier */
+
+ Crepeat(cd, 0, 8); /* unused */
+ Cputn(cd, 0, 4); /* volume space size */
+ Cputc(cd, 0x25); /* escape sequences: UCS-2 Level 2 */
+ Cputc(cd, 0x2F);
+ Cputc(cd, 0x43);
+
+ Crepeat(cd, 0, 29);
+ 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 */
+ Cputjolietdir(cd, nil, DTroot, 1, Cwoffset(cd)); /* root directory */
+ Cputrscvt(cd, info.volumeset, 128); /* volume set identifier */
+ Cputrscvt(cd, info.publisher, 128); /* publisher identifier */
+ Cputrscvt(cd, info.preparer, 128); /* data preparer identifier */
+ Cputrscvt(cd, info.application, 128); /* application identifier */
+ Cputrscvt(cd, "", 37); /* copyright notice */
+ Cputrscvt(cd, "", 37); /* abstract */
+ Cputrscvt(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);
+}
+