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; }
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)); }
int32_t xar_linuxattr_extract(xar_t x, xar_file_t f, const char* file, char *buffer, size_t len) { #if defined HAVE_SYS_XATTR_H && defined(HAVE_LSETXATTR) && !defined(__APPLE__) const char *fsname = "bogus"; struct statfs sfs; int eaopt = 0; struct _linuxattr_context context; xar_prop_t p; memset(&context,0,sizeof(struct _linuxattr_context)); /* data buffers, can't store linux attrs */ if(len){ return 0; } /* Check for EA extraction behavior */ memset(&sfs, 0, sizeof(sfs)); if( statfs(file, &sfs) != 0 ) { char *tmp, *bname; tmp = strdup(file); bname = dirname(tmp); statfs(bname, &sfs); free(tmp); } switch(sfs.f_type) { case EXT3_SUPER_MAGIC: fsname = "ext3"; break; /* assume ext3 */ case JFS_SUPER_MAGIC: fsname = "jfs" ; break; case REISERFS_SUPER_MAGIC:fsname = "reiser" ; break; case XFS_SUPER_MAGIC: fsname = "xfs" ; break; }; for(p = xar_prop_pfirst(f); p; p = xar_prop_pnext(p)) { const char *fs = NULL; const char *prop; const char *eaname = NULL; xar_prop_t tmpp; prop = xar_prop_getkey(p); if( strncmp(prop, XAR_EA_FORK, strlen(XAR_EA_FORK)) != 0 ) continue; if( strlen(prop) != strlen(XAR_EA_FORK) ) continue; tmpp = xar_prop_pget(p, "fstype"); if( tmpp ) fs = xar_prop_getvalue(tmpp); if( !eaopt && fs && strcmp(fs, fsname) != 0 ) { continue; } if( !fs ) continue; tmpp = xar_prop_pget(p, "name"); if( tmpp ) eaname = xar_prop_getvalue(tmpp); context.file = file; context.attrname = eaname; xar_attrcopy_from_heap(x, f, p, xar_linuxattr_write, &context); } #endif return 0; }