X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fdirectory.c;h=84b5093d12c355543d0e4dfac64ff73f49c87027;hb=b362b6f7b22b6e4e9e74760989f389149677917b;hp=1181a94ecb49b00adfdb83ae895568a4e1f7b046;hpb=ea3f0e0c29ce0c434ce39d3f723a3cea0db11315;p=netatalk.git diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index 1181a94e..84b5093d 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -29,6 +29,8 @@ #include #include #include +#include +#include #include "directory.h" #include "dircache.h" @@ -37,7 +39,6 @@ #include "fork.h" #include "file.h" #include "filedir.h" -#include "globals.h" #include "unix.h" #include "mangle.h" #include "hash.h" @@ -131,7 +132,7 @@ static int netatalk_mkdir(const struct vol *vol, const char *name) } /* ------------------- */ -static int deletedir(int dirfd, char *dir) +static int deletedir(const struct vol *vol, int dirfd, char *dir) { char path[MAXPATHLEN + 1]; DIR *dp; @@ -162,11 +163,11 @@ static int deletedir(int dirfd, char *dir) break; } strcpy(path + len, de->d_name); - if (lstatat(dirfd, path, &st)) { + if (ostatat(dirfd, path, &st, vol_syml_opt(vol))) { continue; } if (S_ISDIR(st.st_mode)) { - err = deletedir(dirfd, path); + err = deletedir(vol, dirfd, path); } else { err = netatalk_unlinkat(dirfd, path); } @@ -228,7 +229,7 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst) } strcpy(spath + slen, de->d_name); - if (lstatat(dirfd, spath, &st) == 0) { + if (ostatat(dirfd, spath, &st, vol_syml_opt(vol)) == 0) { if (strlen(de->d_name) > drem) { err = AFPERR_PARAM; break; @@ -250,7 +251,7 @@ static int copydir(const struct vol *vol, int dirfd, char *src, char *dst) } /* keep the same time stamp. */ - if (lstatat(dirfd, src, &st) == 0) { + if (ostatat(dirfd, src, &st, vol_syml_opt(vol)) == 0) { ut.actime = ut.modtime = st.st_mtime; utime(dst, &ut); } @@ -462,7 +463,15 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path) cnid = htonl(2); dir = vol->v_root; + LOG(log_debug, logtype_afpd, "dirlookup_bypath(\"%s\")", path); + + if (strcmp(vol->v_path, path) == 0) + return dir; + EC_NULL(rpath = rel_path_in_vol(path, vol->v_path)); /* 1. */ + + LOG(log_debug, logtype_afpd, "dirlookup_bypath: rpath: \"%s\"", cfrombstr(rpath)); + EC_NULL(statpath = bfromcstr(vol->v_path)); /* 2. */ l = bsplit(rpath, '/'); @@ -470,6 +479,9 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path) did = cnid; EC_ZERO(bcatcstr(statpath, "/")); EC_ZERO(bconcat(statpath, l->entry[i])); + + LOG(log_debug, logtype_afpd, "dirlookup_bypath: statpath: \"%s\"", cfrombstr(statpath)); + EC_ZERO_LOGSTR(lstat(cfrombstr(statpath), &st), "lstat(rpath: %s, elem: %s): %s: %s", cfrombstr(rpath), cfrombstr(l->entry[i]), @@ -482,14 +494,14 @@ struct dir *dirlookup_bypath(const struct vol *vol, const char *path) dir, cfrombstr(l->entry[i]), blength(l->entry[i]))) == NULL) { + if ((cnid = cnid_add(vol->v_cdb, /* 6. */ &st, did, cfrombstr(l->entry[i]), blength(l->entry[i]), - 0)) == CNID_INVALID) { + 0)) == CNID_INVALID) EC_FAIL; - } if ((dir = dirlookup(vol, cnid)) == NULL) /* 7. */ EC_FAIL; @@ -503,6 +515,9 @@ EC_CLEANUP: if (ret != 0) return NULL; + LOG(log_debug, logtype_afpd, "dirlookup_bypath: result: \"%s\"", + cfrombstr(dir->d_fullpath)); + return dir; } @@ -626,7 +641,7 @@ struct dir *dirlookup(const struct vol *vol, cnid_t did) LOG(log_debug, logtype_afpd, "dirlookup(did: %u): stating \"%s\"", ntohl(did), cfrombstr(fullpath)); - if (lstat(cfrombstr(fullpath), &st) != 0) { /* 5a */ + if (ostat(cfrombstr(fullpath), &st, vol_syml_opt(vol)) != 0) { /* 5a */ switch (errno) { case ENOENT: afp_errno = AFPERR_NOOBJ; @@ -714,7 +729,7 @@ int caseenumerate(const struct vol *vol, struct path *path, struct dir *dir) if ( dir->d_did == did && strcmp(lname, path->u_name) == 0) { path->u_name = cname; path->d_dir = NULL; - if (of_stat( path ) == 0 ) { + if (of_stat(vol, path ) == 0 ) { return 0; } /* something changed, we cannot stat ... */ @@ -745,7 +760,7 @@ int caseenumerate(const struct vol *vol, struct path *path, struct dir *dir) strlcpy(cname, de->d_name, sizeof(cname)); path->u_name = cname; path->d_dir = NULL; - if (of_stat( path ) == 0 ) { + if (of_stat(vol, path ) == 0 ) { LOG(log_debug, logtype_afpd, "caseenumerate: using dir: %s, path: %s", de->d_name, path->u_name); strlcpy(lname, tmp, sizeof(lname)); did = dir->d_did; @@ -1244,7 +1259,7 @@ struct path *cname(struct vol *vol, struct dir *dir, char **cpath) * and thus call continue which should terminate the while loop because * len = 0. Ok? */ - if (of_stat(&ret) != 0) { /* 9 */ + if (of_stat(vol, &ret) != 0) { /* 9 */ /* * ret.u_name doesn't exist, might be afp_createfile|dir * that means it should have been the last part @@ -1362,9 +1377,9 @@ int movecwd(const struct vol *vol, struct dir *dir) LOG(log_debug, logtype_afpd, "movecwd(to: did: %u, \"%s\")", ntohl(dir->d_did), cfrombstr(dir->d_fullpath)); - if ((ret = lchdir(cfrombstr(dir->d_fullpath))) != 0 ) { - LOG(log_debug, logtype_afpd, "movecwd(\"%s\"): ret: %u, %s", - cfrombstr(dir->d_fullpath), ret, strerror(errno)); + if ((ret = ochdir(cfrombstr(dir->d_fullpath), vol_syml_opt(vol))) != 0 ) { + LOG(log_debug, logtype_afpd, "movecwd(\"%s\"): %s", + cfrombstr(dir->d_fullpath), strerror(errno)); if (ret == 1) { /* p is a symlink or getcwd failed */ afp_errno = AFPERR_BADTYPE; @@ -1409,7 +1424,7 @@ int check_access(char *path, int mode) if (!p) return -1; - accessmode(p, &ma, curdir, NULL); + accessmode(current_vol, p, &ma, curdir, NULL); if ((mode & OPENACC_WR) && !(ma.ma_user & AR_UWRITE)) return -1; if ((mode & OPENACC_RD) && !(ma.ma_user & AR_UREAD)) @@ -1423,7 +1438,7 @@ int file_access(struct path *path, int mode) { struct maccess ma; - accessmode(path->u_name, &ma, curdir, &path->st); + accessmode(current_vol, path->u_name, &ma, curdir, &path->st); LOG(log_debug, logtype_afpd, "file_access(\"%s\"): mapped user mode: 0x%02x", path->u_name, ma.ma_user); @@ -1530,7 +1545,6 @@ int getdirparams(const struct vol *vol, ashort = htons(ATTRBIT_INVISIBLE); } else ashort = 0; - ashort |= htons(ATTRBIT_SHARED); memcpy( data, &ashort, sizeof( ashort )); data += sizeof( ashort ); break; @@ -1628,7 +1642,7 @@ int getdirparams(const struct vol *vol, break; case DIRPBIT_ACCESS : - accessmode( upath, &ma, dir , st); + accessmode(vol, upath, &ma, dir , st); *data++ = ma.ma_user; *data++ = ma.ma_world; @@ -1663,6 +1677,9 @@ int getdirparams(const struct vol *vol, break; case DIRPBIT_UNIXPR : + /* accessmode may change st_mode with ACLs */ + accessmode(vol, upath, &ma, dir, st); + aint = htonl(st->st_uid); memcpy( data, &aint, sizeof( aint )); data += sizeof( aint ); @@ -1675,8 +1692,6 @@ int getdirparams(const struct vol *vol, memcpy( data, &aint, sizeof( aint )); data += sizeof( aint ); - accessmode( upath, &ma, dir , st); - *data++ = ma.ma_user; *data++ = ma.ma_world; *data++ = ma.ma_group; @@ -2252,7 +2267,7 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ return err; } - if (of_stat(s_path) < 0) { + if (of_stat(vol, s_path) < 0) { return AFPERR_MISC; } @@ -2275,6 +2290,8 @@ int afp_createdir(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf, size_ 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); + fce_register_new_dir(s_path); + ad_flush( &ad); ad_close_metadata( &ad); @@ -2318,10 +2335,10 @@ int renamedir(const struct vol *vol, /* this needs to copy and delete. bleah. that means we have * to deal with entire directory hierarchies. */ if ((err = copydir(vol, dirfd, src, dst)) < 0) { - deletedir(-1, dst); + deletedir(vol, -1, dst); return err; } - if ((err = deletedir(dirfd, src)) < 0) + if ((err = deletedir(vol, dirfd, src)) < 0) return err; break; default : @@ -2372,7 +2389,7 @@ int deletecurdir(struct vol *vol) err = vol->vfs->vfs_deletecurdir(vol); if (err) { LOG(log_error, logtype_afpd, "deletecurdir: error deleting .AppleDouble in \"%s\"", - curdir->d_fullpath); + cfrombstr(curdir->d_fullpath)); return err; } @@ -2412,7 +2429,7 @@ int deletecurdir(struct vol *vol) dir_remove( vol, fdir ); } else { LOG(log_error, logtype_afpd, "deletecurdir(\"%s\"): netatalk_rmdir_all_errors error", - curdir->d_fullpath); + cfrombstr(curdir->d_fullpath)); } delete_done: @@ -2601,12 +2618,12 @@ int afp_mapname(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, siz case 2 : /* unicode */ case 4 : - LOG(log_debug, logtype_afpd, "afp_mapname: gettgrnam for name: %s",ibuf); + LOG(log_debug, logtype_afpd, "afp_mapname: getgrnam for name: %s",ibuf); if (NULL == ( gr = (struct group *)getgrnam( ibuf ))) { return( AFPERR_NOITEM ); } id = gr->gr_gid; - LOG(log_debug, logtype_afpd, "afp_mapname: gettgrnam for name: %s -> id: %d",ibuf, id); + LOG(log_debug, logtype_afpd, "afp_mapname: getgrnam for name: %s -> id: %d",ibuf, id); id = htonl(id); memcpy( rbuf, &id, sizeof( id )); *rbuflen = sizeof( id ); @@ -2700,7 +2717,7 @@ int afp_opendir(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf, si return path_error(path, AFPERR_NOOBJ); } - if ( !path->st_valid && of_stat(path ) < 0 ) { + if ( !path->st_valid && of_stat(vol, path) < 0 ) { return( AFPERR_NOOBJ ); } if ( path->st_errno ) {