/* Filename: extattr.h Simple routines for dealing with extended attributes on OS X and FreeBSD https://github.com/bfoz/pocket/blob/3978b7461cf5f46ce394adc6b7000c17f96af639/extattr.h Created June 19, 2005 Brandon Fosdick */ #ifndef XATTR_H #define XATTR_H #if defined(__APPLE__) && defined(__MACH__) #include #endif #if defined(__linux__) /* #include */ #include #endif #if defined(__FreeBSD__) #include #endif #include #include typedef std::pair ext_attr_t; typedef std::vector attr_names_t; typedef std::vector ext_attrs_t; /* inline int setxattr(int fd, const std::string &name, const std::string &value, int options=0) { #if defined(__APPLE__) && defined(__MACH__) return fsetxattr(fd, name.c_str(), value.data(), value.length(), 0, options); #endif #if defined(__linux__) return fsetxattr(fd, name.c_str(), value.data(), value.length(), 0); #endif #if defined(__FreeBSD__) return extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, name.c_str(), value.data(), value.length()); #endif } */ inline int setxattr(const std::string path, const std::string &name, const std::string &value, int options=0) { #if defined(__APPLE__) && defined(__MACH__) return setxattr(path.c_str(), name.c_str(), value.data(), value.length(), 0, options); #endif #if defined(__linux__) /* By default (i.e., options flags is zero), the extended attribute will be * created if it does not exist, or the value will be replaced if the attribute exists.*/ if (options == 0){ return setxattr(path.c_str(), name.c_str(), value.data(), value.length(), 0); } else { return lsetxattr(path.c_str(), name.c_str(), value.data(), value.length(), 0); } #endif #if defined(__FreeBSD__) return extattr_set_file(path.c_str(), EXTATTR_NAMESPACE_USER, name.c_str(), value.data(), value.length()); #endif } inline ssize_t getxattrsize(const std::string path, const std::string &name, int options=0) { #if defined(__APPLE__) && defined(__MACH__) return getxattr(path.c_str(), name.c_str(), NULL, 0, 0, options); #endif #if defined(__linux__) if (options == 0){ return getxattr(path.c_str(), name.c_str(), NULL, 0); } else{ return lgetxattr(path.c_str(), name.c_str(), NULL, 0); } #endif #if defined(__FreeBSD__) return extattr_get_file(path.c_str(), EXTATTR_NAMESPACE_USER, name.c_str(), NULL, 0); #endif } inline std::string getxattr(const std::string path, const std::string &name, int options=0) { ssize_t size = getxattrsize(path, name, options); char *buf; if( size <= 0 ) return ""; buf = new char[size]; #if defined(__APPLE__) && defined(__MACH__) getxattr(path.c_str(), name.c_str(), buf, size, 0, options); #endif #if defined(__linux__) if (options == 0){ getxattr(path.c_str(), name.c_str(), buf, size); } else{ lgetxattr(path.c_str(), name.c_str(), buf, size); } #endif #if defined(__FreeBSD__) extattr_get_file(path.c_str(), EXTATTR_NAMESPACE_USER, name.c_str(), buf, size); #endif return std::string(buf, size); } // ***** List attributes // Return the size of the list of extended attributes inline ssize_t listxattrsize(const std::string path, int options=0) { #if defined(__APPLE__) && defined(__MACH__) return listxattr(path.c_str(), NULL, 0, options); #endif #if defined(__linux__) if (options == 0){ return listxattr(path.c_str(), NULL, 0); } else{ return llistxattr(path.c_str(), NULL, 0); } #endif #if defined(__FreeBSD__) return extattr_list_file(path.c_str(), EXTATTR_NAMESPACE_USER, NULL, 0); #endif } //Read the extended attributes into one long string // *** The FreeBSD version returns an array of [length, data] // *** The OS X Tiger version returns an array of null terminated strings inline size_t _listxattr(const std::string path, char *buf, const size_t size, int options=0) { #if defined(__APPLE__) && defined(__MACH__) return listxattr(path.c_str(), buf, size, options); #endif #if defined(__linux__) if (options == 0){ return listxattr(path.c_str(), buf, size); } else{ return llistxattr(path.c_str(), buf, size); } #endif #if defined(__FreeBSD__) return extattr_list_file(path.c_str(), EXTATTR_NAMESPACE_USER, buf, size); #endif } #define MIN(a,b) ((a " << names.size() << std::endl; for(attr_names_t::iterator i = names.begin(); i != names.end(); ++i) { s = getxattr(path, (*i)); // std::cout << (*i) << " => " << s << std::endl; attrs.push_back(ext_attr_t((*i), s)); } return attrs; } #endif