コード例 #1
0
ファイル: _obnammodule.c プロジェクト: hsivonen/obnam
static PyObject *
llistxattr_wrapper(PyObject *self, PyObject *args)
{
    const char *filename;
    size_t bufsize;
    PyObject *o;
    char* buf;
    ssize_t n;

    if (!PyArg_ParseTuple(args, "s", &filename))
        return NULL;

#ifdef __FreeBSD__
    bufsize = extattr_list_link(filename, EXTATTR_NAMESPACE_USER, NULL, 0);
    buf = malloc(bufsize);
    if (buf == NULL) {
        Py_INCREF(Py_None);
        return Py_None;
    }
    n = extattr_list_link(filename, EXTATTR_NAMESPACE_USER, buf, bufsize);
    if (n >= 0) {
         /* Convert from length-prefixed BSD style to '\0'-suffixed
            Linux style. */
         size_t i = 0;
         while (i < n) {
             unsigned char length = (unsigned char) buf[i];
             memmove(buf + i, buf + i + 1, length);
             buf[i + length] = '\0';
             i += length + 1;
         }
         o = Py_BuildValue("s#", buf, (int) n);
    } else {
         o = Py_BuildValue("i", errno);
    }
    free(buf);
#else
    bufsize = 0;
    o = NULL;
    do {
        bufsize += 1024;
        buf = malloc(bufsize);
        if (buf == NULL) {
            Py_INCREF(Py_None);
            return Py_None;
        }
        n = llistxattr(filename, buf, bufsize);

        if (n >= 0)
            o = Py_BuildValue("s#", buf, (int) n);
        else if (n == -1 && errno != ERANGE)
            o = Py_BuildValue("i", errno);
        free(buf);
    } while (o == NULL);
#endif
    return o;
}
コード例 #2
0
ファイル: extattr.c プロジェクト: Netatalk/test-suite
static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
{
	ssize_t list_size;
	int i, len;

    switch(type) {
#if defined(HAVE_EXTATTR_LIST_FILE)
    case 0:
        list_size = extattr_list_file(arg.path, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
#if defined(HAVE_EXTATTR_LIST_LINK)
    case 1:
        list_size = extattr_list_link(arg.path, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
#if defined(HAVE_EXTATTR_LIST_FD)
    case 2:
        list_size = extattr_list_fd(arg.filedes, EXTATTR_NAMESPACE_USER, list, size);
        break;
#endif
    default:
        errno = ENOSYS;
        return -1;
    }

    /* Some error happend. Errno should be set by the previous call */
    if(list_size < 0)
        return -1;

    /* No attributes */
    if(list_size == 0)
        return 0;

    /* XXX: Call with an empty buffer may be used to calculate
       necessary buffer size. Unfortunately, we can't say, how
       many attributes were returned, so here is the potential
       problem with the emulation.
    */
    if(list == NULL)
        return list_size;

    /* Buffer is too small to fit the results */
    if(list_size > size) {
        errno = ERANGE;
        return -1;
    }

    /* Convert from pascal strings to C strings */
    len = list[0];
    memmove(list, list + 1, list_size);

    for(i = len; i < list_size; ) {
        len = list[i];
        list[i] = '\0';
        i += len + 1;
    }

	return list_size;
}
コード例 #3
0
ファイル: sysxattrs.c プロジェクト: JevonQ/rsync
ssize_t sys_llistxattr(const char *path, char *list, size_t size)
{
	unsigned char keylen;
	ssize_t off, len = extattr_list_link(path, EXTATTR_NAMESPACE_USER, list, size);

	if (len <= 0 || (size_t)len > size)
		return len;

	/* FreeBSD puts a single-byte length before each string, with no '\0'
	 * terminator.  We need to change this into a series of null-terminted
	 * strings.  Since the size is the same, we can simply transform the
	 * output in place. */
	for (off = 0; off < len; off += keylen + 1) {
		keylen = ((unsigned char*)list)[off];
		if (off + keylen >= len) {
			/* Should be impossible, but kernel bugs happen! */
			errno = EINVAL;
			return -1;
		}
		memmove(list+off, list+off+1, keylen);
		list[off+keylen] = '\0';
	}

	return len;
}
コード例 #4
0
ファイル: xattr.c プロジェクト: EmisFR/burp
int has_xattr(const char *path)
{
	int i=0;
	for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++)
	{
		if(extattr_list_link(path, namespaces[i], NULL, 0)>0)
			return 1;
	}
	return 0;
}
コード例 #5
0
/*
   @param flag          Bitfield for control purposes
                        bit5=  in case of symbolic link: inquire link target
*/
static int aaip_extattr_make_list(char *path, int attrnamespace,
                                  char **list, ssize_t *list_size, int flag)
{
 *list= NULL;
 *list_size= 0;

 /* man 2 extattr_list_file:
    If data is NULL in a call to extattr_get_file() and extattr_list_file()
    then the size of defined extended attribute data will be returned,
 */
 if(flag & 32) /* follow link */
   *list_size= extattr_list_file(path, attrnamespace, NULL, (size_t) 0);
 else
   *list_size= extattr_list_link(path, attrnamespace, NULL, (size_t) 0);
 if(*list_size == -1) {
   if(! aaip_extattr_path_supp(path, 0)) {
     *list_size = 0;
     return(2);
   }
   return(0);
 }
 if(*list_size == 0)
   return(2);
 *list= calloc(*list_size, 1);
 if(*list == NULL)
   return(-1);
 if(flag & 32)
   *list_size= extattr_list_file(path, attrnamespace, *list,
                                 (size_t) *list_size);
 else
   *list_size= extattr_list_link(path, attrnamespace, *list,
                                 (size_t) *list_size);
 if(*list_size == -1)
   return(0);
 return(1);
}
コード例 #6
0
ファイル: lib_build.c プロジェクト: xattr/xattr
static ssize_t xattr_listxattr(const char *path, char *namebuf,
                               size_t size, int options)
{
    ssize_t rv = 0;
    if (!(options == 0 ||
          options == XATTR_XATTR_NOFOLLOW)) {
        return -1;
    }

    if (options & XATTR_XATTR_NOFOLLOW) {
        rv = extattr_list_link(path, EXTATTR_NAMESPACE_USER, namebuf, size);
    }
    else {
        rv = extattr_list_file(path, EXTATTR_NAMESPACE_USER, namebuf, size);
    }

    if (rv > 0 && namebuf) {
        convert_bsd_list(namebuf, rv);
    }

    return rv;
}
コード例 #7
0
int
main(int argc, char *argv[])
{
	char	*buf, *visbuf, *p;

	const char *options, *attrname;
	size_t	len;
	ssize_t	ret;
	int	 buflen, visbuflen, ch, error, i, arg_counter, attrnamespace,
		 minargc;

	int	flag_force = 0;
	int	flag_nofollow = 0;
	int	flag_null = 0;
	int	flag_quiet = 0;
	int	flag_string = 0;
	int	flag_hex = 0;

	visbuflen = buflen = 0;
	visbuf = buf = NULL;

	p = basename(argv[0]);
	if (p == NULL)
		p = argv[0];
	if (!strcmp(p, "getextattr")) {
		what = EAGET;
		options = "fhqsx";
		minargc = 3;
	} else if (!strcmp(p, "setextattr")) {
		what = EASET;
		options = "fhnq";
		minargc = 4;
	} else if (!strcmp(p, "rmextattr")) {
		what = EARM;
		options = "fhq";
		minargc = 3;
	} else if (!strcmp(p, "lsextattr")) {
		what = EALS;
		options = "fhq";
		minargc = 2;
	} else {
		usage();
	}

	while ((ch = getopt(argc, argv, options)) != -1) {
		switch (ch) {
		case 'f':
			flag_force = 1;
			break;
		case 'h':
			flag_nofollow = 1;
			break;
		case 'n':
			flag_null = 1;
			break;
		case 'q':
			flag_quiet = 1;
			break;
		case 's':
			flag_string = 1;
			break;
		case 'x':
			flag_hex = 1;
			break;
		case '?':
		default:
			usage();
		}
	}

	argc -= optind;
	argv += optind;

	if (argc < minargc)
		usage();

	error = extattr_string_to_namespace(argv[0], &attrnamespace);
	if (error)
		err(-1, "%s", argv[0]);
	argc--; argv++;

	if (what != EALS) {
		attrname = argv[0];
		argc--; argv++;
	} else
		attrname = NULL;

	if (what == EASET) {
		mkbuf(&buf, &buflen, strlen(argv[0]) + 1);
		strcpy(buf, argv[0]);
		argc--; argv++;
	}

	for (arg_counter = 0; arg_counter < argc; arg_counter++) {
		switch (what) {
		case EARM:
			if (flag_nofollow)
				error = extattr_delete_link(argv[arg_counter],
				    attrnamespace, attrname);
			else
				error = extattr_delete_file(argv[arg_counter],
				    attrnamespace, attrname);
			if (error >= 0)
				continue;
			break;
		case EASET:
			len = strlen(buf) + flag_null;
			if (flag_nofollow)
				ret = extattr_set_link(argv[arg_counter],
				    attrnamespace, attrname, buf, len);
			else
				ret = extattr_set_file(argv[arg_counter],
				    attrnamespace, attrname, buf, len);
			if (ret >= 0) {
				if ((size_t)ret != len && !flag_quiet) {
					warnx("Set %zd bytes of %zu for %s",
					    ret, len, attrname);
				}
				continue;
			}
			break;
		case EALS:
			if (flag_nofollow)
				ret = extattr_list_link(argv[arg_counter],
				    attrnamespace, NULL, 0);
			else
				ret = extattr_list_file(argv[arg_counter],
				    attrnamespace, NULL, 0);
			if (ret < 0)
				break;
			mkbuf(&buf, &buflen, ret);
			if (flag_nofollow)
				ret = extattr_list_link(argv[arg_counter],
				    attrnamespace, buf, buflen);
			else
				ret = extattr_list_file(argv[arg_counter],
				    attrnamespace, buf, buflen);
			if (ret < 0)
				break;
			if (!flag_quiet)
				printf("%s\t", argv[arg_counter]);
			for (i = 0; i < ret; i += ch + 1) {
			    /* The attribute name length is unsigned. */
			    ch = (unsigned char)buf[i];
			    printf("%s%*.*s", i ? "\t" : "",
				ch, ch, buf + i + 1);
			}
			if (!flag_quiet || ret > 0)
				printf("\n");
			continue;
		case EAGET:
			if (flag_nofollow)
				ret = extattr_get_link(argv[arg_counter],
				    attrnamespace, attrname, NULL, 0);
			else
				ret = extattr_get_file(argv[arg_counter],
				    attrnamespace, attrname, NULL, 0);
			if (ret < 0)
				break;
			mkbuf(&buf, &buflen, ret);
			if (flag_nofollow)
				ret = extattr_get_link(argv[arg_counter],
				    attrnamespace, attrname, buf, buflen);
			else
				ret = extattr_get_file(argv[arg_counter],
				    attrnamespace, attrname, buf, buflen);
			if (ret < 0)
				break;
			if (!flag_quiet)
				printf("%s\t", argv[arg_counter]);
			if (flag_string) {
				mkbuf(&visbuf, &visbuflen, ret * 4 + 1);
				strvisx(visbuf, buf, ret,
				    VIS_SAFE | VIS_WHITE);
				printf("\"%s\"\n", visbuf);
				continue;
			} else if (flag_hex) {
				for (i = 0; i < ret; i++)
					printf("%s%02x", i ? " " : "",
					    buf[i]);
				printf("\n");
				continue;
			} else {
				fwrite(buf, ret, 1, stdout);
				printf("\n");
				continue;
			}
		default:
			break;
		}
		if (!flag_quiet) 
			warn("%s: failed", argv[arg_counter]);
		if (flag_force)
			continue;
		return(1);
	}
	return (0);
}
コード例 #8
0
ファイル: xattr.c プロジェクト: EmisFR/burp
int get_xattr(struct asfd *asfd, const char *path,
	char **xattrtext, size_t *xlen, struct cntr *cntr)
{
	int i=0;
	ssize_t maxlen=0xFFFFFFFF/2;

	for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++)
	{
		int j=0;
		ssize_t len=0;
		int have_acl=0;
		char *xattrlist=NULL;
		char *cnamespace=NULL;
		ssize_t totallen=0;
		char *toappend=NULL;
		char z[BSD_BUF_SIZE]="";
		char cattrname[BSD_BUF_SIZE]="";
		if((len=extattr_list_link(path, namespaces[i], NULL, 0))<0)
		{
			logw(asfd, cntr, "could not extattr_list_link of '%s': %zd\n",
				path, len);
			return 0; // carry on
		}
		if(!len) continue;
		if(xattrtext && *xattrtext)
		{
			// Already have some meta text, which means that some
			// ACLs were set.
			have_acl++;
		}
		if(!(xattrlist=(char *)calloc_w(1, len+1, __func__)))
			return -1;
		if((len=extattr_list_link(path, namespaces[i], xattrlist, len))<=0)
		{
			logw(asfd, cntr, "could not extattr_list_link '%s': %zd\n",
				path, len);
			free_w(&xattrlist);
			return 0; // carry on
		}
		xattrlist[len]='\0';

		if(extattr_namespace_to_string(namespaces[i], &cnamespace))
		{
			logp("Failed to convert %d into namespace on '%s'\n",
				 namespaces[i], path);
			free_w(&xattrlist);
			return 0; // carry on
		}


		for(j=0; j<(int)len; j+=xattrlist[j]+1)
		{
			int cnt=0;
			char tmp1[9];
			char tmp2[9];
			size_t newlen=0;
			size_t zlen=0;
			ssize_t vlen=0;
			char *val=NULL;
			cnt=xattrlist[j];
			if(cnt>((int)sizeof(cattrname)-1))
				cnt=((int)sizeof(cattrname)-1);
			strncpy(cattrname, xattrlist+(j+1), cnt);
			cattrname[cnt]='\0';
			snprintf(z, sizeof(z), "%s.%s",
				cnamespace, cattrname);

			if(have_acl && in_skiplist(z))
				continue;
			zlen=strlen(z);
			//printf("\ngot: %s (%s)\n", z, path);

			if((vlen=extattr_list_link(path, namespaces[i],
				xattrlist, len))<0)
			{
				logw(asfd, cntr, "could not extattr_list_link on %s for %s: %zd\n", path, cnamespace, vlen);
				continue;
			}
			if(vlen)
			{
				if(!(val=(char *)malloc_w(vlen+1, __func__)))
				{
					free_w(&xattrlist);
					free_w(&toappend);
					return -1;
				}
				if((vlen=extattr_get_link(path, namespaces[i],
					cattrname, val, vlen))<0)
				{
					logw(asfd, cntr, "could not extattr_list_link %s for %s: %zd\n", path, cnamespace, vlen);
					free_w(&val);
					continue;
				}
				val[vlen]='\0';

				if(vlen>maxlen)
				{
					logw(asfd, cntr, "xattr value of '%s' too long: %zd\n",
						path, vlen);
					free_w(&toappend);
					free_w(&val);
					break;
				}
			}

			snprintf(tmp1, sizeof(tmp1), "%08X", (unsigned int)zlen);
			snprintf(tmp2, sizeof(tmp2), "%08X", (unsigned int)vlen);
			newlen=totallen+8+zlen+8+vlen;
			if(!(toappend=(char *)realloc_w(toappend, newlen, __func__)))
			{
				free_w(&val);
				free_w(&xattrlist);
				return -1;
			}
			memcpy(toappend+totallen, tmp1, 8);
			totallen+=8;
			memcpy(toappend+totallen, z, zlen);
			totallen+=zlen;
			memcpy(toappend+totallen, tmp2, 8);
			totallen+=8;
			memcpy(toappend+totallen, val, vlen);
			totallen+=vlen;
			free_w(&val);

			if(totallen>maxlen)
			{
				logw(asfd, cntr,
				  "xattr length of '%s' grew too long: %lu\n",
				  path, (unsigned long)totallen);
				free_w(&val);
				free_w(&toappend);
				free_w(&xattrlist);
				return 0; // carry on
			}
		}

		if(toappend)
		{
			if(append_to_extrameta(toappend, META_XATTR_BSD,
				xattrtext, xlen, totallen))
			{
				free_w(&toappend);
				free_w(&xattrlist);
				return -1;
			}
		}
		free_w(&toappend);
		free_w(&xattrlist);
	}

	return 0;
}
コード例 #9
0
ファイル: xattr.c プロジェクト: rchicoli/samba
static ssize_t bsd_attr_list (int type, extattr_arg arg, char *list, size_t size)
{
	ssize_t list_size, total_size = 0;
	int i, t, len;
	char *buf;
	/* Iterate through extattr(2) namespaces */
	for(t = 0; t < ARRAY_SIZE(extattr); t++) {
		if (t != EXTATTR_NAMESPACE_USER && geteuid() != 0) {
			/* ignore all but user namespace when we are not root, see bug 10247 */
			continue;
		}
		switch(type) {
#if defined(HAVE_EXTATTR_LIST_FILE)
			case 0:
				list_size = extattr_list_file(arg.path, extattr[t].space, list, size);
				break;
#endif
#if defined(HAVE_EXTATTR_LIST_LINK)
			case 1:
				list_size = extattr_list_link(arg.path, extattr[t].space, list, size);
				break;
#endif
#if defined(HAVE_EXTATTR_LIST_FD)
			case 2:
				list_size = extattr_list_fd(arg.filedes, extattr[t].space, list, size);
				break;
#endif
			default:
				errno = ENOSYS;
				return -1;
		}
		/* Some error happend. Errno should be set by the previous call */
		if(list_size < 0)
			return -1;
		/* No attributes */
		if(list_size == 0)
			continue;
		/* XXX: Call with an empty buffer may be used to calculate
		   necessary buffer size. Unfortunately, we can't say, how
		   many attributes were returned, so here is the potential
		   problem with the emulation.
		*/
		if(list == NULL) {
			/* Take the worse case of one char attribute names - 
			   two bytes per name plus one more for sanity.
			*/
			total_size += list_size + (list_size/2 + 1)*extattr[t].len;
			continue;
		}
		/* Count necessary offset to fit namespace prefixes */
		len = 0;
		for(i = 0; i < list_size; i += list[i] + 1)
			len += extattr[t].len;

		total_size += list_size + len;
		/* Buffer is too small to fit the results */
		if(total_size > size) {
			errno = ERANGE;
			return -1;
		}
		/* Shift results back, so we can prepend prefixes */
		buf = (char *)memmove(list + len, list, list_size);

		for(i = 0; i < list_size; i += len + 1) {
			len = buf[i];
			strncpy(list, extattr[t].name, extattr[t].len + 1);
			list += extattr[t].len;
			strncpy(list, buf + i + 1, len);
			list[len] = '\0';
			list += len + 1;
		}
		size -= total_size;
	}
	return total_size;
}
コード例 #10
0
ファイル: xattr.c プロジェクト: Kalimeiro/burp
int get_xattr(const char *path, struct stat *statp,
	char **xattrtext, size_t *xlen, struct conf *conf)
{
	int i=0;
	size_t maxlen=0xFFFFFFFF/2;

	for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++)
	{
		int j=0;
		size_t len=0;
		int have_acl=0;
		char *xattrlist=NULL;
		char *cnamespace=NULL;
		size_t totallen=0;
		char *toappend=NULL;
		char ctuple[BSD_BUF_SIZE]="";
		char cattrname[BSD_BUF_SIZE]="";
		if((len=extattr_list_link(path, namespaces[i], NULL, 0))<0)
		{
			logw(conf, "could not extattr_list_link of '%s': %d\n",
				path, len);
			return 0; // carry on
		}
		if(!len) continue;
		if(xattrtext && *xattrtext)
		{
			// Already have some meta text, which means that some
			// ACLs were set.
			have_acl++;
		}
		if(!(xattrlist=(char *)malloc(len+1)))
		{
			log_out_of_memory(__func__);
			return -1;
		}
		memset(xattrlist, 0, len+1);
		if((len=extattr_list_link(path, namespaces[i], xattrlist, len))<=0)
		{
			logw(conf, "could not extattr_list_link '%s': %d\n",
				path, len);
			free(xattrlist);
			return 0; // carry on
		}
		xattrlist[len]='\0';

		// Convert namespace number to string. It has to be freed
		// later on.
		if(extattr_namespace_to_string(namespaces[i], &cnamespace))
		{
			logp("Failed to convert %d into namespace on '%s'\n",
				 namespaces[i], path);
			free(xattrlist);
			return 0; // carry on
		}


		for(j=0; j<(int)len; j+=xattrlist[j]+1)
		{
			int cnt=0;
			char tmp1[9];
			char tmp2[9];
			size_t zlen=0;
			size_t vlen=0;
			char *val=NULL;
			cnt=xattrlist[j];
			if(cnt>((int)sizeof(cattrname)-1))
				cnt=((int)sizeof(cattrname)-1);
			strncpy(cattrname, xattrlist+(j+1), cnt);
			cattrname[cnt]='\0';
			snprintf(ctuple, sizeof(ctuple), "%s.%s",
				cnamespace, cattrname);

			if(have_acl)
			{
				int c=0;
				int skip=0;
				// skip xattr entries that were already saved
				// as ACLs.
				for(c=0; acl_skiplist[c]; c++)
				{
					if(!strcmp(ctuple, acl_skiplist[c]))
					{
						skip++;
						break;
					}
				}
				if(skip) continue;
			}
			zlen=strlen(ctuple);
			//printf("\ngot: %s (%s)\n", ctuple, path);

			if((vlen=extattr_list_link(path, namespaces[i],
				xattrlist, len))<0)
			{
				logw(conf, "could not extattr_list_link on %s for %s: %d\n", path, namespaces[i], vlen);
				continue;
			}
			if(!(val=(char *)malloc(vlen+1)))
			{
				log_out_of_memory(__func__);
				free(xattrlist);
				if(toappend) free(toappend);
				return -1;
			}
			if((vlen=extattr_get_link(path, namespaces[i],
				cattrname, val, vlen))<0)
			{
				logw(conf, "could not extattr_list_link %s for %s: %d\n", path, namespaces[i], vlen);
				free(val);
				continue;
			}
			val[vlen]='\0';

			if(vlen>maxlen)
			{
				logw(conf, "xattr value of '%s' too long: %d\n",
					path, vlen);
				if(toappend) { free(toappend); toappend=NULL; }
				free(val);
				break;
			}

			snprintf(tmp1, sizeof(tmp1), "%08X", (unsigned)zlen);
			snprintf(tmp2, sizeof(tmp2), "%08X", (unsigned)vlen);
			if(!(toappend=prepend_len(toappend, totallen,
				tmp1, 8, "", 0, &totallen))
			  || !(toappend=prepend_len(toappend, totallen,
				ctuple, zlen, "", 0, &totallen))
			  || !(toappend=prepend_len(toappend, totallen,
				tmp2, 8, "", 0, &totallen))
			  || !(toappend=prepend_len(toappend, totallen,
				val, vlen, "", 0, &totallen)))
			{
				log_out_of_memory(__func__);
				free(val);
				free(xattrlist);
				return -1;
			}
			free(val);

			if(totallen>maxlen)
			{
				logw(conf, "xattr length of '%s' grew too long: %d\n",
					path, totallen);
				free(val);
				free(toappend);
				free(xattrlist);
				return 0; // carry on
			}

			//printf("now: %s\n", toappend);
		}

		free(cnamespace);

		if(toappend)
		{
			char tmp3[10];
			snprintf(tmp3, sizeof(tmp3), "%c%08X",
				META_XATTR_BSD, (unsigned)totallen);
			if(!(*xattrtext=prepend_len(*xattrtext, *xlen,
				tmp3, 9, "", 0, xlen))
			  || !(*xattrtext=prepend_len(*xattrtext, *xlen,
				toappend, totallen, "", 0, xlen)))
			{
				log_out_of_memory(__func__);
				free(toappend);
				free(xattrlist);
				return -1;
			}
			free(toappend);
			//printf("and: %s %li\n", *xattrtext, *xlen);
		}
		free(xattrlist);
	}

	return 0;
}