Clean up deleted files.

This commit is contained in:
mycroft 1994-06-08 11:22:09 +00:00
parent 36d501bf10
commit 1968713466
6 changed files with 0 additions and 1495 deletions

View File

@ -1,77 +0,0 @@
# $Id: TODO,v 1.4 1993/09/07 15:40:51 ws Exp $
1) should understand "older", original High Sierra ("CDROM001") type
Not yet. ( I don't have this technical information, yet. )
2) should understand Rock Ridge
Yes, we have follows function.
o Symbolic Link
o Real Name(long name)
o File Attribute
o Time stamp
o uid, gid
o Devices
o Relocated directories
Except follows:
o POSIX device number mapping
There is some preliminary stuff in there that (ab-)uses the mknod
system call, but this needs a writable filesystem
3) should be called cdfs, as there are other ISO file system soon possible
Not yet. Probably we should make another file system when the ECMA draft
is valid and do it. For doing Rock Ridge Support, I can use almost same
code. So I just use the same file system interface...
4) should have file handles implemented for use with NFS, etc
Yes. we have already this one, and I based it for this release.
5) should have name translation enabled by mount flag
Yes. we can disable the Rock Ridge Extension by follows option;
"mount -t isofs -o -norrip /dev/cd0d /cdrom"
6) should run as a user process, and not take up kernel space (cdroms
are slow)
Not yet.
7) ECMA support.
Not yet. we need not only a technical spec but also ECMA format
cd-rom itself!
8) Character set change by SVD ( multi SVD support )
Not yet. We should also hack the other part of system as 8 bit
clean. As far as I know, if you export the cdrom by NFS, the client
can access the 8 bit clean (ie. Solaris Japanese with EUC code )
9) Access checks in isofs_access
Not yet.
10) Support for generation numbers
Yes. Default is to list only the last file (the one with the highest
generation number). If you mount with -gen, all files are shown with
their generation numbers. In both cases you can specify the generation
number on opening files (if you happen to know it) or leave it off,
when it will again find the last file.
11) Support for extended attributes
Yes. Since this requires an extra block buffer for the attributes
this must be enabled on mounting with the option -extattr.
----------
Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp)
Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de)

View File

