/*
- * $Id: adouble.h,v 1.49 2009-11-13 02:52:07 didg Exp $
+ * $Id: adouble.h,v 1.50 2009-11-18 11:14:59 didg Exp $
* Copyright (c) 1990,1991 Regents of The University of Michigan.
* All Rights Reserved.
*
int sys_setxattr (const char *path, const char *name, const void *value, size_t size, int flags);
int sys_lsetxattr (const char *path, const char *name, const void *value, size_t size, int flags);
int sys_fsetxattr (int filedes, const char *name, const void *value, size_t size, int flags);
+int sys_copyxattr (const char *src, const char *dst);
/* ad_read.c/ad_write.c */
extern int sys_ftruncate(int fd, off_t length);
/*
- $Id: ea.h,v 1.8 2009-11-17 12:33:30 franklahm Exp $
+ $Id: ea.h,v 1.9 2009-11-18 11:14:59 didg Exp $
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
extern int sys_list_eas(VFS_FUNC_ARGS_EA_LIST);
extern int sys_set_ea(VFS_FUNC_ARGS_EA_SET);
extern int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE);
+/* native EA VFSfile/dir cp/mv/rm */
+extern int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE);
#endif /* ATALK_EA_H */
/*
- $Id: ea_sys.c,v 1.1 2009-11-17 12:33:30 franklahm Exp $
+ $Id: ea_sys.c,v 1.2 2009-11-18 11:14:59 didg Exp $
Copyright (c) 2009 Frank Lahm <franklahm@gmail.com>
This program is free software; you can redistribute it and/or modify
return AFP_OK;
}
+
+/* ---------------------
+ copy EA
+*/
+int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE)
+{
+ int ret;
+ ret = sys_copyxattr(src, dst);
+ if (ret == -1) {
+ switch(errno) {
+ case ENOENT:
+ /* no attribute */
+ break;
+ case EACCES:
+ LOG(log_debug, logtype_afpd, "sys_ea_copyfile(%s, %s): error: %s", src, dst, strerror(errno));
+ return AFPERR_ACCESS;
+ default:
+ LOG(log_error, logtype_afpd, "sys_ea_copyfile(%s, %s): error: %s", src, dst, strerror(errno));
+ return AFPERR_MISC;
+ }
+ }
+
+ return AFP_OK;
+}
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ sys_copyxattr modified from LGPL2.1 libattr copyright
+ Copyright (C) 2001-2002 Silicon Graphics, Inc. All Rights Reserved.
+ Copyright (C) 2001 Andreas Gruenbacher.
+
Samba 3.0.28, modified for netatalk.
- $Id: sys_ea.c,v 1.1 2009-11-17 12:33:30 franklahm Exp $
+ $Id: sys_ea.c,v 1.2 2009-11-18 11:14:59 didg Exp $
*/
#include "config.h"
#endif
+#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#endif
}
+/* copy EA, from LGPL2.1 libattr attr_copy_file.c
+ should use fgetxattr? We don't have them but they are in Samba.
+ Or add a sys_copyfxattr? Currently it's only call by afp_copyfile so we can open
+ the both files for reading and get a fd.
+
+ Or don't use sys_xxx and copy all attributes.
+
+*/
+int sys_copyxattr(const char *src_path, const char *dst_path)
+{
+#if defined(HAVE_LISTXATTR) && defined(HAVE_GETXATTR) && defined(HAVE_SETXATTR)
+ int ret = 0;
+ ssize_t size;
+ char *names = NULL, *end_names, *name, *value = NULL;
+ unsigned int setxattr_ENOTSUP = 0;
+
+ size = sys_listxattr(src_path, NULL, 0);
+ if (size < 0) {
+ if (errno != ENOSYS && errno != ENOTSUP) {
+ ret = -1;
+ }
+ goto getout;
+ }
+ names = malloc(size+1);
+ if (names == NULL) {
+ ret = -1;
+ goto getout;
+ }
+ size = sys_listxattr(src_path, names, size);
+ if (size < 0) {
+ ret = -1;
+ goto getout;
+ } else {
+ names[size] = '\0';
+ end_names = names + size;
+ }
+
+ for (name = names; name != end_names; name = strchr(name, '\0') + 1) {
+ void *old_value;
+
+ /* check if this attribute shall be preserved */
+ if (!*name)
+ continue;
+
+ size = sys_getxattr (src_path, name, NULL, 0);
+ if (size < 0) {
+ ret = -1;
+ continue;
+ }
+ value = realloc(old_value = value, size);
+ if (size != 0 && value == NULL) {
+ free(old_value);
+ ret = -1;
+ }
+ size = sys_getxattr(src_path, name, value, size);
+ if (size < 0) {
+ ret = -1;
+ continue;
+ }
+ if (sys_setxattr(dst_path, name, value, size, 0) != 0) {
+ if (errno == ENOTSUP)
+ setxattr_ENOTSUP++;
+ else {
+ if (errno == ENOSYS) {
+ ret = -1;
+ /* no hope of getting any further */
+ break;
+ } else {
+ ret = -1;
+ }
+ }
+ }
+ }
+ if (setxattr_ENOTSUP) {
+ errno = ENOTSUP;
+ ret = -1;
+ }
+getout:
+ free(value);
+ free(names);
+ return ret;
+#else
+ /* FIXME same for solaris */
+ return 0;
+#endif
+}
+
/**************************************************************************
helper functions for Solaris' EA support
****************************************************************************/
/* rf_setdirowner: */ NULL,
/* rf_deletefile: */ NULL,
/* rf_renamefile: */ NULL,
- /* vfs_copyfile: */ NULL,
+ /* vfs_copyfile: */ sys_ea_copyfile,
/* rf_acl: */ NULL,
/* rf_remove_acl */ NULL,
/* ea_getsize */ sys_get_easize,