/*
- * $Id: ad_open.c,v 1.14 2002-04-14 10:51:39 srittau Exp $
+ * $Id: ad_open.c,v 1.22 2002-11-14 17:11:54 srittau Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
static __inline__ int ad_v1tov2(struct adouble *ad, const char *path)
{
struct stat st;
- struct timeval tv;
u_int16_t attr;
char *buf;
int fd, off;
if ((fd = open(path, O_RDWR)) < 0)
goto bail_lock;
- if (gettimeofday(&tv, NULL) < 0)
- goto bail_lock;
-
if (fstat(fd, &st) ||
ftruncate(fd, st.st_size + SHIFTDATA) < 0) {
goto bail_open;
off = ad->ad_eid[ADEID_RFORK].ade_off;
-#ifdef USE_MMAPPED_HEADERS
- /* okay, unmap our old ad header and point it to our local copy */
- munmap(ad->ad_data, off);
- ad->ad_data = buf;
-#endif /* USER_MMAPPED_HEADERS */
-
/* move the RFORK. this assumes that the RFORK is at the end */
memmove(buf + off + SHIFTDATA, buf + off,
ad->ad_eid[ADEID_RFORK].ade_len);
/* now, fill in the space with appropriate stuff. we're
operating as a v2 file now. */
- ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, tv.tv_sec);
+ ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
memset(ad_entry(ad, ADEID_DID), 0, ADEDLEN_DID);
memset(ad_entry(ad, ADEID_AFPFILEI), 0, ADEDLEN_AFPFILEI);
ad_setattr(ad, attr);
close(fd);
ad_tmplock(ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
-#ifdef USE_MMAPPED_HEADERS
- /* now remap our header */
- ad->ad_data = mmap(NULL, ADEDOFF_RFORK_V2, PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ? MAP_SHARED :
- MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED)
- goto bail_err;
-#endif /* USE_MMAPPED_HEADERS */
-
return 0;
bail_truncate:
}
#endif /* AD_VERSION == AD_VERSION2 */
+#ifdef ATACC
+mode_t ad_hf_mode (mode_t mode)
+{
+#ifndef USE_FLOCK_LOCKS
+ /* fnctl lock need write access */
+ if ((mode & S_IRUSR))
+ mode |= S_IWUSR;
+ if ((mode & S_IRGRP))
+ mode |= S_IWGRP;
+ if ((mode & S_IROTH))
+ mode |= S_IWOTH;
+#endif
+ /* if write mode set add read mode */
+ if ((mode & S_IWUSR))
+ mode |= S_IRUSR;
+ if ((mode & S_IWGRP))
+ mode |= S_IRGRP;
+ if ((mode & S_IWOTH))
+ mode |= S_IROTH;
+
+ return mode;
+}
+
+#endif
-/* read in the entries */
-static __inline__ void parse_entries(struct adouble *ad, char *buf,
+/* -------------------------------------
+ read in the entries
+*/
+static void parse_entries(struct adouble *ad, char *buf,
u_int16_t nentries)
{
u_int32_t eid, len, off;
* NOTE: we're assuming that the resource fork is kept at the end of
* the file. also, mmapping won't work for the hfs fs until it
* understands how to mmap header files. */
-static __inline__ int ad_header_read(struct adouble *ad)
+static int ad_header_read(struct adouble *ad, struct stat *hst)
{
-#ifdef USE_MMAPPED_HEADERS
- char buf[AD_ENTRY_LEN*ADEID_MAX];
-#else /* USE_MMAPPED_HEADERS */
char *buf = ad->ad_data;
-#endif /* USE_MMAPPED_HEADERS */
u_int16_t nentries;
int len;
+ ssize_t header_len;
static int warning = 0;
+ struct stat st;
/* read the header */
- if ( ad->ad_hf.adf_off != 0 ) {
- if ( lseek( ad->ad_hf.adf_fd, 0L, SEEK_SET ) < 0L ) {
- return( -1 );
- }
- ad->ad_hf.adf_off = 0;
+ if ((header_len = adf_pread( &ad->ad_hf, buf, sizeof(ad->ad_data), 0)) < 0) {
+ return -1;
}
-
- if (read( ad->ad_hf.adf_fd, buf, AD_HEADER_LEN) != AD_HEADER_LEN) {
- if ( errno == 0 ) {
- errno = EIO;
- }
- return( -1 );
+ if (header_len < AD_HEADER_LEN) {
+ errno = EIO;
+ return -1;
}
- ad->ad_hf.adf_off = AD_HEADER_LEN;
memcpy(&ad->ad_magic, buf, sizeof( ad->ad_magic ));
- memcpy(&ad->ad_version, buf + ADEDOFF_VERSION,
- sizeof( ad->ad_version ));
+ memcpy(&ad->ad_version, buf + ADEDOFF_VERSION, sizeof( ad->ad_version ));
/* tag broken v1 headers. just assume they're all right.
* we detect two cases: null magic/version
ad->ad_magic = AD_MAGIC;
ad->ad_version = AD_VERSION1;
- } else if ((ad->ad_magic == AD_MAGIC) &&
- (ad->ad_version == AD_VERSION1)) {
+ } else if (ad->ad_magic == AD_MAGIC && ad->ad_version == AD_VERSION1) {
if (!warning) {
LOG(log_debug, logtype_default, "notice: fixing up byte-swapped v1 magic/version.");
warning++;
/* read in all the entry headers. if we have more than the
* maximum, just hope that the rfork is specified early on. */
len = nentries*AD_ENTRY_LEN;
-#ifdef USE_MMAPPED_HEADERS
- if (len > sizeof(buf))
- len = sizeof(buf);
-#else /* USE_MMAPPED_HEADERS */
+
if (len + AD_HEADER_LEN > sizeof(ad->ad_data))
len = sizeof(ad->ad_data) - AD_HEADER_LEN;
+
buf += AD_HEADER_LEN;
-#endif /* USE_MMAPPED_HEADERS */
- if (read(ad->ad_hf.adf_fd, buf, len) != len) {
- if (errno == 0)
- errno = EIO;
+ if (len > header_len - AD_HEADER_LEN) {
+ errno = EIO;
LOG(log_debug, logtype_default, "ad_header_read: can't read entry info.");
return -1;
}
- ad->ad_hf.adf_off += len;
/* figure out all of the entry offsets and lengths. if we aren't
* able to read a resource fork entry, bail. */
parse_entries(ad, buf, nentries);
if (!ad_getentryoff(ad, ADEID_RFORK)
-#ifndef USE_MMAPPED_HEADERS
|| (ad_getentryoff(ad, ADEID_RFORK) > sizeof(ad->ad_data))
-#endif /* ! USE_MMAPPED_HEADERS */
) {
LOG(log_debug, logtype_default, "ad_header_read: problem with rfork entry offset.");
return -1;
}
- /* read/mmap up to the beginning of the resource fork. */
-#ifdef USE_MMAPPED_HEADERS
- ad->ad_data = mmap(NULL, ad_getentryoff(ad, ADEID_RFORK),
- PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ? MAP_SHARED :
- MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED)
- return -1;
-#else /* USE_MMAPPED_HEADERS */
- buf += len;
- len = ad_getentryoff(ad, ADEID_RFORK) - ad->ad_hf.adf_off;
- if (read(ad->ad_hf.adf_fd, buf, len) != len) {
- if (errno == 0)
- errno = EIO;
+ if (ad_getentryoff(ad, ADEID_RFORK) > header_len) {
+ errno = EIO;
LOG(log_debug, logtype_default, "ad_header_read: can't read in entries.");
return -1;
}
-#endif /* USE_MMAPPED_HEADERS */
+ if (hst == NULL) {
+ hst = &st;
+ if (fstat(ad->ad_hf.adf_fd, &st) < 0) {
+ return 1; /* fail silently */
+ }
+ }
+ ad->ad_rlen = hst->st_size - ad_getentryoff(ad, ADEID_RFORK);
+
/* fix up broken dates */
if (ad->ad_version == AD_VERSION1) {
- struct stat st;
u_int32_t aint;
- if (fstat(ad->ad_hf.adf_fd, &st) < 0) {
- return 1; /* fail silently */
- }
-
/* check to see if the ad date is wrong. just see if we have
* a modification date in the future. */
if (((ad_getdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, &aint)) == 0) &&
- (aint > TIMEWARP_DELTA + st.st_mtime)) {
+ (aint > TIMEWARP_DELTA + hst->st_mtime)) {
ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, aint - AD_DATE_DELTA);
ad_getdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, &aint);
ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, aint - AD_DATE_DELTA);
*/
char *
ad_path( path, adflags )
- char *path;
+ const char *path;
int adflags;
{
static char pathbuf[ MAXPATHLEN + 1];
#define DEFMASK 07700 /* be conservative */
-int
-ad_mode( path, mode )
- char *path;
- int mode;
+char
+*ad_dir(path)
+ const char *path;
{
static char modebuf[ MAXPATHLEN + 1];
- struct stat stbuf;
char *slash;
- if ( mode == 0 ) {
- return( mode ); /* save on syscalls */
- }
-
if ( strlen( path ) >= MAXPATHLEN ) {
- return( mode & DEFMASK ); /* can't do it */
+ return NULL; /* can't do it */
}
/*
modebuf[0] = '.'; /* use current directory */
modebuf[1] = '\0';
}
+ return modebuf;
+}
- if ( stat( modebuf, &stbuf ) != 0 ) {
+int
+ad_mode( path, mode )
+ const char *path;
+ int mode;
+{
+ struct stat stbuf;
+ char *p;
+
+ if ( mode == 0 ) {
+ return( mode ); /* save on syscalls */
+ }
+ p = ad_dir(path);
+ if (!p) {
+ return( mode & DEFMASK ); /* can't do it */
+ }
+
+ if ( stat( p, &stbuf ) != 0 ) {
return( mode & DEFMASK ); /* bail out... can't stat dir? */
}
*/
int
ad_mkdir( path, mode )
- char *path;
+ const char *path;
int mode;
{
#ifdef DEBUG
}
+static int new_rfork(const char *path, struct adouble *ad, int adflags);
+
+#ifdef HAVE_PREAD
+#define AD_SET(a)
+#else
+#define AD_SET(a) a = 0
+#endif
/*
* It's not possible to open the header file O_RDONLY -- the read
* will fail and return an error. this refcounts things now.
*/
int ad_open( path, adflags, oflags, mode, ad )
- char *path;
+ const char *path;
int adflags, oflags, mode;
struct adouble *ad;
{
- const struct entry *eid;
struct stat st;
char *slash, *ad_p;
- int hoflags, phflags, admode;
- u_int16_t ashort;
+ int hoflags, admode;
if (ad->ad_inited != AD_INITED) {
ad_dfileno(ad) = -1;
ad_hfileno(ad) = -1;
adf_lock_init(&ad->ad_df);
adf_lock_init(&ad->ad_hf);
-#ifdef USE_MMAPPED_HEADERS
- ad->ad_data = MAP_FAILED;
-#endif /* USE_MMAPPED_HEADERS */
ad->ad_inited = AD_INITED;
ad->ad_refcount = 1;
}
- // File is always opened RW. Server checks if client may or may not write to.
- // FIXME: is this a correct solution to this problem ?
- phflags = (oflags & ~(O_RDONLY | O_WRONLY | O_RDWR)) | O_RDWR;
-
- if (adflags & ADFLAGS_DF) {
+ if ((adflags & ADFLAGS_DF)) {
if (ad_dfileno(ad) == -1) {
- if (( ad->ad_df.adf_fd =
- open( path, phflags, ad_mode( path, mode ) )) < 0 ) {
- return( -1 );
+ hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+ admode = ad_mode( path, mode );
+ if (( ad->ad_df.adf_fd = open( path, hoflags, admode )) < 0 ) {
+ if (errno == EACCES && !(oflags & O_RDWR)) {
+ hoflags = oflags;
+ ad->ad_df.adf_fd =open( path, hoflags, admode );
+ }
}
- ad->ad_df.adf_off = 0;
- ad->ad_df.adf_flags = oflags;
+ if ( ad->ad_df.adf_fd < 0)
+ return -1;
+
+ AD_SET(ad->ad_df.adf_off);
+ ad->ad_df.adf_flags = hoflags;
}
+ else {
+ /* the file is already open... but */
+ if ((oflags & ( O_RDWR | O_WRONLY)) && /* we want write access */
+ !(ad->ad_df.adf_flags & ( O_RDWR | O_WRONLY))) /* and it was denied the first time */
+ {
+ errno = EACCES;
+ return -1;
+ }
+ }
ad->ad_df.adf_refcount++;
}
- if (adflags & ADFLAGS_HF) {
- if (ad_hfileno(ad) == -1) {
- ad_p = ad_path( path, adflags );
- admode = ad_mode( ad_p, mode ); /* FIXME? */
-
- hoflags = oflags & ~O_CREAT;
- if (( ad->ad_hf.adf_fd = open( ad_p, (hoflags & ~(O_RDONLY | O_WRONLY | O_RDWR)) | O_RDWR, admode )) < 0 ) {
- if ( errno == ENOENT && hoflags != oflags ) {
- /*
- * We're expecting to create a new adouble header file,
- * here.
- */
- errno = 0;
- if (( ad->ad_hf.adf_fd = open( ad_p, phflags,
- admode )) < 0 ) {
+ if (!(adflags & ADFLAGS_HF))
+ return 0;
+
+ if (ad_hfileno(ad) != -1) { /* the file is already open */
+ if ((oflags & ( O_RDWR | O_WRONLY)) &&
+ !(ad->ad_hf.adf_flags & ( O_RDWR | O_WRONLY))) {
+ if (adflags & ADFLAGS_DF) {
+ /* don't call with ADFLAGS_HF because we didn't open ressource fork */
+ ad_close( ad, ADFLAGS_DF );
+ }
+ errno = EACCES;
+ return -1;
+ }
+ ad_refresh(ad);
+ ad->ad_hf.adf_refcount++;
+ return 0;
+ }
+
+ ad_p = ad_path( path, adflags );
+
+ hoflags = oflags & ~O_CREAT;
+ hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
+ if (( ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 )) < 0 ) {
+ if (errno == EACCES && !(oflags & O_RDWR)) {
+ hoflags = oflags & ~O_CREAT;
+ ad->ad_hf.adf_fd = open( ad_p, hoflags, 0 );
+ }
+ }
+
+ if ( ad->ad_hf.adf_fd < 0 ) {
+ if (errno == ENOENT && (oflags & O_CREAT) ) {
+ /*
+ * We're expecting to create a new adouble header file,
+ * here.
+ * if ((oflags & O_CREAT) ==> (oflags & O_RDWR)
+ */
+ admode = ad_hf_mode(ad_mode( ad_p, mode ));
+ errno = 0;
+ if (( ad->ad_hf.adf_fd = open( ad_p, oflags,admode )) < 0 ) {
/*
* Probably .AppleDouble doesn't exist, try to
* mkdir it.
*/
- if ((errno == ENOENT) &&
- ((adflags & ADFLAGS_NOADOUBLE) == 0)) {
- if (( slash = strrchr( ad_p, '/' )) == NULL ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- *slash = '\0';
- errno = 0;
- if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- *slash = '/';
- if (( ad->ad_hf.adf_fd =
- open( ad_p, phflags, ad_mode( ad_p, mode) )) < 0 ) {
- ad_close( ad, adflags );
- return( -1 );
- }
+ if (errno == ENOENT && (adflags & ADFLAGS_NOADOUBLE) == 0) {
+ if (( slash = strrchr( ad_p, '/' )) == NULL ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ *slash = '\0';
+ errno = 0;
+ if ( ad_mkdir( ad_p, 0777 ) < 0 ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ *slash = '/';
+ if (( ad->ad_hf.adf_fd =
+ open( ad_p, oflags, ad_mode( ad_p, mode) )) < 0 ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
} else {
ad_close( ad, adflags );
return( -1 );
}
- }
- ad->ad_hf.adf_flags = oflags;
- } else {
- ad_close( ad, adflags );
- return( -1 );
}
- } else if ((fstat(ad->ad_hf.adf_fd, &st) == 0) &&
- (st.st_size == 0)) {
- /* for 0 length files, treat them as new. */
ad->ad_hf.adf_flags = oflags;
- } else {
- ad->ad_hf.adf_flags = hoflags;
- }
- ad->ad_hf.adf_off = 0;
+ } else {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ } else if (fstat(ad->ad_hf.adf_fd, &st) == 0 && st.st_size == 0) {
+ /* for 0 length files, treat them as new. */
+ ad->ad_hf.adf_flags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR | O_TRUNC;
+ } else {
+ ad->ad_hf.adf_flags = hoflags;
+ }
+ AD_SET(ad->ad_hf.adf_off);
- /*
- * This is a new adouble header file. Initialize the structure,
- * instead of reading it.
- */
- memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
- if ( ad->ad_hf.adf_flags & ( O_TRUNC | O_CREAT )) {
- struct timeval tv;
-
- ad->ad_magic = AD_MAGIC;
- ad->ad_version = AD_VERSION;
- memset(ad->ad_filler, 0, sizeof( ad->ad_filler ));
-
-#ifdef USE_MMAPPED_HEADERS
- /* truncate the header file and mmap it. */
- ftruncate(ad->ad_hf.adf_fd, AD_DATASZ);
- ad->ad_data = mmap(NULL, AD_DATASZ, PROT_READ | PROT_WRITE,
- MAP_SHARED, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED) {
- ad_close(ad, adflags);
- return -1;
- }
-#else /* USE_MMAPPED_HEADERS */
- memset(ad->ad_data, 0, sizeof(ad->ad_data));
-#endif /* USE_MMAPPED_HEADERS */
-
- eid = entry_order;
- while (eid->id) {
- ad->ad_eid[eid->id].ade_off = eid->offset;
- ad->ad_eid[eid->id].ade_len = eid->len;
- eid++;
- }
+ memset(ad->ad_eid, 0, sizeof( ad->ad_eid ));
+ if ((ad->ad_hf.adf_flags & ( O_TRUNC | O_CREAT ))) {
+ /*
+ * This is a new adouble header file. Initialize the structure,
+ * instead of reading it.
+ */
+ if (new_rfork(path, ad, adflags) < 0) {
+ ad_close(ad, adflags);
+ return -1;
+ }
+ } else {
+ /* Read the adouble header in and parse it.*/
+ if ((ad_header_read( ad , &st) < 0)
+#if AD_VERSION == AD_VERSION2
+ || (ad_v1tov2(ad, ad_p) < 0)
+#endif /* AD_VERSION == AD_VERSION2 */
+ ) {
+ ad_close( ad, adflags );
+ return( -1 );
+ }
+ }
+ ad->ad_hf.adf_refcount++;
+ return 0 ;
+}
+
+/* ----------------------------------- */
+static int new_rfork(const char *path, struct adouble *ad, int adflags)
+{
+#if 0
+ struct timeval tv;
+#endif
+ const struct entry *eid;
+ u_int16_t ashort;
+ struct stat st;
+
+ ad->ad_magic = AD_MAGIC;
+ ad->ad_version = AD_VERSION;
+
+ memset(ad->ad_filler, 0, sizeof( ad->ad_filler ));
+ memset(ad->ad_data, 0, sizeof(ad->ad_data));
+
+ eid = entry_order;
+ while (eid->id) {
+ ad->ad_eid[eid->id].ade_off = eid->offset;
+ ad->ad_eid[eid->id].ade_len = eid->len;
+ eid++;
+ }
- /* put something sane in the directory finderinfo */
- if (adflags & ADFLAGS_DIR) {
- /* set default view */
- ashort = htons(FINDERINFO_CLOSEDVIEW);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRVIEWOFF,
+ /* put something sane in the directory finderinfo */
+ if (adflags & ADFLAGS_DIR) {
+ /* set default view */
+ ashort = htons(FINDERINFO_CLOSEDVIEW);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRVIEWOFF,
&ashort, sizeof(ashort));
- } else {
- /* set default creator/type fields */
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRTYPEOFF,
- "TEXT", 4);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRCREATOFF,
- "UNIX", 4);
- }
+ } else {
+ /* set default creator/type fields */
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRTYPEOFF,"TEXT", 4);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRCREATOFF,"UNIX", 4);
+ }
- /* make things invisible */
- if ((*path == '.') && strcmp(path, ".") && strcmp(path, "..")) {
- ashort = htons(ATTRBIT_INVISIBLE);
- ad_setattr(ad, ashort);
- ashort = htons(FINDERINFO_INVISIBLE);
- memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,
+ /* make things invisible */
+ if ((*path == '.') && strcmp(path, ".") && strcmp(path, "..")) {
+ ashort = htons(ATTRBIT_INVISIBLE);
+ ad_setattr(ad, ashort);
+ ashort = htons(FINDERINFO_INVISIBLE);
+ memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF,
&ashort, sizeof(ashort));
- }
+ }
- if (gettimeofday(&tv, NULL) < 0) {
- ad_close(ad, adflags);
- return -1;
- }
+#if 0
+ if (gettimeofday(&tv, NULL) < 0) {
+ return -1;
+ }
+#endif
+
+ if (stat(path, &st) < 0) {
+ return -1;
+ }
- /* put something sane in the date fields */
- ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, tv.tv_sec);
- ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, tv.tv_sec);
- ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, tv.tv_sec);
- ad_setdate(ad, AD_DATE_BACKUP, AD_DATE_START);
-
- } else {
- /*
- * Read the adouble header in and parse it.
- */
- if ((ad_header_read( ad ) < 0)
-#if AD_VERSION == AD_VERSION2
- || (ad_v1tov2(ad, ad_p) < 0)
-#endif /* AD_VERSION == AD_VERSION2 */
- ) {
- ad_close( ad, adflags );
- return( -1 );
- }
- }
- } // if (ad_hfileno(ad) == -1)
- // FIXME: This assumes that the only way while changing flags is RO->RW.
- // There may be cases where this is not true, so now it's possible to
- // open fork RO, then open RW, then close RW and be able to write to it.
- // Higher layers (afpd?) may mask this behavior, but it must be corrected.
- if (ad->ad_hf.adf_flags != oflags)
- ad->ad_hf.adf_flags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
-
- ad->ad_hf.adf_refcount++;
- } // if (adflags & ADFLAGS_HF)
-
- return( 0 );
+ /* put something sane in the date fields */
+ ad_setdate(ad, AD_DATE_CREATE | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_MODIFY | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_ACCESS | AD_DATE_UNIX, st.st_mtime);
+ ad_setdate(ad, AD_DATE_BACKUP, AD_DATE_START);
+ return 0;
}
/* to do this with mmap, we need the hfs fs to understand how to mmap
header files. */
int ad_refresh(struct adouble *ad)
{
-#ifdef USE_MMAPPED_HEADERS
- off_t off;
-#endif /* USE_MMAPPED_HEADERS */
if (ad->ad_hf.adf_fd < -1)
return -1;
-#ifdef USE_MMAPPED_HEADERS
- if (ad->ad_data == MAP_FAILED)
- return -1;
-
- /* re-read the header */
- off = ad_getentryoff(ad, ADEID_RFORK);
- memcpy(&nentries, ad->ad_data + ADEDOFF_NENTRIES, sizeof(nentries));
- nentries = ntohs(nentries);
- parse_entries(ad, ad->ad_data + AD_HEADER_LEN, nentries);
-
- /* check to see if something screwy happened */
- if (!ad_getentryoff(ad, ADEID_RFORK))
- return -1;
-
- /* if there's a length discrepancy, remap the header. this shouldn't
- * really ever happen. */
- if (off != ad_getentryoff(ad, ADEID_RFORK)) {
- char *buf = ad->ad_data;
- buf = ad->ad_data;
- ad->ad_data = mmap(NULL, ad_getentryoff(ad, ADEID_RFORK),
- PROT_READ | PROT_WRITE,
- (ad_getoflags(ad, ADFLAGS_HF) & O_RDWR) ?
- MAP_SHARED : MAP_PRIVATE, ad->ad_hf.adf_fd, 0);
- if (ad->ad_data == MAP_FAILED) {
- ad->ad_data = buf;
- return -1;
- }
- munmap(buf, off);
- }
- return 0;
-
-#else /* USE_MMAPPED_HEADERS */
- return ad_header_read(ad);
-#endif /* USE_MMAPPED_HEADERS */
+ return ad_header_read(ad, NULL);
}