Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#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);
}