X-Git-Url: https://arthur.barton.de/gitweb/?a=blobdiff_plain;f=etc%2Fafpd%2Fofork.c;h=7c975c38f9ed581702e74827aaaf2c2d863e8ce7;hb=40ec4cf6aa9f58d91a7b11f562163b0ffb3b86f4;hp=f5f8a38de8d7fff65a380ac83674fe9c755c190a;hpb=ff3b4646472add7902b0d36dd1a941ec1a54e999;p=netatalk.git diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index f5f8a38d..7c975c38 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -1,6 +1,4 @@ /* - * $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. */ @@ -23,18 +21,17 @@ #include #include #include +#include +#include -#include "globals.h" #include "volume.h" #include "directory.h" #include "fork.h" -/* we need to have a hashed list of oforks (by dev inode). just hash - * by first letter. */ +/* we need to have a hashed list of oforks (by dev inode) */ #define OFORK_HASHSIZE 64 -static struct ofork *ofork_table[OFORK_HASHSIZE]; - -static struct ofork **oforks = NULL; +static struct ofork *ofork_table[OFORK_HASHSIZE]; /* forks hashed by dev/inode */ +static struct ofork **oforks = NULL; /* point to allocated table of open forks pointers */ static int nforks = 0; static u_short lastrefnum = 0; @@ -42,12 +39,6 @@ static u_short lastrefnum = 0; /* OR some of each character for the hash*/ static unsigned long hashfn(const struct file_key *key) { -#if 0 - unsigned long i = 0; - while (*name) { - i = ((i << 4) | (8*sizeof(i) - 4)) ^ *name++; - } -#endif return key->inode & (OFORK_HASHSIZE - 1); } @@ -71,22 +62,6 @@ static void of_unhash(struct ofork *of) } } -#ifdef DEBUG1 -void of_pforkdesc( FILE *f) -{ - int ofrefnum; - - if (!oforks) - return; - - for ( ofrefnum = 0; ofrefnum < nforks; ofrefnum++ ) { - if ( oforks[ ofrefnum ] != NULL ) { - fprintf( f, "%hu <%s>\n", ofrefnum, of_name(oforks[ ofrefnum ])); - } - } -} -#endif - int of_flush(const struct vol *vol) { int refnum; @@ -123,7 +98,9 @@ int of_rename(const struct vol *vol, && s_of->key.dev == of->key.dev && s_of->key.inode == of->key.inode ) { if (!done) { - strlcpy( of_name(of), newpath, of->of_ad->ad_m_namelen); + free(of_name(of)); + if ((of_name(of) = strdup(newpath)) == NULL) + return AFPERR_MISC; done = 1; } if (newdir != olddir) @@ -140,13 +117,13 @@ struct ofork * of_alloc(struct vol *vol, struct dir *dir, char *path, - u_int16_t *ofrefnum, + uint16_t *ofrefnum, const int eid, struct adouble *ad, struct stat *st) { struct ofork *of; - u_int16_t refnum, of_refnum; + uint16_t refnum, of_refnum; int i; @@ -211,24 +188,18 @@ of_alloc(struct vol *vol, /* initialize to zero. This is important to ensure that ad_open really does reinitialize the structure. */ - ad_init(ad, vol->v_adouble, vol->v_ad_options); - - ad->ad_m_namelen = 255 +1; - /* here's the deal: we allocate enough for the standard mac file length. - * in the future, we'll reallocate in fairly large jumps in case - * of long unicode names */ - if (( ad->ad_m_name =(char *)malloc( ad->ad_m_namelen )) == NULL ) { + ad_init(ad, vol); + if ((ad->ad_name = strdup(path)) == NULL) { LOG(log_error, logtype_afpd, "of_alloc: malloc: %s", strerror(errno) ); free(ad); free(of); oforks[ of_refnum ] = NULL; return NULL; } - strlcpy( ad->ad_m_name, path, ad->ad_m_namelen); } else { /* Increase the refcount on this struct adouble. This is decremented again in oforc_dealloc. */ - ad->ad_refcount++; + ad_ref(ad); } of->of_ad = ad; @@ -248,7 +219,7 @@ of_alloc(struct vol *vol, return( of ); } -struct ofork *of_find(const u_int16_t ofrefnum ) +struct ofork *of_find(const uint16_t ofrefnum ) { if (!oforks || !nforks) return NULL; @@ -257,14 +228,14 @@ struct ofork *of_find(const u_int16_t ofrefnum ) } /* -------------------------- */ -int of_stat(struct path *path) +int of_stat(const struct vol *vol, struct path *path) { int ret; path->st_errno = 0; path->st_valid = 1; - if ((ret = lstat(path->u_name, &path->st)) < 0) { + if ((ret = ostat(path->u_name, &path->st, vol_syml_opt(vol))) < 0) { LOG(log_debug, logtype_afpd, "of_stat('%s/%s': %s)", cfrombstr(curdir->d_fullpath), path->u_name, strerror(errno)); path->st_errno = errno; @@ -274,7 +245,7 @@ int of_stat(struct path *path) } -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS int of_fstatat(int dirfd, struct path *path) { int ret; @@ -287,7 +258,7 @@ int of_fstatat(int dirfd, struct path *path) return ret; } -#endif /* HAVE_RENAMEAT */ +#endif /* HAVE_ATFUNCS */ /* -------------------------- stat the current directory. @@ -303,7 +274,7 @@ int of_statdir(struct vol *vol, struct path *path) if (*path->m_name) { /* not curdir */ - return of_stat (path); + return of_stat(vol, path); } path->st_errno = 0; path->st_valid = 1; @@ -315,7 +286,7 @@ int of_statdir(struct vol *vol, struct path *path) LOG(log_debug, logtype_afpd, "of_statdir: stating: '%s'", pathname); - if (!(ret = lstat(pathname, &path->st))) + if (!(ret = ostat(pathname, &path->st, vol_syml_opt(vol)))) return 0; path->st_errno = errno; @@ -326,7 +297,7 @@ int of_statdir(struct vol *vol, struct path *path) return -1; path->st_errno = 0; - if ((ret = lstat(cfrombstr(path->d_dir->d_u_name), &path->st)) < 0) + if ((ret = ostat(cfrombstr(path->d_dir->d_u_name), &path->st, vol_syml_opt(vol))) < 0) path->st_errno = errno; } @@ -334,13 +305,13 @@ int of_statdir(struct vol *vol, struct path *path) } /* -------------------------- */ -struct ofork *of_findname(struct path *path) +struct ofork *of_findname(const struct vol *vol, struct path *path) { struct ofork *of; struct file_key key; if (!path->st_valid) { - of_stat(path); + of_stat(vol, path); } if (path->st_errno) @@ -367,7 +338,7 @@ struct ofork *of_findname(struct path *path) * @param dirfd (r) directory fd * @param path (rw) pointer to struct path */ -#ifdef HAVE_RENAMEAT +#ifdef HAVE_ATFUNCS struct ofork *of_findnameat(int dirfd, struct path *path) { struct ofork *of; @@ -393,7 +364,7 @@ struct ofork *of_findnameat(int dirfd, struct path *path) } #endif -void of_dealloc( struct ofork *of) +void of_dealloc(struct ofork *of) { if (!oforks) return; @@ -405,48 +376,65 @@ void of_dealloc( struct ofork *of) of->of_ad->ad_refcount--; if ( of->of_ad->ad_refcount <= 0) { - free( of->of_ad->ad_m_name ); + free( of->of_ad->ad_name ); free( of->of_ad); - } else {/* someone's still using it. just free this user's locks */ - ad_unlock(of->of_ad, of->of_refnum); } free( of ); } /* --------------------------- */ -int of_closefork(struct ofork *ofork) +int of_closefork(const AFPObj *obj, struct ofork *ofork) { struct timeval tv; - int adflags, doflush = 0; + int adflags = 0; int ret; adflags = 0; - if ((ofork->of_flags & AFPFORK_DATA) && (ad_data_fileno( ofork->of_ad ) != -1)) { + if (ofork->of_flags & AFPFORK_DATA) adflags |= ADFLAGS_DF; - } - if ( (ofork->of_flags & AFPFORK_OPEN) && ad_reso_fileno( ofork->of_ad ) != -1 ) { + if (ofork->of_flags & AFPFORK_META) adflags |= ADFLAGS_HF; - /* - * Only set the rfork's length if we're closing the rfork. - */ - if ((ofork->of_flags & AFPFORK_RSRC)) { - ad_refresh( ofork->of_ad ); - if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) { - ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec); - doflush++; - } - if ( doflush ) { - ad_flush( ofork->of_ad ); - } + if (ofork->of_flags & AFPFORK_RSRC) { + adflags |= ADFLAGS_RF; + /* Only set the rfork's length if we're closing the rfork. */ + ad_refresh(NULL, ofork->of_ad ); + if ((ofork->of_flags & AFPFORK_DIRTY) && !gettimeofday(&tv, NULL)) { + ad_setdate(ofork->of_ad, AD_DATE_MODIFY | AD_DATE_UNIX,tv.tv_sec); + ad_flush( ofork->of_ad ); } } + + /* Somone has used write_fork, we assume file was changed, register it to file change event api */ + if (ofork->of_flags & AFPFORK_MODIFIED) { + struct dir *dir = dirlookup(ofork->of_vol, ofork->of_did); + if (dir) { + bstring forkpath = bformat("%s/%s", bdata(dir->d_fullpath), of_name(ofork)); + fce_register(FCE_FILE_MODIFY, bdata(forkpath), NULL, fce_file); + bdestroy(forkpath); + } + } + + ad_unlock(ofork->of_ad, ofork->of_refnum, ofork->of_flags & AFPFORK_ERROR ? 0 : 1); + +#ifdef HAVE_FSHARE_T + if (obj->options.flags & OPTION_SHARE_RESERV) { + fshare_t shmd; + shmd.f_id = ofork->of_refnum; + if (AD_DATA_OPEN(ofork->of_ad)) + fcntl(ad_data_fileno(ofork->of_ad), F_UNSHARE, &shmd); + if (AD_RSRC_OPEN(ofork->of_ad)) + fcntl(ad_reso_fileno(ofork->of_ad), F_UNSHARE, &shmd); + } +#endif + ret = 0; - if ( ad_close( ofork->of_ad, adflags ) < 0 ) { + if ( ad_close( ofork->of_ad, adflags | ADFLAGS_SETSHRMD) < 0 ) { ret = -1; } - of_dealloc( ofork ); + of_dealloc(ofork); + return ret; } @@ -458,10 +446,10 @@ struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble * struct ofork *of; struct adouble *adp; - if ((of = of_findname(path))) { + if ((of = of_findname(vol, path))) { adp = of->of_ad; } else { - ad_init(ad, vol->v_adouble, vol->v_ad_options); + ad_init(ad, vol); adp = ad; } return adp; @@ -470,7 +458,7 @@ struct adouble *of_ad(const struct vol *vol, struct path *path, struct adouble * /* ---------------------- close all forks for a volume */ -void of_closevol(const struct vol *vol) +void of_closevol(const AFPObj *obj, const struct vol *vol) { int refnum; @@ -479,7 +467,7 @@ void of_closevol(const struct vol *vol) for ( refnum = 0; refnum < nforks; refnum++ ) { if (oforks[ refnum ] != NULL && oforks[refnum]->of_vol == vol) { - if (of_closefork( oforks[ refnum ]) < 0 ) { + if (of_closefork(obj, oforks[ refnum ]) < 0 ) { LOG(log_error, logtype_afpd, "of_closevol: %s", strerror(errno) ); } } @@ -487,3 +475,23 @@ void of_closevol(const struct vol *vol) return; } +/* ---------------------- + close all forks for a volume +*/ +void of_close_all_forks(const AFPObj *obj) +{ + int refnum; + + if (!oforks) + return; + + for ( refnum = 0; refnum < nforks; refnum++ ) { + if (oforks[ refnum ] != NULL) { + if (of_closefork(obj, oforks[ refnum ]) < 0 ) { + LOG(log_error, logtype_afpd, "of_close_all_forks: %s", strerror(errno) ); + } + } + } + return; +} +