@ -1,217 +0,0 @@
/*
* $Id: iso.h,v 1.6 1993/10/28 17:38:42 ws Exp $
*/
#define ISODCL(from, to) (to - from + 1)
struct iso_volume_descriptor {
char type[ISODCL(1,1)]; /* 711 */
char id[ISODCL(2,6)];
char version[ISODCL(7,7)];
char data[ISODCL(8,2048)];
};
/* volume descriptor types */
#define ISO_VD_PRIMARY 1
#define ISO_VD_END 255
#define ISO_STANDARD_ID "CD001"
#define ISO_ECMA_ID "CDW01"
struct iso_primary_descriptor {
char type [ISODCL ( 1, 1)]; /* 711 */
char id [ISODCL ( 2, 6)];
char version [ISODCL ( 7, 7)]; /* 711 */
char unused1 [ISODCL ( 8, 8)];
char system_id [ISODCL ( 9, 40)]; /* achars */
char volume_id [ISODCL ( 41, 72)]; /* dchars */
char unused2 [ISODCL ( 73, 80)];
char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
char unused3 [ISODCL ( 89, 120)];
char volume_set_size [ISODCL (121, 124)]; /* 723 */
char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
char logical_block_size [ISODCL (129, 132)]; /* 723 */
char path_table_size [ISODCL (133, 140)]; /* 733 */
char type_l_path_table [ISODCL (141, 144)]; /* 731 */
char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
char type_m_path_table [ISODCL (149, 152)]; /* 732 */
char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
char volume_set_id [ISODCL (191, 318)]; /* dchars */
char publisher_id [ISODCL (319, 446)]; /* achars */
char preparer_id [ISODCL (447, 574)]; /* achars */
char application_id [ISODCL (575, 702)]; /* achars */
char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
char file_structure_version [ISODCL (882, 882)]; /* 711 */
char unused4 [ISODCL (883, 883)];
char application_data [ISODCL (884, 1395)];
char unused5 [ISODCL (1396, 2048)];
};
struct iso_directory_record {
char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
unsigned char extent [ISODCL (3, 10)]; /* 733 */
unsigned char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
char name_len [ISODCL (33, 33)]; /* 711 */
char name [0];
};
/* can't take sizeof(iso_directory_record), because of possible alignment
of the last entry (34 instead of 33) */
#define ISO_DIRECTORY_RECORD_SIZE 33
struct iso_extended_attributes {
unsigned char owner [ISODCL (1, 4)]; /* 723 */
unsigned char group [ISODCL (5, 8)]; /* 723 */
unsigned char perm [ISODCL (9, 10)]; /* 9.5.3 */
char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
char recfmt [ISODCL (79, 79)]; /* 711 */
char recattr [ISODCL (80, 80)]; /* 711 */
unsigned char reclen [ISODCL (81, 84)]; /* 723 */
char system_id [ISODCL (85, 116)]; /* achars */
char system_use [ISODCL (117, 180)];
char version [ISODCL (181, 181)]; /* 711 */
char len_esc [ISODCL (182, 182)]; /* 711 */
char reserved [ISODCL (183, 246)];
unsigned char len_au [ISODCL (247, 250)]; /* 723 */
};
/* CD-ROM Format type */
enum ISO_FTYPE { ISO_FTYPE_DEFAULT, ISO_FTYPE_9660, ISO_FTYPE_RRIP, ISO_FTYPE_ECMA };
#ifndef ISOFSMNT_ROOT
#define ISOFSMNT_ROOT 0
#endif
struct iso_mnt {
int im_flags;
int logical_block_size;
int volume_space_size;
struct vnode *im_devvp;
char im_fsmnt[50];
struct mount *im_mountp;
dev_t im_dev;
int im_bshift;
int im_bmask;
char root[ISODCL (157, 190)];
int root_extent;
int root_size;
enum ISO_FTYPE iso_ftype;
int rr_skip;
int rr_skip0;
};
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
#define iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask)
#define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size)
#define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
int isofs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
int isofs_start __P((struct mount *mp, int flags, struct proc *p));
int isofs_unmount __P((struct mount *mp, int mntflags, struct proc *p));
int isofs_root __P((struct mount *mp, struct vnode **vpp));
int isofs_statfs __P((struct mount *mp, struct statfs *sbp, struct proc *p));
int isofs_sync __P((struct mount *mp, int waitfor));
int isofs_fhtovp __P((struct mount *mp, struct fid *fhp, struct vnode **vpp));
int isofs_vptofh __P((struct vnode *vp, struct fid *fhp));
int isofs_init __P(());
struct iso_node;
int iso_bmap __P((struct iso_node *ip, int lblkno, daddr_t *result));
int iso_blkatoff __P((struct iso_node *ip, off_t offset, struct buf **bpp));
int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated,
struct iso_node **ipp, struct iso_directory_record *isodir));
int iso_iput __P((struct iso_node *ip));
int iso_ilock __P((struct iso_node *ip));
int iso_iunlock __P((struct iso_node *ip));
int isofs_mountroot __P((void));
extern inline int
isonum_711(p)
unsigned char *p;
{
return *p;
}
extern inline int
isonum_712(p)
char *p;
{
return *p;
}
extern inline int
isonum_721(p)
unsigned char *p;
{
return *p|((char)p[1] << 8);
}
extern inline int
isonum_722(p)
unsigned char *p;
{
return ((char)*p << 8)|p[1];
}
extern inline int
isonum_723(p)
unsigned char *p;
{
return isonum_721(p);
}
extern inline int
isonum_731(p)
unsigned char *p;
{
return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
}
extern inline int
isonum_732(p)
unsigned char *p;
{
return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
}
extern inline int
isonum_733(p)
unsigned char *p;
{
return isonum_731(p);
}
int isofncmp __P((unsigned char *fn, int fnlen,
unsigned char *isofn, int isolen));
void isofntrans __P((unsigned char *infn, int infnlen,
unsigned char *outfn, unsigned short *outfnlen,
int original, int assoc));
/*
* Associated files have a leading '='.
*/
#define ASSOCCHAR '='

View File

@ -1,76 +0,0 @@
/*
* Copyright (c) 1993 Atsushi Murai (amurai@spec.co.jp)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Atsushi Murai(amurai@spec.co.jp)``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_rrip.h
* $Id: iso_rrip.h,v 1.3 1993/09/07 15:40:53 ws Exp $
*/
/*
* Analyze function flag (similar to RR field bits)
*/
#define ISO_SUSP_ATTR 0x0001
#define ISO_SUSP_DEVICE 0x0002
#define ISO_SUSP_SLINK 0x0004
#define ISO_SUSP_ALTNAME 0x0008
#define ISO_SUSP_CLINK 0x0010
#define ISO_SUSP_PLINK 0x0020
#define ISO_SUSP_RELDIR 0x0040
#define ISO_SUSP_TSTAMP 0x0080
#define ISO_SUSP_IDFLAG 0x0100
#define ISO_SUSP_EXTREF 0x0200
#define ISO_SUSP_CONT 0x0400
#define ISO_SUSP_OFFSET 0x0800
#define ISO_SUSP_STOP 0x1000
#define ISO_SUSP_UNKNOWN 0x8000
typedef struct {
struct iso_node *inop;
int fields; /* interesting fields in this analysis */
daddr_t iso_ce_blk; /* block of continuation area */
off_t iso_ce_off; /* offset of continuation area */
int iso_ce_len; /* length of continuation area */
struct iso_mnt *imp; /* mount structure */
ino_t *inump; /* inode number pointer */
char *outbuf; /* name/symbolic link output area */
u_short *outlen; /* length of above */
u_short maxlen; /* maximum length of above */
int cont; /* continuation of above */
} ISO_RRIP_ANALYZE;
int isofs_rrip_analyze __P((struct iso_directory_record *isodir,
struct iso_node *inop, struct iso_mnt *imp));
int isofs_rrip_getname __P((struct iso_directory_record *isodir,
char *outbuf, u_short *outlen,
ino_t *inump, struct iso_mnt *imp));
int isofs_rrip_getsymname __P((struct iso_directory_record *isodir,
char *outbuf, u_short *outlen,
struct iso_mnt *imp));
int isofs_rrip_offset __P((struct iso_directory_record *isodir,
struct iso_mnt *imp));

