/* * Copyright (C) 2006 James Antill * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * email: james@and.org */ /* These are the base functions for most of the the xattr_*.c higher level * abstractions */ #define _GNU_SOURCE 1 /* make sure we have strdup() */ #include "xattrs.h" #include Xattrs *xattr_make(void) { Xattrs *ret = NULL; if (!(ret = malloc(sizeof(Xattrs)))) return (NULL); ret->num = 0; ret->sz = 2; if (!(ret->ents = malloc(sizeof(Xattr_node) * ret->sz))) { free(ret); return (NULL); } return (ret); } static void xattr__free(Xattr_node *xattr) { free(xattr->key); free(xattr->val); } void xattr_free(Xattrs *xattrs) { unsigned int scan = 0; if (!xattrs) return; while (scan < xattrs->num) { xattr__free(xattrs->ents + scan); ++scan; } free(xattrs->ents); free(xattrs); } static void *xzmemdup(const void *ptr, size_t len) { /* always keeps a 0 at the end... */ void *ret = NULL; if (!(ret = malloc(len+1))) return (NULL); memcpy(ret, ptr, len); ((char*)ret)[len] = 0; return (ret); } int xattr_add(Xattrs *xattrs, const char *key, const char *val, size_t vsz) { Xattr_node *node = NULL; if (xattrs->num >= xattrs->sz) { size_t sz = xattrs->sz << 1; if (!(node = realloc(xattrs->ents, sizeof(Xattr_node) * sz))) return (0); xattrs->ents = node; xattrs->sz = sz; } node = xattrs->ents + xattrs->num; node->key = strdup(key); node->val = xzmemdup(val, vsz); node->vsz = vsz; if (!node->key || !node->val) { free(node->key); free(node->val); return (0); } xattrs->num += 1; return (1); } int xattr_del(Xattrs *xattrs, size_t num) { if (num > xattrs->num) return (0); --num; xattr__free(xattrs->ents + num); --xattrs->num; if (num != xattrs->num) memmove(xattrs->ents + num, xattrs->ents + num + 1, (xattrs->num - num) * sizeof(Xattr_node)); return (1); } int xattr_srch_key(Xattrs *xattrs, const char *key) { size_t scan = 0; while (scan < xattrs->num) { if (!strcmp(key, xattrs->ents[scan].key)) return (scan + 1); ++scan; } return (0); }