/*
- * $Id: file.c,v 1.92.2.2.2.31.2.13 2005-04-28 09:24:04 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.31.2.14 2005-05-26 11:49:55 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
/* ----------------------------------
* if newname is NULL (from directory.c) we don't want to copy ressource fork.
* because we are doing it elsewhere.
+ * currently if newname is NULL then adp is NULL.
*/
int copyfile(s_vol, d_vol, src, dst, newname, adp )
const struct vol *s_vol, *d_vol;
int ret_err = 0;
int adflags;
int noadouble = vol_noadouble(d_vol);
+ int stat_result;
struct stat st;
#ifdef DEBUG
adflags &= ~ADFLAGS_HF;
}
- if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, 0666, &add) < 0) {
+ stat_result = fstat(ad_dfileno(adp), &st); /* saving stat exit code, thus saving us on one more stat later on */
+
+ if (stat_result < 0) {
+ /* unlikely but if fstat fails, the default file mode will be 0666. */
+ st.st_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+ }
+
+ if (ad_open(dst , adflags | noadouble, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
ret_err = errno;
ad_close( adp, adflags );
if (EEXIST != ret_err) {
}
return AFPERR_EXIST;
}
+ /* XXX if the source and the dest don't use the same resource type it's broken
+ */
if (ad_hfileno(adp) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(adp)))){
/* copy the data fork */
err = copy_fd(ad_dfileno(&add), ad_dfileno(adp));
ret_err = errno;
goto done;
}
- else {
+
+ if (!ret_err && newname && (adflags & ADFLAGS_HF)) {
+ /* set the new name in the resource fork */
ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
- if (ad_open(dst , adflags | noadouble, O_RDWR, 0666, &add) < 0) {
+ if (ad_open(dst , ADFLAGS_HF | noadouble, O_RDWR, 0666, &add) < 0) {
ret_err = errno;
}
+ else {
+ ad_setname(&add, newname);
+ ad_flush( &add, ADFLAGS_HF );
+ if (ad_close( &add, ADFLAGS_HF ) <0) {
+ ret_err = errno;
+ }
+ }
}
- if (!ret_err && newname) {
- ad_setname(&add, newname);
- }
-
- ad_flush( &add, adflags );
- if (ad_close( &add, adflags ) <0) {
- ret_err = errno;
- }
if (ret_err) {
deletefile(d_vol, dst, 0);
}
- else if (!stat(src, &st)) {
+ else if (stat_result == 0) {
/* set dest modification date to src date */
struct utimbuf ut;
/*
- * $Id: unix.c,v 1.43.2.1.2.10 2004-06-15 22:53:55 didg Exp $
+ * $Id: unix.c,v 1.43.2.1.2.10.2.1 2005-05-26 11:49:55 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
struct stat *st;
{
struct stat sb;
-mode_t mask = S_IRUSR |S_IWUSR | S_IRGRP | S_IWGRP |S_IROTH | S_IWOTH;
+mode_t mask = S_IRWXU | S_IRWXG | S_IRWXO; /* rwx for owner group and other, by default */
if (!st) {
if (stat(name, &sb) != 0)
return -1;
st = &sb;
}
- mode &= mask; /* keep only rw-rw-rw in mode */
+
mode |= st->st_mode & ~mask; /* keep other bits from previous mode */
if ( chmod( name, mode & ~default_options.umask ) < 0 && errno != EPERM ) {
return -1;
/*
- * $Id: volume.c,v 1.51.2.7.2.33.2.5 2005-04-24 22:26:31 didg Exp $
+ * $Id: volume.c,v 1.51.2.7.2.33.2.6 2005-05-26 11:49:55 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
volume->v_ad_options |= ADVOL_NODEV;
if ((volume->v_flags & AFPVOL_CACHE))
volume->v_ad_options |= ADVOL_CACHE;
-
+ if ((volume->v_flags & AFPVOL_UNIX_PRIV))
+ volume->v_ad_options |= ADVOL_UNIXPRIV;
+
if (options[VOLOPT_PASSWORD].c_value)
volume->v_password = strdup(options[VOLOPT_PASSWORD].c_value);
/*
- * $Id: adouble.h,v 1.21.6.20.2.3 2005-02-12 11:22:05 didg Exp $
+ * $Id: adouble.h,v 1.21.6.20.2.4 2005-05-26 11:49:56 didg Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
/* adouble v2 cnid cache */
#define ADVOL_NODEV (1 << 0)
#define ADVOL_CACHE (1 << 1)
+/* adouble unix priv */
+#define ADVOL_UNIXPRIV (1 << 2)
/* lock flags */
#define ADLOCK_CLR (0)
#define ad_metadata(name, flags, adp) ad_open(name, ADFLAGS_HF|(flags), O_RDONLY, 0666, adp)
#endif
-/* extend header to RW if R or W (W if R for locking),
+/* build a resource fork mode from the data fork mode:
+ * remove X mode and extend header to RW if R or W (W if R for locking),
*/
#ifndef ATACC
#ifndef __inline__
#endif
static __inline__ mode_t ad_hf_mode (mode_t mode)
{
-#if 0
- mode |= S_IRUSR;
-#endif
+ mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
/* fnctl lock need write access */
if ((mode & S_IRUSR))
mode |= S_IWUSR;
/*
- * $Id: ad_open.c,v 1.30.6.18.2.4 2005-02-12 11:22:05 didg Exp $
+ * $Id: ad_open.c,v 1.30.6.18.2.5 2005-05-26 11:49:56 didg Exp $
*
* Copyright (c) 1999 Adrian Sun (asun@u.washington.edu)
* Copyright (c) 1990,1991 Regents of The University of Michigan.
#if 0
mode |= S_IRUSR;
#endif
+ mode &= ~(S_IXUSR | S_IXGRP | S_IXOTH);
/* fnctl lock need write access */
if ((mode & S_IRUSR))
mode |= S_IWUSR;
struct stat st;
char *slash, *ad_p;
int hoflags, admode;
- int st_invalid;
+ int st_invalid = -1;
int open_df = 0;
if (ad->ad_inited != AD_INITED) {
if (ad_dfileno(ad) == -1) {
hoflags = (oflags & ~(O_RDONLY | O_WRONLY)) | O_RDWR;
admode = mode;
- st_invalid = ad_mode_st(path, &admode, &st);
+ if ((oflags & O_CREAT)) {
+ st_invalid = ad_mode_st(path, &admode, &st);
+ if ((ad->ad_options & ADVOL_UNIXPRIV)) {
+ admode = mode;
+ }
+ }
ad->ad_df.adf_fd =open( path, hoflags, admode );
if (ad->ad_df.adf_fd < 0 ) {
if ((errno == EACCES || errno == EROFS) && !(oflags & O_RDWR)) {
hoflags = oflags;
- ad->ad_df.adf_fd =open( path, hoflags, admode );
+ ad->ad_df.adf_fd = open( path, hoflags, admode );
}
}
if ( ad->ad_df.adf_fd < 0)
AD_SET(ad->ad_df.adf_off);
ad->ad_df.adf_flags = hoflags;
- if ((oflags & O_CREAT) && !st_invalid) {
+ if (!st_invalid) {
/* just created, set owner if admin (root) */
ad_chown(path, &st);
}
admode = mode;
errno = 0;
st_invalid = ad_mode_st(ad_p, &admode, &st);
+ if ((ad->ad_options & ADVOL_UNIXPRIV)) {
+ admode = mode;
+ }
admode = ad_hf_mode(admode);
if ( errno == ENOENT && !(adflags & ADFLAGS_NOADOUBLE) && ad->ad_flags != AD_VERSION2_OSX) {
/*
*slash = '/';
admode = mode;
st_invalid = ad_mode_st(ad_p, &admode, &st);
+ if ((ad->ad_options & ADVOL_UNIXPRIV)) {
+ admode = mode;
+ }
admode = ad_hf_mode(admode);
}
/* retry with O_CREAT */