X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=etc%2Fafpd%2Fofork.c;h=49c014ccef9befec7be7f15068e5c7039e757139;hb=refs%2Ftags%2Fafter-renameat;hp=1d59b06115e69501a605fa9f81ede423aaa70809;hpb=97860a15f34963e8d8e7a68650851cfb7387d4c5;p=netatalk.git diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 1d59b061..49c014cc 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -1,5 +1,5 @@ /* - * $Id: ofork.c,v 1.26 2008-08-16 21:11:36 didg Exp $ + * $Id: ofork.c,v 1.32 2010-03-12 15:16:49 franklahm Exp $ * * Copyright (c) 1996 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -38,7 +38,7 @@ static u_short lastrefnum = 0; /* OR some of each character for the hash*/ -static __inline__ unsigned long hashfn(const struct file_key *key) +static unsigned long hashfn(const struct file_key *key) { #if 0 unsigned long i = 0; @@ -49,7 +49,7 @@ static __inline__ unsigned long hashfn(const struct file_key *key) return key->inode & (OFORK_HASHSIZE - 1); } -static __inline__ void of_hash(struct ofork *of) +static void of_hash(struct ofork *of) { struct ofork **table; @@ -60,7 +60,7 @@ static __inline__ void of_hash(struct ofork *of) of->prevp = table; } -static __inline__ void of_unhash(struct ofork *of) +static void of_unhash(struct ofork *of) { if (of->prevp) { if (of->next) @@ -70,8 +70,7 @@ static __inline__ void of_unhash(struct ofork *of) } #ifdef DEBUG1 -void of_pforkdesc( f ) -FILE *f; +void of_pforkdesc( FILE *f) { int ofrefnum; @@ -102,11 +101,10 @@ int of_flush(const struct vol *vol) return( 0 ); } -int of_rename(vol, s_of, olddir, oldpath, newdir, newpath) -const struct vol *vol; -struct ofork *s_of; -struct dir *olddir, *newdir; -const char *oldpath _U_, *newpath; +int of_rename(const struct vol *vol, + struct ofork *s_of, + struct dir *olddir, const char *oldpath _U_, + struct dir *newdir, const char *newpath) { struct ofork *of, *next, *d_ofork; int done = 0; @@ -151,14 +149,13 @@ const char *oldpath _U_, *newpath; #define min(a,b) ((a)<(b)?(a):(b)) struct ofork * - of_alloc(vol, dir, path, ofrefnum, eid, ad, st) -struct vol *vol; -struct dir *dir; -char *path; -u_int16_t *ofrefnum; -const int eid; -struct adouble *ad; -struct stat *st; +of_alloc(struct vol *vol, + struct dir *dir, + char *path, + u_int16_t *ofrefnum, + const int eid, + struct adouble *ad, + struct stat *st) { struct ofork *of, *d_ofork; u_int16_t refnum, of_refnum; @@ -287,15 +284,34 @@ int of_stat (struct path *path) int ret; path->st_errno = 0; path->st_valid = 1; - if ((ret = stat(path->u_name, &path->st)) < 0) + if ((ret = lstat(path->u_name, &path->st)) < 0) path->st_errno = errno; return ret; } -/* -------------------------- */ -int of_statdir (const struct vol *vol, struct path *path) +#ifdef HAVE_RENAMEAT +int of_fstatat(int dirfd, struct path *path) { -static char pathname[ MAXPATHLEN + 1]; + int ret; + + path->st_errno = 0; + path->st_valid = 1; + + if ((ret = fstatat(dirfd, path->u_name, &path->st, AT_SYMLINK_NOFOLLOW)) < 0) + path->st_errno = errno; + + return ret; +} +#endif /* HAVE_RENAMEAT */ + +/* -------------------------- + stat the current directory. + stat(".") works even if "." is deleted thus + we have to stat ../name because we want to know if it's there +*/ +int of_statdir (struct vol *vol, struct path *path) +{ +static char pathname[ MAXPATHLEN + 1] = "../"; int ret; if (*path->m_name) { @@ -305,10 +321,9 @@ int ret; path->st_errno = 0; path->st_valid = 1; /* FIXME, what about: we don't have r-x perm anymore ? */ - strcpy(pathname, "../"); - strlcat(pathname, path->d_dir->d_u_name, MAXPATHLEN); + strlcpy(pathname +3, path->d_dir->d_u_name, sizeof (pathname) -3); - if (!(ret = stat(pathname, &path->st))) + if (!(ret = lstat(pathname, &path->st))) return 0; path->st_errno = errno; @@ -317,15 +332,14 @@ int ret; if (movecwd(vol, curdir->d_parent)) return -1; path->st_errno = 0; - if ((ret = stat(path->d_dir->d_u_name, &path->st)) < 0) + if ((ret = lstat(path->d_dir->d_u_name, &path->st)) < 0) path->st_errno = errno; } return ret; } /* -------------------------- */ -struct ofork * - of_findname(struct path *path) +struct ofork *of_findname(struct path *path) { struct ofork *of; struct file_key key; @@ -349,8 +363,42 @@ struct ofork * return NULL; } -void of_dealloc( of ) -struct ofork *of; +/*! + * @brief Search for open fork by dirfd/name + * + * Function call of_fstatat with dirfd and path and uses dev and ino + * to search the open fork table. + * + * @param dirfd (r) directory fd + * @param path (rw) pointer to struct path + */ +#ifdef HAVE_RENAMEAT +struct ofork *of_findnameat(int dirfd, struct path *path) +{ + struct ofork *of; + struct file_key key; + + if ( ! path->st_valid) { + of_fstatat(dirfd, path); + } + + if (path->st_errno) + return NULL; + + key.dev = path->st.st_dev; + key.inode = path->st.st_ino; + + for (of = ofork_table[hashfn(&key)]; of; of = of->next) { + if (key.dev == of->key.dev && key.inode == of->key.inode ) { + return of; + } + } + + return NULL; +} +#endif + +void of_dealloc( struct ofork *of) { if (!oforks) return;