/* * Function: sys_set_ea * * Purpose: set a native EA * * Arguments: * * vol (r) current volume * uname (r) filename * attruname (r) EA name * ibuf (r) buffer with EA content * attrsize (r) length EA in ibuf * oflag (r) link and create flag * * Returns: AFP code: AFP_OK on success or appropiate AFP error code * * Effects: * */ int sys_set_ea(VFS_FUNC_ARGS_EA_SET) { int attr_flag; int ret; char *eabuf; /* * Buffer for a copy of the xattr plus one byte in case * AFPVOL_EA_SAMBA is used */ eabuf = malloc(attrsize + 1); if (eabuf == NULL) { return AFPERR_MISC; } memcpy(eabuf, ibuf, attrsize); eabuf[attrsize] = 0; attr_flag = 0; if ((oflag & O_CREAT) ) attr_flag |= XATTR_CREATE; else if ((oflag & O_TRUNC) ) attr_flag |= XATTR_REPLACE; if (vol->v_flags & AFPVOL_EA_SAMBA) { attrsize++; } /* PBaranski fix */ if ( fd != -1) { LOG(log_debug, logtype_afpd, "sys_set_ea(%s): file is already opened", uname); ret = sys_fsetxattr(fd, attruname, eabuf, attrsize, attr_flag); } else { if ((oflag & O_NOFOLLOW) ) { ret = sys_lsetxattr(uname, attruname, eabuf, attrsize,attr_flag); } else { ret = sys_setxattr(uname, attruname, eabuf, 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\", 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_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" : "-", oflag & O_NOFOLLOW ? "O_NOFOLLOW" : "-", strerror(errno)); return AFPERR_MISC; } } return AFP_OK; }
int vfswrap_fsetxattr(struct vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, const void *value, size_t size, int flags) { return sys_fsetxattr(fd, name, value, size, flags); }