/*
- * $Id: file.c,v 1.92.2.2.2.29 2004-09-02 12:31:55 didg Exp $
+ * $Id: file.c,v 1.92.2.2.2.31.2.22 2008-11-25 15:16:33 didg Exp $
*
* Copyright (c) 1990,1993 Regents of The University of Michigan.
* All Rights Reserved. See COPYRIGHT.
* putawayID 4 home directory id
*/
-const u_char ufinderi[] = {
- 'T', 'E', 'X', 'T', 'U', 'N', 'I', 'X',
+const u_char ufinderi[ADEDLEN_FINDERI] = {
0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0
};
-/* FIXME mpath : unix or mac name ? (for now it's mac name ) */
-void *get_finderinfo(const char *mpath, struct adouble *adp, void *data)
+static const u_char old_ufinderi[] = {
+ 'T', 'E', 'X', 'T', 'U', 'N', 'I', 'X'
+ };
+
+/* ----------------------
+*/
+static int default_type(void *finder)
+{
+ if (!memcmp(finder, ufinderi, 8) || !memcmp(finder, old_ufinderi, 8))
+ return 1;
+ return 0;
+}
+
+/* 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)
{
struct extmap *em;
- void *ad_finder;
+ void *ad_finder = NULL;
+ int chk_ext = 0;
+
+ if (adp)
+ ad_finder = ad_entry(adp, ADEID_FINDERI);
- if (adp && (ad_finder = ad_entry(adp, ADEID_FINDERI))) {
- memcpy(data, ad_finder, 32);
+ if (ad_finder) {
+ memcpy(data, ad_finder, ADEDLEN_FINDERI);
+ /* default type ? */
+ if (default_type(ad_finder))
+ chk_ext = 1;
}
else {
- memcpy(data, ufinderi, 32);
+ memcpy(data, ufinderi, ADEDLEN_FINDERI);
+ chk_ext = 1;
+ if (vol_inv_dots(vol) && *upath == '.') { /* make it invisible */
+ u_int16_t ashort;
+
+ ashort = htons(FINDERINFO_INVISIBLE);
+ memcpy((char *)data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
+ }
}
-
- if ((!adp || !memcmp(ad_entry(adp, ADEID_FINDERI),ufinderi , 8 ))
- && (em = getextmap( mpath ))
- ) {
+ /** 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 ));
memcpy((char *)data + 4, em->em_creator, sizeof(em->em_creator));
}
(1 << FILPBIT_FINFO) |\
(1 << FILPBIT_RFLEN) |\
(1 << FILPBIT_EXTRFLEN) |\
- (1 << FILPBIT_PDINFO)))
+ (1 << FILPBIT_PDINFO) |\
+ (1 << FILPBIT_UNIXPR)))
/* -------------------------- */
u_int32_t get_id(struct vol *vol, struct adouble *adp, const struct stat *st,
- const cnid_t did, const char *upath, const int len)
+ const cnid_t did, char *upath, const int len)
{
u_int32_t aint = 0;
#if AD_VERSION > AD_VERSION1
-dev_t dev;
-ino_t ino;
-cnid_t a_did;
-char stamp[ADEDLEN_PRIVSYN];
- /* look in AD v2 header
- * note inode and device are opaques and not in network order
- */
- if (adp
- && sizeof(dev_t) == ad_getentrylen(adp, ADEID_PRIVDEV)
- && sizeof(ino_t) == ad_getentrylen(adp,ADEID_PRIVINO)
- && sizeof(stamp) == ad_getentrylen(adp,ADEID_PRIVSYN)
- && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_DID)
- && sizeof(cnid_t) == ad_getentrylen(adp, ADEID_PRIVID)
-
- ) {
- memcpy(&dev, ad_entry(adp, ADEID_PRIVDEV), sizeof(dev_t));
- memcpy(&ino, ad_entry(adp, ADEID_PRIVINO), sizeof(ino_t));
- memcpy(stamp, ad_entry(adp, ADEID_PRIVSYN), sizeof(stamp));
- memcpy(&a_did, ad_entry(adp, ADEID_DID), sizeof(cnid_t));
-
- if ( ( (vol->v_flags & AFPVOL_NODEV) || dev == st->st_dev)
- && ino == st->st_ino && a_did == did
- && !memcmp(vol->v_stamp, stamp, sizeof(stamp))) {
- memcpy(&aint, ad_entry(adp, ADEID_PRIVID), sizeof(aint));
- return aint;
- }
+
+ if ((aint = ad_getid(adp, st->st_dev, st->st_ino, did, vol->v_stamp))) {
+ return aint;
}
#endif
+
if (vol->v_cdb != NULL) {
aint = cnid_add(vol->v_cdb, st, did, upath, len, aint);
/* Throw errors if cnid_add fails. */
}
}
#if AD_VERSION > AD_VERSION1
- else if (adp && sizeof(dev_t) == ADEDLEN_PRIVDEV && sizeof(ino_t) == ADEDLEN_PRIVINO) {
+ else if (adp ) {
/* update the ressource fork
* for a folder adp is always null
*/
- ad_setid(adp,(vol->v_flags & AFPVOL_NODEV)?0:st->st_dev, st->st_ino, aint, did, vol->v_stamp);
- ad_flush(adp, ADFLAGS_HF);
+ if (ad_setid(adp, st->st_dev, st->st_ino, aint, did, vol->v_stamp)) {
+ ad_flush(adp, ADFLAGS_HF);
+ }
}
#endif
}
case FILPBIT_ATTR :
if ( adp ) {
ad_getattr(adp, &ashort);
- } else if (*upath == '.') {
+ } else if (vol_inv_dots(vol) && *upath == '.') {
ashort = htons(ATTRBIT_INVISIBLE);
} else
ashort = 0;
break;
case FILPBIT_FINFO :
- get_finderinfo(path->m_name, adp, (char *)data);
- if (!adp) {
- if (*upath == '.') { /* make it invisible */
- ashort = htons(FINDERINFO_INVISIBLE);
- memcpy(data + FINDERINFO_FRFLAGOFF, &ashort, sizeof(ashort));
- }
- }
- data += 32;
+ get_finderinfo(vol, upath, adp, (char *)data);
+ data += ADEDLEN_FINDERI;
break;
case FILPBIT_LNAME :
memcpy(data, &aint, sizeof( aint ));
data += sizeof( aint );
break;
- case FILPBIT_UNIXPR :
+ case FILPBIT_UNIXPR :
/* accessmode may change st_mode with ACLs */
accessmode( upath, &ma, dir , st);
memcpy( data, &aint, sizeof( aint ));
data += sizeof( aint );
- aint = htonl(st->st_mode);
+ /* FIXME: ugly hack
+ type == slnk indicates an OSX style symlink,
+ we have to add S_IFLNK to the mode, otherwise
+ 10.3 clients freak out. */
+
+ aint = st->st_mode;
+ if (adp) {
+ memcpy(fdType, ad_entry( adp, ADEID_FINDERI ), 4 );
+ if ( memcmp( fdType, "slnk", 4 ) == 0 ) {
+ aint |= S_IFLNK;
+ }
+ }
+ aint = htonl(aint);
+
memcpy( data, &aint, sizeof( aint ));
data += sizeof( aint );
attrbits = ((of->of_ad->ad_df.adf_refcount > 0) ? ATTRBIT_DOPEN : 0);
attrbits |= ((of->of_ad->ad_hf.adf_refcount > of->of_ad->ad_df.adf_refcount)? ATTRBIT_ROPEN : 0);
} else {
- ad_init(&ad, vol->v_adouble);
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
adp = &ad;
}
/* ----------------------------- */
int afp_createfile(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct adouble ad, *adp;
struct vol *vol;
if ((of = of_findname(s_path))) {
adp = of->of_ad;
} else {
- ad_init(&ad, vol->v_adouble);
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
adp = &ad;
}
if ( creatf) {
openf = O_RDWR|O_CREAT|O_EXCL;
}
- if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF,
+ if ( ad_open( upath, vol_noadouble(vol)|ADFLAGS_DF|ADFLAGS_HF|ADFLAGS_NOHF|ADFLAGS_CREATE,
openf, 0666, adp) < 0 ) {
switch ( errno ) {
case EROFS:
return( AFPERR_EXIST );
case EACCES :
return( AFPERR_ACCESS );
+ case EDQUOT:
+ case ENOSPC :
+ return( AFPERR_DFULL );
default :
return( AFPERR_PARAM );
}
}
int afp_setfilparams(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct vol *vol;
struct dir *dir;
struct path *path, u_int16_t f_bitmap, char *buf )
{
struct adouble ad, *adp;
- struct ofork *of;
struct extmap *em;
int bit, isad = 1, err = AFP_OK;
char *upath;
- u_char achar, *fdType, xyy[4];
+ u_char achar, *fdType, xyy[4]; /* uninitialized, OK 310105 */
u_int16_t ashort, bshort;
u_int32_t aint;
u_int32_t upriv;
#endif /* DEBUG */
upath = path->u_name;
- if ((of = of_findname(path))) {
- adp = of->of_ad;
- } else {
- ad_init(&ad, vol->v_adouble);
- adp = &ad;
- }
+ adp = of_ad(vol, path, &ad);
+
if (!vol_unix_priv(vol) && check_access(upath, OPENACC_WR ) < 0) {
return AFPERR_ACCESS;
ad_setdate(adp, AD_DATE_BACKUP, bdate);
break;
case FILPBIT_FINFO :
- if (!memcmp( ad_entry( adp, ADEID_FINDERI ), ufinderi, 8 )
+ if (default_type( ad_entry( adp, ADEID_FINDERI ))
&& (
((em = getextmap( path->m_name )) &&
!memcmp(finder_buf, em->em_type, sizeof( em->em_type )) &&
)) {
memcpy(finder_buf, ufinderi, 8 );
}
-
memcpy(ad_entry( adp, ADEID_FINDERI ), finder_buf, 32 );
break;
case FILPBIT_UNIXPR :
/* FIXME warning in syslog so admin'd know there's a conflict ?*/
return AFPERR_OLOCK; /* little lie */
}
- if (AFP_OK != ( rc = copyfile(vol, vol, src, dst, newname )) ) {
+ if (AFP_OK != ( rc = copyfile(vol, vol, src, dst, newname, NULL )) ) {
/* on error copyfile delete dest */
return( rc );
}
* create .AppleDouble if the file is already opened, so we
* use a diff one, it's not a pb,ie it's not the same file, yet.
*/
- ad_init(&ad, vol->v_adouble);
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options);
if (!ad_open(dst, ADFLAGS_HF, O_RDWR | O_CREAT, 0666, &ad)) {
ad_close(&ad, ADFLAGS_HF);
if (!unix_rename( adsrc, vol->ad_path( dst, 0 )) )
return( AFP_OK );
}
-int copy_path_name(char *newname, char *ibuf)
+/* ----------------
+ convert a Mac long name to an utf8 name,
+*/
+size_t mtoUTF8(const struct vol *vol, const char *src, size_t srclen, char *dest, size_t destlen)
+{
+size_t outlen;
+
+ if ((size_t)-1 == (outlen = convert_string ( vol->v_maccharset, CH_UTF8_MAC, src, srclen, dest, destlen)) ) {
+ return -1;
+ }
+ return outlen;
+}
+
+/* ---------------- */
+int copy_path_name(const struct vol *vol, char *newname, char *ibuf)
{
char type = *ibuf;
size_t plen = 0;
switch (type) {
case 2:
if (( plen = (unsigned char)*ibuf++ ) != 0 ) {
- strncpy( newname, ibuf, plen );
- newname[ plen ] = '\0';
+ if (afp_version >= 30) {
+ /* convert it to UTF8
+ */
+ if ((plen = mtoUTF8(vol, ibuf, plen, newname, AFPOBJ_TMPSIZ)) == (size_t)-1)
+ return -1;
+ }
+ else {
+ strncpy( newname, ibuf, plen );
+ newname[ plen ] = '\0';
+ }
if (strlen(newname) != plen) {
/* there's \0 in newname, e.g. it's a pathname not
* only a filename.
/* -----------------------------------
*/
int afp_copyfile(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct vol *s_vol, *d_vol;
struct dir *dir;
int err, retvalue = AFP_OK;
u_int16_t svid, dvid;
+ struct adouble ad, *adp;
+ int denyreadset;
+
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin afp_copyfile:");
#endif /* DEBUG */
* and locks need to stay coherent. as a result,
* we just balk if the file is opened already. */
- newname = obj->newtmp;
- strcpy( newname, s_path->m_name );
+ adp = of_ad(s_vol, s_path, &ad);
- if (of_findname(s_path))
+ if (ad_open(s_path->u_name , ADFLAGS_DF |ADFLAGS_HF | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) {
+ return AFPERR_DENYCONF;
+ }
+ denyreadset = (getforkmode(adp, ADEID_DFORK, AD_FILELOCK_DENY_RD) != 0 ||
+ getforkmode(adp, ADEID_RFORK, AD_FILELOCK_DENY_RD) != 0 );
+ ad_close( adp, ADFLAGS_DF |ADFLAGS_HF );
+ if (denyreadset) {
return AFPERR_DENYCONF;
+ }
+
+ newname = obj->newtmp;
+ strcpy( newname, s_path->m_name );
p = ctoupath( s_vol, curdir, newname );
if (!p) {
}
/* one of the handful of places that knows about the path type */
- if (copy_path_name(newname, ibuf) < 0) {
+ if (copy_path_name(d_vol, newname, ibuf) < 0) {
return( AFPERR_PARAM );
}
/* newname is always only a filename so curdir *is* its
if (NULL == (upath = mtoupath(d_vol, newname, curdir->d_did, utf8_encoding()))) {
return( AFPERR_PARAM );
}
- if ( (err = copyfile(s_vol, d_vol, p, upath , newname)) < 0 ) {
+ if ( (err = copyfile(s_vol, d_vol, p, upath , newname, adp)) < 0 ) {
return err;
}
curdir->offcnt++;
}
/* ----------------------- */
-static __inline__ int copy_all(const int dfd, const void *buf,
+static int copy_all(const int dfd, const void *buf,
size_t buflen)
{
ssize_t cc;
/* ----------------------------------
* 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 )
+int copyfile(s_vol, d_vol, src, dst, newname, adp )
const struct vol *s_vol, *d_vol;
char *src, *dst, *newname;
+struct adouble *adp;
{
struct adouble ads, add;
int err = 0;
int ret_err = 0;
int adflags;
int noadouble = vol_noadouble(d_vol);
+ int stat_result;
struct stat st;
#ifdef DEBUG
LOG(log_info, logtype_afpd, "begin copyfile:");
#endif /* DEBUG */
- ad_init(&ads, s_vol->v_adouble);
- ad_init(&add, d_vol->v_adouble);
+ if (adp == NULL) {
+ ad_init(&ads, s_vol->v_adouble, s_vol->v_ad_options);
+ adp = &ads;
+ }
+ ad_init(&add, d_vol->v_adouble, d_vol->v_ad_options);
adflags = ADFLAGS_DF;
if (newname) {
adflags |= ADFLAGS_HF;
}
- if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, &ads) < 0) {
+ if (ad_open(src , adflags | ADFLAGS_NOHF, O_RDONLY, 0, adp) < 0) {
ret_err = errno;
goto done;
}
- if (ad_hfileno(&ads) == -1) {
+ if (ad_hfileno(adp) == -1) {
/* no resource fork, don't create one for dst file */
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, O_RDWR|O_CREAT|O_EXCL, st.st_mode, &add) < 0) {
ret_err = errno;
- ad_close( &ads, adflags );
+ ad_close( adp, adflags );
if (EEXIST != ret_err) {
deletefile(d_vol, dst, 0);
goto done;
}
return AFPERR_EXIST;
}
- if (ad_hfileno(&ads) == -1 || 0 == (err = copy_fd(ad_hfileno(&add), ad_hfileno(&ads)))){
+ /* 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(&ads));
+ err = copy_fd(ad_dfileno(&add), ad_dfileno(adp));
}
/* Now, reopen destination file */
if (err < 0) {
ret_err = errno;
}
- ad_close( &ads, adflags );
+ ad_close( adp, adflags );
if (ad_close( &add, adflags ) <0) {
+ if (!ret_err) {
+ ret_err = errno;
+ }
deletefile(d_vol, dst, 0);
- ret_err = errno;
goto done;
}
- else {
- ad_init(&add, d_vol->v_adouble);
- if (ad_open(dst , adflags | noadouble, O_RDWR, 0666, &add) < 0) {
+
+ 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_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;
/* try to open both forks at once */
adflags = ADFLAGS_DF|ADFLAGS_HF;
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */
while(1) {
- ad_init(&ad, vol->v_adouble); /* OK */
if ( ad_open( file, adflags, O_RDONLY, 0, &ad ) < 0 ) {
switch (errno) {
case ENOENT:
}
else if (!adp) {
/* was EACCESS error try to get only metadata */
- ad_init(&ad, vol->v_adouble); /* OK */
+ ad_init(&ad, vol->v_adouble, vol->v_ad_options); /* OK */
if ( ad_metadata( file , 0, &ad) == 0 ) {
ad_getattr(&ad, &bshort);
ad_close( &ad, ADFLAGS_HF );
/* ------------------------------------ */
/* return a file id */
int afp_createid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
+AFPObj *obj _U_;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
{
struct stat *st;
struct vol *vol;
#if AD_VERSION > AD_VERSION1
if (aint != CNID_INVALID && !S_ISDIR(path.st.st_mode)) {
- struct ofork *of;
struct adouble ad, *adp;
path.st_errno = 0;
path.st_valid = 1;
path.u_name = de->d_name;
- if (!(of = of_findname(&path))) {
- ad_init(&ad, vol->v_adouble);
- adp = &ad;
- } else
- adp = of->of_ad;
+ adp = of_ad(vol, &path, &ad);
if ( ad_open( de->d_name, ADFLAGS_HF, O_RDWR, 0, adp ) < 0 ) {
continue;
}
- ad_setid(adp,(vol->v_flags & AFPVOL_NODEV)?0:path.st.st_dev, path.st.st_ino, aint, did, vol->v_stamp);
- ad_flush(adp, ADFLAGS_HF);
+ if (ad_setid(adp, path.st.st_dev, path.st.st_ino, aint, did, vol->v_stamp)) {
+ ad_flush(adp, ADFLAGS_HF);
+ }
ad_close(adp, ADFLAGS_HF);
}
#endif /* AD_VERSION > AD_VERSION1 */
/* ------------------------------
resolve a file id */
int afp_resolveid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
+AFPObj *obj _U_;
char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+int ibuflen _U_, *rbuflen;
{
struct vol *vol;
struct dir *dir;
memcpy(&id, ibuf, sizeof( id ));
ibuf += sizeof(id);
cnid = id;
-
+
+ if (!id) {
+ /* some MacOS versions after a catsearch do a *lot* of afp_resolveid with 0 */
+ return AFPERR_NOID;
+ }
retry:
if (NULL == (upath = cnid_resolve(vol->v_cdb, &id, buffer, len)) ) {
return AFPERR_NOID; /* was AFPERR_BADID, but help older Macs */
/* ------------------------------ */
int afp_deleteid(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj _U_;
+char *ibuf, *rbuf _U_;
+int ibuflen _U_, *rbuflen;
{
struct stat st;
struct vol *vol;
#define APPLETEMP ".AppleTempXXXXXX"
int afp_exchangefiles(obj, ibuf, ibuflen, rbuf, rbuflen )
-AFPObj *obj;
-char *ibuf, *rbuf;
-int ibuflen, *rbuflen;
+AFPObj *obj;
+char *ibuf, *rbuf _U_ ;
+int ibuflen _U_, *rbuflen;
{
struct stat srcst, destst;
struct vol *vol;
return AFPERR_PARAM ;
}
- ad_init(&ads, vol->v_adouble);
+ ad_init(&ads, vol->v_adouble, vol->v_ad_options);
if (!(adsp = find_adouble( path, &s_of, &ads))) {
return afp_errno;
}
goto err_exchangefile;
}
- ad_init(&add, vol->v_adouble);
+ ad_init(&add, vol->v_adouble, vol->v_ad_options);
if (!(addp = find_adouble( path, &d_of, &add))) {
err = afp_errno;
goto err_exchangefile;
}
if (crossdev) {
- /* we need to close fork for copy, both s_of and d_of are null */
+ /* FIXME we need to close fork for copy, both s_of and d_of are null */
ad_close(adsp, ADFLAGS_HF);
ad_close(addp, ADFLAGS_HF);
}
}
/* here we need to reopen if crossdev */
- if (sid)
- ad_setid(addp,(vol->v_flags & AFPVOL_NODEV)?0:destst.st_dev, destst.st_ino, sid, sdir->d_did, vol->v_stamp);
- if (did)
- ad_setid(adsp,(vol->v_flags & AFPVOL_NODEV)?0:srcst.st_dev, srcst.st_ino, did, curdir->d_did, vol->v_stamp);
+ if (sid && ad_setid(addp, destst.st_dev, destst.st_ino, sid, sdir->d_did, vol->v_stamp))
+ {
+ ad_flush( addp, ADFLAGS_HF );
+ }
+
+ if (did && ad_setid(adsp, srcst.st_dev, srcst.st_ino, did, curdir->d_did, vol->v_stamp))
+ {
+ ad_flush( adsp, ADFLAGS_HF );
+ }
/* change perms, src gets dest perm and vice versa */
err_exchangefile:
if ( !s_of && adsp && ad_hfileno(adsp) != -1 ) {
- ad_flush( adsp, ADFLAGS_HF );
ad_close(adsp, ADFLAGS_HF);
}
if ( !d_of && addp && ad_hfileno(addp) != -1 ) {
- ad_flush( addp, ADFLAGS_HF );
ad_close(addp, ADFLAGS_HF);
}