View File

@ -1,23 +0,0 @@
/*
* $Id: isofs_bmap.c,v 1.6 1993/12/18 04:31:28 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/namei.h>
#include <sys/buf.h>
#include <sys/file.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <isofs/iso.h>
#include <isofs/isofs_node.h>
iso_bmap(ip, lblkno, result)
struct iso_node *ip;
int lblkno;
daddr_t *result;
{
*result = (ip->iso_start + lblkno)
* (ip->i_mnt->logical_block_size / DEV_BSIZE);
return 0;
}

View File

@ -1,460 +0,0 @@
/*
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Copyright (c) 1983 Atsushi Murai (amurai@spec.co.jp)
* All rights reserved for Rock Ridge Extension Support.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)ufs_lookup.c 7.33 (Berkeley) 5/19/91
* $Id: isofs_lookup.c,v 1.17 1994/04/25 03:49:27 cgd Exp $
*/
#include <sys/param.h>
#include <sys/namei.h>
#include <sys/buf.h>
#include <sys/file.h>
#include <sys/vnode.h>
#include <sys/mount.h>
#include <isofs/iso.h>
#include <isofs/isofs_node.h>
#include <isofs/iso_rrip.h>
#include <isofs/isofs_rrip.h>
struct nchstats iso_nchstats;
/*
* Convert a component of a pathname into a pointer to a locked inode.
* This is a very central and rather complicated routine.
* If the file system is not maintained in a strict tree hierarchy,
* this can result in a deadlock situation (see comments in code below).
*
* The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
* whether the name is to be looked up, created, renamed, or deleted.
* When CREATE, RENAME, or DELETE is specified, information usable in
* creating, renaming, or deleting a directory entry may be calculated.
* If flag has LOCKPARENT or'ed into it and the target of the pathname
* exists, lookup returns both the target and its parent directory locked.
* When creating or renaming and LOCKPARENT is specified, the target may
* not be ".". When deleting and LOCKPARENT is specified, the target may
* be "."., but the caller must check to ensure it does an vrele and iput
* instead of two iputs.
*
* Overall outline of ufs_lookup:
*
* check accessibility of directory
* look for name in cache, if found, then if at end of path
* and deleting or creating, drop it, else return name
* search for name in directory, to found or notfound
* notfound:
* if creating, return locked directory, leaving info on available slots
* else return error
* found:
* if at end of path and deleting, return information to allow delete
* if at end of path and rewriting (RENAME and LOCKPARENT), lock target
* inode and return info to allow rewrite
* if not at end, add name to cache; if at end and neither creating
* nor deleting, add name to cache
*
* NOTE: (LOOKUP | LOCKPARENT) currently returns the parent inode unlocked.
*/
isofs_lookup(vdp, ndp, p)
register struct vnode *vdp;
register struct nameidata *ndp;
struct proc *p;
{
register struct iso_node *dp; /* the directory we are searching */
register struct iso_mnt *imp; /* file system that directory is in */
struct buf *bp = 0; /* a buffer of directory entries */
struct iso_directory_record *ep;/* the current directory entry */
off_t entryoffsetinblock; /* offset of ep in bp's buffer */
off_t saveoffset; /* offset of last directory entry in dir */
int numdirpasses; /* strategy for directory search */
off_t endsearch; /* offset to end directory search */
struct iso_node *pdp; /* saved dp during symlink work */
struct iso_node *tdp; /* returned by iget */
int flag; /* LOOKUP, CREATE, RENAME, or DELETE */
int lockparent; /* 1 => lockparent flag is set */
int wantparent; /* 1 => wantparent or lockparent flag */
int error;
ino_t ino = 0;
int reclen;
u_short namelen;
char altname[NAME_MAX];
int res;
int assoc, len;
char *name;
ndp->ni_dvp = vdp;
ndp->ni_vp = NULL;
dp = VTOI(vdp);
imp = dp->i_mnt;
lockparent = ndp->ni_nameiop & LOCKPARENT;
flag = ndp->ni_nameiop & OPMASK;
wantparent = ndp->ni_nameiop & (LOCKPARENT|WANTPARENT);
/*
* Check accessiblity of directory.
*/
if (vdp->v_type != VDIR)
return ENOTDIR;
if (error = isofs_access(vdp, VEXEC, ndp->ni_cred, p))
return error;
/*
* We now have a segment name to search for, and a directory to search.
*
* Before tediously performing a linear scan of the directory,
* check the name cache to see if the directory/name pair
* we are looking for is known already.
*/
if (error = cache_lookup(ndp)) {
int vpid; /* capability number of vnode */
if (error == ENOENT)
return (error);
#ifdef DIAGNOSTIC
if (vdp == ndp->ni_rootdir && ndp->ni_isdotdot)
panic("ufs_lookup: .. through root");
#endif
/*
* Get the next vnode in the path.
* See comment below starting `Step through' for
* an explaination of the locking protocol.
*/
pdp = dp;
dp = VTOI(ndp->ni_vp);
vdp = ndp->ni_vp;
vpid = vdp->v_id;
if (pdp == dp) {
VREF(vdp);
error = 0;
} else if (ndp->ni_isdotdot) {
ISO_IUNLOCK(pdp);
error = vget(vdp, 1);
if (!error && lockparent && *ndp->ni_next == '\0')
ISO_ILOCK(pdp);
} else {
error = vget(vdp, 1);
if (!lockparent || error || *ndp->ni_next != '\0')
ISO_IUNLOCK(pdp);
}
/*
* Check that the capability number did not change
* while we were waiting for the lock.
*/
if (!error) {
if (vpid == vdp->v_id)
return (0);
iso_iput(dp);
if (lockparent && pdp != dp && *ndp->ni_next == '\0')
ISO_IUNLOCK(pdp);
}
ISO_ILOCK(pdp);
dp = pdp;
vdp = ITOV(dp);
ndp->ni_vp = NULL;
}
len = ndp->ni_namelen;
name = ndp->ni_ptr;
/*
* A leading `=' means, we are looking for an associated file
*/
if (assoc = (imp->iso_ftype != ISO_FTYPE_RRIP && *name == ASSOCCHAR)) {
len--;
name++;
}
/*
* If there is cached information on a previous search of
* this directory, pick up where we last left off.
* We cache only lookups as these are the most common
* and have the greatest payoff. Caching CREATE has little
* benefit as it usually must search the entire directory
* to determine that the entry does not exist. Caching the
* location of the last DELETE or RENAME has not reduced
* profiling time and hence has been removed in the interest
* of simplicity.
*/
if (flag != LOOKUP || dp->i_diroff == 0 || dp->i_diroff > dp->i_size) {
ndp->ni_ufs.ufs_offset = 0;
numdirpasses = 1;
} else {
ndp->ni_ufs.ufs_offset = dp->i_diroff;
entryoffsetinblock = iso_blkoff(imp, ndp->ni_ufs.ufs_offset);
if (entryoffsetinblock != 0) {
if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
return error;
}
numdirpasses = 2;
iso_nchstats.ncs_2passes++;
}
endsearch = roundup(dp->i_size,imp->logical_block_size);
searchloop:
while (ndp->ni_ufs.ufs_offset < endsearch) {
/*
* If offset is on a block boundary,
* read the next directory block.
* Release previous if it exists.
*/
if (iso_blkoff(imp,ndp->ni_ufs.ufs_offset) == 0) {
if (bp != NULL)
brelse(bp);
if (error = iso_blkatoff(dp,ndp->ni_ufs.ufs_offset,&bp))
return error;
entryoffsetinblock = 0;
}
/*
* Get pointer to next entry.
*/
ep = (struct iso_directory_record *)
(bp->b_un.b_addr + entryoffsetinblock);
reclen = isonum_711 (ep->length);
if (reclen == 0) {
/* skip to next block, if any */
ndp->ni_ufs.ufs_offset =
roundup(ndp->ni_ufs.ufs_offset,
imp->logical_block_size);
continue;
}
if (reclen < ISO_DIRECTORY_RECORD_SIZE)
/* illegal entry, stop */
break;
if (entryoffsetinblock + reclen > imp->logical_block_size)
/* entries are not allowed to cross boundaries */
break;
/*
* Check for a name match.
*/
namelen = isonum_711(ep->name_len);
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
/* illegal entry, stop */
break;
switch (imp->iso_ftype) {
default:
if ((!(isonum_711(ep->flags)&4)) == !assoc) {
if ((len == 1
&& *name == '.')
|| ndp->ni_isdotdot) {
if (namelen == 1
&& ep->name[0] == (ndp->ni_isdotdot ? 1 : 0)) {
/*
* Save directory entry's inode number and
* reclen in ndp->ni_ufs area, and release
* directory buffer.
*/
isodirino(&ndp->ni_ufs.ufs_ino,ep,imp);
goto found;
}
if (namelen != 1
|| ep->name[0] != 0)
goto notfound;
} else if (!(res = isofncmp(name,len,
ep->name,namelen))) {
if (isonum_711(ep->flags)&2)
isodirino(&ino,ep,imp);
else
ino = (bp->b_blkno << DEV_BSHIFT)
+ entryoffsetinblock;
saveoffset = ndp->ni_ufs.ufs_offset;
} else if (ino)
goto foundino;
#ifdef NOSORTBUG /* On some CDs directory entries are not sorted correctly */
else if (res < 0)
goto notfound;
else if (res > 0 && numdirpasses == 2)
numdirpasses++;
#endif
}
break;
case ISO_FTYPE_RRIP:
if (isonum_711(ep->flags)&2)
isodirino(&ino,ep,imp);
else
ino = (bp->b_blkno << DEV_BSHIFT) + entryoffsetinblock;
ndp->ni_ufs.ufs_ino = ino;
isofs_rrip_getname(ep,altname,&namelen,&ndp->ni_ufs.ufs_ino,imp);
if (namelen == ndp->ni_namelen
&& !bcmp(name,altname,namelen))
goto found;
ino = 0;
break;
}
ndp->ni_ufs.ufs_offset += reclen;
entryoffsetinblock += reclen;
}
if (ino) {
foundino:
ndp->ni_ufs.ufs_ino = ino;
if (saveoffset != ndp->ni_ufs.ufs_offset) {
if (iso_lblkno(imp,ndp->ni_ufs.ufs_offset)
!= iso_lblkno(imp,saveoffset)) {
if (bp != NULL)
brelse(bp);
if (error = iso_blkatoff(dp,saveoffset,&bp))
return error;
}
ep = (struct iso_directory_record *)(bp->b_un.b_addr
+ iso_blkoff(imp,saveoffset));
ndp->ni_ufs.ufs_offset = saveoffset;
}
goto found;
}
notfound:
/*
* If we started in the middle of the directory and failed
* to find our target, we must check the beginning as well.
*/
if (numdirpasses == 2) {
numdirpasses--;
ndp->ni_ufs.ufs_offset = 0;
endsearch = dp->i_diroff;
goto searchloop;
}
if (bp != NULL)
brelse(bp);
/*
* Insert name into cache (as non-existent) if appropriate.
*/
if (ndp->ni_makeentry)
cache_enter(ndp);
if (flag == CREATE || flag == RENAME)
return EJUSTRETURN;
return (ENOENT);
found:
if (numdirpasses > 1)
iso_nchstats.ncs_pass2++;
/*
* Found component in pathname.
* If the final component of path name, save information
* in the cache as to where the entry was found.
*/
if (*ndp->ni_next == '\0' && flag == LOOKUP)
dp->i_diroff = ndp->ni_ufs.ufs_offset;
/*
* Step through the translation in the name. We do not `iput' the
* directory because we may need it again if a symbolic link
* is relative to the current directory. Instead we save it
* unlocked as "pdp". We must get the target inode before unlocking
* the directory to insure that the inode will not be removed
* before we get it. We prevent deadlock by always fetching
* inodes from the root, moving down the directory tree. Thus
* when following backward pointers ".." we must unlock the
* parent directory before getting the requested directory.
* There is a potential race condition here if both the current
* and parent directories are removed before the `iget' for the
* inode associated with ".." returns. We hope that this occurs
* infrequently since we cannot avoid this race condition without
* implementing a sophisticated deadlock detection algorithm.
* Note also that this simple deadlock detection scheme will not
* work if the file system has any hard links other than ".."
* that point backwards in the directory structure.
*/
pdp = dp;
/*
* If ino is different from ndp->ni_ufs.ufs_ino,
* it's a relocated directory.
*/
if (ndp->ni_isdotdot) {
ISO_IUNLOCK(pdp); /* race to get the inode */
if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
ndp->ni_ufs.ufs_ino != ino,
&tdp,ep)) {
brelse(bp);
ISO_ILOCK(pdp);
return error;
}
if (lockparent && *ndp->ni_next == '\0')
ISO_ILOCK(pdp);
ndp->ni_vp = ITOV(tdp);
} else if (dp->i_number == ndp->ni_ufs.ufs_ino) {
VREF(vdp); /* we want ourself, ie "." */
ndp->ni_vp = vdp;
} else {
if (error = iso_iget(dp,ndp->ni_ufs.ufs_ino,
ndp->ni_ufs.ufs_ino != ino,
&tdp,ep)) {
brelse(bp);
return error;
}
if (!lockparent || *ndp->ni_next != '\0')
ISO_IUNLOCK(pdp);
ndp->ni_vp = ITOV(tdp);
}
brelse(bp);
/*
* Insert name into cache if appropriate.
*/
if (ndp->ni_makeentry)
cache_enter(ndp);
return 0;
}
/*
* Return buffer with contents of block "offset"
* from the beginning of directory "ip". If "res"
* is non-zero, fill it in with a pointer to the
* remaining space in the directory.
*/
iso_blkatoff(ip, offset, bpp)
struct iso_node *ip;
off_t offset;
struct buf **bpp;
{
register struct iso_mnt *imp = ip->i_mnt;
daddr_t lbn = iso_lblkno(imp,offset);
int bsize = iso_blksize(imp,ip,lbn);
struct buf *bp;
int error;
if (error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp)) {
brelse(bp);
*bpp = 0;
return error;
}
*bpp = bp;
return 0;
}

