/*
- * $Id: directory.c,v 1.31 2002-04-29 06:56:02 morgana Exp $
+ * $Id: directory.c,v 1.32 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#endif /* ! REMOVE_NODES */
}
+/* ---------------------------------------
+ * remove the node and its childs from the tree
+ *
+ * FIXME what about opened forks with refs to it?
+ * it's an afp specs violation because you can't delete
+ * an opened forks. Now afpd doesn't care about forks opened by other
+ * process. It's fixable within afpd if fnctl_lock, doable with smb and
+ * next to impossible for nfs and local filesystem access.
+ */
+
+static void dir_invalidate( vol, dir )
+const struct vol *vol;
+struct dir *dir;
+{
+ if (curdir == dir) {
+ /* v_root can't be deleted */
+ if (movecwd(vol, vol->v_root) < 0)
+ printf("Yuup cant change dir to v_root\n");
+ }
+ /* FIXME */
+ dirchildremove(dir->d_parent, dir);
+ dir_remove( vol, dir );
+}
+/* ------------------------------------ */
static struct dir *dir_insert(vol, dir)
const struct vol *vol;
struct dir *dir;
struct dir *cdir;
static char path[ MAXPATHLEN + 1];
char *data, *p;
+ char *u;
int extend = 0;
int len;
-
+ int olen = 0;
+
data = *cpath;
if ( *data++ != 2 ) { /* path type */
return( NULL );
len = (unsigned char) *data++;
*cpath += len + 2;
*path = '\0';
+ u = NULL;
for ( ;; ) {
if ( len == 0 ) {
if ( !extend && movecwd( vol, dir ) < 0 ) {
- return( NULL );
+ /* it's tricky:
+ movecwd failed so dir is not there anymore.
+ FIXME Is it true with other errors?
+ if path == '\0' ==> the cpath parameter is that dir,
+ and maybe we are trying to recreate it! So we can't
+ fail here.
+
+ */
+ if ( dir->d_did == DIRDID_ROOT_PARENT)
+ return NULL;
+ cdir = dir->d_parent;
+ dir_invalidate(vol, dir);
+ if (*path != '\0' || u == NULL) {
+ /* FIXME: if path != '\0' then extend != 0 ?
+ * u == NUL ==> cpath is something like:
+ * toto\0\0\0
+ */
+ return NULL;
+ }
+ if (movecwd(vol, cdir) < 0) {
+ printf("can't change to parent\n");
+ return NULL; /* give up the whole tree is out of synch*/
+ }
+ /* restore the previous token */
+ strncpy(path, u, olen);
+ path[olen] = '\0';
}
return( path );
}
data++;
len--;
}
+ u = NULL;
while ( *data == '\0' && len > 0 ) {
if ( dir->d_parent == NULL ) {
/* would this be faster with strlen + strncpy? */
p = path;
+ if (len > 0) {
+ u = data;
+ olen = len;
+ }
while ( *data != '\0' && len > 0 ) {
*p++ = *data++;
len--;
}
if ( cdir == NULL ) {
++extend;
+ /* if dir == curdir it always succeed,
+ even if curdir is deleted.
+ it's not a pb because it will failed in extenddir
+ */
if ( movecwd( vol, dir ) < 0 ) {
+ /* dir is not valid anymore
+ we delete dir from the cache and abort.
+ */
+ dir_invalidate(vol, dir);
return( NULL );
}
cdir = extenddir( vol, dir, path );
}
} else {
- dir = cdir;
+ dir = cdir;
*path = '\0';
}
}
switch( errno ) {
case EACCES:
return( AFPERR_ACCESS );
- case EEXIST:
+ case EEXIST: /* FIXME this on is impossible? */
return( AFPERR_EXIST );
default:
return( AFPERR_NOOBJ );
}
}
-
+ /* FIXME check done elswhere? cname was able to move curdir to it! */
+ if (*path == '\0')
+ return AFPERR_EXIST;
upath = mtoupath(vol, path);
-
- /* check for illegal bits in the unix filename */
- if (!wincheck(vol, upath))
- return AFPERR_PARAM;
-
- if ((vol->v_flags & AFPVOL_NOHEX) && strchr(upath, '/'))
- return AFPERR_PARAM;
-
- if (!validupath(vol, upath))
- return AFPERR_EXIST;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, upath))
- return AFPERR_EXIST;
+ {
+ int ret;
+ if (0 != (ret = check_name(vol, upath))) {
+ return ret;
+ }
+ }
#ifdef FORCE_UIDGID
save_uidgid ( &uidgid );
/*
- * $Id: file.c,v 1.43 2002-03-24 17:43:39 jmarcus Exp $
+ * $Id: file.c,v 1.44 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
0, 0, 0, 0, 0, 0, 0, 0
};
-int getfilparams(struct vol *vol,
+int getmetadata(struct vol *vol,
u_int16_t bitmap,
char *path, struct dir *dir, struct stat *st,
- char *buf, int *buflen )
+ char *buf, int *buflen, struct adouble *adp, int attrbits )
{
#ifndef USE_LASTDID
- struct stat hst, lst, *lstp;
-#else /* USE_LASTDID */
- struct stat hst;
+ struct stat lst, *lstp;
#endif /* USE_LASTDID */
- struct adouble ad, *adp;
- struct ofork *of;
+ struct stat hst;
struct extmap *em;
char *data, *nameoff = NULL, *upath;
- int bit = 0, isad = 1;
+ int bit = 0;
u_int32_t aint;
u_int16_t ashort;
u_char achar, fdType[4];
#ifdef DEBUG
- LOG(log_info, logtype_afpd, "begin getfilparams:");
+ LOG(log_info, logtype_afpd, "begin getmetadata:");
#endif /* DEBUG */
upath = mtoupath(vol, path);
- if ((of = of_findname(vol, curdir, path))) {
- adp = of->of_ad;
- } else {
- memset(&ad, 0, sizeof(ad));
- adp = &ad;
- }
-
- if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) {
- isad = 0;
- } else if ( fstat( ad_hfileno( adp ), &hst ) < 0 ) {
- LOG(log_error, logtype_afpd, "getfilparams fstat: %s", strerror(errno) );
- }
data = buf;
while ( bitmap != 0 ) {
switch ( bit ) {
case FILPBIT_ATTR :
- if ( isad ) {
+ if ( adp ) {
ad_getattr(adp, &ashort);
} else if (*upath == '.') {
ashort = htons(ATTRBIT_INVISIBLE);
} else
ashort = 0;
+ if (attrbits)
+ ashort = htons(ntohs(ashort) | attrbits);
memcpy(data, &ashort, sizeof( ashort ));
- data += sizeof( u_short );
+ data += sizeof( ashort );
break;
case FILPBIT_PDID :
break;
case FILPBIT_CDATE :
- if (!isad || (ad_getdate(adp, AD_DATE_CREATE, &aint) < 0))
+ if (!adp || (ad_getdate(adp, AD_DATE_CREATE, &aint) < 0))
aint = AD_DATE_FROM_UNIX(st->st_mtime);
memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
case FILPBIT_MDATE :
- if ( isad && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) {
- if ((st->st_mtime > AD_DATE_TO_UNIX(aint)) &&
- (hst.st_mtime < st->st_mtime)) {
- aint = AD_DATE_FROM_UNIX(st->st_mtime);
+ if ( adp && (ad_getdate(adp, AD_DATE_MODIFY, &aint) == 0)) {
+ if ((st->st_mtime > AD_DATE_TO_UNIX(aint))) {
+ if ( fstat( ad_hfileno( adp ), &hst ) < 0 ) {
+ LOG(log_error, logtype_default, "getfilparams fstat: %s", strerror(errno) );
+ }
+ else if (hst.st_mtime < st->st_mtime)
+ aint = AD_DATE_FROM_UNIX(st->st_mtime);
+ else
+ aint = AD_DATE_FROM_UNIX(hst.st_mtime);
}
} else {
aint = AD_DATE_FROM_UNIX(st->st_mtime);
break;
case FILPBIT_BDATE :
- if (!isad || (ad_getdate(adp, AD_DATE_BACKUP, &aint) < 0))
+ if (!adp || (ad_getdate(adp, AD_DATE_BACKUP, &aint) < 0))
aint = AD_DATE_START;
memcpy(data, &aint, sizeof( int ));
data += sizeof( int );
break;
case FILPBIT_FINFO :
- if (isad)
+ if (adp)
memcpy(data, ad_entry(adp, ADEID_FINDERI), 32);
else {
memcpy(data, ufinderi, 32);
}
}
- if ((!isad || (memcmp(ad_entry(adp, ADEID_FINDERI),
+ if ((!adp || (memcmp(ad_entry(adp, ADEID_FINDERI),
ufinderi, 8 ) == 0)) &&
(em = getextmap( path ))) {
memcpy(data, em->em_type, sizeof( em->em_type ));
aint = 0;
#if AD_VERSION > AD_VERSION1
/* look in AD v2 header */
- if (isad)
+ if (adp)
memcpy(&aint, ad_entry(adp, ADEID_DID), sizeof(aint));
#endif /* AD_VERSION > AD_VERSION1 */
break;
case FILPBIT_RFLEN :
- if ( isad ) {
+ if ( adp ) {
aint = htonl( ad_getentrylen( adp, ADEID_RFORK ));
} else {
aint = 0;
to "pXYZ" when we created it. See IA, Ver 2.
<shirsch@ibm.net> */
case FILPBIT_PDINFO :
- if ( isad ) {
+ if ( adp ) {
memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
if ( memcmp( fdType, "TEXT", 4 ) == 0 ) {
break;
default :
- if ( isad ) {
- ad_close( adp, ADFLAGS_HF );
- }
return( AFPERR_BITMAP );
}
bitmap = bitmap>>1;
memcpy(data, path, aint );
data += aint;
}
- if ( isad ) {
- ad_close( adp, ADFLAGS_HF );
- }
*buflen = data - buf;
+ return (AFP_OK);
+}
+
+/* ----------------------- */
+int getfilparams(struct vol *vol,
+ u_int16_t bitmap,
+ char *path, struct dir *dir, struct stat *st,
+ char *buf, int *buflen )
+{
+ struct adouble ad, *adp;
+ struct ofork *of;
+ char *upath;
+ int rc;
+#ifdef DEBUG
+ LOG(log_info, logtype_default, "begin getfilparams:");
+#endif /* DEBUG */
+ upath = mtoupath(vol, path);
+ if ((of = of_findname(vol, dir, path))) {
+ adp = of->of_ad;
+ } else {
+ memset(&ad, 0, sizeof(ad));
+ adp = &ad;
+ }
+
+ if ( ad_open( upath, ADFLAGS_HF, O_RDONLY, 0, adp) < 0 ) {
+ adp = NULL;
+ }
+ rc = getmetadata(vol, bitmap, path, dir, st, buf, buflen, adp, 0);
+ if ( adp ) {
+ ad_close( adp, ADFLAGS_HF );
+ }
#ifdef DEBUG
LOG(log_info, logtype_afpd, "end getfilparams:");
#endif /* DEBUG */
- return( AFP_OK );
+ return( rc );
}
+/* ----------------------------- */
int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
}
upath = mtoupath(vol, path);
-
- /* check for illegal bits in the unix filename */
- if (!wincheck(vol, upath))
- return AFPERR_PARAM;
-
- if ((vol->v_flags & AFPVOL_NOHEX) && strchr(upath, '/'))
- return AFPERR_PARAM;
-
- if (!validupath(vol, upath))
- return AFPERR_EXIST;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, upath))
- return AFPERR_EXIST;
+ {
+ int ret;
+ if (0 != (ret = check_name(vol, upath)))
+ return ret;
+ }
if ((of = of_findname(vol, curdir, path))) {
adp = of->of_ad;
* and the new mac name.
* NOTE: if we have to copy a file instead of renaming it, locks
* will break.
+ * FIXME: locks on ressource fork will always break thanks to ad_close, done ?
+ *
+ * src the full source absolute path
+ * dst the dest filename in current dir
+ * newname the dest mac name
+ * adp adouble struct of src file, if open, or & zeroed one
+ *
*/
-int renamefile(src, dst, newname, noadouble )
+int renamefile(src, dst, newname, noadouble, adp )
char *src, *dst, *newname;
const int noadouble;
+struct adouble *adp;
{
- struct adouble ad;
+ struct ofork *opened;
char adsrc[ MAXPATHLEN + 1];
int len, rc;
case ENOENT :
/* check for a source appledouble header. if it exists, make
* a dest appledouble directory and do the rename again. */
- memset(&ad, 0, sizeof(ad));
if (rc || stat(adsrc, &st) ||
- (ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad) < 0))
+ (ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, adp) < 0))
return AFP_OK;
rc++;
- ad_close(&ad, ADFLAGS_HF);
+ ad_close(adp, ADFLAGS_HF);
goto rename_retry;
case EPERM:
case EACCES :
}
}
- memset(&ad, 0, sizeof(ad));
- if ( ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, &ad) < 0 ) {
+ if ( ad_open( dst, ADFLAGS_HF, O_RDWR, 0666, adp) < 0 ) {
switch ( errno ) {
case ENOENT :
return( AFPERR_NOOBJ );
}
len = strlen( newname );
- ad_setentrylen( &ad, ADEID_NAME, len );
- memcpy(ad_entry( &ad, ADEID_NAME ), newname, len );
- ad_flush( &ad, ADFLAGS_HF );
- ad_close( &ad, ADFLAGS_HF );
+ ad_setentrylen( adp, ADEID_NAME, len );
+ memcpy(ad_entry( adp, ADEID_NAME ), newname, len );
+ ad_flush( adp, ADFLAGS_HF );
+ ad_close( adp, ADFLAGS_HF );
#ifdef DEBUG
LOG(log_info, logtype_afpd, "end renamefile:");
/* -----------------------------------
checkAttrib: 1 check kFPDeleteInhibitBit
- ie deletfile called from afp_delete
-
+ ie deletfile called by afp_delete
+
+ when deletefile is called we don't have lock on it, file is closed (for us)
*/
int deletefile( file, checkAttrib )
char *file;
return(AFPERR_OLOCK);
}
}
-
- if ((adflags & ADFLAGS_HF) &&
- (ad_tmplock(&ad, ADEID_RFORK, locktype, 0, 0) < 0 )) {
- ad_close( &ad, adflags );
- return( AFPERR_BUSY );
+
+ if ((adflags & ADFLAGS_HF) ) {
+ /* FIXME we have a pb here because we want to know if a file is open
+ * there's a 'priority inversion' if you can't open the ressource fork RW
+ * you can delete it if it's open because you can't get a write lock.
+ *
+ * ADLOCK_FILELOCK means the whole ressource fork, not only after the
+ * metadatas
+ *
+ * FIXME it doesn't for RFORK open read only and fork open without deny mode
+ */
+ if (ad_tmplock(&ad, ADEID_RFORK, locktype |ADLOCK_FILELOCK, 0, 0) < 0 ) {
+ ad_close( &ad, adflags );
+ return( AFPERR_BUSY );
+ }
}
if (ad_tmplock( &ad, ADEID_DFORK, locktype, 0, 0 ) < 0) {
delete_unlock:
if (adflags & ADFLAGS_HF)
- ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR, 0, 0);
+ ad_tmplock(&ad, ADEID_RFORK, ADLOCK_CLR |ADLOCK_FILELOCK, 0, 0);
ad_tmplock(&ad, ADEID_DFORK, ADLOCK_CLR, 0, 0);
ad_close( &ad, adflags );
char *spath, temp[17], *path, *p;
char *supath, *upath;
int err;
+ struct adouble ads;
+ struct adouble add;
+ struct adouble *adsp;
+ struct adouble *addp;
+ struct ofork *opened;
+
#ifdef CNID_DB
int slen, dlen;
#endif /* CNID_DB */
}
if ( *path == '\0' ) {
- return( AFPERR_BADTYPE );
+ return( AFPERR_BADTYPE ); /* it's a dir */
}
upath = mtoupath(vol, path);
return AFPERR_PARAM;
}
}
-
+ memset(&ads, 0, sizeof(ads));
+ adsp = &ads;
+ if ((opened = of_findname(vol, curdir, path))) {
+ /* reuse struct adouble so it won't break locks */
+ adsp = opened->of_ad;
+ }
/* save some stuff */
sdir = curdir;
spath = obj->oldtmp;
return AFPERR_PARAM;
}
}
-
+ memset(&add, 0, sizeof(add));
+ addp = &add;
+ if ((opened = of_findname(vol, curdir, path))) {
+ /* reuse struct adouble so it won't break locks */
+ addp = opened->of_ad;
+ }
#ifdef CNID_DB
/* look for destination id. */
did = cnid_lookup(vol->v_db, &destst, curdir->d_did, upath,
return AFPERR_MISC;
/* now, quickly rename the file. we error if we can't. */
- if ((err = renamefile(p, temp, temp, vol_noadouble(vol))) < 0)
+ if ((err = renamefile(p, temp, temp, vol_noadouble(vol), adsp)) < 0)
goto err_exchangefile;
of_rename(vol, sdir, spath, curdir, temp);
/* rename destination to source */
- if ((err = renamefile(path, p, spath, vol_noadouble(vol))) < 0)
+ if ((err = renamefile(path, p, spath, vol_noadouble(vol), addp)) < 0)
goto err_src_to_tmp;
of_rename(vol, curdir, path, sdir, spath);
/* rename temp to destination */
- if ((err = renamefile(temp, upath, path, vol_noadouble(vol))) < 0)
+ if ((err = renamefile(temp, upath, path, vol_noadouble(vol), adsp)) < 0)
goto err_dest_to_src;
of_rename(vol, curdir, temp, curdir, path);
* properly. */
err_temp_to_dest:
/* rename dest to temp */
- renamefile(upath, temp, temp, vol_noadouble(vol));
+ renamefile(upath, temp, temp, vol_noadouble(vol), adsp);
of_rename(vol, curdir, upath, curdir, temp);
err_dest_to_src:
/* rename source back to dest */
- renamefile(p, upath, path, vol_noadouble(vol));
+ renamefile(p, upath, path, vol_noadouble(vol), addp);
of_rename(vol, sdir, spath, curdir, path);
err_src_to_tmp:
/* rename temp back to source */
- renamefile(temp, p, spath, vol_noadouble(vol));
+ renamefile(temp, p, spath, vol_noadouble(vol), adsp);
of_rename(vol, curdir, temp, sdir, spath);
err_exchangefile:
/*
- * $Id: file.h,v 1.6 2002-03-24 17:43:39 jmarcus Exp $
+ * $Id: file.h,v 1.7 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
struct dir *, struct stat *, char *buf,
int *));
extern int setfilparams __P((struct vol *, char *, u_int16_t, char *));
-extern int renamefile __P((char *, char *, char *, const int));
+extern int renamefile __P((char *, char *, char *, const int, struct adouble *));
extern int copyfile __P((char *, char *, char *, const int));
extern int deletefile __P((char *, int));
/*
- * $Id: filedir.c,v 1.26 2002-03-24 17:43:39 jmarcus Exp $
+ * $Id: filedir.c,v 1.27 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return( rc );
}
+/* --------------------------------------------
+ Factorise some check on a pathname
+*/
+int check_name(const struct vol *vol, char *name)
+{
+ /* check for illegal characters in the unix filename */
+ if (!wincheck(vol, name))
+ return AFPERR_PARAM;
+
+ if ((vol->v_flags & AFPVOL_NOHEX) && strchr(name, '/'))
+ return AFPERR_PARAM;
+
+ if (!validupath(vol, name))
+ return AFPERR_EXIST;
+
+ /* check for vetoed filenames */
+ if (veto_file(vol->v_veto, name))
+ return AFPERR_EXIST;
+ return 0;
+}
+
+/* -------------------------
+ move and rename sdir:oldname to curdir:newname in volume vol
+
+ special care is needed for lock
+*/
+static int moveandrename(vol, sdir, oldname, newname, isdir)
+const struct vol *vol;
+struct dir *sdir;
+char *oldname;
+char *newname;
+int isdir;
+{
+ char *p;
+ char *upath;
+ int rc;
+ struct stat st;
+ int adflags;
+ struct adouble ad;
+ struct adouble *adp;
+ struct ofork *opened;
+
+#ifdef CNID_DB
+ cnid_t id;
+#endif /* CNID_DB */
+
+ memset(&ad, 0, sizeof(ad));
+ adp = &ad;
+ adflags = 0;
+
+ if (!isdir) {
+#ifdef CNID_DB
+ p = mtoupath(vol, oldname);
+ id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
+#endif /* CNID_DB */
+ p = ctoupath( vol, sdir, oldname );
+ if ((opened = of_findname(vol, sdir, oldname))) {
+ /* reuse struct adouble so it won't break locks */
+ adp = opened->of_ad;
+ }
+ }
+ else {
+#ifdef CNID_DB
+ id = sdir->d_did; /* we already have the CNID */
+#endif /* CNID_DB */
+ p = ctoupath( vol, sdir->d_parent, oldname );
+ adflags = ADFLAGS_DIR;
+ }
+ /*
+ * p now points to the full pathname of the source fs object.
+ *
+ * we are in the dest folder so we need to use p for ad_open
+ */
+
+ if (!ad_open(p, ADFLAGS_HF |adflags, O_RDONLY, 0666, adp)) {
+ u_int16_t bshort;
+
+ ad_getattr(adp, &bshort);
+ ad_close( adp, ADFLAGS_HF );
+ if ((bshort & htons(ATTRBIT_NORENAME)))
+ return(AFPERR_OLOCK);
+ }
+
+ upath = mtoupath(vol, newname);
+ if (0 != (rc = check_name(vol, upath))) {
+ return rc;
+ }
+
+ /* source == destination. we just silently accept this. */
+ if (curdir == sdir) {
+ if (strcmp(oldname, newname) == 0)
+ return AFP_OK;
+
+ /* deal with case insensitive, case-preserving filesystems. */
+ if ((stat(upath, &st) == 0) && strdiacasecmp(oldname, newname))
+ return AFPERR_EXIST;
+
+ } else if (stat(upath, &st ) == 0)
+ return AFPERR_EXIST;
+
+ if ( !isdir ) {
+ if (of_findname(vol, curdir, newname)) {
+ rc = AFPERR_EXIST; /* was AFPERR_BUSY; */
+ } else if ((rc = renamefile( p, upath, newname,
+ vol_noadouble(vol), adp )) == AFP_OK) {
+ /* if it's still open, rename the ofork as well. */
+ rc = of_rename(vol, sdir, oldname, curdir, newname);
+ }
+ } else {
+ rc = renamedir(p, upath, sdir, curdir, newname, vol_noadouble(vol));
+ }
+ if ( rc == AFP_OK ) {
+#ifdef CNID_DB
+ /* renaming may have moved the file/dir across a filesystem */
+ if (stat(upath, &st) < 0)
+ return AFPERR_MISC;
+
+ /* fix up the catalog entry */
+ cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
+#endif /* CNID_DB */
+ }
+
+ return rc;
+}
+
+/* -------------------------------------------- */
int afp_rename(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
- struct adouble ad;
- struct stat st;
- struct vol *vol;
- struct dir *dir, *odir = NULL;
- char *path, *buf, *upath, *newpath;
- char *newadpath;
- u_int32_t did;
+ struct vol *vol;
+ struct dir *sdir;
+ char *path, *oldname, *newname;
+ u_int32_t did;
int plen;
- u_int16_t vid;
-#ifdef CNID_DB
- cnid_t id;
-#endif /* CNID_DB */
-
+ u_int16_t vid;
+ int isdir = 0;
+ int rc;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_rename:");
#endif /* DEBUG */
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
- if (( dir = dirsearch( vol, did )) == NULL ) {
+ if (( sdir = dirsearch( vol, did )) == NULL ) {
return( AFPERR_NOOBJ );
}
- if (( path = cname( vol, dir, &ibuf )) == NULL ) {
+ /* source pathname */
+ if (( path = cname( vol, sdir, &ibuf )) == NULL ) {
return( AFPERR_NOOBJ );
}
- /* another place where we know about the path type */
- if ( *ibuf++ != 2 ) {
- return( AFPERR_PARAM );
+ sdir = curdir;
+ newname = obj->newtmp;
+ oldname = obj->oldtmp;
+ if ( *path != '\0' ) {
+ strcpy(oldname, path); /* an extra copy for of_rename */
}
- plen = (unsigned char) *ibuf++;
- *( ibuf + plen ) = '\0';
-
- if ( *path == '\0' ) {
- if ( curdir->d_parent == NULL ) { /* root directory */
+ else {
+ if ( sdir->d_parent == NULL ) { /* root directory */
return( AFPERR_NORENAME );
}
- odir = curdir;
- path = curdir->d_name;
- if ( movecwd( vol, curdir->d_parent ) < 0 ) {
+ /* move to destination dir */
+ if ( movecwd( vol, sdir->d_parent ) < 0 ) {
return( AFPERR_NOOBJ );
}
+ isdir = 1;
+ strcpy(oldname, sdir->d_name);
}
-#ifdef notdef
- if ( strcasecmp( path, ibuf ) == 0 ) {
- return( AFP_OK );
+ /* another place where we know about the path type */
+ if ( *ibuf++ != 2 ) {
+ return( AFPERR_PARAM );
}
-#endif /* notdef */
-
- /* if a curdir/newname ofork exists, return busy */
- if (of_findname(vol, curdir, ibuf))
- return AFPERR_BUSY;
-
- /* source == destination. just say okay. */
- if (strcmp(path, ibuf) == 0)
- return AFP_OK;
- newpath = obj->oldtmp;
- strcpy( newpath, mtoupath(vol, ibuf ));
-
- /* check for illegal characters in the unix filename */
- if (!wincheck(vol, newpath))
- return AFPERR_PARAM;
-
- if ((vol->v_flags & AFPVOL_NOHEX) && strchr(newpath, '/'))
- return AFPERR_PARAM;
-
- if (!validupath(vol, newpath))
- return AFPERR_EXIST;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, newpath))
- return AFPERR_EXIST;
-
- /* the strdiacasecmp deals with case-insensitive, case preserving
- filesystems */
- if (stat( newpath, &st ) == 0 && strdiacasecmp(path, ibuf))
- return( AFPERR_EXIST );
-
- upath = mtoupath(vol, path);
-
-#ifdef CNID_DB
- id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
-#endif /* CNID_DB */
-
- if ( rename( upath, newpath ) < 0 ) {
- switch ( errno ) {
- case ENOENT :
- return( AFPERR_NOOBJ );
- case EACCES :
- return( AFPERR_ACCESS );
- default :
- return( AFPERR_PARAM );
- }
+ if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
+ strncpy( newname, ibuf, plen );
+ newname[ plen ] = '\0';
}
-
-#ifdef CNID_DB
- if (stat(newpath, &st) < 0) /* this shouldn't fail */
- return AFPERR_MISC;
- cnid_update(vol->v_db, id, &st, curdir->d_did, newpath, strlen(newpath));
-#endif /* CNID_DB */
-
- if ( !odir ) {
- newadpath = obj->newtmp;
- strcpy( newadpath, ad_path( newpath, 0 ));
- if ( rename( ad_path( upath, 0 ), newadpath ) < 0 ) {
- if ( errno == ENOENT ) { /* no adouble header file */
- if (( unlink( newadpath ) < 0 ) && ( errno != ENOENT )) {
- return( AFPERR_PARAM );
- }
- goto out;
- }
- return( AFPERR_PARAM );
- }
-
- memset(&ad, 0, sizeof(ad));
- if ( ad_open( newpath, ADFLAGS_HF, O_RDWR|O_CREAT, 0666,
- &ad) < 0 ) {
- return( AFPERR_PARAM );
- }
- } else {
- int isad = 1;
-
- memset(&ad, 0, sizeof(ad));
- if ( ad_open( newpath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
- O_RDWR|O_CREAT, 0666, &ad) < 0 ) {
- if (!((errno == ENOENT) && vol_noadouble(vol)))
- return( AFPERR_PARAM );
- isad = 0;
- }
- if ((buf = realloc( odir->d_name, plen + 1 )) == NULL ) {
- LOG(log_error, logtype_afpd, "afp_rename: realloc: %s", strerror(errno) );
- if (isad) {
- ad_flush(&ad, ADFLAGS_HF); /* in case of create */
- ad_close(&ad, ADFLAGS_HF);
- }
- return AFPERR_MISC;
- }
- odir->d_name = buf;
- strcpy( odir->d_name, ibuf );
- if (!isad)
- goto out;
+ else {
+ return AFP_OK; /* newname == oldname same dir */
}
+
+ rc = moveandrename(vol, sdir, oldname, newname, isdir);
- ad_setentrylen( &ad, ADEID_NAME, plen );
- memcpy( ad_entry( &ad, ADEID_NAME ), ibuf, plen );
- ad_flush( &ad, ADFLAGS_HF );
- ad_close( &ad, ADFLAGS_HF );
-
-out:
- setvoltime(obj, vol );
-
- /* if it's still open, rename the ofork as well. */
- if (of_rename(vol, curdir, path, curdir, ibuf) < 0)
- return AFPERR_MISC;
+ if ( rc == AFP_OK ) {
+ setvoltime(obj, vol );
+ }
#ifdef DEBUG
LOG(log_info, logtype_afpd, "end afp_rename:");
#endif /* DEBUG */
- return( AFP_OK );
+ return( rc );
}
-
+/* ------------------------------- */
int afp_delete(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
return( p );
}
-
+/* ------------------------- */
int afp_moveandrename(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
int ibuflen, *rbuflen;
{
struct vol *vol;
- struct dir *sdir, *ddir, *odir = NULL;
- struct stat st;
- char *oldname, *newname;
- char *path, *p, *upath;
- int did, rc;
+ struct dir *sdir, *ddir;
+ int isdir = 0;
+ char *oldname, *newname;
+ char *path;
+ int did;
int plen;
u_int16_t vid;
-#ifdef CNID_DB
- cnid_t id;
-#endif /* CNID_DB */
+ int rc;
#ifdef DROPKLUDGE
int retvalue;
#endif /* DROPKLUDGE */
oldname = obj->oldtmp;
if ( *path != '\0' ) {
/* not a directory */
- strcpy(newname, path);
strcpy(oldname, path); /* an extra copy for of_rename */
-#ifdef CNID_DB
- p = mtoupath(vol, path);
- id = cnid_get(vol->v_db, sdir->d_did, p, strlen(p));
-#endif /* CNID_DB */
- p = ctoupath( vol, sdir, newname );
} else {
- odir = curdir;
- strcpy( newname, odir->d_name );
- strcpy(oldname, odir->d_name);
- p = ctoupath( vol, odir->d_parent, newname );
-#ifdef CNID_DB
- id = curdir->d_did; /* we already have the CNID */
-#endif /* CNID_DB */
+ isdir = 1;
+ strcpy(oldname, sdir->d_name);
}
- /*
- * p now points to the full pathname of the source fs object.
- */
/* get the destination directory */
if (( ddir = dirsearch( vol, did )) == NULL ) {
strncpy( newname, ibuf, plen );
newname[ plen ] = '\0';
}
-
- upath = mtoupath(vol, newname);
-
- /* check for illegal characters in the unix filename */
- if (!wincheck(vol, upath))
- return AFPERR_PARAM;
-
- if ((vol->v_flags & AFPVOL_NOHEX) && strchr(upath, '/'))
- return AFPERR_PARAM;
-
- if (!validupath(vol, upath))
- return AFPERR_EXIST;
-
- /* check for vetoed filenames */
- if (veto_file(vol->v_veto, upath))
- return AFPERR_EXIST;
-
- /* source == destination. we just silently accept this. */
- if (curdir == sdir) {
- if (strcmp(oldname, newname) == 0)
- return AFP_OK;
-
- /* deal with case insensitive, case-preserving filesystems. */
- if ((stat(upath, &st) == 0) && strdiacasecmp(oldname, newname))
- return AFPERR_EXIST;
-
- } else if (stat(upath, &st ) == 0)
- return( AFPERR_EXIST );
-
- if ( !odir ) {
- if (of_findname(vol, curdir, newname)) {
- rc = AFPERR_BUSY;
- } else if ((rc = renamefile( p, upath, newname,
- vol_noadouble(vol) )) == AFP_OK) {
- /* if it's still open, rename the ofork as well. */
- rc = of_rename(vol, sdir, oldname, curdir, newname);
- }
- } else {
- rc = renamedir(p, upath, odir, curdir, newname, vol_noadouble(vol));
+ else {
+ strcpy(newname, oldname);
}
+
+ rc = moveandrename(vol, sdir, oldname, newname, isdir);
+ if ( rc == AFP_OK ) {
#ifdef DROPKLUDGE
- if (vol->v_flags & AFPVOL_DROPBOX) {
- if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) {
- return retvalue;
+ if (vol->v_flags & AFPVOL_DROPBOX) {
+ if (retvalue=matchfile2dirperms (newname, vol, did) != AFP_OK) {
+ return retvalue;
+ }
}
- }
#endif /* DROPKLUDGE */
-
- if ( rc == AFP_OK ) {
-#ifdef CNID_DB
- /* renaming may have moved the file/dir across a filesystem */
- if (stat(upath, &st) < 0)
- return AFPERR_MISC;
-
- /* fix up the catalog entry */
- cnid_update(vol->v_db, id, &st, curdir->d_did, upath, strlen(upath));
-#endif /* CNID_DB */
setvoltime(obj, vol );
}
/*
- * $Id: filedir.h,v 1.6 2001-12-03 05:03:38 jmarcus Exp $
+ * $Id: filedir.h,v 1.7 2002-05-13 04:59:36 jmarcus Exp $
*/
#ifndef AFPD_FILEDIR_H
extern char *ctoupath __P((const struct vol *, struct dir *,
char *));
extern int veto_file __P((const char *veto_str, const char *path));
+extern int check_name __P((const struct vol *vol, char *name));
/* FP functions */
extern int matchfile2dirperms __P((char *, struct vol *, int));
/*
- * $Id: fork.c,v 1.26 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: fork.c,v 1.27 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
#define BYTELOCK_MAX 0x7FFFFFFFU
struct ofork *writtenfork;
+extern int getmetadata(struct vol *vol,
+ u_int16_t bitmap,
+ char *path, struct dir *dir, struct stat *st,
+ char *buf, int *buflen, struct adouble *adp, int attrbits );
static int getforkparams(ofork, bitmap, buf, buflen, attrbits )
struct ofork *ofork;
#endif /* !USE_LASTDID */
struct stat st;
struct extmap *em;
- char *data, *nameoff = NULL, *upath;
- int bit = 0, isad = 1;
- u_int32_t aint;
+ char *data, *nameoff = NULL, *upath;
+ int bit = 0;
+ u_int32_t aint;
u_int16_t ashort;
+ struct adouble *adp;
+ struct dir *dir;
+ struct vol *vol;
+
if ( ad_hfileno( ofork->of_ad ) == -1 ) {
- isad = 0;
+ adp = NULL;
} else {
aint = ad_getentrylen( ofork->of_ad, ADEID_RFORK );
if ( ad_refresh( ofork->of_ad ) < 0 ) {
}
/* See afp_closefork() for why this is bad */
ad_setentrylen( ofork->of_ad, ADEID_RFORK, aint );
+ adp = ofork->of_ad;
}
/* can only get the length of the opened fork */
}
}
}
+ dir = ofork->of_dir;
+ vol = ofork->of_vol;
+ return getmetadata(vol, bitmap, ofork->of_name, dir, &st, buf, buflen, adp, attrbits );
+}
- data = buf;
- while ( bitmap != 0 ) {
- while (( bitmap & 1 ) == 0 ) {
- bitmap = bitmap>>1;
- bit++;
- }
-
- switch ( bit ) {
- case FILPBIT_ATTR :
- if ( isad ) {
- ad_getattr(ofork->of_ad, &ashort);
- } else {
- ashort = 0;
- }
- if (attrbits)
- ashort = htons(ntohs(ashort) | attrbits);
- memcpy(data, &ashort, sizeof( ashort ));
- data += sizeof( ashort );
- break;
-
- case FILPBIT_PDID :
- memcpy(data, &ofork->of_dir->d_did, sizeof( aint ));
- data += sizeof( aint );
- break;
-
- case FILPBIT_CDATE :
- if (!isad ||
- (ad_getdate(ofork->of_ad, AD_DATE_CREATE, &aint) < 0))
- aint = AD_DATE_FROM_UNIX(st.st_mtime);
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
-
- case FILPBIT_MDATE :
- if (!isad ||
- (ad_getdate(ofork->of_ad, AD_DATE_MODIFY, &aint) < 0) ||
- (AD_DATE_TO_UNIX(aint) < st.st_mtime))
- aint = AD_DATE_FROM_UNIX(st.st_mtime);
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
-
- case FILPBIT_BDATE :
- if (!isad ||
- (ad_getdate(ofork->of_ad, AD_DATE_BACKUP, &aint) < 0))
- aint = AD_DATE_START;
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
-
- case FILPBIT_FINFO :
- memcpy(data, isad ?
- (void *) ad_entry(ofork->of_ad, ADEID_FINDERI) :
- (void *) ufinderi, 32);
- if ( !isad ||
- memcmp( ad_entry( ofork->of_ad, ADEID_FINDERI ),
- ufinderi, 8 ) == 0 ) {
- memcpy(data, ufinderi, 8 );
- if (( em = getextmap( ofork->of_name )) != NULL ) {
- memcpy(data, em->em_type, sizeof( em->em_type ));
- memcpy(data + 4, em->em_creator,
- sizeof( em->em_creator ));
- }
- }
- data += 32;
- break;
-
- case FILPBIT_LNAME :
- nameoff = data;
- data += sizeof(u_int16_t);
- break;
-
- case FILPBIT_SNAME :
- memset(data, 0, sizeof(u_int16_t));
- data += sizeof(u_int16_t);
- break;
+/* -------------------------
+*/
+#define SHARE 0
+#define EXCL 1
+static int setforkmode(struct adouble *adp, int eid, int ofrefnum, int what, int mode)
+{
+ int lockmode;
+ int lockop;
+
+ /* NOTE: we can't write lock a read-only file. on those, we just
+ * make sure that we have a read lock set. that way, we at least prevent
+ * someone else from really setting a deny read/write on the file.
+ */
+ lockmode = (ad_getoflags(adp, eid) & O_RDWR) ?ADLOCK_WR : ADLOCK_RD;
+ lockop = (mode == EXCL)?lockmode:ADLOCK_RD;
+
+ return ad_lock(adp, eid, lockop | ADLOCK_FILELOCK | ADLOCK_UPGRADE,
+ what, 1, ofrefnum);
+}
- case FILPBIT_FNUM :
- aint = 0;
-#if AD_VERSION > AD_VERSION1
- /* look in AD v2 header */
- if (isad)
- memcpy(&aint, ad_entry(ofork->of_ad, ADEID_DID), sizeof(aint));
-#endif /* AD_VERSION > AD_VERSION1 */
+/* -------------------------
+*/
+extern int ad_testlock(struct adouble *adp, int eid, int off);
-#ifdef CNID_DB
- aint = cnid_add(ofork->of_vol->v_db, &st,
- ofork->of_dir->d_did,
- upath, strlen(upath), aint);
- if (aint == CNID_INVALID) {
- switch (errno) {
- case CNID_ERR_PARAM:
- LOG(log_error, logtype_afpd, "getforkparams: Incorrect parameters passed to cnid_add");
- return(AFPERR_PARAM);
- case CNID_ERR_PATH:
- return(AFPERR_PARAM);
- case CNID_ERR_DB:
- case CNID_ERR_MAX:
- return(AFPERR_MISC);
- }
- }
-#endif /* CNID_DB */
-
- if (aint == 0) {
-#ifdef USE_LASTDID
- aint = htonl(( st.st_dev << 16 ) | ( st.st_ino & 0x0000ffff ));
-#else /* USE_LASTDID */
- lstp = lstat(upath, &lst) < 0 ? &st : &lst;
-#ifdef DID_MTAB
- aint = htonl( afpd_st_cnid ( lstp ) );
-#else /* DID_MTAB */
- aint = htonl(CNID(lstp, 1));
-#endif /* DID_MTAB */
-#endif /* USE_LASTDID */
- }
+static int getforkmode(struct adouble *adp, int eid, int what)
+{
+ return ad_testlock(adp, eid, what);
+}
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
+/* --------------------------
+ a lot of races, some can be remove. but I try first to get the semantic right
+*/
- case FILPBIT_DFLEN :
- aint = htonl( st.st_size );
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
+static int setmode(struct adouble *adp, int eid, int access, int ofrefnum)
+{
+ int ret;
+ int readset;
+ int writeset;
+ int denyreadset;
+ int denywriteset;
+ int mode;
+
+ if (! (access & (OPENACC_WR | OPENACC_RD | OPENACC_DWR | OPENACC_DRD))) {
+ return setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_NONE, SHARE);
+ }
- case FILPBIT_RFLEN :
- if ( isad ) {
- aint = htonl( ad_getentrylen( ofork->of_ad, ADEID_RFORK ));
- } else {
- aint = 0;
- }
- memcpy(data, &aint, sizeof( aint ));
- data += sizeof( aint );
- break;
+ if ((access & (OPENACC_RD | OPENACC_DRD))) {
+ if ((readset = getforkmode(adp, eid, AD_FILELOCK_OPEN_RD)) <0)
+ return readset;
+ if ((denyreadset = getforkmode(adp, eid, AD_FILELOCK_DENY_RD)) <0)
+ return denyreadset;
- default :
- return( AFPERR_BITMAP );
+ if ((access & OPENACC_RD) && denyreadset) {
+ errno = EACCES;
+ return -1;
+ }
+ if ((access & OPENACC_DRD) && readset) {
+ errno = EACCES;
+ return -1;
+ }
+ /* boolean logic is not enough, because getforkmode is not always telling the
+ * true
+ */
+ mode = ((access & OPENACC_DRD))?EXCL: SHARE;
+ if ((access & OPENACC_RD)) {
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_RD, mode);
+ if (ret)
+ return ret;
+ }
+ if ((access & OPENACC_DRD)) {
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_RD, SHARE);
+ if (ret)
+ return ret;
}
- bitmap = bitmap>>1;
- bit++;
}
-
- if ( nameoff ) {
- ashort = htons( data - buf );
- memcpy(nameoff, &ashort, sizeof( ashort ));
- aint = strlen( ofork->of_name );
- aint = ( aint > MACFILELEN ) ? MACFILELEN : aint;
- *data++ = aint;
- memcpy(data, ofork->of_name, aint );
- data += aint;
+ /* ------------same for writing -------------- */
+ if ((access & (OPENACC_WR | OPENACC_DWR))) {
+ if ((writeset = getforkmode(adp, eid, AD_FILELOCK_OPEN_WR)) <0)
+ return writeset;
+ if ((denywriteset = getforkmode(adp, eid, AD_FILELOCK_DENY_WR)) <0)
+ return denywriteset;
+
+ if ((access & OPENACC_WR) && denywriteset) {
+ errno = EACCES;
+ return -1;
+ }
+ if ((access & OPENACC_DWR) && writeset) {
+ errno = EACCES;
+ return -1;
+ }
+ mode = ((access & OPENACC_DWR))?EXCL: SHARE;
+ if ((access & OPENACC_WR)) {
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_OPEN_WR, mode);
+ if (ret)
+ return ret;
+ }
+ if ((access & OPENACC_DWR)) {
+ ret = setforkmode(adp, eid, ofrefnum, AD_FILELOCK_DENY_WR, SHARE);
+ if (ret)
+ return ret;
+ }
}
-
- *buflen = data - buf;
- return( AFP_OK );
+ return 0;
}
+/* ----------------------- */
int afp_openfork(obj, ibuf, ibuflen, rbuf, rbuflen )
AFPObj *obj;
char *ibuf, *rbuf;
/*
* synchronization locks:
- *
- * here's the ritual:
- * 1) attempt a read lock to see if we have read or write
- * privileges.
- * 2) if that succeeds, set a write lock to correspond to the
- * deny mode requested.
- * 3) whenever a file is read/written, locks get set which
- * prevent conflicts.
*/
/* don't try to lock non-existent rforks. */
if ((eid == ADEID_DFORK) || (ad_hfileno(ofork->of_ad) != -1)) {
- /* try to see if we have access. */
- ret = 0;
- if (access & OPENACC_WR) {
- ofork->of_flags |= AFPFORK_ACCWR;
- ret = ad_lock(ofork->of_ad, eid, ADLOCK_RD | ADLOCK_FILELOCK,
- AD_FILELOCK_WR, 1, ofrefnum);
- }
-
- if (!ret && (access & OPENACC_RD)) {
- ofork->of_flags |= AFPFORK_ACCRD;
- ret = ad_lock(ofork->of_ad, eid, ADLOCK_RD | ADLOCK_FILELOCK,
- AD_FILELOCK_RD, 1, ofrefnum);
- }
-
+ ret = setmode(ofork->of_ad, eid, access, ofrefnum);
/* can we access the fork? */
- if (ret < 0) {
- ad_close( ofork->of_ad, adflags );
- of_dealloc( ofork );
- ofrefnum = 0;
- memcpy(rbuf, &ofrefnum, sizeof(ofrefnum));
- return (AFPERR_DENYCONF);
- }
-
- /* now try to set the deny lock. if the fork is open for read or
- * write, a read lock will already have been set. otherwise, we upgrade
- * our lock to a write lock.
- *
- * NOTE: we can't write lock a read-only file. on those, we just
- * make sure that we have a read lock set. that way, we at least prevent
- * someone else from really setting a deny read/write on the file. */
- lockop = (ad_getoflags(ofork->of_ad, eid) & O_RDWR) ?
- ADLOCK_WR : ADLOCK_RD;
- ret = (access & OPENACC_DWR) ? ad_lock(ofork->of_ad, eid,
- lockop | ADLOCK_FILELOCK |
- ADLOCK_UPGRADE, AD_FILELOCK_WR, 1,
- ofrefnum) : 0;
- if (!ret && (access & OPENACC_DRD))
- ret = ad_lock(ofork->of_ad, eid, lockop | ADLOCK_FILELOCK |
- ADLOCK_UPGRADE, AD_FILELOCK_RD, 1, ofrefnum);
-
if (ret < 0) {
ret = errno;
ad_close( ofork->of_ad, adflags );
return( AFPERR_PARAM );
}
}
+ if ((access & OPENACC_WR))
+ ofork->of_flags |= AFPFORK_ACCWR;
+ if ((access & OPENACC_RD))
+ ofork->of_flags |= AFPFORK_ACCRD;
}
memcpy(rbuf, &ofrefnum, sizeof(ofrefnum));
/*
- * $Id: ofork.c,v 1.13 2002-04-22 07:46:00 rlewczuk Exp $
+ * $Id: ofork.c,v 1.14 2002-05-13 04:59:36 jmarcus Exp $
*
* Copyright (c) 1996 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return( oforks[ ofrefnum % nforks ] );
}
+/* --------------------------
+ it doesn't work :-(
+ mac1 open file "test" with simple text
+ mac2 rename "test" ==> "test1"
+
+ now of_findname return NULL
+
+
+*/
struct ofork *
of_findname(const struct vol *vol, const struct dir *dir, const char *name)
{