Ejemplo n.º 1
0
static int32_t e2prop_get(xar_file_t f, const char *name, char **value) {
	char v[1024];

	memset(v, 0, sizeof(v));
	snprintf(v, sizeof(v)-1, "%s/%s", XAR_ATTR_FORK, name);
	return xar_prop_get(f, v, (const char**)value);
}
Ejemplo n.º 2
0
int32_t xar_data_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) {
	const char *opt;
	int32_t retval = 0;
	struct _data_context context;
	xar_prop_t tmpp;
	
	memset(&context,0,sizeof(struct _data_context));
	
	/* Only regular files are copied in and out of the heap here */
	xar_prop_get(f, "type", &opt);
	if( !opt ) return 0;
	if( strcmp(opt, "file") != 0 ) {
		if( strcmp(opt, "hardlink") == 0 ) {
			opt = xar_attr_get(f, "type", "link");
			if( !opt )
				return 0;
			if( strcmp(opt, "original") != 0 )
				return 0; 
			/* else, we're an original hardlink, so keep going */
		} else
			return 0;
	}
	
	if ( len ){
		context.length = len;
		context.buffer = buffer;
		context.offset = 0;
	}else{
		/* mode 600 since other modules may need to operate on the file
		* prior to the real permissions being set.
		*/
		context.fd = open(file, O_RDWR|O_TRUNC|O_EXLOCK, 0600);
		if( context.fd < 0 ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "io: Could not create file");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			return -1;
		}
		
	}
	
	tmpp = xar_prop_pfirst(f);
	if( tmpp )
		tmpp = xar_prop_find(tmpp, "data");
	if( !tmpp ) {
		close(context.fd);
		return 0;
	}
	retval = xar_attrcopy_from_heap(x, f, tmpp, xar_data_write, (void *)(&context));
	
	if( context.fd > 0 ){		
		close(context.fd);
		context.fd = -1;
	}
	
	return retval;
}
Ejemplo n.º 3
0
/* xar_data_archive
 * This is the arcmod archival entry point for archiving the file's
 * data into the heap file.
 */
int32_t xar_data_archive(xar_t x, xar_file_t f, const char *file, const char *buffer, size_t len) {
	const char *opt;
	int32_t retval = 0;
	struct _data_context context;
	xar_prop_t tmpp;
	
	memset(&context,0,sizeof(struct _data_context));

	if( !xar_check_prop(x, "data") )
		return 0;

	xar_prop_get(f, "type", &opt);
	if(!opt) return 0;
	if( strcmp(opt, "file") != 0 ) {
		if( strcmp(opt, "hardlink") == 0 ) {
			opt = xar_attr_get(f, "type", "link");
			if( !opt )
				return 0;
			if( strcmp(opt, "original") != 0 )
				return 0;
			/* else, we're an original hardlink, so keep going */
		} else
			return 0;
	}

	if( 0 == len ){
		context.fd = open(file, O_RDONLY);
		if( context.fd < 0 ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "io: Could not open file");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_CREATION);
			return -1;
		}		
	}else{
		context.buffer = (void *)buffer;
		context.length = len;
		context.offset = 0;
	}

#ifdef F_NOCACHE
	fcntl(context.fd, F_NOCACHE, 1);
