/*
- * $Id: directory.c,v 1.78 2005-04-30 21:33:41 didg Exp $
+ * $Id: directory.c,v 1.83 2006-09-19 23:00:49 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
{
struct dir *dir = NULL;
- if (cdir->d_did == DIRDID_ROOT_PARENT) {
- if ( !strcmp(vol->v_dir->d_u_name, name)) {
- dir = vol->v_dir;
- }
- } else if ( cdir->d_child) {
+ if ((cdir->d_did != DIRDID_ROOT_PARENT) && (cdir->d_child)) {
struct dir key;
hnode_t *hn;
}
else {
noucsfallback:
- cdir = dirsearch_byname(vol, dir, ret.u_name);
+ if (dir->d_did == DIRDID_ROOT_PARENT) {
+ /* root parent has only one child and d_m_name is *NOT* utm (d_u_name)
+ * d_m_name is the Mac volume name
+ * d_u_name is the volume unix directory name
+ *
+ */
+ cdir = NULL;
+ if (!strcmp(vol->v_dir->d_m_name, ret.m_name)) {
+ cdir = vol->v_dir;
+ }
+ }
+ else {
+ cdir = dirsearch_byname(vol, dir, ret.u_name);
+ }
}
if (cdir == NULL && scdir != NULL) {
return st->st_ctime == dir->ctime && (dir->d_flags & DIRF_CNID);
}
+/* --------------------- */
+static int invisible_dots(const struct vol *vol, const char *name)
+{
+ return vol_inv_dots(vol) && *name == '.' && strcmp(name, ".") && strcmp(name, "..");
+}
+
/* ------------------------------
(".", curdir)
(name, dir) with curdir:name == dir, from afp_enumerate
case DIRPBIT_ATTR :
if ( isad ) {
ad_getattr(&ad, &ashort);
- } else if (*dir->d_u_name == '.' && strcmp(dir->d_u_name, ".")
- && strcmp(dir->d_u_name, "..")) {
+ } else if (invisible_dots(vol, dir->d_u_name)) {
ashort = htons(ATTRBIT_INVISIBLE);
} else
ashort = 0;
ashort = htons(FINDERINFO_CLOSEDVIEW);
memcpy(data + FINDERINFO_FRVIEWOFF, &ashort, sizeof(ashort));
- /* dot files are by default invisible */
- if (*dir->d_u_name == '.' && strcmp(dir->d_u_name , ".") &&
- strcmp(dir->d_u_name , "..")) {
+ /* dot files are by default visible */
+ if (invisible_dots(vol, dir->d_u_name)) {
ashort = htons(FINDERINFO_INVISIBLE);
- memcpy(data + FINDERINFO_FRFLAGOFF,
- &ashort, sizeof(ashort));
+ memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
}
}
data += 32;
default :
if ( isad ) {
- ad_close( &ad, ADFLAGS_HF );
+ ad_close_metadata( &ad );
}
return( AFPERR_BITMAP );
}
data = set_name(vol, data, pdid, dir->d_m_name, dir->d_did, utf8);
}
if ( isad ) {
- ad_close( &ad, ADFLAGS_HF );
+ ad_close_metadata( &ad );
}
*buflen = data - buf;
return( AFP_OK );
u_int16_t bitmap = d_bitmap;
u_char finder_buf[32];
u_int32_t upriv;
- mode_t mpriv; /* uninitialized, OK 310105 */
+ mode_t mpriv = 0;
u_int16_t upriv_bit = 0;
bit = 0;
ma.ma_world = *buf++;
ma.ma_group = *buf++;
ma.ma_owner = *buf++;
- mpriv = mtoumode( &ma );
+ mpriv = mtoumode( &ma ) | vol->v_perm;
if (dir_rx_set(mpriv) && setdirmode( vol, upath, mpriv) < 0 ) {
err = set_dir_errors(path, "setdirmode", errno);
bitmap = 0;
break;
case DIRPBIT_UNIXPR :
if (vol_unix_priv(vol)) {
- /* Skip UID and GID for now, there seems to be no way to set them from an OSX client anyway */
- buf += sizeof( aint );
- buf += sizeof( aint );
+ memcpy( &owner, buf, sizeof(owner)); /* FIXME need to change owner too? */
+ buf += sizeof( owner );
+ memcpy( &group, buf, sizeof( group ));
+ buf += sizeof( group );
change_mdate = 1;
change_parent_mdate = 1;
memcpy( &upriv, buf, sizeof( upriv ));
buf += sizeof( upriv );
- upriv = ntohl (upriv);
+ upriv = ntohl (upriv) | vol->v_perm;
if (dir_rx_set(upriv)) {
/* maybe we are trying to set perms back */
if ( setdirunixmode(vol, upath, upriv) < 0 ) {
bitmap = 0;
- err = set_dir_errors(path, "setdirmode", errno);
+ err = set_dir_errors(path, "setdirunixmode", errno);
}
}
else {
}
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open( upath, vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
- O_RDWR|O_CREAT, 0666, &ad) < 0) {
+ if (ad_open_metadata( upath, vol_noadouble(vol)|ADFLAGS_DIR, O_CREAT, &ad) < 0) {
/*
* Check to see what we're trying to set. If it's anything
* but ACCESS, UID, or GID, give an error. If it's any of those
goto setdirparam_done;
}
break;
-
case DIRPBIT_GID :
if (dir->d_did == DIRDID_ROOT)
setdeskowner( -1, ntohl(group) );
-
-#if 0 /* don't error if we can't set the desktop owner. */
- err = set_dir_errors(path, "setdeskowner", errno);
- if (isad && err == AFPERR_PARAM) {
- err = AFP_OK; /* ???*/
- }
- else {
- goto setdirparam_done;
- }
-#endif /* 0 */
-
if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
err = set_dir_errors(path, "setdirowner", errno);
goto setdirparam_done;
}
break;
-
case DIRPBIT_ACCESS :
if (dir->d_did == DIRDID_ROOT) {
setdeskmode(mpriv);
case DIRPBIT_UNIXPR :
if (vol_unix_priv(vol)) {
if (dir->d_did == DIRDID_ROOT) {
- setdeskmode( upriv );
if (!dir_rx_set(upriv)) {
/* we can't remove read and search for owner on volume root */
err = AFPERR_ACCESS;
goto setdirparam_done;
}
+ setdeskowner( -1, ntohl(group) );
+ setdeskmode( upriv );
+ }
+ if ( setdirowner(vol, upath, -1, ntohl(group) ) < 0 ) {
+ err = set_dir_errors(path, "setdirowner", errno);
+ goto setdirparam_done;
}
if ( upriv_bit && setdirunixmode(vol, upath, upriv) < 0 ) {
- err = set_dir_errors(path, "setdirmode", errno);
+ err = set_dir_errors(path, "setdirunixmode", errno);
goto setdirparam_done;
}
- break;
}
- /* fall through */
+ else {
+ err = AFPERR_BITMAP;
+ goto setdirparam_done;
+ }
+ break;
default :
err = AFPERR_BITMAP;
goto setdirparam_done;
ad_setid(&ad, st->st_dev, st->st_ino, dir->d_did, dir->d_parent->d_did, vol->v_stamp);
}
}
- ad_flush( &ad, ADFLAGS_HF );
- ad_close( &ad, ADFLAGS_HF );
+ ad_flush_metadata( &ad);
+ ad_close_metadata( &ad);
}
if (change_parent_mdate && dir->d_did != DIRDID_ROOT
}
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (ad_open( ".", vol_noadouble(vol)|ADFLAGS_HF|ADFLAGS_DIR,
- O_RDWR|O_CREAT, 0666, &ad ) < 0) {
+ if (ad_open_metadata( ".", vol_noadouble(vol)|ADFLAGS_DIR, O_CREAT, &ad ) < 0) {
if (vol_noadouble(vol))
goto createdir_done;
return( AFPERR_ACCESS );
ad_setname(&ad, s_path->m_name);
ad_setid( &ad, s_path->st.st_dev, s_path->st.st_ino, dir->d_did, did, vol->v_stamp);
- ad_flush( &ad, ADFLAGS_HF );
- ad_close( &ad, ADFLAGS_HF );
+ ad_flush_metadata( &ad);
+ ad_close_metadata( &ad);
createdir_done:
memcpy( rbuf, &dir->d_did, sizeof( u_int32_t ));
ad_init(&ad, vol->v_adouble, vol->v_ad_options);
- if (!ad_open( dst, ADFLAGS_HF|ADFLAGS_DIR, O_RDWR, 0, &ad)) {
+ if (!ad_open_metadata( dst, ADFLAGS_DIR, 0, &ad)) {
ad_setname(&ad, newname);
- ad_flush( &ad, ADFLAGS_HF );
- ad_close( &ad, ADFLAGS_HF );
+ ad_flush_metadata( &ad);
+ ad_close_metadata( &ad);
}
dir_hash_del(vol, dir);