/*
 * Copyright (C) 2024 Olaf Wintermann <olaf.wintermann@gmail.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * anypurpose with or without fee is hereby granted.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef LIBXATTR_H
#define LIBXATTR_H

#include <sys/types.h>
#include <stdlib.h>

#ifdef __cplusplus
extern "C" {
#endif


/*
 * Platform specific notices
 *
 * Linux:
 * Only attributes from the user namespace can be accessed. Attribute names
 * returned by xattr_list() omit the 'user.' prefix.
 * The get/set/remove functions automatically add the 'user.' prefix to the
 * attribute name.
 * 
 * FreeBSD:
 * Only attributes from the EXTATTR_NAMESPACE_USER namespace can be accessed.
 *
 * Solaris:
 * The attribute names SUNWattr_ro and SUNWattr_rw are not listed by xattr_list.
 * 
 * macOS:
 * It just works.
 */


/*
 * Retrieves a list of attribute names associated with a given path.
 * The length of the returned array is stored in nelm.
 *
 * path:    File path
 * nelm:    Pointer to a variable to store the number of attributes in the list
 * Returns: Dynamically allocated array of strings containing the
 *          attribute names or NULL if an error occurs.
 *          The returned array must be manually freed using xattr_free_list().
 */
char ** xattr_list(const char *path, ssize_t *nelm);

/*
 * Retrieves the value of a specific attribute and its length.
 * The value is guaranteed to be null-terminated for convenience, but the
 * length stored in len excludes the null terminator.
 *
 * The value is dynamically allocated and must be manually freed.
 *
 * path:    File path
 * attr:    Attribute name
 * len      Pointer to a variable to store the length of the value
 *          (without terminating 0-byte)
 * Returns: Dynamically allocated buffer containing the attribute value
 *          or NULL if an error occurs.
 *          The buffer must be manually freed using free().
 */
char * xattr_get(const char *path, const char *attr, ssize_t *len);

/*
 * Sets an attribute value.
 *
 * path:    File path
 * name:    Attribute name
 * value:   The attribute value, that should be stored
 * len:     Size of the value in bytes
 * Returns: 0 on success, -1 on error
 */
int xattr_set(const char *path, const char *name, const void *value, size_t len);

/*
 * Removes an attribute
 *
 * path:    file path
 * name:    attribute name
 * Returns: 0 on success, -1 on error
 */
int xattr_remove(const char *path, const char *name);

/*
 * Frees an attribute name list, returned by xattr_list.
 */
void xattr_free_list(char **attrnames, ssize_t nelm);

#ifdef __cplusplus
}
#endif

#endif /* LIBXATTR_H */

