/*
- * $Id: directory.c,v 1.28 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: directory.c,v 1.29 2002-03-24 17:43:39 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return NULL;
}
+/* -----------------------------------------
+ * if did is not in the cache resolve it with cnid
+ *
+ */
+struct dir *
+ dirlookup( vol, did )
+ const struct vol *vol;
+u_int32_t did;
+{
+#ifdef CNID_DB
+ struct dir *ret;
+ char *upath;
+ u_int32_t id;
+ static char path[MAXPATHLEN + 1];
+ int len;
+ int pathlen;
+ char *ptr;
+ static char buffer[12 + MAXPATHLEN + 1];
+ int buflen = 12 + MAXPATHLEN + 1;
+
+ ret = dirsearch(vol, did);
+ if (ret != NULL)
+ return ret;
+
+ id = did;
+ if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL) {
+ return NULL;
+ }
+ ptr = path + MAXPATHLEN;
+ len = strlen(upath);
+ pathlen = len; /* no 0 in the last part */
+ len++;
+ strcpy(ptr - len, upath);
+ ptr -= len;
+ while (1) {
+ ret = dirsearch(vol,id);
+ if (ret != NULL) {
+ break;
+ }
+ if ((upath = cnid_resolve(vol->v_db, &id, buffer, buflen)) == NULL)
+ return NULL;
+ len = strlen(upath) + 1;
+ pathlen += len;
+ if (pathlen > 255)
+ return NULL;
+ strcpy(ptr - len, upath);
+ ptr -= len;
+ }
+ /* fill the cache */
+ ptr--;
+ *ptr = (unsigned char)pathlen;
+ ptr--;
+ *ptr = 2;
+ /* cname is not efficient */
+ if (cname( vol, ret, &ptr ) == NULL )
+ return NULL;
+#endif
+ return dirsearch(vol, did);
+}
+/* --------------------------- */
/* rotate the tree to the left */
static void dir_leftrotate(vol, dir)
struct vol *vol;
struct stat st;
struct dir *fdir;
DIR *dp;
+ struct adouble ad;
+ u_int16_t ashort;
#ifdef FORCE_UIDGID
uidgidset *uidgid;
set_uidgid ( vol );
#endif /* FORCE_UIDGID */
+ if ( ad_open( ".", ADFLAGS_HF|ADFLAGS_DIR, O_RDONLY,
+ DIRBITS | 0777, &ad) == 0 ) {
+
+ ad_getattr(&ad, &ashort);
+ ad_close( &ad, ADFLAGS_HF );
+ if ((ashort & htons(ATTRBIT_NODELETE))) {
+#ifdef FORCE_UIDGID
+ restore_uidgid ( &uidgid );
+#endif /* FORCE_UIDGID */
+ return AFPERR_OLOCK;
+ }
+ }
+
/* delete stray .AppleDouble files. this happens to get .Parent files
as well. */
if ((dp = opendir(".AppleDouble"))) {
/*
- * $Id: directory.h,v 1.3 2001-12-03 05:03:38 jmarcus Exp $
+ * $Id: directory.h,v 1.4 2002-03-24 17:43:39 jmarcus Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
extern struct dir *dirnew __P((const int));
extern void dirfree __P((struct dir *));
extern struct dir *dirsearch __P((const struct vol *, u_int32_t));
+extern struct dir *dirlookup __P((const struct vol *, u_int32_t));
extern struct dir *adddir __P((struct vol *, struct dir *, char *,
int, char *, int, struct stat *));
extern struct dir *dirinsert __P((struct vol *, struct dir *));
/*
- * $Id: file.c,v 1.42 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: file.c,v 1.43 2002-03-24 17:43:39 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
return AFPERR_VLOCK;
case EXDEV : /* Cross device move -- try copy */
if (( rc = copyfile(src, dst, newname, noadouble )) != AFP_OK ) {
- deletefile( dst );
+ deletefile( dst, 0 );
return( rc );
}
- return deletefile( src );
+ return deletefile( src, 0);
default :
return( AFPERR_PARAM );
}
}
-int deletefile( file )
+/* -----------------------------------
+ checkAttrib: 1 check kFPDeleteInhibitBit
+ ie deletfile called from afp_delete
+
+*/
+int deletefile( file, checkAttrib )
char *file;
+int checkAttrib;
{
struct adouble ad;
int adflags, err = AFP_OK;
}
break; /* from the while */
}
+ /*
+ * Does kFPDeleteInhibitBit (bit 8) set?
+ */
+ if (checkAttrib && (adflags & ADFLAGS_HF)) {
+ u_int16_t bshort;
+
+ ad_getattr(&ad, &bshort);
+ if ((bshort & htons(ATTRBIT_NODELETE))) {
+ ad_close( &ad, adflags );
+ return(AFPERR_OLOCK);
+ }
+ }
if ((adflags & ADFLAGS_HF) &&
(ad_tmplock(&ad, ADEID_RFORK, locktype, 0, 0) < 0 )) {
cnid_t id;
u_int16_t vid, bitmap;
+ static char buffer[12 + MAXPATHLEN + 1];
+ int len = 12 + MAXPATHLEN + 1;
+
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_resolveid:");
#endif /* DEBUG */
memcpy(&id, ibuf, sizeof( id ));
ibuf += sizeof(id);
- if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) {
+ if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) {
return AFPERR_BADID;
}
- if (( dir = dirsearch( vol, id )) == NULL ) {
+ if (( dir = dirlookup( vol, id )) == NULL ) {
return( AFPERR_PARAM );
}
cnid_t id;
cnid_t fileid;
u_short vid;
+ static char buffer[12 + MAXPATHLEN + 1];
+ int len = 12 + MAXPATHLEN + 1;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_deleteid:");
memcpy(&id, ibuf, sizeof( id ));
ibuf += sizeof(id);
fileid = id;
-
- if ((upath = cnid_resolve(vol->v_db, &id)) == NULL) {
+
+ if ((upath = cnid_resolve(vol->v_db, &id, buffer, len)) == NULL) {
return AFPERR_NOID;
}
- if (( dir = dirsearch( vol, id )) == NULL ) {
+ if (( dir = dirlookup( vol, id )) == NULL ) {
return( AFPERR_PARAM );
}
/* all this stuff is so that we can unwind a failed operation
* properly. */
-
+err_temp_to_dest:
/* rename dest to temp */
renamefile(upath, temp, temp, vol_noadouble(vol));
of_rename(vol, curdir, upath, curdir, temp);
/*
- * $Id: file.h,v 1.5 2002-03-13 19:29:17 srittau Exp $
+ * $Id: file.h,v 1.6 2002-03-24 17:43:39 jmarcus Exp $
*
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
extern int setfilparams __P((struct vol *, char *, u_int16_t, char *));
extern int renamefile __P((char *, char *, char *, const int));
extern int copyfile __P((char *, char *, char *, const int));
-extern int deletefile __P((char *));
+extern int deletefile __P((char *, int));
/* FP functions */
extern int afp_exchangefiles __P((AFPObj *, char *, int, char *, int *));
/*
- * $Id: filedir.c,v 1.25 2002-03-24 01:23:40 sibaz Exp $
+ * $Id: filedir.c,v 1.26 2002-03-24 17:43:39 jmarcus Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
memcpy( &did, ibuf, sizeof( did ));
ibuf += sizeof( did );
- if (( dir = dirsearch( vol, did )) == NULL ) {
+ if (( dir = dirlookup( vol, did )) == NULL ) {
return( AFPERR_NOOBJ );
}
rc = deletecurdir( vol, obj->oldtmp, AFPOBJ_TMPSIZ);
} else if (of_findname(vol, curdir, path)) {
rc = AFPERR_BUSY;
- } else if ((rc = deletefile( upath = mtoupath(vol, path ))) == AFP_OK) {
+ } else if ((rc = deletefile( upath = mtoupath(vol, path ), 1)) == AFP_OK) {
#ifdef CNID_DB /* get rid of entry */
cnid_t id = cnid_get(vol->v_db, curdir->d_did, upath, strlen(upath));
cnid_delete(vol->v_db, id);
/* cnid_get.c */
extern cnid_t cnid_get __P((void *, const cnid_t, const char *, const int));
-extern char *cnid_resolve __P((void *, cnid_t *));
+extern char *cnid_resolve __P((void *, cnid_t *, void *, u_int32_t ));
extern cnid_t cnid_lookup __P((void *, const struct stat *, const cnid_t,
const char *, const int));
/*
- * $Id: cnid_resolve.c,v 1.11 2002-01-19 21:42:08 jmarcus Exp $
+ * $Id: cnid_resolve.c,v 1.12 2002-03-24 17:43:42 jmarcus Exp $
*/
#ifdef HAVE_CONFIG_H
#include "cnid_private.h"
/* Return the did/name pair corresponding to a CNID. */
-char *cnid_resolve(void *CNID, cnid_t *id) {
+char *cnid_resolve(void *CNID, cnid_t *id, void *buffer, u_int32_t len) {
CNID_private *db;
DBT key, data;
int rc;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
+ data.data = buffer;
+ data.ulen = len;
+ data.flags = DB_DBT_USERMEM;
+
key.data = id;
key.size = sizeof(cnid_t);
while ((rc = db->db_cnid->get(db->db_cnid, NULL, &key, &data, 0))) {