X-Git-Url: https://arthur.barton.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=libatalk%2Fvfs%2Fea_sys.c;h=7ed87294825a4f7f2085b739f9d81c98c5d11314;hb=76b379ad71f4b129fade5611356b103b7ca6d39a;hp=77ab783b04c8d3546f20ecb66e5d6335e387ae82;hpb=fa3903158f401ef06aaa524059c64f4412c39c7e;p=netatalk.git diff --git a/libatalk/vfs/ea_sys.c b/libatalk/vfs/ea_sys.c index 77ab783b..7ed87294 100644 --- a/libatalk/vfs/ea_sys.c +++ b/libatalk/vfs/ea_sys.c @@ -1,5 +1,4 @@ /* - $Id: ea_sys.c,v 1.8 2010-04-13 08:05:06 franklahm Exp $ Copyright (c) 2009 Frank Lahm This program is free software; you can redistribute it and/or modify @@ -26,20 +25,7 @@ #include #include #include - -#if HAVE_ATTR_XATTR_H -#include -#elif HAVE_SYS_XATTR_H -#include -#endif - -#ifdef HAVE_SYS_EA_H -#include -#endif - -#ifdef HAVE_SYS_EXTATTR_H -#include -#endif +#include #include #include @@ -51,11 +37,6 @@ #include #include -#ifndef ENOATTR -#define ENOATTR ENODATA -#endif - - /********************************************************************************** * EA VFS funcs for storing EAs in nativa filesystem EAs **********************************************************************************/ @@ -87,12 +68,20 @@ int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE) LOG(log_debug7, logtype_afpd, "sys_getextattr_size(%s): attribute: \"%s\"", uname, attruname); - if ((oflag & O_NOFOLLOW) ) { - ret = sys_lgetxattr(uname, attruname, rbuf +4, 0); - } - else { - ret = sys_getxattr(uname, attruname, rbuf +4, 0); + /* PBaranski fix */ + if (fd != -1) { + LOG(log_debug, logtype_afpd, "sys_get_easize(%s): file is already opened", uname); + ret = sys_fgetxattr(fd, attruname, rbuf +4, 0); + } else { + if ((oflag & O_NOFOLLOW) ) { + ret = sys_lgetxattr(uname, attruname, rbuf +4, 0); + } + else { + ret = sys_getxattr(uname, attruname, rbuf +4, 0); + } } + /* PBaranski fix */ + if (ret == -1) { memset(rbuf, 0, 4); @@ -100,14 +89,17 @@ int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE) switch(errno) { case OPEN_NOFOLLOW_ERRNO: /* its a symlink and client requested O_NOFOLLOW */ - LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): encountered symlink with kXAttrNoFollow", uname); - return AFP_OK; + LOG(log_debug, logtype_afpd, "sys_getextattr_size(%s): symlink with kXAttrNoFollow", uname); + return AFPERR_MISC; case ENOATTR: + case ENOENT: + if (vol->v_obj->afp_version >= 34) + return AFPERR_NOITEM; return AFPERR_MISC; default: - LOG(log_error, logtype_afpd, "sys_getextattr_size: error: %s", strerror(errno)); + LOG(log_debug, logtype_afpd, "sys_getextattr_size: error: %s", strerror(errno)); return AFPERR_MISC; } } @@ -141,7 +133,7 @@ int sys_get_easize(VFS_FUNC_ARGS_EA_GETSIZE) * oflag (r) link and create flag * attruname (r) name of attribute * maxreply (r) maximum EA size as of current specs/real-life - * + * fd (r) file descriptor * Returns: AFP code: AFP_OK on success or appropiate AFP error code * * Effects: @@ -162,27 +154,36 @@ int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT) LOG(log_debug7, logtype_afpd, "sys_getextattr_content(%s): attribute: \"%s\", size: %u", uname, attruname, maxreply); - if ((oflag & O_NOFOLLOW) ) { - ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply); - } - else { - ret = sys_getxattr(uname, attruname, rbuf +4, maxreply); + /* PBaranski fix */ + if (fd != -1) { + LOG(log_debug, logtype_afpd, "sys_get_eacontent(%s): file is already opened", uname); + ret = sys_fgetxattr(fd, attruname, rbuf +4, maxreply); + } else { + if ((oflag & O_NOFOLLOW) ) { + ret = sys_lgetxattr(uname, attruname, rbuf +4, maxreply); + } + else { + ret = sys_getxattr(uname, attruname, rbuf +4, maxreply); + } } - + /* PBaranski fix */ + if (ret == -1) { memset(rbuf, 0, 4); *rbuflen += 4; switch(errno) { case OPEN_NOFOLLOW_ERRNO: /* its a symlink and client requested O_NOFOLLOW */ - LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): encountered symlink with kXAttrNoFollow", uname); - return AFP_OK; + LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): symlink with kXAttrNoFollow", uname); + return AFPERR_MISC; case ENOATTR: + if (vol->v_obj->afp_version >= 34) + return AFPERR_NOITEM; return AFPERR_MISC; default: - LOG(log_error, logtype_afpd, "sys_getextattr_content(%s): error: %s", attruname, strerror(errno)); + LOG(log_debug, logtype_afpd, "sys_getextattr_content(%s): error: %s", attruname, strerror(errno)); return AFPERR_MISC; } } @@ -215,6 +216,8 @@ int sys_get_eacontent(VFS_FUNC_ARGS_EA_GETCONTENT) * * Copies names of all EAs of uname as consecutive C strings into rbuf. * Increments *rbuflen accordingly. + * We hide the adouble:ea extended attributes here, but we currently + * allow reading, writing and deleteting them. */ int sys_list_eas(VFS_FUNC_ARGS_EA_LIST) { @@ -222,57 +225,62 @@ int sys_list_eas(VFS_FUNC_ARGS_EA_LIST) int ret, len, nlen; char *buf; char *ptr; - + struct adouble ad, *adp; + buf = malloc(ATTRNAMEBUFSIZ); if (!buf) return AFPERR_MISC; - if ((oflag & O_NOFOLLOW)) { - ret = sys_llistxattr(uname, buf, ATTRNAMEBUFSIZ); - } - else { - ret = sys_listxattr(uname, buf, ATTRNAMEBUFSIZ); + /* PBaranski fix */ + if ( fd != -1) { + LOG(log_debug, logtype_afpd, "sys_list_eas(%s): file is already opened", uname); + ret = sys_flistxattr(fd, uname, buf, ATTRNAMEBUFSIZ); + } else { + if ((oflag & O_NOFOLLOW)) { + ret = sys_llistxattr(uname, buf, ATTRNAMEBUFSIZ); + } + else { + ret = sys_listxattr(uname, buf, ATTRNAMEBUFSIZ); + } } + /* PBaranski fix */ if (ret == -1) switch(errno) { case OPEN_NOFOLLOW_ERRNO: - /* its a symlink and client requested O_NOFOLLOW */ - ret = AFPERR_BADTYPE; - goto exit; -#ifdef HAVE_ATTROPEN /* Solaris */ - case ENOATTR: + /* its a symlink and client requested O_NOFOLLOW, we pretend 0 EAs */ + LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): symlink with kXAttrNoFollow", uname); ret = AFP_OK; goto exit; -#endif default: - LOG(log_error, logtype_afpd, "sys_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno)); - ret= AFPERR_MISC; + LOG(log_debug, logtype_afpd, "sys_list_extattr(%s): error opening atttribute dir: %s", uname, strerror(errno)); + ret = AFPERR_MISC; goto exit; } ptr = buf; while (ret > 0) { len = strlen(ptr); + if (NOT_NETATALK_EA(ptr)) { + /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */ + if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) { + ret = AFPERR_MISC; + goto exit; + } - /* Convert name to CH_UTF8_MAC and directly store in in the reply buffer */ - if ( 0 >= ( nlen = convert_string(vol->v_volcharset, CH_UTF8_MAC, ptr, len, attrnamebuf + attrbuflen, 256)) ) { - ret = AFPERR_MISC; - goto exit; - } - - LOG(log_debug7, logtype_afpd, "sys_list_extattr(%s): attribute: %s", uname, ptr); + LOG(log_debug7, logtype_afpd, "sys_list_extattr(%s): attribute: %s", uname, ptr); - attrbuflen += nlen + 1; - if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) { - /* Next EA name could overflow, so bail out with error. - FIXME: evantually malloc/memcpy/realloc whatever. - Is it worth it ? */ - LOG(log_warning, logtype_afpd, "sys_list_extattr(%s): running out of buffer for EA names", uname); - ret = AFPERR_MISC; - goto exit; + attrbuflen += nlen + 1; + if (attrbuflen > (ATTRNAMEBUFSIZ - 256)) { + /* Next EA name could overflow, so bail out with error. + FIXME: evantually malloc/memcpy/realloc whatever. + Is it worth it ? */ + LOG(log_warning, logtype_afpd, "sys_list_extattr(%s): running out of buffer for EA names", uname); + ret = AFPERR_MISC; + goto exit; + } } - ret -= len +1; - ptr += len +1; + ret -= len + 1; + ptr += len + 1; } ret = AFP_OK; @@ -314,26 +322,38 @@ int sys_set_ea(VFS_FUNC_ARGS_EA_SET) else if ((oflag & O_TRUNC) ) attr_flag |= XATTR_REPLACE; - if ((oflag & O_NOFOLLOW) ) { - ret = sys_lsetxattr(uname, attruname, ibuf, attrsize,attr_flag); - } - else { - ret = sys_setxattr(uname, attruname, ibuf, attrsize, attr_flag); + /* PBaranski fix */ + if ( fd != -1) { + LOG(log_debug, logtype_afpd, "sys_set_ea(%s): file is already opened", uname); + ret = sys_fsetxattr(fd, attruname, ibuf, attrsize, attr_flag); + } else { + if ((oflag & O_NOFOLLOW) ) { + ret = sys_lsetxattr(uname, attruname, ibuf, attrsize,attr_flag); + } + else { + ret = sys_setxattr(uname, attruname, ibuf, attrsize, attr_flag); + } } + /* PBaranski fix */ if (ret == -1) { switch(errno) { case OPEN_NOFOLLOW_ERRNO: /* its a symlink and client requested O_NOFOLLOW */ - LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): encountered symlink with kXAttrNoFollow", - getcwdpath(), uname, attruname); + LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s\", ea:'%s'): symlink with kXAttrNoFollow", + uname, attruname); return AFP_OK; case EEXIST: LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s'): EA already exists", getcwdpath(), uname, attruname); return AFPERR_EXIST; + case ENOATTR: + case ENOENT: + if ((attr_flag & XATTR_REPLACE) && (vol->v_obj->afp_version >= 34)) + return AFPERR_NOITEM; + return AFPERR_MISC; default: - LOG(log_error, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s', size: %u, flags: %s|%s|%s): %s", + LOG(log_debug, logtype_afpd, "sys_set_ea(\"%s/%s\", ea:'%s', size: %u, flags: %s|%s|%s): %s", getcwdpath(), uname, attruname, attrsize, oflag & O_CREAT ? "XATTR_CREATE" : "-", oflag & O_TRUNC ? "XATTR_REPLACE" : "-", @@ -357,6 +377,7 @@ int sys_set_ea(VFS_FUNC_ARGS_EA_SET) * uname (r) filename * attruname (r) EA name * oflag (r) link and create flag + * fd (r) file descriptor * * Returns: AFP code: AFP_OK on success or appropiate AFP error code * @@ -368,24 +389,28 @@ int sys_remove_ea(VFS_FUNC_ARGS_EA_REMOVE) { int ret; - if ((oflag & O_NOFOLLOW) ) { - ret = sys_lremovexattr(uname, attruname); - } - else { - ret = sys_removexattr(uname, attruname); + /* PBaranski fix */ + if ( fd != -1) { + LOG(log_debug, logtype_afpd, "sys_remove_ea(%s): file is already opened", uname); + ret = sys_fremovexattr(fd, uname, attruname); + } else { + if ((oflag & O_NOFOLLOW) ) { + ret = sys_lremovexattr(uname, attruname); + } + else { + ret = sys_removexattr(uname, attruname); + } } + /* PBaranski fix */ if (ret == -1) { switch(errno) { case OPEN_NOFOLLOW_ERRNO: /* its a symlink and client requested O_NOFOLLOW */ - LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): encountered symlink with kXAttrNoFollow", uname); + LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): symlink with kXAttrNoFollow", uname); return AFP_OK; - case EACCES: - LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): error: %s", uname, attruname, strerror(errno)); - return AFPERR_ACCESS; default: - LOG(log_error, logtype_afpd, "sys_remove_ea(%s/%s): error: %s", uname, attruname, strerror(errno)); + LOG(log_debug, logtype_afpd, "sys_remove_ea(%s/%s): error: %s", uname, attruname, strerror(errno)); return AFPERR_MISC; } } @@ -461,6 +486,9 @@ int sys_ea_copyfile(VFS_FUNC_ARGS_COPYFILE) if (!*name) continue; + if (STRCMP(name, ==, AD_EA_META)) + continue; + if (sfd != -1) { if (fchdir(sfd) == -1) { LOG(log_error, logtype_afpd, "sys_ea_copyfile: cant chdir to sfd: %s",