diff options
-rw-r--r-- | isofs/ChangeLog | 22 | ||||
-rw-r--r-- | isofs/Makefile | 1 | ||||
-rw-r--r-- | isofs/inode.c | 47 | ||||
-rw-r--r-- | isofs/isofs.h | 3 | ||||
-rw-r--r-- | isofs/rr.c | 93 | ||||
-rw-r--r-- | isofs/rr.h | 52 |
6 files changed, 183 insertions, 35 deletions
diff --git a/isofs/ChangeLog b/isofs/ChangeLog index ee961d51..6fe78202 100644 --- a/isofs/ChangeLog +++ b/isofs/ChangeLog @@ -1,3 +1,25 @@ +Tue Sep 16 15:34:21 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> + + * rr.c (gnuext_live): New variable. + (rrip_work): Comprehend AU, TR, MD, and FL, all as GNU + extensions. Recognize GNU extension id field when processing ER + fields. + (release_rrip): Free RR->trans if it's live. + * inode.c (read_disknode): Interpret and install the values set by + AU, TR, MD, and FL extensions. + (diskfs_node_norefs): Free NP->translator if it's set. + * isofs.h (struct disknode): New members `translen' and + `translator'. + * rr.h (struct gn_au, struct gn_tr, struct gn_md, struct gn_fl): + New strucures. + (GNUEXT_SRC, GNUEXT_DES, GNUEXT_ID, GNUEXT_VERS): New macros. + (struct rrip_lookup): New members author, translen, trans, + allmode, flags. + (VALID_AU, VALID_TR, VALID_MD, VALID_FL): New macros. + + * Makefile (DIST_FILES): Add, referring to EXTENSIONS. + * EXTENSIONS: New file. + Wed Aug 20 14:29:11 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu> * pager.c (diskfs_get_filemap): If pager_create fails, return diff --git a/isofs/Makefile b/isofs/Makefile index 1367ae3c..2b57d81a 100644 --- a/isofs/Makefile +++ b/isofs/Makefile @@ -21,6 +21,7 @@ makemode := server target = isofs SRCS = inode.c main.c lookup.c pager.c rr.c LCLHDRS = iso9660.h isofs.h rr.h +DIST_FILES = EXTENSIONS OBJS = $(SRCS:.c=.o) HURDLIBS = diskfs iohelp fshelp store pager ports threads ihash shouldbeinlibc diff --git a/isofs/inode.c b/isofs/inode.c index 13777b6d..cf74ecb7 100644 --- a/isofs/inode.c +++ b/isofs/inode.c @@ -322,26 +322,36 @@ read_disknode (struct node *np, struct dirrect *dr, if (rl->valid & VALID_PX) { - st->st_mode = rl->mode; + if ((rl->valid & VALID_MD) == 0) + st->st_mode = rl->mode; st->st_nlink = rl->nlink; st->st_uid = rl->uid; st->st_gid = rl->gid; } else { - /* If there are no periods, it's a directory. */ - if (((rl->valid & VALID_NM) && !index (rl->name, '.')) - || (!(rl->valid & VALID_NM) && !memchr (dr->name, '.', dr->namelen))) - st->st_mode = S_IFDIR | 0777; - else - st->st_mode = S_IFREG | 0666; - + if ((rl->valid & VALID_MD) == 0) + { + /* If there are no periods, it's a directory. */ + if (((rl->valid & VALID_NM) && !index (rl->name, '.')) + || (!(rl->valid & VALID_NM) && !memchr (dr->name, '.', + dr->namelen))) + st->st_mode = S_IFDIR | 0777; + else + st->st_mode = S_IFREG | 0666; + } st->st_nlink = 1; st->st_uid = 0; st->st_gid = 0; } + + if (rl->valid & VALID_MD) + st->st_mode = rl->allmode; - st->st_author = st->st_gid; + if (rl->valid & VALID_AU) + st->st_author = rl->author; + else + st->st_author = st->st_gid; st->st_size = isonum_733 (dr->size); @@ -391,7 +401,11 @@ read_disknode (struct node *np, struct dirrect *dr, st->st_blksize = logical_block_size; st->st_blocks = (st->st_size - 1) / 512 + 1; - st->st_flags = 0; + + if (rl->valid & VALID_FL) + st->st_flags = rl->flags; + else + st->st_flags = 0; if (S_ISLNK (st->st_mode)) { @@ -408,6 +422,16 @@ read_disknode (struct node *np, struct dirrect *dr, } } + if (rr->valid & VALID_TR) + { + st->st_mode |= S_IPTRANS; + np->dn->translen = rl->translen; + np->dn->translator = rl->trans; + rl->trans = 0; + } + else + np->dn->translator = np->dn->translen = 0; + diskfs_end_catch_exception (); return 0; @@ -432,6 +456,9 @@ diskfs_node_norefs (struct node *np) assert (node_cache[np->cache_id - 1].np == np); node_cache[np->cache_id - 1].np = 0; + if (np->translator) + free (np->translator); + assert (!np->dn->fileinfo); free (np->dn); free (np); diff --git a/isofs/isofs.h b/isofs/isofs.h index 25c449a6..9bec3c92 100644 --- a/isofs/isofs.h +++ b/isofs/isofs.h @@ -37,6 +37,9 @@ struct disknode struct user_pager_info *fileinfo; char *link_target; /* for S_ISLNK */ + + size_t translen; + char *translator; }; struct user_pager_info @@ -27,6 +27,7 @@ /* These tell whether the specified extensions are on or not. */ int susp_live = 0; int rock_live = 0; +int gnuext_live = 0; /* How far to skip when reading SUSP fields. */ int susp_skip = 0; @@ -38,6 +39,8 @@ release_rrip (struct rrip_lookup *rr) free (rr->name); if ((rr->valid & VALID_SL) && rr->target) free (rr->target); + if ((rr->valid & VALID_TR) && rr->trans) + free (rr->trans); } @@ -186,35 +189,20 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr, struct su_er *er = body; char *c; - /* The only extension we currently support is Rock-Ridge. */ - /* Make sure the ER field is valid */ if ((void *) er->more + er->len_id + er->len_des + er->len_src < terminus) - goto nomatch; - - if (er->ext_ver != ROCK_VERS) - goto nomatch; + goto next_field; - c = er->more; - if (memcmp (ROCK_ID, c, er->len_id)) - goto nomatch; - - /* At this point we know we have Rock-Ridge, but - we check these and moan about it if they are wrong. */ - - c += er->len_id; - if (memcmp (ROCK_DES, c, er->len_des)) - fprintf (stderr, "isofs warning: Rock-Ridge extension description is not standard: %s\n", c); - - c += er->len_des; - if (memcmp (ROCK_SRC, c, er->len_src)) - fprintf (stderr, "isofs warning: Rock-Ridge extensions source is not standard: %s\n", c); - - rock_live = 1; - - nomatch: - goto next_field; + /* Check for rock-ridge */ + if (er->ext_ver == ROCK_VERS + && !memcmp (ROCK_ID, er->more, er->lenid)) + rock_live = 1; + + /* Check for Gnuext */ + else if (er->ext_ver == GNUEXT_VERS + && !memcmp (GNUEXT_ID, er->more, er->lenid)) + gnuext_live = 1; } /* PD fields are padding and just get ignored. */ @@ -554,6 +542,61 @@ rrip_work (struct dirrect *dr, struct rrip_lookup *rr, goto next_field; } + /* The rest are GNU ext. */ + if (!gnuext_live) + goto next_field; + + /* Author */ + if (susp->sig[0] == 'A' + && susp->sig[1] == 'U' + && susp->version == 1) + { + struct gn_au *au = body; + + rr->author = isonum_733 (au->author); + rr->valid |= VALID_AU; + + goto next_field; + } + + if (susp->sig[0] == 'T' + && susp->sig[1] == 'R' + && susp->version == 1) + { + struct gn_tr *tr = body; + + rr->translen = tr->len; + rr->trans = malloc (rr->translen); + memcpy (tr->data, rr->trans, rr->translen); + rr->valid |= VALID_TR; + + goto next_field; + } + + if (susp->sig[0] == 'M' + && susp->sig[1] == 'D' + && susp->version == 1) + { + struct gn_md *md = body; + + rr->allmode = isonum_733 (md->mode); + rr->valid |= VALID_MD; + + goto next_field; + } + + if (susp->sig[0] == 'F' + && susp->sig[1] == 'L' + && susp->version == 1) + { + struct gn_fl *fl = body; + + rr->flags = isonum_733 (fl->flags); + rr->valid |= VALID_FL; + + goto next_field; + } + next_field: bp = bp + susp->len; } @@ -54,6 +54,19 @@ struct rrip_lookup /* RL */ off_t realfilestart; /* override file start in dir entry */ + /* AU */ + uid_t author; + + /* TR */ + size_t translen; + char *trans; + + /* MD */ + mode_t allmode; + + /* FL */ + long flags; + int valid; }; @@ -66,6 +79,10 @@ struct rrip_lookup #define VALID_PL 0x0020 #define VALID_TF 0x0040 #define VALID_RE 0x0080 +#define VALID_AU 0x0100 +#define VALID_TR 0x0200 +#define VALID_MD 0x0400 +#define VALID_FL 0x0800 /* Definitions for System Use Sharing Protocol. @@ -204,6 +221,41 @@ struct rr_sf char size[8]; }; + +/* GNU extensions */ + +#define GNUEXT_VERS 1 +#define GNUEXT_ID GNUEXT_1997 +#define GNUEXT_DES \ + "The GNU Extensions provide support for special GNU filesystem features" +#define GNUEXT_SRC \ + "GNU Hurd source release 0.3 or later" + +/* AU -- author (version 1) */ +struct gn_au +{ + char author[8]; +}; + +/* TR -- translator (version 1) */ +struct gn_tr +{ + u_char len; + char data[0]; +}; + +/* MD -- full mode (version 1) */ +struct gn_md +{ + char mode[8]; +}; + +/* FL -- flags (version 1) */ +struct gn_fl +{ + char flags[8]; +}; + /* Rock-Ridge related functions. */ |