From: franklahm Date: Sat, 2 Jan 2010 10:22:32 +0000 (+0000) Subject: Symlink patch from Anton Starikov X-Git-Tag: branch-symlink-commit X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?p=netatalk.git;a=commitdiff_plain;h=1b20936596f89b2706f1122ca2fabad6ffe00c98;hp=edefad2f0703ed2f6a21025d615600ed18c83d18 Symlink patch from Anton Starikov --- diff --git a/etc/afpd/acls.c b/etc/afpd/acls.c index a3d17f3f..d0ef6a45 100644 --- a/etc/afpd/acls.c +++ b/etc/afpd/acls.c @@ -1,5 +1,5 @@ /* - $Id: acls.c,v 1.7 2009-11-28 13:06:30 franklahm Exp $ + $Id: acls.c,v 1.7.2.1 2010-01-02 10:22:32 franklahm Exp $ Copyright (c) 2008,2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -583,7 +583,7 @@ static int check_acl_access(const char *path, const uuidp_t uuid, uint32_t reque } /* File or dir */ - if ((stat(path, &st)) != 0) { + if ((lstat(path, &st)) != 0) { LOG(log_error, logtype_afpd, "check_access: stat: %s", strerror(errno)); ret = AFPERR_PARAM; goto exit; diff --git a/etc/afpd/afp_asp.c b/etc/afpd/afp_asp.c index dddb3da5..c15c156a 100644 --- a/etc/afpd/afp_asp.c +++ b/etc/afpd/afp_asp.c @@ -1,5 +1,5 @@ /* - * $Id: afp_asp.c,v 1.27 2009-10-25 07:18:11 didg Exp $ + * $Id: afp_asp.c,v 1.27.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1997 Adrian Sun (asun@zoology.washington.edu) * Copyright (c) 1990,1993 Regents of The University of Michigan. @@ -81,7 +81,7 @@ static void afp_authprint_remove(AFPObj *obj) memset( addr_filename_buff, 0, 256 ); - if(stat(addr_filename, &cap_st) == 0) { + if(lstat(addr_filename, &cap_st) == 0) { if( S_ISREG(cap_st.st_mode) ) { int len; int capfd = open( addr_filename, O_RDONLY ); diff --git a/etc/afpd/catsearch.c b/etc/afpd/catsearch.c index 28fe3411..42790807 100644 --- a/etc/afpd/catsearch.c +++ b/etc/afpd/catsearch.c @@ -237,13 +237,13 @@ static struct finderinfo *unpack_buffer(struct finderinfo *finfo, char *buffer) /* -------------------- */ static struct finderinfo * -unpack_finderinfo(struct vol *vol, struct path *path, struct adouble **adp, struct finderinfo *finfo) +unpack_finderinfo(struct vol *vol, struct path *path, struct adouble **adp, struct finderinfo *finfo, int islnk) { packed_finder buf; void *ptr; *adp = adl_lkup(vol, path, *adp); - ptr = get_finderinfo(vol, path->u_name, *adp, &buf); + ptr = get_finderinfo(vol, path->u_name, *adp, &buf,islnk); return unpack_buffer(finfo, ptr); } @@ -265,6 +265,8 @@ static int crit_check(struct vol *vol, struct path *path) { u_int32_t ac_date, ab_date; static char convbuf[514]; /* for convert_charset dest_len parameter +2 */ size_t len; + int islnk; + islnk=S_ISLNK(path->st.st_mode); if (S_ISDIR(path->st.st_mode)) { if (!c1.dbitmap) @@ -379,7 +381,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check file type ID */ if ((c1.rbitmap & (1<f_type != c1.finfo.f_type) goto crit_check_ret; } @@ -387,7 +389,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check creator ID */ if ((c1.rbitmap & (1<creator != c1.finfo.creator) goto crit_check_ret; @@ -396,7 +398,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check finder info attributes */ if ((c1.rbitmap & (1<attrs & c2.finfo.attrs) != c1.finfo.attrs) @@ -406,7 +408,7 @@ static int crit_check(struct vol *vol, struct path *path) { /* Check label */ if ((c1.rbitmap & (1<label & c2.finfo.label) != c1.finfo.label) goto crit_check_ret; diff --git a/etc/afpd/directory.c b/etc/afpd/directory.c index d6845297..c50429ee 100644 --- a/etc/afpd/directory.c +++ b/etc/afpd/directory.c @@ -1,5 +1,5 @@ /* - * $Id: directory.c,v 1.121 2009-11-27 12:37:24 didg Exp $ + * $Id: directory.c,v 1.121.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -776,7 +776,7 @@ static int deletedir(char *dir) break; } strcpy(path + len, de->d_name); - if (stat(path, &st)) { + if (lstat(path, &st)) { continue; } if (S_ISDIR(st.st_mode)) { @@ -842,7 +842,7 @@ static int copydir(const struct vol *vol, char *src, char *dst) } strcpy(spath + slen, de->d_name); - if (stat(spath, &st) == 0) { + if (lstat(spath, &st) == 0) { if (strlen(de->d_name) > drem) { err = AFPERR_PARAM; break; @@ -864,7 +864,7 @@ static int copydir(const struct vol *vol, char *src, char *dst) } /* keep the same time stamp. */ - if (stat(src, &st) == 0) { + if (lstat(src, &st) == 0) { ut.actime = ut.modtime = st.st_mtime; utime(dst, &ut); } diff --git a/etc/afpd/enumerate.c b/etc/afpd/enumerate.c index 4608ecb4..523223b1 100644 --- a/etc/afpd/enumerate.c +++ b/etc/afpd/enumerate.c @@ -1,5 +1,5 @@ /* - * $Id: enumerate.c,v 1.47 2009-10-15 10:43:13 didg Exp $ + * $Id: enumerate.c,v 1.47.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -277,7 +277,7 @@ static int enumerate(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, if ( sindex == 1 || curdir->d_did != sd.sd_did || vid != sd.sd_vid ) { sd.sd_last = sd.sd_buf; /* if dir was in the cache we don't have the inode */ - if (( !o_path->st_valid && stat( ".", &o_path->st ) < 0 ) || + if (( !o_path->st_valid && lstat( ".", &o_path->st ) < 0 ) || (ret = for_each_dirent(vol, ".", enumerate_loop, (void *)&sd)) < 0) { switch (errno) { diff --git a/etc/afpd/file.c b/etc/afpd/file.c index a5a2c1cc..7d76f040 100644 --- a/etc/afpd/file.c +++ b/etc/afpd/file.c @@ -1,5 +1,5 @@ /* - * $Id: file.c,v 1.126 2009-11-30 15:27:48 didg Exp $ + * $Id: file.c,v 1.126.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -89,7 +89,7 @@ static int default_type(void *finder) } /* FIXME path : unix or mac name ? (for now it's unix name ) */ -void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data) +void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *adp, void *data, int islink) { struct extmap *em; void *ad_finder = NULL; @@ -114,6 +114,14 @@ void *get_finderinfo(const struct vol *vol, const char *upath, struct adouble *a memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); } } + if (islink){ + u_int16_t linkflag; + linkflag=htons(FINDERINFO_ISALIAS); + memcpy((char *)data + FINDERINFO_FRTYPEOFF,"slnk",4); + memcpy((char *)data + FINDERINFO_FRCREATOFF,"rhap",4); + *((u_int16_t*)((char *)data+FINDERINFO_FRFLAGOFF))|=linkflag; + chk_ext=0; + } /** Only enter if no appledouble information and no finder information found. */ if (chk_ext && (em = getextmap( upath ))) { memcpy(data, em->em_type, sizeof( em->em_type )); @@ -332,7 +340,7 @@ int getmetadata(struct vol *vol, break; case FILPBIT_FINFO : - get_finderinfo(vol, upath, adp, (char *)data); + get_finderinfo(vol, upath, adp, (char *)data,S_ISLNK(st->st_mode)); data += ADEDLEN_FINDERI; break; @@ -795,6 +803,27 @@ int setfilparams(struct vol *vol, case FILPBIT_FINFO : change_mdate = 1; memcpy(finder_buf, buf, 32 ); + if (memcmp(buf,"slnkrhap",8)==0 && !S_ISLNK(path->st.st_mode)){ + // SLFINFO + int fp; + ssize_t len; + int erc=1; + char buf[PATH_MAX+1]; + if ((fp=open(path->u_name,O_RDONLY))>=0){ + if (len=read(fp,buf,PATH_MAX+1)){ + if (unlink(path->u_name)==0){ + buf[len]=0; + erc=symlink(buf,path->u_name); + lstat(path->u_name,&(path->st)); + } + } + close(fp); + } + if (erc!=0){ + err=AFPERR_BITMAP; + goto setfilparam_done; + } + } buf += 32; break; case FILPBIT_UNIXPR : @@ -1654,7 +1683,7 @@ static int reenumerate_loop(struct dirent *de, char *mname _U_, void *data) cnid_t did = param->did; cnid_t aint; - if ( stat(de->d_name, &path.st)<0 ) + if ( lstat(de->d_name, &path.st)<0 ) return 0; /* update or add to cnid */ @@ -1699,7 +1728,7 @@ reenumerate_id(struct vol *vol, char *name, struct dir *dir) } /* FIXME use of_statdir ? */ - if (stat(name, &st)) { + if (lstat(name, &st)) { return -1; } @@ -1869,7 +1898,7 @@ int afp_deleteid(AFPObj *obj _U_, char *ibuf, size_t ibuflen _U_, char *rbuf _U_ } err = AFP_OK; - if ((movecwd(vol, dir) < 0) || (stat(upath, &st) < 0)) { + if ((movecwd(vol, dir) < 0) || (lstat(upath, &st) < 0)) { switch (errno) { case EACCES: case EPERM: @@ -2114,10 +2143,10 @@ int afp_exchangefiles(AFPObj *obj, char *ibuf, size_t ibuflen _U_, char *rbuf _U if (did) { cnid_delete(vol->v_cdb, did); } - if ((did && ( (crossdev && stat( upath, &srcst) < 0) || + if ((did && ( (crossdev && lstat( upath, &srcst) < 0) || cnid_update(vol->v_cdb, did, &srcst, curdir->d_did,upath, dlen) < 0)) || - (sid && ( (crossdev && stat(p, &destst) < 0) || + (sid && ( (crossdev && lstat(p, &destst) < 0) || cnid_update(vol->v_cdb, sid, &destst, sdir->d_did,supath, slen) < 0)) ) { switch (errno) { diff --git a/etc/afpd/file.h b/etc/afpd/file.h index c4253ca0..90e3aa1d 100644 --- a/etc/afpd/file.h +++ b/etc/afpd/file.h @@ -1,5 +1,5 @@ /* - * $Id: file.h,v 1.24 2009-10-15 10:43:13 didg Exp $ + * $Id: file.h,v 1.24.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -122,7 +122,7 @@ extern int deletefile (const struct vol *, char *, int); extern int getmetadata (struct vol *vol, u_int16_t bitmap, struct path *path, struct dir *dir, char *buf, size_t *buflen, struct adouble *adp); -extern void *get_finderinfo (const struct vol *, const char *, struct adouble *, void *); +extern void *get_finderinfo (const struct vol *, const char *, struct adouble *, void *, int); extern size_t mtoUTF8 (const struct vol *, const char *, size_t , char *, size_t ); extern int copy_path_name (const struct vol *, char *, char *i); diff --git a/etc/afpd/ofork.c b/etc/afpd/ofork.c index 9bb69667..75f89eba 100644 --- a/etc/afpd/ofork.c +++ b/etc/afpd/ofork.c @@ -1,5 +1,5 @@ /* - * $Id: ofork.c,v 1.30 2009-11-13 00:27:36 didg Exp $ + * $Id: ofork.c,v 1.30.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1996 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -285,7 +285,7 @@ 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; } @@ -309,7 +309,7 @@ int ret; /* FIXME, what about: we don't have r-x perm anymore ? */ 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; @@ -318,7 +318,7 @@ 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; diff --git a/etc/afpd/quota.c b/etc/afpd/quota.c index 2a12ca5e..f4d6d273 100644 --- a/etc/afpd/quota.c +++ b/etc/afpd/quota.c @@ -1,5 +1,5 @@ /* - * $Id: quota.c,v 1.32 2009-10-14 02:24:05 didg Exp $ + * $Id: quota.c,v 1.32.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -296,7 +296,7 @@ mountp( char *file, int *nfs) dev_t devno; static struct mnttab mnt; - if ( stat( file, &sb ) < 0 ) { + if ( lstat( file, &sb ) < 0 ) { return( NULL ); } devno = sb.st_dev; @@ -307,14 +307,14 @@ mountp( char *file, int *nfs) while ( getmntent( mtab, &mnt ) == 0 ) { /* local fs */ - if ( (stat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) { + if ( (lstat( mnt.mnt_special, &sb ) == 0) && (devno == sb.st_rdev)) { fclose( mtab ); return mnt.mnt_mountp; } /* check for nfs. we probably should use * strcmp(mnt.mnt_fstype, MNTTYPE_NFS), but that's not as fast. */ - if ((stat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) && + if ((lstat(mnt.mnt_mountp, &sb) == 0) && (devno == sb.st_dev) && strchr(mnt.mnt_special, ':')) { *nfs = 1; fclose( mtab ); @@ -384,7 +384,7 @@ special(char *file, int *nfs) struct mntent *mnt; int found=0; - if ( stat( file, &sb ) < 0 ) { + if ( lstat( file, &sb ) < 0 ) { return( NULL ); } devno = sb.st_dev; @@ -395,14 +395,14 @@ special(char *file, int *nfs) while (( mnt = getmntent( mtab )) != NULL ) { /* check for local fs */ - if ( (stat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) { + if ( (lstat( mnt->mnt_fsname, &sb ) == 0) && devno == sb.st_rdev) { found = 1; break; } /* check for an nfs mount entry. the alternative is to use * strcmp(mnt->mnt_type, MNTTYPE_NFS) instead of the strchr. */ - if ((stat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) && + if ((lstat(mnt->mnt_dir, &sb) == 0) && (devno == sb.st_dev) && strchr(mnt->mnt_fsname, ':')) { *nfs = 1; found = 1; diff --git a/etc/afpd/unix.c b/etc/afpd/unix.c index 6880f3a6..29ec76a1 100644 --- a/etc/afpd/unix.c +++ b/etc/afpd/unix.c @@ -1,5 +1,5 @@ /* - * $Id: unix.c,v 1.59 2009-10-29 10:04:35 didg Exp $ + * $Id: unix.c,v 1.59.2.1 2010-01-02 10:22:32 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -178,7 +178,7 @@ struct stat sb; ma->ma_user = ma->ma_owner = ma->ma_world = ma->ma_group = 0; if (!st) { - if (stat(path, &sb) != 0) + if (lstat(path, &sb) != 0) return; st = &sb; } @@ -281,7 +281,7 @@ int setdeskmode(const mode_t mode) *m = '\0'; strcat( modbuf, subp->d_name ); /* XXX: need to preserve special modes */ - if (stat(modbuf, &st) < 0) { + if (lstat(modbuf, &st) < 0) { LOG(log_error, logtype_afpd, "setdeskmode: stat %s: %s",fullpathname(modbuf), strerror(errno) ); continue; } @@ -384,7 +384,7 @@ int setdirmode(const struct vol *vol, const char *name, mode_t mode) if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) { continue; } - if ( stat( dirp->d_name, &st ) < 0 ) { + if ( lstat( dirp->d_name, &st ) < 0 ) { LOG(log_error, logtype_afpd, "setdirmode: stat %s: %s",dirp->d_name, strerror(errno) ); continue; } @@ -519,7 +519,7 @@ int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const if ( *dirp->d_name == '.' && (!osx || dirp->d_name[1] != '_')) { continue; } - if ( stat( dirp->d_name, &st ) < 0 ) { + if ( lstat( dirp->d_name, &st ) < 0 ) { LOG(log_error, logtype_afpd, "setdirowner: stat %s: %s", fullpathname(dirp->d_name), strerror(errno) ); continue; @@ -538,7 +538,7 @@ int setdirowner(const struct vol *vol, const char *name, const uid_t uid, const return -1; } - if ( stat( ".", &st ) < 0 ) { + if ( lstat( ".", &st ) < 0 ) { return( -1 ); } if ( gid && gid != st.st_gid && chown( ".", uid, gid ) < 0 && errno != EPERM ) { @@ -565,7 +565,7 @@ static int recursive_chown(const char *path, uid_t uid, gid_t gid) { return -1; } - if (stat(path, &sbuf) < 0) { + if (lstat(path, &sbuf) < 0) { LOG(log_error, logtype_afpd, "cannot chown() file [%s] (uid = %d): %s", path, uid, strerror(errno)); return -1; } diff --git a/include/atalk/adouble.h b/include/atalk/adouble.h index 0ac822a4..82026714 100644 --- a/include/atalk/adouble.h +++ b/include/atalk/adouble.h @@ -1,5 +1,5 @@ /* - * $Id: adouble.h,v 1.50 2009-11-18 11:14:59 didg Exp $ + * $Id: adouble.h,v 1.50.2.1 2010-01-02 10:22:33 franklahm Exp $ * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. * @@ -244,6 +244,7 @@ struct ad_fd { off_t adf_off; #endif + char *adf_syml; int adf_flags; int adf_excl; adf_lock_t *adf_lock; diff --git a/libatalk/adouble/ad_flush.c b/libatalk/adouble/ad_flush.c index a9383315..e0325bd9 100644 --- a/libatalk/adouble/ad_flush.c +++ b/libatalk/adouble/ad_flush.c @@ -1,5 +1,5 @@ /* - * $Id: ad_flush.c,v 1.12 2009-10-13 22:55:37 didg Exp $ + * $Id: ad_flush.c,v 1.12.2.1 2010-01-02 10:22:33 franklahm Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -200,9 +200,14 @@ int ad_close( struct adouble *ad, int adflags) if (( adflags & ADFLAGS_DF ) && ad_data_fileno(ad) != -1 && !(--ad->ad_data_fork.adf_refcount)) { + if (ad->ad_data_fork.adf_syml!=0){ + free(ad->ad_data_fork.adf_syml); + ad->ad_data_fork.adf_syml=0; + }else{ if ( close( ad_data_fileno(ad) ) < 0 ) { err = -1; } + } ad_data_fileno(ad) = -1; adf_lock_free(&ad->ad_data_fork); } diff --git a/libatalk/adouble/ad_open.c b/libatalk/adouble/ad_open.c index a3043866..0c0e1cbb 100644 --- a/libatalk/adouble/ad_open.c +++ b/libatalk/adouble/ad_open.c @@ -1,5 +1,5 @@ /* - * $Id: ad_open.c,v 1.60 2009-11-27 12:37:25 didg Exp $ + * $Id: ad_open.c,v 1.60.2.1 2010-01-02 10:22:33 franklahm Exp $ * * Copyright (c) 1999 Adrian Sun (asun@u.washington.edu) * Copyright (c) 1990,1991 Regents of The University of Michigan. @@ -1008,8 +1008,8 @@ int ad_stat(const char *path, struct stat *stbuf) if (!p) { return -1; } - - return stat( p, stbuf ); +//FIXME! + return lstat( p, stbuf ); } /* ---------------- @@ -1212,6 +1212,7 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble { struct stat st_dir; struct stat st_meta; + struct stat st_link; struct stat *pst = NULL; char *ad_p; int hoflags, admode; @@ -1225,6 +1226,7 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble ad->ad_adflags = adflags; ad->ad_resource_fork.adf_refcount = 0; ad->ad_data_fork.adf_refcount = 0; + ad->ad_data_fork.adf_syml=0; } else { ad->ad_open_forks = ((ad->ad_data_fork.adf_refcount > 0) ? ATTRBIT_DOPEN : 0); @@ -1243,11 +1245,27 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble admode = mode; } } - ad->ad_data_fork.adf_fd =open( path, hoflags, admode ); + lstat(path,&st_link); + if (S_ISLNK(st_link.st_mode) && (oflags == O_RDONLY)) { + int lsz; + ad->ad_data_fork.adf_syml=(char *)malloc(PATH_MAX+1); + lsz=readlink(path,ad->ad_data_fork.adf_syml,PATH_MAX); + if (lsz<=0) { + free(ad->ad_data_fork.adf_syml); + return -1; + } + ad->ad_data_fork.adf_syml[lsz]=0; + ad->ad_data_fork.adf_syml=(char *)realloc(ad->ad_data_fork.adf_syml,lsz+1); + ad->ad_data_fork.adf_fd=0; + }else{ + + ad->ad_data_fork.adf_fd =open( path, hoflags | O_NOFOLLOW, admode ); + if (ad->ad_data_fork.adf_fd < 0 ) { if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) { hoflags = oflags; - ad->ad_data_fork.adf_fd = open( path, hoflags, admode ); + ad->ad_data_fork.adf_fd = open( path, hoflags | O_NOFOLLOW, admode ); + } } } if ( ad->ad_data_fork.adf_fd < 0) @@ -1309,11 +1327,11 @@ int ad_open( const char *path, int adflags, int oflags, int mode, struct adouble if (!(adflags & ADFLAGS_RDONLY)) { hoflags = (hoflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR; } - ad->ad_md->adf_fd = open( ad_p, hoflags, 0 ); + ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 ); if (ad->ad_md->adf_fd < 0 ) { if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) { hoflags = oflags & ~(O_CREAT | O_EXCL); - ad->ad_md->adf_fd = open( ad_p, hoflags, 0 ); + ad->ad_md->adf_fd = open( ad_p, hoflags | O_NOFOLLOW, 0 ); } } @@ -1566,7 +1584,7 @@ static int new_rfork(const char *path, struct adouble *ad, int adflags) memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort)); } - if (stat(path, &st) < 0) { + if (lstat(path, &st) < 0) { return -1; } diff --git a/libatalk/adouble/ad_read.c b/libatalk/adouble/ad_read.c index 19d6218f..58c38def 100644 --- a/libatalk/adouble/ad_read.c +++ b/libatalk/adouble/ad_read.c @@ -1,5 +1,5 @@ /* - * $Id: ad_read.c,v 1.9 2009-10-13 22:55:37 didg Exp $ + * $Id: ad_read.c,v 1.9.2.1 2010-01-02 10:22:33 franklahm Exp $ * * Copyright (c) 1990,1991 Regents of The University of Michigan. * All Rights Reserved. @@ -66,7 +66,13 @@ ssize_t ad_read( struct adouble *ad, const u_int32_t eid, off_t off, char *buf, /* We're either reading the data fork (and thus the data file) * or we're reading anything else (and thus the header file). */ if ( eid == ADEID_DFORK ) { + if (ad->ad_data_fork.adf_syml !=0) { + cc=strlen(ad->ad_data_fork.adf_syml); + if (buflen >=cc) memcpy(buf,ad->ad_data_fork.adf_syml,cc); + else cc=0; + }else{ cc = adf_pread(&ad->ad_data_fork, buf, buflen, off); + } } else { off_t r_off; diff --git a/libatalk/vfs/unix.c b/libatalk/vfs/unix.c index 789a13ec..6679c296 100644 --- a/libatalk/vfs/unix.c +++ b/libatalk/vfs/unix.c @@ -1,5 +1,5 @@ /* - * $Id: unix.c,v 1.6 2009-10-27 10:24:02 franklahm Exp $ + * $Id: unix.c,v 1.6.2.1 2010-01-02 10:22:33 franklahm Exp $ * * Copyright (c) 1990,1993 Regents of The University of Michigan. * All Rights Reserved. See COPYRIGHT. @@ -83,11 +83,13 @@ int setfilmode(const char * name, mode_t mode, struct stat *st, mode_t v_umask) mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO; /* rwx for owner group and other, by default */ if (!st) { - if (stat(name, &sb) != 0) + if (lstat(name, &sb) != 0) return -1; st = &sb; } + if (S_ISLNK(st->st_mode)) return 0; /* we don't want to change link permissions */ + mode |= st->st_mode & ~mask; /* keep other bits from previous mode */ if ( chmod( name, mode & ~v_umask ) < 0 && errno != EPERM ) { return -1;