From: Richard D. <ric...@us...> - 2006-10-02 20:27:16
|
Update of /cvsroot/file-extattr/File-ExtAttr In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv25949 Modified Files: extattr_linux.c Log Message: Linux *listxattr with namespace awareness Index: extattr_linux.c =================================================================== RCS file: /cvsroot/file-extattr/File-ExtAttr/extattr_linux.c,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** extattr_linux.c 2 Oct 2006 20:05:22 -0000 1.6 --- extattr_linux.c 2 Oct 2006 20:27:13 -0000 1.7 *************** *** 74,92 **** { char *res = NULL; ! char *ns; size_t reslen; ! ns = flags2namespace(flags); ! if (ns) { ! reslen = strlen(ns) + strlen(attrname) + 2; /* ns + "." + attrname + nul */ res = malloc(reslen); } if (res) ! snprintf(res, reslen, "%s.%s", ns, attrname); ! if (ns) ! free(ns); return res; --- 74,92 ---- { char *res = NULL; ! char *pNS; size_t reslen; ! pNS = flags2namespace(flags); ! if (pNS) { ! reslen = strlen(pNS) + strlen(attrname) + 2; /* pNS + "." + attrname + nul */ res = malloc(reslen); } if (res) ! snprintf(res, reslen, "%s.%s", pNS, attrname); ! if (pNS) ! free(pNS); return res; *************** *** 261,305 **** } - ssize_t - linux_listxattr (const char *path, - char *buf, - const size_t buflen, - struct hv *flags) - { - #if 0 - /* XXX: We need some kind of hash returned here: { namespace => attrname } */ - int ret; - char *q; - - /* XXX: Other flags? */ - q = qualify_attrname(attrname, flags); - if (q) - { - ret = listxattr(path, buf, buflen); - free(q); - } - else - { - ret = -1; - errno = ENOMEM; - } - - return ret; - #else - return listxattr(path, buf, buflen); - #endif - } - - ssize_t - linux_flistxattr (const int fd, - char *buf, - const size_t buflen, - struct hv *flags) - { - return flistxattr(fd, buf, buflen); - } - static ssize_t ! attrlist2nslist (char *sbuf, const size_t slen, char *buf, const size_t buflen) { ssize_t sbuiltlen = 0; --- 261,268 ---- } static ssize_t ! attrlist2list (char *sbuf, const size_t slen, ! char *buf, const size_t buflen, ! const int iWantNames, const char *pWantNS) { ssize_t sbuiltlen = 0; *************** *** 309,328 **** for (spos = 0; (spos < slen); ) { ! char *pns, *pval; /* Get the namespace. */ ! pns = &sbuf[spos]; ! pval = strchr(pns, '.'); ! if (!pval) break; /* Point spos at the next attribute. */ ! spos += strlen(pval) + 1; ! /* Check we haven't already seen this namespace. */ ! *pval = '\0'; ! ++pval; ! if (memstr(sbuf, pns, sbuiltlen) != NULL) ! continue; /* --- 272,308 ---- for (spos = 0; (spos < slen); ) { ! char *pNS, *pname, *psrc; /* Get the namespace. */ ! pNS = &sbuf[spos]; ! pname = strchr(pNS, '.'); ! if (!pname) break; /* Point spos at the next attribute. */ ! spos += strlen(pNS) + 1; ! *pname = '\0'; ! ++pname; ! ! if (iWantNames) ! { ! psrc = pname; ! ! /* Name list wanted. Check this is in the right namespace. */ ! if (strcmp(pNS, pWantNS) != 0) ! continue; ! } ! else ! { ! psrc = pNS; ! ! /* ! * Namespace list wanted. Check we haven't already seen ! * this namespace. ! */ ! if (memstr(sbuf, pNS, sbuiltlen) != NULL) ! continue; ! } /* *************** *** 331,336 **** * We shift the namespaces from the list to the start of the buffer. */ ! memmove(&sbuf[sbuiltlen], pns, strlen(pns) + 1 /* nul */); ! sbuiltlen += strlen(pns) + 1; } --- 311,316 ---- * We shift the namespaces from the list to the start of the buffer. */ ! memmove(&sbuf[sbuiltlen], psrc, strlen(psrc) + 1 /* nul */); ! sbuiltlen += strlen(psrc) + 1; } *************** *** 354,358 **** --- 334,450 ---- } + /* XXX: More common code below */ /* XXX: Just return a Perl list? */ + + ssize_t + linux_listxattr (const char *path, + char *buf, + const size_t buflen, + struct hv *flags) + { + char *pNS; + ssize_t ret = 0; + + pNS = flags2namespace(flags); + if (!pNS) + { + ret = -1; + errno = ENOMEM; + } + + /* + * Get a buffer of nul-delimited "namespace.attribute"s, + * then extract the attributes into buf. + */ + if (ret == 0) + { + ssize_t slen; + + slen = listxattr(path, buf, 0); + if (slen >= 0) + { + char *sbuf; + + sbuf = malloc(slen); + if (sbuf) + slen = listxattr(path, sbuf, slen); + else + ret = -1; + + if (slen) + ret = attrlist2list(sbuf, slen, buf, buflen, 1, pNS); + else + ret = slen; + + if (sbuf) + free(sbuf); + } + else + { + ret = slen; + } + } + + if (pNS) + free(pNS); + + return ret; + } + + ssize_t + linux_flistxattr (const int fd, + char *buf, + const size_t buflen, + struct hv *flags) + { + char *pNS; + ssize_t ret = 0; + + pNS = flags2namespace(flags); + if (!pNS) + { + ret = -1; + errno = ENOMEM; + } + + /* + * Get a buffer of nul-delimited "namespace.attribute"s, + * then extract the attributes into buf. + */ + if (ret == 0) + { + ssize_t slen; + + slen = flistxattr(fd, buf, 0); + if (slen >= 0) + { + char *sbuf; + + sbuf = malloc(slen); + if (sbuf) + slen = flistxattr(fd, sbuf, slen); + else + ret = -1; + + if (slen) + ret = attrlist2list(sbuf, slen, buf, buflen, 1, pNS); + else + ret = slen; + + if (sbuf) + free(sbuf); + } + else + { + ret = slen; + } + } + + if (pNS) + free(pNS); + + return ret; + } + ssize_t linux_listxattrns (const char *path, *************** *** 380,384 **** if (slen) ! ret = attrlist2nslist(sbuf, slen, buf, buflen); else ret = slen; --- 472,476 ---- if (slen) ! ret = attrlist2list(sbuf, slen, buf, buflen, 0, NULL); else ret = slen; *************** *** 420,424 **** if (slen) ! ret = attrlist2nslist(sbuf, slen, buf, buflen); else ret = slen; --- 512,516 ---- if (slen) ! ret = attrlist2list(sbuf, slen, buf, buflen, 0, NULL); else ret = slen; |