mirror of
https://github.com/9fans/plan9port.git
synced 2025-01-15 11:20:03 +00:00
7285a491c1
intelligent with symlinks or put in a switch for things like dump9660, this is of rather limited utility under Unix.
424 lines
8.9 KiB
C
424 lines
8.9 KiB
C
/*
|
|
* iso9660.h
|
|
*
|
|
* Routines and data structures to support reading and writing
|
|
* ISO 9660 CD images. See the ISO 9660 or ECMA 119 standards.
|
|
*
|
|
* Also supports Rock Ridge extensions for long file names and Unix stuff.
|
|
* Also supports Microsoft's Joliet extensions for Unicode and long file names.
|
|
* Also supports El Torito bootable CD spec.
|
|
*/
|
|
|
|
typedef struct Cdimg Cdimg;
|
|
typedef struct Cdinfo Cdinfo;
|
|
typedef struct Conform Conform;
|
|
typedef struct Direc Direc;
|
|
typedef struct Dumproot Dumproot;
|
|
typedef struct Voldesc Voldesc;
|
|
typedef struct XDir XDir;
|
|
|
|
#ifndef CHLINK
|
|
#define CHLINK 0
|
|
#endif
|
|
|
|
struct XDir {
|
|
char *name;
|
|
char *uid;
|
|
char *gid;
|
|
char *symlink;
|
|
ulong uidno; /* Numeric uid */
|
|
ulong gidno; /* Numeric gid */
|
|
|
|
ulong mode;
|
|
ulong atime;
|
|
ulong mtime;
|
|
ulong ctime;
|
|
|
|
vlong length;
|
|
};
|
|
|
|
/*
|
|
* A directory entry in a ISO9660 tree.
|
|
* The extra data (uid, etc.) here is put into the system use areas.
|
|
*/
|
|
struct Direc {
|
|
char *name; /* real name */
|
|
char *confname; /* conformant name */
|
|
char *srcfile; /* file to copy onto the image */
|
|
|
|
ulong block;
|
|
ulong length;
|
|
int flags;
|
|
|
|
char *uid;
|
|
char *gid;
|
|
char *symlink;
|
|
ulong mode;
|
|
long atime;
|
|
long ctime;
|
|
long mtime;
|
|
|
|
ulong uidno;
|
|
ulong gidno;
|
|
|
|
Direc *child;
|
|
int nchild;
|
|
};
|
|
enum { /* Direc flags */
|
|
Dbadname = 1<<0, /* Non-conformant name */
|
|
};
|
|
|
|
/*
|
|
* Data found in a volume descriptor.
|
|
*/
|
|
struct Voldesc {
|
|
char *systemid;
|
|
char *volumeset;
|
|
char *publisher;
|
|
char *preparer;
|
|
char *application;
|
|
|
|
/* file names for various parameters */
|
|
char *abstract;
|
|
char *biblio;
|
|
char *notice;
|
|
|
|
/* path table */
|
|
ulong pathsize;
|
|
ulong lpathloc;
|
|
ulong mpathloc;
|
|
|
|
/* root of file tree */
|
|
Direc root;
|
|
};
|
|
|
|
/*
|
|
* An ISO9660 CD image. Various parameters are kept in memory but the
|
|
* real image file is opened for reading and writing on fd.
|
|
*
|
|
* The bio buffers brd and bwr moderate reading and writing to the image.
|
|
* The routines we use are careful to flush one before or after using the other,
|
|
* as necessary.
|
|
*/
|
|
struct Cdimg {
|
|
char *file;
|
|
int fd;
|
|
ulong dumpblock;
|
|
ulong nextblock;
|
|
ulong iso9660pvd;
|
|
ulong jolietsvd;
|
|
ulong pathblock;
|
|
ulong rrcontin; /* rock ridge continuation offset */
|
|
ulong nulldump; /* next dump block */
|
|
ulong nconform; /* number of conform entries written already */
|
|
ulong bootcatptr;
|
|
ulong bootcatblock;
|
|
ulong bootimageptr;
|
|
Direc *bootdirec;
|
|
char *bootimage;
|
|
|
|
Biobuf brd;
|
|
Biobuf bwr;
|
|
|
|
int flags;
|
|
|
|
Voldesc iso;
|
|
Voldesc joliet;
|
|
};
|
|
enum { /* Cdimg->flags, Cdinfo->flags */
|
|
CDjoliet = 1<<0,
|
|
CDplan9 = 1<<1,
|
|
CDconform = 1<<2,
|
|
CDrockridge = 1<<3,
|
|
CDnew = 1<<4,
|
|
CDdump = 1<<5,
|
|
CDbootable = 1<<6,
|
|
};
|
|
|
|
typedef struct Tx Tx;
|
|
struct Tx {
|
|
char *bad; /* atoms */
|
|
char *good;
|
|
};
|
|
|
|
struct Conform {
|
|
Tx *t;
|
|
int nt; /* delta = 32 */
|
|
};
|
|
|
|
struct Cdinfo {
|
|
int flags;
|
|
|
|
char *volumename;
|
|
|
|
char *volumeset;
|
|
char *publisher;
|
|
char *preparer;
|
|
char *application;
|
|
char *bootimage;
|
|
};
|
|
|
|
enum {
|
|
Blocklen = 2048,
|
|
};
|
|
|
|
/*
|
|
* This is a doubly binary tree.
|
|
* We have a tree keyed on the MD5 values
|
|
* as well as a tree keyed on the block numbers.
|
|
*/
|
|
typedef struct Dump Dump;
|
|
typedef struct Dumpdir Dumpdir;
|
|
|
|
struct Dump {
|
|
Cdimg *cd;
|
|
Dumpdir *md5root;
|
|
Dumpdir *blockroot;
|
|
};
|
|
|
|
struct Dumpdir {
|
|
char *name;
|
|
uchar md5[MD5dlen];
|
|
ulong block;
|
|
ulong length;
|
|
Dumpdir *md5left;
|
|
Dumpdir *md5right;
|
|
Dumpdir *blockleft;
|
|
Dumpdir *blockright;
|
|
};
|
|
|
|
struct Dumproot {
|
|
char *name;
|
|
int nkid;
|
|
Dumproot *kid;
|
|
Direc root;
|
|
Direc jroot;
|
|
};
|
|
|
|
/*
|
|
* ISO9660 on-CD structures.
|
|
*/
|
|
typedef struct Cdir Cdir;
|
|
typedef struct Cpath Cpath;
|
|
typedef struct Cvoldesc Cvoldesc;
|
|
|
|
/* a volume descriptor block */
|
|
struct Cvoldesc {
|
|
uchar magic[8]; /* 0x01, "CD001", 0x01, 0x00 */
|
|
uchar systemid[32]; /* system identifier */
|
|
uchar volumeid[32]; /* volume identifier */
|
|
uchar unused[8]; /* character set in secondary desc */
|
|
uchar volsize[8]; /* volume size */
|
|
uchar charset[32];
|
|
uchar volsetsize[4]; /* volume set size = 1 */
|
|
uchar volseqnum[4]; /* volume sequence number = 1 */
|
|
uchar blocksize[4]; /* logical block size */
|
|
uchar pathsize[8]; /* path table size */
|
|
uchar lpathloc[4]; /* Lpath */
|
|
uchar olpathloc[4]; /* optional Lpath */
|
|
uchar mpathloc[4]; /* Mpath */
|
|
uchar ompathloc[4]; /* optional Mpath */
|
|
uchar rootdir[34]; /* directory entry for root */
|
|
uchar volumeset[128]; /* volume set identifier */
|
|
uchar publisher[128];
|
|
uchar preparer[128]; /* data preparer identifier */
|
|
uchar application[128]; /* application identifier */
|
|
uchar notice[37]; /* copyright notice file */
|
|
uchar abstract[37]; /* abstract file */
|
|
uchar biblio[37]; /* bibliographic file */
|
|
uchar cdate[17]; /* creation date */
|
|
uchar mdate[17]; /* modification date */
|
|
uchar xdate[17]; /* expiration date */
|
|
uchar edate[17]; /* effective date */
|
|
uchar fsvers; /* file system version = 1 */
|
|
};
|
|
|
|
/* a directory entry */
|
|
struct Cdir {
|
|
uchar len;
|
|
uchar xlen;
|
|
uchar dloc[8];
|
|
uchar dlen[8];
|
|
uchar date[7];
|
|
uchar flags;
|
|
uchar unitsize;
|
|
uchar gapsize;
|
|
uchar volseqnum[4];
|
|
uchar namelen;
|
|
uchar name[1]; /* chumminess */
|
|
};
|
|
|
|
/* a path table entry */
|
|
struct Cpath {
|
|
uchar namelen;
|
|
uchar xlen;
|
|
uchar dloc[4];
|
|
uchar parent[2];
|
|
uchar name[1]; /* chumminess */
|
|
};
|
|
|
|
enum { /* Rockridge flags */
|
|
RR_PX = 1<<0,
|
|
RR_PN = 1<<1,
|
|
RR_SL = 1<<2,
|
|
RR_NM = 1<<3,
|
|
RR_CL = 1<<4,
|
|
RR_PL = 1<<5,
|
|
RR_RE = 1<<6,
|
|
RR_TF = 1<<7,
|
|
};
|
|
|
|
enum { /* CputrripTF type argument */
|
|
TFcreation = 1<<0,
|
|
TFmodify = 1<<1,
|
|
TFaccess = 1<<2,
|
|
TFattributes = 1<<3,
|
|
TFbackup = 1<<4,
|
|
TFexpiration = 1<<5,
|
|
TFeffective = 1<<6,
|
|
TFlongform = 1<<7,
|
|
};
|
|
|
|
enum { /* CputrripNM flag types */
|
|
NMcontinue = 1<<0,
|
|
NMcurrent = 1<<1,
|
|
NMparent = 1<<2,
|
|
NMroot = 1<<3,
|
|
NMvolroot = 1<<4,
|
|
NMhost = 1<<5,
|
|
};
|
|
|
|
/* boot.c */
|
|
void Cputbootvol(Cdimg*);
|
|
void Cputbootcat(Cdimg*);
|
|
void Cupdatebootvol(Cdimg*);
|
|
void Cupdatebootcat(Cdimg*);
|
|
void findbootimage(Cdimg*, Direc*);
|
|
|
|
/* cdrdwr.c */
|
|
Cdimg *createcd(char*, Cdinfo);
|
|
Cdimg *opencd(char*, Cdinfo);
|
|
void Creadblock(Cdimg*, void*, ulong, ulong);
|
|
ulong big(void*, int);
|
|
ulong little(void*, int);
|
|
int parsedir(Cdimg*, Direc*, uchar*, int, char *(*)(uchar*, int));
|
|
void setroot(Cdimg*, ulong, ulong, ulong);
|
|
void setvolsize(Cdimg*, ulong, ulong);
|
|
void setpathtable(Cdimg*, ulong, ulong, ulong, ulong);
|
|
void Cputc(Cdimg*, int);
|
|
void Cputnl(Cdimg*, ulong, int);
|
|
void Cputnm(Cdimg*, ulong, int);
|
|
void Cputn(Cdimg*, long, int);
|
|
void Crepeat(Cdimg*, int, int);
|
|
void Cputs(Cdimg*, char*, int);
|
|
void Cwrite(Cdimg*, void*, int);
|
|
void Cputr(Cdimg*, Rune);
|
|
void Crepeatr(Cdimg*, Rune, int);
|
|
void Cputrs(Cdimg*, Rune*, int);
|
|
void Cputrscvt(Cdimg*, char*, int);
|
|
void Cpadblock(Cdimg*);
|
|
void Cputdate(Cdimg*, ulong);
|
|
void Cputdate1(Cdimg*, ulong);
|
|
void Cread(Cdimg*, void*, int);
|
|
void Cwflush(Cdimg*);
|
|
void Cwseek(Cdimg*, ulong);
|
|
ulong Cwoffset(Cdimg*);
|
|
ulong Croffset(Cdimg*);
|
|
int Cgetc(Cdimg*);
|
|
void Crseek(Cdimg*, ulong);
|
|
char *Crdline(Cdimg*, int);
|
|
int Clinelen(Cdimg*);
|
|
|
|
/* conform.c */
|
|
void rdconform(Cdimg*);
|
|
char *conform(char*, int);
|
|
void wrconform(Cdimg*, int, ulong*, ulong*);
|
|
|
|
/* direc.c */
|
|
void mkdirec(Direc*, XDir*);
|
|
Direc *walkdirec(Direc*, char*);
|
|
Direc *adddirec(Direc*, char*, XDir*);
|
|
void copydirec(Direc*, Direc*);
|
|
void checknames(Direc*, int (*)(char*));
|
|
void convertnames(Direc*, char* (*)(char*, char*));
|
|
void dsort(Direc*, int (*)(const void*, const void*));
|
|
void setparents(Direc*);
|
|
|
|
/* dump.c */
|
|
ulong Cputdumpblock(Cdimg*);
|
|
int hasdump(Cdimg*);
|
|
Dump *dumpcd(Cdimg*, Direc*);
|
|
Dumpdir *lookupmd5(Dump*, uchar*);
|
|
void insertmd5(Dump*, char*, uchar*, ulong, ulong);
|
|
|
|
Direc readdumpdirs(Cdimg*, XDir*, char*(*)(uchar*,int));
|
|
char *adddumpdir(Direc*, ulong, XDir*);
|
|
void copybutname(Direc*, Direc*);
|
|
|
|
void readkids(Cdimg*, Direc*, char*(*)(uchar*,int));
|
|
void freekids(Direc*);
|
|
void readdumpconform(Cdimg*);
|
|
void rmdumpdir(Direc*, char*);
|
|
|
|
/* ichar.c */
|
|
char *isostring(uchar*, int);
|
|
int isbadiso9660(char*);
|
|
int isocmp(const void*, const void*);
|
|
int isisofrog(char);
|
|
void Cputisopvd(Cdimg*, Cdinfo);
|
|
|
|
/* jchar.c */
|
|
char *jolietstring(uchar*, int);
|
|
int isbadjoliet(char*);
|
|
int jolietcmp(const void*, const void*);
|
|
int isjolietfrog(Rune);
|
|
void Cputjolietsvd(Cdimg*, Cdinfo);
|
|
|
|
/* path.c */
|
|
void writepathtables(Cdimg*);
|
|
|
|
/* util.c */
|
|
void *emalloc(ulong);
|
|
void *erealloc(void*, ulong);
|
|
char *atom(char*);
|
|
char *struprcpy(char*, char*);
|
|
int chat(char*, ...);
|
|
|
|
/* unix.c, plan9.c */
|
|
void dirtoxdir(XDir*, Dir*);
|
|
void fdtruncate(int, ulong);
|
|
long uidno(char*);
|
|
long gidno(char*);
|
|
|
|
/* rune.c */
|
|
Rune *strtorune(Rune*, char*);
|
|
Rune *runechr(Rune*, Rune);
|
|
int runecmp(Rune*, Rune*);
|
|
|
|
/* sysuse.c */
|
|
int Cputsysuse(Cdimg*, Direc*, int, int, int);
|
|
|
|
/* write.c */
|
|
void writefiles(Dump*, Cdimg*, Direc*);
|
|
void writedirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int));
|
|
void writedumpdirs(Cdimg*, Direc*, int(*)(Cdimg*, Direc*, int, int, int));
|
|
int Cputisodir(Cdimg*, Direc*, int, int, int);
|
|
int Cputjolietdir(Cdimg*, Direc*, int, int, int);
|
|
void Cputendvd(Cdimg*);
|
|
|
|
enum {
|
|
Blocksize = 2048,
|
|
Ndirblock = 16, /* directory blocks allocated at once */
|
|
|
|
DTdot = 0,
|
|
DTdotdot,
|
|
DTiden,
|
|
DTroot,
|
|
DTrootdot,
|
|
};
|
|
|
|
extern ulong now;
|
|
extern Conform *map;
|
|
extern int chatty;
|
|
extern int docolon;
|
|
extern int mk9660;
|