/ libpkg / extattr.c
extattr.c
  1  /*-
  2   * Copyright (c) 2020 Shawn Webb <shawn.webb@hardenedbsd.org>
  3   * 
  4   * Redistribution and use in source and binary forms, with or without
  5   * modification, are permitted provided that the following conditions
  6   * are met:
  7   * 1. Redistributions of source code must retain the above copyright
  8   *    notice, this list of conditions and the following disclaimer
  9   *    in this position and unchanged.
 10   * 2. Redistributions in binary form must reproduce the above copyright
 11   *    notice, this list of conditions and the following disclaimer in the
 12   *    documentation and/or other materials provided with the distribution.
 13   * 
 14   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
 15   * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 16   * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 17   * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
 18   * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 19   * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 20   * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 21   * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 22   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 23   * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 24   */
 25  
 26  
 27  #include <archive.h>
 28  #include <archive_entry.h>
 29  #include <assert.h>
 30  #include <fcntl.h>
 31  #include <fts.h>
 32  #include <string.h>
 33  #include <pwd.h>
 34  #include <grp.h>
 35  #include <errno.h>
 36  
 37  #include <sys/types.h>
 38  #include <sys/extattr.h>
 39  
 40  #include "pkg.h"
 41  #include "private/event.h"
 42  #include "private/pkg.h"
 43  
 44  int
 45  pkg_archive_extattrs(int fd, struct archive_entry *entry)
 46  {
 47  	const char *nameprefix = "system.";
 48  	char *endp, *name, *names, *namep;
 49  	ssize_t datasize, listsize;
 50  	int err, namespace;
 51  	uint8_t namesize;
 52  	void *attrdata;
 53  
 54  	err = EPKG_OK;
 55  	attrdata = NULL;
 56  	names = NULL;
 57  
 58  	namespace = EXTATTR_NAMESPACE_SYSTEM;
 59  
 60  	listsize = extattr_list_fd(fd, namespace, NULL, 0);
 61  	if (listsize < 0) {
 62  		return (EPKG_OK);
 63  	}
 64  
 65  	if (listsize == 0) {
 66  		return (EPKG_OK);
 67  	}
 68  
 69  	names = calloc(listsize, 1);
 70  	if (names == NULL) {
 71  		return (EPKG_OK);
 72  	}
 73  
 74  	if (extattr_list_fd(fd, namespace, names, listsize) !=
 75  	    listsize) {
 76  		goto end;
 77  	}
 78  	endp = names + (size_t)listsize;
 79  	for (namep = names; namep < endp; namep += namesize) {
 80  		namesize = *((uint8_t *)(namep));
 81  		name = calloc(strlen(nameprefix) + namesize+1, 1);
 82  		if (name == NULL) {
 83  			goto end;
 84  		}
 85  		namep += sizeof(uint8_t);
 86  		strcpy(name, nameprefix);
 87  		strncat(name, namep, namesize);
 88  
 89  		datasize = extattr_get_fd(fd, namespace, name+strlen(nameprefix), NULL, 0);
 90  		if (datasize < 0) {
 91  			free(name);
 92  			continue;
 93  		}
 94  
 95  		attrdata = calloc(1, (size_t)datasize);
 96  		if (attrdata == NULL) {
 97  			free(name);
 98  			goto end;
 99  		}
100  
101  		if (extattr_get_fd(fd, namespace, name+strlen(nameprefix), attrdata,
102  		    datasize) != datasize) {
103  			perror("extattr_get_fd");
104  			free(name);
105  			free(attrdata);
106  			goto end;
107  		}
108  
109  		archive_entry_xattr_add_entry(entry, name, attrdata,
110  		    datasize);
111  
112  		free(name);
113  		free(attrdata);
114  	}
115  
116  end:
117  	free(names);
118  	return (EPKG_OK);
119  }