/*
- $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 <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
}
/* 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;
/*
- * $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.
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 );
/* -------------------- */
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);
}
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)
/* Check file type ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.f_type != 0) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
if (finfo->f_type != c1.finfo.f_type)
goto crit_check_ret;
}
/* Check creator ID */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.creator != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if (finfo->creator != c1.finfo.creator)
goto crit_check_ret;
/* Check finder info attributes */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.attrs != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if ((finfo->attrs & c2.finfo.attrs) != c1.finfo.attrs)
/* Check label */
if ((c1.rbitmap & (1<<DIRPBIT_FINFO)) && c2.finfo.label != 0) {
if (!finfo) {
- finfo = unpack_finderinfo(vol, path, &adp, &finderinfo);
+ finfo = unpack_finderinfo(vol, path, &adp, &finderinfo,islnk);
}
if ((finfo->label & c2.finfo.label) != c1.finfo.label)
goto crit_check_ret;
/*
- * $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.
break;
}
strcpy(path + len, de->d_name);
- if (stat(path, &st)) {
+ if (lstat(path, &st)) {
continue;
}
if (S_ISDIR(st.st_mode)) {
}
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;
}
/* 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);
}
/*
- * $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.
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) {
/*
- * $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.
}
/* 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;
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 ));
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;
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 :
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 */
}
/* FIXME use of_statdir ? */
- if (stat(name, &st)) {
+ if (lstat(name, &st)) {
return -1;
}
}
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:
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) {
/*
- * $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.
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);
/*
- * $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.
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;
}
/* 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;
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;
/*
- * $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.
dev_t devno;
static struct mnttab mnt;
- if ( stat( file, &sb ) < 0 ) {
+ if ( lstat( file, &sb ) < 0 ) {
return( NULL );
}
devno = sb.st_dev;
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 );
struct mntent *mnt;
int found=0;
- if ( stat( file, &sb ) < 0 ) {
+ if ( lstat( file, &sb ) < 0 ) {
return( NULL );
}
devno = sb.st_dev;
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;
/*
- * $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.
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;
}
*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;
}
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;
}
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;
return -1;
}
- if ( stat( ".", &st ) < 0 ) {
+ if ( lstat( ".", &st ) < 0 ) {
return( -1 );
}
if ( gid && gid != st.st_gid && chown( ".", uid, gid ) < 0 && errno != EPERM ) {
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;
}
/*
- * $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.
*
off_t adf_off;
#endif
+ char *adf_syml;
int adf_flags;
int adf_excl;
adf_lock_t *adf_lock;
/*
- * $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.
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);
}
/*
- * $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.
if (!p) {
return -1;
}
-
- return stat( p, stbuf );
+//FIXME!
+ return lstat( p, stbuf );
}
/* ----------------
{
struct stat st_dir;
struct stat st_meta;
+ struct stat st_link;
struct stat *pst = NULL;
char *ad_p;
int hoflags, admode;
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);
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)
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 );
}
}
memcpy(ad_entry(ad, ADEID_FINDERI) + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
}
- if (stat(path, &st) < 0) {
+ if (lstat(path, &st) < 0) {
return -1;
}
/*
- * $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.
/* 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;
/*
- * $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.
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;