X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fdirectory.c;h=224f397973e7500aacaf5c60049d4f7a1d9e262c;hb=56ef10db116a731b4cffdc41ceae813f25b2208a;hp=0431c188eff24936332144b0a2967e2c4882e146;hpb=e8bbed26dae8f9a20594285a82a2c08181bef90a;p=netatalk.git diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 0431c188..224f3979 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $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. @@ -152,11 +152,7 @@ dirsearch_byname( const struct vol *vol, struct dir *cdir, char *name) { 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; @@ -1414,7 +1410,20 @@ char **cpath; } 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) { @@ -1592,6 +1601,12 @@ int dirreenumerate(struct dir *dir, struct stat *st) 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 @@ -1645,8 +1660,7 @@ int getdirparams(const struct vol *vol, 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; @@ -1689,12 +1703,10 @@ int getdirparams(const struct vol *vol, 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; @@ -1803,7 +1815,7 @@ int getdirparams(const struct vol *vol, default : if ( isad ) { - ad_close( &ad, ADFLAGS_HF ); + ad_close_metadata( &ad ); } return( AFPERR_BITMAP ); } @@ -1821,7 +1833,7 @@ int getdirparams(const struct vol *vol, 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 ); @@ -1952,7 +1964,7 @@ int setdirparams(const struct vol *vol, 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; @@ -2006,7 +2018,7 @@ int setdirparams(const struct vol *vol, 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; @@ -2026,20 +2038,21 @@ int setdirparams(const struct vol *vol, 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 { @@ -2060,8 +2073,7 @@ int setdirparams(const struct vol *vol, } 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 @@ -2157,27 +2169,14 @@ int setdirparams(const struct vol *vol, 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); @@ -2202,21 +2201,29 @@ int setdirparams(const struct vol *vol, 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; @@ -2246,8 +2253,8 @@ 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 @@ -2329,8 +2336,7 @@ int ibuflen _U_, *rbuflen; } 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 ); @@ -2338,8 +2344,8 @@ int ibuflen _U_, *rbuflen; 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 )); @@ -2400,10 +2406,10 @@ struct dir *dir, *newparent; 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);