View File

@ -1,642 +0,0 @@
/*
* Copyright (c) 1982, 1986, 1989 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)ufs_inode.c (unknown version)
* $Id: isofs_node.c,v 1.12 1994/04/25 03:49:30 cgd Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/file.h>
#include <sys/buf.h>
#include <sys/vnode.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/stat.h>
#include <isofs/iso.h>
#include <isofs/isofs_node.h>
#include <isofs/iso_rrip.h>
#define IFTOVT(mode) (iftovt_tab[((mode) & 0170000) >> 12])
static enum vtype iftovt_tab[16] = {
VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
};
#define INOHSZ 512
#if ((INOHSZ&(INOHSZ-1)) == 0)
#define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))
#else
#define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)
#endif
union iso_ihead {
union iso_ihead *ih_head[2];
struct iso_node *ih_chain[2];
} iso_ihead[INOHSZ];
#ifdef ISODEVMAP
#define DNOHSZ 64
#if ((DNOHSZ&(DNOHSZ-1)) == 0)
#define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))
#else
#define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)
#endif
union iso_dhead {
union iso_dhead *dh_head[2];
struct iso_dnode *dh_chain[2];
} iso_dhead[DNOHSZ];
#endif
int prtactive; /* 1 => print out reclaim of active vnodes */
/*
* Initialize hash links for inodes and dnodes.
*/
isofs_init()
{
register int i;
register union iso_ihead *ih = iso_ihead;
#ifdef ISODEVMAP
register union iso_dhead *dh = iso_dhead;
#endif
#ifndef lint
if (VN_MAXPRIVATE < sizeof(struct iso_node))
panic("ihinit: too small");
#endif /* not lint */
for (i = INOHSZ; --i >= 0; ih++) {
ih->ih_head[0] = ih;
ih->ih_head[1] = ih;
}
#ifdef ISODEVMAP
for (i = DNOHSZ; --i >= 0; dh++) {
dh->dh_head[0] = dh;
dh->dh_head[1] = dh;
}
#endif
}
#ifdef ISODEVMAP
/*
* Enter a new node into the device hash list
*/
struct iso_dnode *
iso_dmap(dev,ino,create)
dev_t dev;
ino_t ino;
int create;
{
struct iso_dnode *dp;
union iso_dhead *dh;
dh = &iso_dhead[DNOHASH(dev, ino)];
for (dp = dh->dh_chain[0];
dp != (struct iso_dnode *)dh;
dp = dp->d_forw)
if (ino == dp->i_number && dev == dp->i_dev)
return dp;
if (!create)
return (struct iso_dnode *)0;
MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK);
dp->i_dev = dev;
dp->i_number = ino;
insque(dp,dh);
return dp;
}
void
iso_dunmap(dev)
dev_t dev;
{
struct iso_dnode *dp, *dq;
union iso_dhead *dh;
for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) {
for (dp = dh->dh_chain[0];
dp != (struct iso_dnode *)dh;
dp = dq) {
dq = dp->d_forw;
if (dev == dp->i_dev) {
remque(dp);
FREE(dp,M_CACHE);
}
}
}
}
#endif
/*
* Look up a ISOFS dinode number to find its incore vnode.
* If it is not in core, read it in from the specified device.
* If it is in core, wait for the lock bit to clear, then
* return the inode locked. Detection and handling of mount
* points must be done by the calling routine.
*/
iso_iget(xp, ino, relocated, ipp, isodir)
struct iso_node *xp;
ino_t ino;
struct iso_node **ipp;
struct iso_directory_record *isodir;
{
dev_t dev = xp->i_dev;
struct mount *mntp = ITOV(xp)->v_mount;
extern struct vnodeops isofs_vnodeops, isofs_spec_inodeops;
register struct iso_node *ip, *iq;
register struct vnode *vp;
register struct iso_dnode *dp;
struct vnode *nvp;
struct buf *bp = NULL, *bp2 = NULL;
union iso_ihead *ih;
union iso_dhead *dh;
int i, error, result;
struct iso_mnt *imp;
ino_t defino;
ih = &iso_ihead[INOHASH(dev, ino)];
loop:
for (ip = ih->ih_chain[0];
ip != (struct iso_node *)ih;
ip = ip->i_forw) {
if (ino != ip->i_number || dev != ip->i_dev)
continue;
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
sleep((caddr_t)ip, PINOD);
goto loop;
}
if (vget(ITOV(ip), 1))
goto loop;
*ipp = ip;
return 0;
}
/*
* Allocate a new inode.
*/
if (error = getnewvnode(VT_ISOFS, mntp, &isofs_vnodeops, &nvp)) {
*ipp = 0;
return error;
}
ip = VTOI(nvp);
ip->i_vnode = nvp;
ip->i_flag = 0;
ip->i_devvp = 0;
ip->i_diroff = 0;
ip->i_lockf = 0;
/*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
* disk portion of this inode to be read.
*/
ip->i_dev = dev;
ip->i_number = ino;
insque(ip, ih);
ISO_ILOCK(ip);
imp = VFSTOISOFS (mntp);
ip->i_mnt = imp;
ip->i_devvp = imp->im_devvp;
VREF(ip->i_devvp);
if (relocated) {
/*
* On relocated directories we must
* read the `.' entry out of a dir.
*/
ip->iso_start = ino >> imp->im_bshift;
if (error = iso_blkatoff(ip,0,&bp)) {
vrele(ip->i_devvp);
remque(ip);
ip->i_forw = ip;
ip->i_back = ip;
iso_iput(ip);
*ipp = 0;
return error;
}
isodir = (struct iso_directory_record *)bp->b_un.b_addr;
}
ip->iso_extent = isonum_733(isodir->extent);
ip->i_size = isonum_733(isodir->size);
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
vp = ITOV(ip);
/*
* Setup time stamp, attribute
*/
vp->v_type = VNON;
switch (imp->iso_ftype) {
default: /* ISO_FTYPE_9660 */
if ((imp->im_flags&ISOFSMNT_EXTATT)
&& isonum_711(isodir->ext_attr_length))
iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length),
&bp2);
isofs_defattr(isodir,ip,bp2 );
isofs_deftstamp(isodir,ip,bp2 );
break;
case ISO_FTYPE_RRIP:
result = isofs_rrip_analyze(isodir,ip,imp);
break;
}
if (bp2)
brelse(bp2);
if (bp)
brelse(bp);
/*
* Initialize the associated vnode
*/
vp->v_type = IFTOVT(ip->inode.iso_mode);
if ( vp->v_type == VFIFO ) {
#ifdef FIFO
extern struct vnodeops isofs_fifo_inodeops;
vp->v_op = &isofs_fifo_inodeops;
#else
iso_iput(ip);
*ipp = 0;
return EOPNOTSUPP;
#endif /* FIFO */
} else if ( vp->v_type == VCHR || vp->v_type == VBLK ) {
/*
* if device, look at device number table for translation
*/
#ifdef ISODEVMAP
if (dp = iso_dmap(dev,ino,0))
ip->inode.iso_rdev = dp->d_dev;
#endif
vp->v_op = &isofs_spec_inodeops;
if (nvp = checkalias(vp, ip->inode.iso_rdev, mntp)) {
/*
* Reinitialize aliased inode.
*/
vp = nvp;
iq = VTOI(vp);
iq->i_vnode = vp;
iq->i_flag = 0;
ISO_ILOCK(iq);
iq->i_dev = dev;
iq->i_number = ino;
iq->i_mnt = ip->i_mnt;
bcopy(&ip->iso_extent,&iq->iso_extent,
(char *)(ip + 1) - (char *)&ip->iso_extent);
insque(iq, ih);
/*
* Discard unneeded vnode
* (This introduces the need of INACTIVE modification)
*/
ip->inode.iso_mode = 0;
iso_iput(ip);
ip = iq;
}
}
if (ip->iso_extent == imp->root_extent)
vp->v_flag |= VROOT;
*ipp = ip;
return 0;
}
/*
* Unlock and decrement the reference count of an inode structure.
*/
iso_iput(ip)
register struct iso_node *ip;
{
if ((ip->i_flag & ILOCKED) == 0)
panic("iso_iput");
ISO_IUNLOCK(ip);
vrele(ITOV(ip));
}
/*
* Last reference to an inode, write the inode out and if necessary,
* truncate and deallocate the file.
*/
isofs_inactive(vp, p)
struct vnode *vp;
struct proc *p;
{
register struct iso_node *ip = VTOI(vp);
int mode, error = 0;
if (prtactive && vp->v_usecount != 0)
vprint("isofs_inactive: pushing active", vp);
ip->i_flag = 0;
/*
* If we are done with the inode, reclaim it
* so that it can be reused immediately.
*/
if (vp->v_usecount == 0 && ip->inode.iso_mode == 0)
vgone(vp);
return error;
}
/*
* Reclaim an inode so that it can be used for other purposes.
*/
isofs_reclaim(vp)
register struct vnode *vp;
{
register struct iso_node *ip = VTOI(vp);
int i;
if (prtactive && vp->v_usecount != 0)
vprint("isofs_reclaim: pushing active", vp);
/*
* Remove the inode from its hash chain.
*/
remque(ip);
ip->i_forw = ip;
ip->i_back = ip;
/*
* Purge old data structures associated with the inode.
*/
cache_purge(vp);
if (ip->i_devvp) {
vrele(ip->i_devvp);
ip->i_devvp = 0;
}
ip->i_flag = 0;
return 0;
}
/*
* Lock an inode. If its already locked, set the WANT bit and sleep.
*/
iso_ilock(ip)
register struct iso_node *ip;
{
while (ip->i_flag & ILOCKED) {
ip->i_flag |= IWANT;
if (ip->i_spare0 == curproc->p_pid)
panic("locking against myself");
ip->i_spare1 = curproc->p_pid;
(void) sleep((caddr_t)ip, PINOD);
}
ip->i_spare1 = 0;
ip->i_spare0 = curproc->p_pid;
ip->i_flag |= ILOCKED;
}
/*
* Unlock an inode. If WANT bit is on, wakeup.
*/
iso_iunlock(ip)
register struct iso_node *ip;
{
if ((ip->i_flag & ILOCKED) == 0)
vprint("iso_iunlock: unlocked inode", ITOV(ip));
ip->i_spare0 = 0;
ip->i_flag &= ~ILOCKED;
if (ip->i_flag&IWANT) {
ip->i_flag &= ~IWANT;
wakeup((caddr_t)ip);
}
}
/*
* File attributes
*/
void
isofs_defattr(isodir,inop,bp)
struct iso_directory_record *isodir;
struct iso_node *inop;
struct buf *bp;
{
struct buf *bp2 = NULL;
struct iso_mnt *imp;
struct iso_extended_attributes *ap = NULL;
int off;
if (isonum_711(isodir->flags)&2) {
inop->inode.iso_mode = S_IFDIR;
/*
* If we return 2, fts() will assume there are no subdirectories
* (just links for the path and .), so instead we return 1.
*/
inop->inode.iso_links = 1;
} else {
inop->inode.iso_mode = S_IFREG;
inop->inode.iso_links = 1;
}
if (!bp
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
bp = bp2;
}
if (bp) {
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
if (isonum_711(ap->version) == 1) {
if (!(ap->perm[0]&0x40))
inop->inode.iso_mode |= VEXEC >> 6;
if (!(ap->perm[0]&0x10))
inop->inode.iso_mode |= VREAD >> 6;
if (!(ap->perm[0]&4))
inop->inode.iso_mode |= VEXEC >> 3;
if (!(ap->perm[0]&1))
inop->inode.iso_mode |= VREAD >> 3;
if (!(ap->perm[1]&0x40))
inop->inode.iso_mode |= VEXEC;
if (!(ap->perm[1]&0x10))
inop->inode.iso_mode |= VREAD;
inop->inode.iso_uid = isonum_723(ap->owner); /* what about 0? */
inop->inode.iso_gid = isonum_723(ap->group); /* what about 0? */
} else
ap = NULL;
}
if (!ap) {
inop->inode.iso_mode |= VREAD|VEXEC|(VREAD|VEXEC)>>3|(VREAD|VEXEC)>>6;
inop->inode.iso_uid = (uid_t)0;
inop->inode.iso_gid = (gid_t)0;
}
if (bp2)
brelse(bp2);
}
/*
* Time stamps
*/
void
isofs_deftstamp(isodir,inop,bp)
struct iso_directory_record *isodir;
struct iso_node *inop;
struct buf *bp;
{
struct buf *bp2 = NULL;
struct iso_mnt *imp;
struct iso_extended_attributes *ap = NULL;
int off;
if (!bp
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
bp = bp2;
}
if (bp) {
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
if (isonum_711(ap->version) == 1) {
if (!isofs_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
if (!isofs_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
inop->inode.iso_ctime = inop->inode.iso_atime;
if (!isofs_tstamp_conv17(ap->mtime,&inop->inode.iso_mtime))
inop->inode.iso_mtime = inop->inode.iso_ctime;
} else
ap = NULL;
}
if (!ap) {
isofs_tstamp_conv7(isodir->date,&inop->inode.iso_ctime);
inop->inode.iso_atime = inop->inode.iso_ctime;
inop->inode.iso_mtime = inop->inode.iso_ctime;
}
if (bp2)
brelse(bp2);
}
int
isofs_tstamp_conv7(pi,pu)
char *pi;
struct timeval *pu;
{
int i;
int crtime, days;
int y, m, d, hour, minute, second, tz;
y = pi[0] + 1900;
m = pi[1];
d = pi[2];
hour = pi[3];
minute = pi[4];
second = pi[5];
tz = pi[6];
if (y < 1970) {
pu->tv_sec = 0;
pu->tv_usec = 0;
return 0;
} else {
#ifdef ORIGINAL
/* computes day number relative to Sept. 19th,1989 */
/* don't even *THINK* about changing formula. It works! */
days = 367*(y-1980)-7*(y+(m+9)/12)/4-3*((y+(m-9)/7)/100+1)/4+275*m/9+d-100;
#else
/*
* Changed :-) to make it relative to Jan. 1st, 1970
* and to disambiguate negative division
*/
days = 367*(y-1960)-7*(y+(m+9)/12)/4-3*((y+(m+9)/12-1)/100+1)/4+275*m/9+d-239;
#endif
crtime = ((((days * 24) + hour) * 60 + minute) * 60) + second;
/* timezone offset is unreliable on some disks */
if (-48 <= tz && tz <= 52)
crtime -= tz * 15 * 60;
}
pu->tv_sec = crtime;
pu->tv_usec = 0;
return 1;
}
static unsigned
isofs_chars2ui(begin,len)
unsigned char *begin;
int len;
{
unsigned rc;
for (rc = 0; --len >= 0;) {
rc *= 10;
rc += *begin++ - '0';
}
return rc;
}
int
isofs_tstamp_conv17(pi,pu)
unsigned char *pi;
struct timeval *pu;
{
unsigned char buf[7];
/* year:"0001"-"9999" -> -1900 */
buf[0] = isofs_chars2ui(pi,4) - 1900;
/* month: " 1"-"12" -> 1 - 12 */
buf[1] = isofs_chars2ui(pi + 4,2);
/* day: " 1"-"31" -> 1 - 31 */
buf[2] = isofs_chars2ui(pi + 6,2);
/* hour: " 0"-"23" -> 0 - 23 */
buf[3] = isofs_chars2ui(pi + 8,2);
/* minute:" 0"-"59" -> 0 - 59 */
buf[4] = isofs_chars2ui(pi + 10,2);
/* second:" 0"-"59" -> 0 - 59 */
buf[5] = isofs_chars2ui(pi + 12,2);
/* difference of GMT */
buf[6] = pi[16];
return isofs_tstamp_conv7(buf,pu);
}
void
isodirino(inump,isodir,imp)
ino_t *inump;
struct iso_directory_record *isodir;
struct iso_mnt *imp;
{
*inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
* imp->logical_block_size;
}