#endif

	tmpp = xar_prop_pset(f, NULL, "data", NULL);
	retval = xar_attrcopy_to_heap(x, f, tmpp, xar_data_read,(void *)(&context));
	if( context.total == 0 )
		xar_prop_unset(f, "data");

	if(context.fd > 0){
		close(context.fd);
		context.fd = -1;
	}
	
	return retval;
}
Ejemplo n.º 4
0
void prop_check(int fd, xar_t x, xar_file_t f) {
    xar_iter_t i;
    const char *key, *value;
    const char *name = NULL;
    char *tmp;
    off_t offset = 0, length = 0;
    const char *origcsum = NULL;

    i = xar_iter_new();
    if( !i ) {
        fprintf(stderr, "Error creating new prop iter\n");
        exit(1);
    }

    xar_prop_get(f, "name", &name);

    for( key = xar_prop_first(f, i); key; key = xar_prop_next(i) ) {
        asprintf(&tmp, "%s/offset", key);
        if( xar_prop_get(f, tmp, &value) == 0 ) {
            offset = strtoll(value, NULL, 10);
        }
        free(tmp);
        asprintf(&tmp, "%s/length", key);
        if( xar_prop_get(f, tmp, &value) == 0 ) {
            length = strtoll(value, NULL, 10);
        }
        free(tmp);
        asprintf(&tmp, "%s/archived-checksum", key);
        if( xar_prop_get(f, tmp, &value) == 0 ) {
            origcsum = value;
        }
        free(tmp);

        if( offset && length && origcsum ) {
            heap_check(fd, name, key, offset, length, origcsum);
            offset = 0;
            length = 0;
            origcsum = NULL;
        }
    }

}
Ejemplo n.º 5
0
int32_t xar_flags_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) {
#ifdef HAVE_CHFLAGS
	char *tmp;
	u_int flags = 0;

	if( xar_prop_get(f, XAR_FLAG_FORK, NULL) )
		return 0;

#ifdef UF_NODUMP
	if( x_getprop(f, "UserNoDump", (char **)&tmp) == 0 )
		flags |= UF_NODUMP;
#endif
#ifdef UF_IMMUTABLE
	if( x_getprop(f, "UserImmutable", (char **)&tmp) == 0 )
		flags |= UF_IMMUTABLE;
#endif
#ifdef UF_APPEND
	if( x_getprop(f, "UserAppend", (char **)&tmp) == 0 )
		flags |= UF_APPEND;
#endif
#ifdef UF_OPAQUE
	if( x_getprop(f, "UserOpaque", (char **)&tmp) == 0 )
		flags |= UF_OPAQUE;
#endif
#ifdef SF_ARCHIVED
	if( x_getprop(f, "SystemArchived", (char **)&tmp) == 0 )
		flags |= SF_ARCHIVED;
#endif
#ifdef SF_IMMUTABLE
	if( x_getprop(f, "SystemImmutable", (char **)&tmp) == 0 )
		flags |= SF_IMMUTABLE;
#endif
#ifdef SF_APPEND
	if( x_getprop(f, "SystemAppend", (char **)&tmp) == 0 )
		flags |= SF_APPEND;
#endif

	if( !flags )
		return 0;

	if( chflags(file, flags) != 0 ) {
		char e[1024];
		memset(e, 0, sizeof(e));
		snprintf(e, sizeof(e)-1, "chflags: %s", strerror(errno));
		xar_err_new(x);
		xar_err_set_file(x, f);
		xar_err_set_string(x, e);
		xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		return -1;
	}
#endif
	
	return 0;
}
Ejemplo n.º 6
0
int32_t xar_data_verify(xar_t x, xar_file_t f)
{
	const char *opt;
	struct _data_context context;
	xar_prop_t tmpp;
	
	memset(&context,0,sizeof(struct _data_context));

	/* Only regular files are copied in and out of the heap here */
	xar_prop_get(f, "type", &opt);
	if( !opt ) return 0;
	if( strcmp(opt, "directory") == 0 ) {
		return 0;
	}
	
	tmpp = xar_prop_pfirst(f);
	if( tmpp )
		tmpp = xar_prop_find(tmpp, "data");
	
	if (!tmpp)		// It appears that xar can have truely empty files, aka, no data. We should just fail to verify these files. 
		return 0;	// After all, the checksum of blank is meaningless. So, failing to do so will cause a crash.
	
	return xar_attrcopy_from_heap(x, f, tmpp, NULL , (void *)(&context));
}
Ejemplo n.º 7
0
int xar_ext2attr_archive(xar_t x, xar_file_t f, const char* file, const char *buffer, size_t len)
{
	int ret = 0;
	
	/* if archiving from a buffer, then there is no place to get extattr */
	if ( len )
		return 0;
		
#if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H)
	int fd, flags=0, version;
	char *vstr;
	const char *opt;

        xar_prop_get(f, "type", &opt);
        if(!opt) return 0;
        if( strcmp(opt, "file") != 0 ) {
                if( strcmp(opt, "hardlink") != 0 )
                	if( strcmp(opt, "directory") != 0 )
				return 0;
	}

	fd = open(file, O_RDONLY);
	if( fd < 0 ) {
		return 0;
	}
	if( ioctl(fd, EXT2_IOC_GETVERSION, &version) < 0 ) {
		ret = 0;
		goto BAIL;
	}
	if( ioctl(fd, EXT2_IOC_GETFLAGS, &flags) < 0 ) {
		ret = 0;
		goto BAIL;
	}

	if( flags == 0 ) goto BAIL;

	xar_prop_set(f, XAR_EXT2_FORK, NULL);
	asprintf(&vstr, "%d", version);
	xar_attr_set(f, XAR_EXT2_FORK, "version", vstr);
	free(vstr);

	if(! (flags & ~EXT2_SECRM_FL) )
		x_addprop(f, "SecureDeletion");
	if(! (flags & ~EXT2_UNRM_FL) )
		x_addprop(f, "Undelete");
	if(! (flags & ~EXT2_COMPR_FL) )
		x_addprop(f, "Compress");
	if(! (flags & ~EXT2_SYNC_FL) )
		x_addprop(f, "Synchronous");
	if(! (flags & ~EXT2_IMMUTABLE_FL) )
		x_addprop(f, "Immutable");
	if(! (flags & ~EXT2_APPEND_FL) )
		x_addprop(f, "AppendOnly");
	if(! (flags & ~EXT2_NODUMP_FL) )
		x_addprop(f, "NoDump");
	if(! (flags & ~EXT2_NOATIME_FL) )
		x_addprop(f, "NoAtime");
	if(! (flags & ~EXT2_DIRTY_FL) )
		x_addprop(f, "CompDirty");
	if(! (flags & ~EXT2_COMPRBLK_FL) )
		x_addprop(f, "CompBlock");
#ifdef EXT2_NOCOMPR_FL
	if(! (flags & ~EXT2_NOCOMPR_FL) )
		x_addprop(f, "NoCompBlock");
#endif
	if(! (flags & ~EXT2_ECOMPR_FL) )
		x_addprop(f, "CompError");
	if(! (flags & ~EXT2_BTREE_FL) )
		x_addprop(f, "BTree");
	if(! (flags & ~EXT2_INDEX_FL) )
		x_addprop(f, "HashIndexed");
	if(! (flags & ~EXT2_IMAGIC_FL) )
		x_addprop(f, "iMagic");
#ifdef EXT3_JOURNAL_DATA_FL
	if(! (flags & ~EXT3_JOURNAL_DATA_FL) )
		x_addprop(f, "Journaled");
#endif
	if(! (flags & ~EXT2_NOTAIL_FL) )
		x_addprop(f, "NoTail");
	if(! (flags & ~EXT2_DIRSYNC_FL) )
		x_addprop(f, "DirSync");
	if(! (flags & ~EXT2_TOPDIR_FL) )
		x_addprop(f, "TopDir");
	if(! (flags & ~EXT2_RESERVED_FL) )
		x_addprop(f, "Reserved");

BAIL:
	close(fd);
#endif
	return ret;
}
Ejemplo n.º 8
0
int xar_ext2attr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len)
{
	/* if extracting to a buffer, then there is no place to write extattr */
	if ( len )
		return 0;
	
#if defined(HAVE_EXT2FS_EXT2_FS_H) || defined(HAVE_LINUX_EXT2_FS_H)
	int fd = -1, version, flags = 0;
	char *tmp;

	if( xar_prop_get(f, XAR_EXT2_FORK, NULL) == 0 ) {
		const char *temp;
		temp = xar_attr_get(f, XAR_EXT2_FORK, "version");
		version = strtol(temp, NULL, 10);
		fd = open(file, O_RDONLY);
		if( fd < 0 )
			return 0;
		ioctl(fd, EXT2_IOC_SETVERSION, &version);
	}

	if( xar_prop_get(f, XAR_ATTR_FORK, NULL)  ) {
		if( fd >= 0 ) close(fd);
		return 0;
	}

	if( e2prop_get(f, "SecureDeletion", (char **)&tmp) == 0 )
		flags |= EXT2_SECRM_FL;
	if( e2prop_get(f, "Undelete", (char **)&tmp) == 0 )
		flags |= EXT2_UNRM_FL ;
	if( e2prop_get(f, "Compress", (char **)&tmp) == 0 )
		flags |= EXT2_COMPR_FL ;
	if( e2prop_get(f, "Synchronous", (char **)&tmp) == 0 )
		flags |= EXT2_SYNC_FL ;
	if( e2prop_get(f, "SystemImmutable", (char **)&tmp) == 0 )
		flags |= EXT2_IMMUTABLE_FL ;
	if( e2prop_get(f, "AppendOnly", (char **)&tmp) == 0 )
		flags |= EXT2_APPEND_FL ;
	if( e2prop_get(f, "NoDump", (char **)&tmp) == 0 )
		flags |= EXT2_NODUMP_FL ;
	if( e2prop_get(f, "NoAtime", (char **)&tmp) == 0 )
		flags |= EXT2_NOATIME_FL ;
	if( e2prop_get(f, "CompDirty", (char **)&tmp) == 0 )
		flags |= EXT2_DIRTY_FL ;
	if( e2prop_get(f, "CompBlock", (char **)&tmp) == 0 )
		flags |= EXT2_COMPRBLK_FL ;
#ifdef EXT2_NOCOMPR_FL
	if( e2prop_get(f, "NoCompBlock", (char **)&tmp) == 0 )
		flags |= EXT2_NOCOMPR_FL ;
#endif
	if( e2prop_get(f, "CompError", (char **)&tmp) == 0 )
		flags |= EXT2_ECOMPR_FL ;
	if( e2prop_get(f, "BTree", (char **)&tmp) == 0 )
		flags |= EXT2_BTREE_FL ;
	if( e2prop_get(f, "HashIndexed", (char **)&tmp) == 0 )
		flags |= EXT2_INDEX_FL ;
	if( e2prop_get(f, "iMagic", (char **)&tmp) == 0 )
		flags |= EXT2_IMAGIC_FL ;
#ifdef EXT3_JOURNAL_DATA_FL
	if( e2prop_get(f, "Journaled", (char **)&tmp) == 0 )
		flags |= EXT3_JOURNAL_DATA_FL ;
#endif
	if( e2prop_get(f, "NoTail", (char **)&tmp) == 0 )
		flags |= EXT2_NOTAIL_FL ;
	if( e2prop_get(f, "DirSync", (char **)&tmp) == 0 )
		flags |= EXT2_DIRSYNC_FL ;
	if( e2prop_get(f, "TopDir", (char **)&tmp) == 0 )
		flags |= EXT2_TOPDIR_FL ;

	if( fd < 0 ) {
		fd = open(file, O_RDONLY);
		if( fd < 0 )
			return 0;
	}

	ioctl(fd, EXT2_IOC_SETFLAGS, &flags);
	close(fd);
#endif
	return 0;
}
Ejemplo n.º 9
0
std::map<std::string, std::string> Extract(std::string file, std::string prefix) {
  std::map<std::string, std::string> files;
#ifdef HAVE_LIBXAR
  xar_t x;
  xar_iter_t xi;
  xar_file_t xf;
  xar_stream xs;
  char buffer[8192];

  x = xar_open(file.c_str(), READ);
  if (x == nullptr) {
    std::cerr << "Could not open xar archive" << std::endl;
  }

  xi = xar_iter_new();
  if (xi == nullptr) {
    xar_close(x);
    std::cerr << "Could not read xar archive" << std::endl;
  }

  for (xf = xar_file_first(x, xi); xf != nullptr; xf = xar_file_next(xi)) {
    char *path = xar_get_path(xf);
    const char *type;
    xar_prop_get(xf, "type", &type);

    if (type == nullptr) {
      std::cerr << "File has no type" << std::endl;
      free(path);
      continue;
    }

    if (std::strcmp(type, "file") != 0) {
      free(path);
      continue;
    }

    if (xar_extract_tostream_init(x, xf, &xs) != XAR_STREAM_OK) {
      std::cerr << "Error initializing stream" << std::endl;
      free(path);
      continue;
    }

    const std::string fileName = prefix + util::uuid::UuidToString(util::uuid::GenerateUUID());

    // Write bitcode to file
    std::FILE *output = std::fopen(fileName.c_str(), "wb");
    if (output == nullptr) {
      std::cerr << "Error opening output file" << std::endl;
      continue;
    }

    xs.avail_out = sizeof(buffer);
    xs.next_out = buffer;

    int32_t ret;
    while ((ret = xar_extract_tostream(&xs)) != XAR_STREAM_END) {
      if (ret == XAR_STREAM_ERR) {
        std::cerr << "Error extracting stream" << std::endl;
        break;
      }
      std::fwrite(buffer, sizeof(char), sizeof(buffer) - xs.avail_out, output);

      xs.avail_out = sizeof(buffer);
      xs.next_out = buffer;
    }

    if (xar_extract_tostream_end(&xs) != XAR_STREAM_OK) {
      std::cerr << "Error ending stream" << std::endl;
    }

    std::fclose(output);

    // Add to list of extracted files
    files[std::string(path)] = fileName;

    free(path);
  }

  xar_iter_free(xi);
  xar_close(x);
#endif
  return files;
}
Ejemplo n.º 10
0
static int32_t eacls(xar_t x, xar_file_t f, const char *file) {
#ifdef HAVE_SYS_ACL_H
#if !defined(__APPLE__)
	const char *t;
	acl_t a;
	const char *type;

	xar_prop_get(f, "type", &type);
	if( !type || (strcmp(type, "symlink") == 0) )
		return 0;


	xar_prop_get(f, "acl/default", &t);
	if( t ) {
		a = acl_from_text(t);
		if( !a ) {
			xar_err_new(x);
			xar_err_set_errno(x, errno);
			xar_err_set_string(x, "Error extracting default acl from toc");
			xar_err_set_file(x, f);
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		} else {
			if( acl_set_file(file, ACL_TYPE_DEFAULT, a) != 0 ) {
				xar_err_new(x);
				xar_err_set_errno(x, errno);
				xar_err_set_string(x, "Error setting default acl");
				xar_err_set_file(x, f);
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
		}
	}

	xar_prop_get(f, "acl/access", &t);
	if( t ) {
		a = acl_from_text(t);
		if( !a ) {
			xar_err_new(x);
			xar_err_set_errno(x, errno);
			xar_err_set_string(x, "Error extracting access acl from toc");
			xar_err_set_file(x, f);
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		} else {
			if( acl_set_file(file, ACL_TYPE_ACCESS, a) != 0 ) {
				xar_err_new(x);
				xar_err_set_errno(x, errno);
				xar_err_set_string(x, "Error setting access acl");
				xar_err_set_file(x, f);
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
			acl_free(a);
		}
	}
#else /* !__APPLE__ */
	const char *t;
	acl_t a;

	xar_prop_get(f, "acl/appleextended", &t);
	if( t ) {
		a = acl_from_text(t);
		if( !a ) {
			xar_err_new(x);
			xar_err_set_errno(x, errno);
			xar_err_set_string(x, "Error extracting access acl from toc");
			xar_err_set_file(x, f);
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		} else {
			if( acl_set_file(file, ACL_TYPE_ACCESS, a) != 0 ) {
				xar_err_new(x);
				xar_err_set_errno(x, errno);
				xar_err_set_string(x, "Error setting access acl");
				xar_err_set_file(x, f);
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
			acl_free(a);
		}
	}
#endif /* !__APPLE__ */
#endif
	return 0;
}
Ejemplo n.º 11
0
int main(int argc, char *argv[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	xar_stream s;
	char buffer[8192];

	x = xar_open(argv[1], READ);
	if( !x ) {
		fprintf(stderr, "Error opening archive\n");
		exit(1);
	}

	xar_register_errhandler(x, err_callback, NULL);

	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		char *path;
		const char *type;
		int32_t ret;
		int fd;

		path = xar_get_path(f);

		xar_prop_get(f, "type", &type);
		if( !type ) {
			fprintf(stderr, "File has no type %s\n", path);
			free(path);
			continue;
		}
		if( strcmp(type, "file") != 0 ) {
			fprintf(stderr, "Skipping %s\n", path);
			free(path);
			continue;
		}
	
		fprintf(stderr, "Extracting %s\n", path);
		if( xar_extract_tostream_init(x, f, &s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error initializing stream %s\n", path);
			free(path);
			continue;
		}
		
		fd = open(path, O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR);
		if( !fd ) {
			fprintf(stderr, "Error opening output file %s\n", path);
			free(path);
			continue;
		}
		s.avail_out = sizeof(buffer);
		s.next_out = buffer;

		while( (ret = xar_extract_tostream(&s)) != XAR_STREAM_END ) {
			if( ret == XAR_STREAM_ERR ) {
				fprintf(stderr, "Error extracting stream %s\n", path);
				exit(2);
			}

			write(fd, buffer, sizeof(buffer)-s.avail_out);

			s.avail_out = sizeof(buffer);
			s.next_out = buffer;
		}

		if( xar_extract_tostream_end(&s) != XAR_STREAM_OK ) {
			fprintf(stderr, "Error ending stream %s\n", path);
		}

		close(fd);
		free(path);
	}
}
Ejemplo n.º 12
0
/* replace_sign: rip out all current signatures and certs and insert a new pair
		Since libxar is currently not capable of doing this directly, we have to create a new xar archive,
		copy all the files and options from the current archive, and sign the new archive
*/
static void replace_sign(const char *filename) {

	xar_t old_xar, new_xar;
	xar_signature_t sig;
	char *new_xar_path = (char *)malloc(15);
	strncpy(new_xar_path, "/tmp/xar.XXXXX", 15);
	new_xar_path = mktemp(new_xar_path);
	char *systemcall;
	int err;
	
	// open both archives
	old_xar = xar_open(filename, READ);
	if ( old_xar == NULL ) {
		fprintf(stderr, "Could not open archive %s!\n", filename);
		exit(1);
	}
	new_xar = xar_open(new_xar_path, WRITE);
	if( !new_xar ) {
		fprintf(stderr, "Error creating new archive %s\n", new_xar_path);
		exit(1);
	}
	
	// install new signature and new certs in new_xar
	sig = xar_signature_new(new_xar, "RSA", SigSize, &signingCallback, NULL);
	if ( LeafCertPath )
		insert_cert(sig, LeafCertPath);
	if ( IntermediateCertPath )
		insert_cert(sig, IntermediateCertPath);
	
	// copy options
	char *opts[6] = {XAR_OPT_TOCCKSUM, XAR_OPT_COMPRESSION, XAR_OPT_COALESCE, XAR_OPT_LINKSAME, XAR_OPT_RSIZE, XAR_OPT_OWNERSHIP};
	int i;
	const char *opt;
	for (i=0; i<6; i++) {
		opt = xar_opt_get(old_xar, opts[i]);
		if (opt)
			xar_opt_set(new_xar, opts[i], opt);
	}

	// skip copy subdocs for now since we don't use them yet
	
	// copy files
	xar_iter_t iter = xar_iter_new();
	xar_file_t f = xar_file_first(old_xar, iter);
		// xar_file_next iterates the archive depth-first, i.e. all children are enumerated before the siblings.
	const char *name;
	char *f_dirname, *stack_top_dirname;
	stack s_new = stack_new();
	stack s_old = stack_new();
	xar_file_t last_copied = NULL, last_added;
	
	xar_iter_t loopIter = xar_iter_new();
	xar_file_t current_xar_file;
	for (current_xar_file = xar_file_first(old_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter))
	{
		printf("old_xar -> %s (parent: %s)\n",xar_get_path(current_xar_file),XAR_FILE(current_xar_file)->parent?xar_get_path(XAR_FILE(current_xar_file)->parent):"(nil)");
	}
	
	do {
		// parent is the parent in the new archive!
		// 3 cases:
		//  1. the file has no parent. Happens for every file at the top level of the archive.
		//  2. the file's parent is the last file we added. Happens while descending down a path
		//  3. the file's parent is one of the ancestors of the last file (and not NULL, that would be case 1)
		//		that means we either go back up the tree and add a sibling of one of the ancestors, or we add a
		//		sibling on the same level
		xar_prop_get(f, "name", &name);	// filename, without any path info
		if (!XAR_FILE(f)->parent) {	// case 1
			printf("root: %s\n",xar_get_path(f));
			last_added = xar_add_from_archive(new_xar, NULL, name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		} else if (f->parent == last_copied) {	// case 2			
			printf("child: %s -> %s\n",xar_get_path(f->parent),xar_get_path(f));
			last_added = xar_add_from_archive(new_xar, last_added, name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		} else {	// case 3
			printf("searching for parent: %s ?\n",xar_get_path(f));
			while (XAR_FILE(f)->parent != XAR_FILE(s_old->top->data)->parent) {
				printf("popping: %s\n",xar_get_path(XAR_FILE(s_old->top->data)));
				stack_pop(s_new);
				stack_pop(s_old);
			}
			printf("found: %s -> %s\n",xar_get_path(XAR_FILE(s_new->top->data)),xar_get_path(f));
			stack_pop(s_new);
			stack_pop(s_old);
			last_added = xar_add_from_archive(new_xar, (xar_file_t)(s_new->top->data), name, old_xar, f);
			last_copied = f;
			stack_push(s_new, (void *)last_added);
			stack_push(s_old, (void *)last_copied);
		}
	} while (f = xar_file_next(iter));
		
	loopIter = xar_iter_new();
	for (current_xar_file = xar_file_first(new_xar, loopIter); current_xar_file; current_xar_file = xar_file_next(loopIter))
	{
		char * current_path = xar_get_path(current_xar_file);
		printf("new_xar -> %s\n",current_path);
	}
	
	xar_iter_free(iter);
	stack_free(s_new);
	stack_free(s_old);
	if( xar_close(new_xar) != 0 ) {
		fprintf(stderr, "Error creating the archive\n");
		if( !Err )
			Err = 42;
	}
	xar_close(old_xar);
	
	// write signature offset to file (have to re-open so xar_close can figure out the correct offset)
	new_xar = xar_open(new_xar_path, READ);
	if( !new_xar ) {
		fprintf(stderr, "Error re-opening new archive %s\n", new_xar_path);
		unlink(new_xar_path);
		exit(1);
	}
	
	if (extract_sig_offset(new_xar, SigOffsetDumpPath)) {
		xar_close(new_xar);
		unlink(new_xar_path);
		exit(1);
	}
		
	xar_close(new_xar);
	
	// delete old archive, move new in its place
	unlink(filename);
	asprintf(&systemcall, "cp \"%s\" \"%s\"", new_xar_path, filename);
	err = system(systemcall);
	if (err) {
		fprintf(stderr, "Could not copy new archive to final location (system() returned %i)\n", err);
		unlink(new_xar_path);
		exit(1);
	}
	
	// Delete the tmp archive
	unlink(new_xar_path);
	
	free(systemcall);
}
Ejemplo n.º 13
0
static void extract_data_to_sign(const char *filename) {
	xar_signature_t sig;
	off_t signatureOffset;
	FILE *file;
	xar_t x;
	int i;
	uint32_t dataToSignOffset = 0;
	uint32_t dataToSignSize = 0;
	char *buffer = NULL;
	const char *value;
	
	// find signature stub
	x = xar_open(filename, READ);
	if ( x == NULL ) {
		fprintf(stderr, "Could not open %s to extract data to sign!\n", filename);
		exit(1);
	}
	sig = xar_signature_first(x);
	if ( !sig ) {
		fprintf(stderr, "No signatures found to extract data from.\n");
		exit(E_NOSIG);
	}

	// locate data to sign
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/offset" ,&value) ){
		fprintf(stderr, "Could not locate checksum/offset in archive.\n");
		exit(1);
	}
	dataToSignOffset = xar_get_heap_offset(x);
	dataToSignOffset += strtoull(value, (char **)NULL, 10);
	if( 0 != xar_prop_get((xar_file_t)x, "checksum/size" ,&value) ){
		fprintf(stderr, "Could not locate checksum/size in archive.\n");
		exit(1);
	}
	dataToSignSize = strtoull(value, (char **)NULL, 10);

	// get signature offset (inject signature here) 
	xar_signature_copy_signed_data(sig, NULL, NULL, NULL, NULL, &signatureOffset);
	signatureOffset += xar_get_heap_offset(x);
	xar_close(x);
	
	// now get data to be signed, using offset and size
	file = fopen(filename, "r");
	if (!file) {
		fprintf(stderr, "Could not open %s for reading data to sign!\n", filename);
		exit(1);
	}
	fseek(file, dataToSignOffset, SEEK_SET);
	buffer = malloc(dataToSignSize);
	i = fread(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to read data to sign from %s!\n", filename);
		exit(1);
	}
	fclose(file);
	
	// save data to sign
	file = fopen(DataToSignDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving data to sign!\n", DataToSignDumpPath);
		exit(1);
	}
	i = fwrite(buffer, dataToSignSize, 1, file);
	if (i != 1) {
		fprintf(stderr, "Failed to write data to sign to %s (fwrite() returned %i)!\n", DataToSignDumpPath, i);
		exit(1);
	}
	fclose(file);

	// save signature offset
	file = fopen(SigOffsetDumpPath, "w");
	if (!file) {
		fprintf(stderr, "Could not open %s for saving signature offset!\n", SigOffsetDumpPath);
		exit(1);
	}
	i = fprintf(file, "%lli\n", signatureOffset);
	if (i < 0) {
		fprintf(stderr, "Failed to write signature offset to %s (fprintf() returned %i)!\n", SigOffsetDumpPath, i);
		exit(1);
	}
	fclose(file);
	
	free(buffer);
}
Ejemplo n.º 14
0
static int extract(const char *filename, int arglen, char *args[]) {
	xar_t x;
	xar_iter_t i;
	xar_file_t f;
	int files_extracted = 0;
	int argi;
	struct lnode *extract_files = NULL;
	struct lnode *extract_tail = NULL;
	struct lnode *lnodei = NULL;
	struct lnode *dirs = NULL;

	for(argi = 0; args[argi]; argi++) {
		struct lnode *tmp;
		int err;
		tmp = malloc(sizeof(struct lnode));
		tmp->str = strdup(args[argi]);
		tmp->next = NULL;
		err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
		if( err ) {
			char errstr[1024];
			regerror(err, &tmp->reg, errstr, sizeof(errstr));
			printf("Error with regular expression %s: %s\n", tmp->str, errstr);
			exit(1);
		}
		if( extract_files == NULL ) {
			extract_files = tmp;
			extract_tail = tmp;
		} else {
			extract_tail->next = tmp;
			extract_tail = tmp;
		}
		
		/* Add a clause for recursive extraction */
		tmp = malloc(sizeof(struct lnode));
		asprintf(&tmp->str, "%s/.*", args[argi]);
		tmp->next = NULL;
		err = regcomp(&tmp->reg, tmp->str, REG_NOSUB);
		if( err ) {
			char errstr[1024];
			regerror(err, &tmp->reg, errstr, sizeof(errstr));
			printf("Error with regular expression %s: %s\n", tmp->str, errstr);
			exit(1);
		}
		if( extract_files == NULL ) {
			extract_files = tmp;
			extract_tail = tmp;
		} else {
			extract_tail->next = tmp;
			extract_tail = tmp;
		}
	}

	x = xar_open(filename, READ);
	if( !x ) {
		fprintf(stderr, "Error opening xar archive: %s\n", filename);
		exit(1);
	}

	if(Chdir) {
		if( chdir(Chdir) != 0 ) {
			fprintf(stderr, "Unable to chdir to %s\n", Chdir);
			exit(1);
		}
	}

	xar_register_errhandler(x, err_callback, NULL);

	if( Perms == SYMBOLIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_SYMBOLIC);
	}
	if( Perms == NUMERIC ) {
		xar_opt_set(x, XAR_OPT_OWNERSHIP, XAR_OPT_VAL_NUMERIC);
	}
	if ( Rsize != NULL ) {
		xar_opt_set(x, XAR_OPT_RSIZE, Rsize);
	}
	if( SaveSuid ) {
		xar_opt_set(x, XAR_OPT_SAVESUID, XAR_OPT_VAL_TRUE);
	}
	
	i = xar_iter_new();
	if( !i ) {
		fprintf(stderr, "Error creating xar iterator\n");
		exit(1);
	}

	for(f = xar_file_first(x, i); f; f = xar_file_next(i)) {
		int matched = 0;
		int exclude_match = 1;
		struct lnode *i;

		char *path = xar_get_path(f);

		if( args[0] ) {
			for(i = extract_files; i != NULL; i = i->next) {
				int extract_match = 1;

				extract_match = regexec(&i->reg, path, 0, NULL, 0);
				if( !extract_match ) {
					matched = 1;
					break;
				}
			}
		} else {
			matched = 1;
		}

		for( i = Exclude; i; i=i->next ) {
			exclude_match = regexec(&i->reg, path, 0, NULL, 0);
			if( !exclude_match )
				break;
		}
		if( !exclude_match ) {
			if( Verbose )
				printf("Excluding %s\n", path);
			free(path);
			continue;
		}
		
		if (!xar_path_issane(path)) {
			if (Verbose)
				printf("Warning, not extracting file \"%s\" because it's path is invalid.\n", path);
			free(path);
			continue;
		}
		
		if( matched ) {
			struct stat sb;
			if( NoOverwrite && (lstat(path, &sb) == 0) ) {
				printf("%s already exists, not overwriting\n", path);
			} else {
				const char *prop = NULL;
				int deferred = 0;
				if( xar_prop_get(f, "type", &prop) == 0 ) {
					if( strcmp(prop, "directory") == 0 ) {
						struct lnode *tmpl = calloc(sizeof(struct lnode),1);
						tmpl->str = (char *)f;
						tmpl->next = dirs;
						dirs = tmpl;
						deferred = 1;
					}
				}
				if( ! deferred ) {
					files_extracted++;
					print_file(x, f);
					xar_extract(x, f);
				}
			}
		}
		free(path);
	}
	for(lnodei = dirs; lnodei; lnodei = lnodei->next) {
		files_extracted++;
		print_file(x,(xar_file_t)lnodei->str);
		xar_extract(x, (xar_file_t)lnodei->str);
	}
	if( args[0] && (files_extracted == 0) ) {
		fprintf(stderr, "No files matched extraction criteria.\n");
		Err = 3;
	}

	if( Subdoc )
		extract_subdoc(x, NULL);

	xar_iter_free(i);
	if( xar_close(x) != 0 ) {
		fprintf(stderr, "Error extracting the archive\n");
		if( !Err )
			Err = 42;
	}

	for(lnodei = extract_files; lnodei != NULL; ) {
		struct lnode *tmp;
		free(lnodei->str);
		regfree(&lnodei->reg);
		tmp = lnodei;
		lnodei = lnodei->next;
		free(tmp);
	}
	return Err;
}
Ejemplo n.º 15
0
int32_t xar_stat_extract(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) {
	const char *opt;
	int ret, fd;
	mode_t modet = 0;

	xar_prop_get(f, "type", &opt);
	if(opt && (strcmp(opt, "character special") == 0))
		modet = S_IFCHR;
	if(opt && (strcmp(opt, "block special") == 0))
		modet = S_IFBLK;

	if( modet ) {
		uint32_t major, minor;
		long long tmpll;
		dev_t devt;

		xar_prop_get(f, "device/major", &opt);
		tmpll = strtoll(opt, NULL, 10);
		if( ( (tmpll == LLONG_MIN) || (tmpll == LLONG_MAX) ) && (errno == ERANGE) )
			return -1;
		if( (tmpll < 0) || (tmpll > 255) )
			return -1;
		major = tmpll;

		xar_prop_get(f, "device/minor", &opt);
		tmpll = strtoll(opt, NULL, 10);
		if( ( (tmpll == LLONG_MIN) || (tmpll == LLONG_MAX) ) && (errno == ERANGE) )
			return -1;
		if( (tmpll < 0) || (tmpll > 255) )
			return -1;
		minor = tmpll;
		
		devt = xar_makedev(major, minor);
		unlink(file);
		if( mknod(file, modet, devt) ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "mknod: Could not create character device");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			return -1;
		}
		return 0;
	}
	if(opt && (strcmp(opt, "directory") == 0)) {
		ret = mkdir(file, 0700);
		if( (ret != 0) && (errno != EEXIST) ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "stat: Could not create directory");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			return ret;
		}
		return 0;
	}
	if(opt && (strcmp(opt, "symlink") == 0)) {
		xar_prop_get(f, "link", &opt);
		if( opt ) {
			unlink(file);
			ret = symlink(opt, file);
			if( ret != 0 ) {
				xar_err_new(x);
				xar_err_set_file(x, f);
				xar_err_set_string(x, "stat: Could not create symlink");
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
			return ret;
		}
	}
	if(opt && (strcmp(opt, "hardlink") == 0)) {
		xar_file_t tmpf;
		opt = xar_attr_get(f, "type", "link");
		if( !opt )
			return 0;
		if( strcmp(opt, "original") == 0 )
			goto CREATEFILE;

		tmpf = xmlHashLookup(XAR(x)->link_hash, BAD_CAST(opt));
		if( !tmpf ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "stat: Encountered hardlink with no original");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			return -1;
		}

		unlink(file);
		if( link(XAR_FILE(tmpf)->fspath, file) != 0 ) {
			if( errno == ENOENT ) {
				xar_iter_t i;
				const char *ptr;
				i = xar_iter_new(x);
				for(ptr = xar_prop_first(tmpf, i); ptr; ptr = xar_prop_next(i)) {
					xar_iter_t a;
					const char *val = NULL;
					const char *akey, *aval;
					if( strncmp("data", ptr, 4) != 0 )
						continue;
	
					if( xar_prop_get(tmpf, ptr, &val) )
						continue;
	
					xar_prop_set(f, ptr, val);
					a = xar_iter_new(x);
					for(akey = xar_attr_first(tmpf, ptr, a); akey; akey = xar_attr_next(a)) {
						aval = xar_attr_get(tmpf, ptr, akey);
						xar_attr_set(f, ptr, akey, aval);
					}
					xar_iter_free(a);
				}
				xar_iter_free(i);
				xar_attr_set(f, "type", "link", "original");
				return 0;
			} else {
				xar_err_new(x);
				xar_err_set_file(x, f);
				xar_err_set_string(x, "stat: Could not link hardlink to original");
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
				return -1;
			}
		}
		return 0;
	}

	if(opt && (strcmp(opt, "fifo") == 0)) {
		unlink(file);
		if( mkfifo(file, 0) ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "mkfifo: Could not create fifo");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			return -1;
		}
		return 0;
	}

	/* skip sockets */
	if(opt && (strcmp(opt, "socket") == 0)) {
		return 0;
	}

CREATEFILE:
	unlink(file);
	fd = open(file, O_RDWR|O_CREAT|O_TRUNC, 0600);
	if( fd > 0 )
		close(fd);
	return 0;
}
Ejemplo n.º 16
0
int32_t xar_set_perm(xar_t x, xar_file_t f, const char *file, char *buffer, size_t len) {
	const char *opt;
	int32_t m=0, mset=0;
	uid_t u;
	gid_t g;
	const char *timestr;
	struct tm t;
	enum {ATIME=0, MTIME};
	struct timeval tv[2];

	/* when writing to a buffer, there are no permissions to set */
	if ( len )
		return 0;
	
	/* in case we don't find anything useful in the archive */
	u = geteuid();
	g = getegid();

	opt = xar_opt_get(x, XAR_OPT_OWNERSHIP);
	if( opt && (strcmp(opt, XAR_OPT_VAL_SYMBOLIC) == 0) ) {
		struct passwd *pw;
		struct group *gr;

		xar_prop_get(f, "user", &opt);
		if( opt ) {
			pw = getpwnam(opt);
			if( pw ) {
				u = pw->pw_uid;
			}
		}
		xar_prop_get(f, "group", &opt);
		if( opt ) {
			gr = getgrnam(opt);
			if( gr ) {
				g = gr->gr_gid;
			}
		}
	}
	if( opt && (strcmp(opt, XAR_OPT_VAL_NUMERIC) == 0) ) {
		xar_prop_get(f, "uid", &opt);
		if( opt ) {
			long long tmp;
			tmp = strtol(opt, NULL, 10);
			if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) {
				return -1;
			}
			u = (uid_t)tmp;
		}

		xar_prop_get(f, "gid", &opt);
		if( opt ) {
			long long tmp;
			tmp = strtol(opt, NULL, 10);
			if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) {
				return -1;
			}
			g = (gid_t)tmp;
		}
	}


	xar_prop_get(f, "mode", &opt);
	if( opt ) {
		long long tmp;
		tmp = strtoll(opt, NULL, 8);
		if( ( (tmp == LLONG_MIN) || (tmp == LLONG_MAX) ) && (errno == ERANGE) ) {
			return -1;
		}
		m = (mode_t)tmp;
		mset = 1;
	}

	xar_prop_get(f, "type", &opt);
	if( opt && !mset ) {
		mode_t u = umask(0);
		umask(u);
		if( strcmp(opt, "directory") == 0 ) {
			m = (mode_t)(0777 & ~u);
		} else {
			m = (mode_t)(0666 & ~u);
		}
		mset = 1;
	}
	if( opt && (strcmp(opt, "symlink") == 0) ) {
#ifdef HAVE_LCHOWN
		if( lchown(file, u, g) ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "perm: could not lchown symlink");
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		}
#ifdef HAVE_LCHMOD
		if( mset )
			if( lchmod(file, m) ) {
				xar_err_new(x);
				xar_err_set_file(x, f);
				xar_err_set_string(x, "perm: could not lchmod symlink");
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
#endif
#endif 
	} else {
		if( chown(file, u, g) ) {
			xar_err_new(x);
			xar_err_set_file(x, f);
			xar_err_set_string(x, "perm: could not chown file");
			xar_err_set_errno(x, errno);
			xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
		}
		if( mset )
			if( chmod(file, m) ) {
				xar_err_new(x);
				xar_err_set_file(x, f);
				xar_err_set_string(x, "perm: could not chmod file");
				xar_err_callback(x, XAR_SEVERITY_NONFATAL, XAR_ERR_ARCHIVE_EXTRACTION);
			}
	}

	eacls(x, f, file);

	memset(tv, 0, sizeof(struct timeval) * 2);
	xar_prop_get(f, "atime", &timestr);
	if( timestr ) {
		memset(&t, 0, sizeof(t));
		strptime(timestr, "%FT%T", &t);
		tv[ATIME].tv_sec = timegm(&t);
	} else {
		tv[ATIME].tv_sec = time(NULL);
	}

	xar_prop_get(f, "mtime", &timestr);
	if( timestr ) {
		memset(&t, 0, sizeof(t));
		strptime(timestr, "%FT%T", &t);
		tv[MTIME].tv_sec = timegm(&t);
	} else {
		tv[MTIME].tv_sec = time(NULL);
	}
	utimes(file, tv);

	return 0;
}
Ejemplo n.º 17
0
Archivo: pkg_toc.c Proyecto: nn/fs-pkg
int pkg_toc_process(const char *path, const char *toc) {
   u_int32_t   pkgid;
   xar_t       x;
   xar_iter_t  i;
   xar_file_t  f;
   struct vfs_fake_stat sb;

   if (!(x = xar_open(path, READ))) {
      Log(LOG_ERROR, "failed opening package %s", path);
      return EXIT_FAILURE;
   }

   xar_register_errhandler(x, pkg_xar_err_callback, NULL);

   if (!(i = xar_iter_new())) {
      Log(LOG_ERROR, "failed getting new xar iter in pkg %s", path);
      return EXIT_FAILURE;
   }

   db_pkg_remove(path);
   pkgid = db_pkg_add(path);
   fprintf(stderr, "id: %d\n", pkgid);

   for (f = xar_file_first(x, i); f; f = xar_file_next(i)) {
      char       *size = xar_get_size(x, f);
      char       *xpath = xar_get_path(f);
      char       *xtype = xar_get_type(x, f);
      char       *mode = xar_get_mode(x, f);
      char       *user = xar_get_owner(x, f);
      char       *group = xar_get_group(x, f);
      char       *mtime = xar_get_mtime(x, f);
      const char *offset;
      char        type = 'u';
/*    *	                  (f)ile, (d)irectory, (l)ink, (p)ipe
      *                    f(i)fo, (c)haracter, (b)lock, (s)ocket,
      *                   (u)ndefined
 */
      if (!strcasecmp(xtype, "file")) {
         xar_prop_get(f, "data/offset", &offset);
         type = 'f';
      } else {
         offset = "0";
         if (!strcasecmp(xtype, "directory"))
            type = 'd';
         else if (!strcasecmp(xtype, "hardlink"))
            type = 'l';
         else if (!strcasecmp(xtype, "symlink"))
            type = 'l';
      }

#if	0
      /*
       * what we gonna do with target? 
       */
      printf("%s: %s %8s/%-8s %10s %s %s @ %s\n", xtype, mode, user,
             group, size, mtime, xpath, offset);

      db_query(QUERY_INT,
               "INSERT INTO files (package, path, type, owner, group, size, offset, ctime, mode) VALUES (%lu, '%s', '%s', %s, %s, %s, %s, %s, %s, %s);",
               pkgid, xpath, type, user, group, size, offset, mtime);
#endif
      free(mtime);
      free(group);
      free(user);
      free(mode);
      free(xtype);
      free(xpath);
      free(size);
   }
   return EXIT_SUCCESS;
}
Ejemplo n.º 18
0
static int32_t aacls(xar_file_t f, const char *file) {
#ifdef HAVE_SYS_ACL_H
#if !defined(__APPLE__)
	acl_t a;
	const char *type;

	xar_prop_get(f, "type", &type);
	if( !type || (strcmp(type, "symlink") == 0) )
		return 0;

	a = acl_get_file(file, ACL_TYPE_DEFAULT);
	if( a ) {
		char *t;
		acl_entry_t e;

		/* If the acl is empty, or not valid, skip it */
		if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 )
			goto NEXT;

		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/default", t);
			acl_free(t);
		}
		acl_free(a);
	}
NEXT:

	a = acl_get_file(file, ACL_TYPE_ACCESS);
	if( a ) {
		char *t;
		acl_entry_t e;

		/* If the acl is empty, or not valid, skip it */
		if( acl_get_entry(a, ACL_FIRST_ENTRY, &e) != 1 )
			goto DONE;

		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/access", t);
			acl_free(t);
		}
		acl_free(a);
	}
DONE:
#else /* !__AAPLE__ */
	acl_entry_t e = NULL;
	acl_t a;
	int i;

	a = acl_get_file(file, ACL_TYPE_EXTENDED);
	if( !a )
		return 0;

	for( i = 0; acl_get_entry(a, e == NULL ? ACL_FIRST_ENTRY : ACL_NEXT_ENTRY, &e) == 0; i++ ) {
		char *t;
		t = acl_to_text(a, NULL);
		if( t ) {
			xar_prop_set(f, "acl/appleextended", t);
			acl_free(t);
		}
		
	}
	acl_free(a);
#endif /* !__APPLE__ */
#endif
	return 0;
}