static foreign_t archive_property(term_t archive, term_t prop, term_t value) { archive_wrapper *ar; atom_t pn; const char *s; if ( !get_archive(archive, &ar) || !PL_get_atom_ex(prop, &pn) ) return FALSE; #ifdef HAVE_ARCHIVE_FILTER_COUNT if ( pn == ATOM_filter ) { int i, fcount = archive_filter_count(ar->archive); term_t tail = PL_copy_term_ref(value); term_t head = PL_new_term_ref(); for(i=0; i<fcount; i++) { s = archive_filter_name(ar->archive, i); if ( !s || strcmp(s, "none") == 0 ) continue; if ( !PL_unify_list(tail, head, tail) || !PL_unify_atom_chars(head, s) ) return FALSE; } return PL_unify_nil(tail); } #endif return FALSE; }
FILE * uncompress(FILE *f, FILE* out, enum Options options) { int fdtmp = -1, i, size; struct archive *a = NULL; struct archive_entry *entry; FILE *rv = f, *ftmp; char buf[BUFSIZ], tmpfile[] = "/tmp/nile.XXXXXX", nfilter = 0; if(!(options & NILE_DECOMPRESS)) goto uncompress_cleanup; a = archive_read_new(); archive_read_support_filter_all(a); archive_read_support_format_raw(a); if(archive_read_open_FILE(a, f) != ARCHIVE_OK || archive_read_next_header(a, &entry) != ARCHIVE_OK) { fprintf(stderr, "Warning: decompression failed while open\n"); goto uncompress_cleanup; } if((nfilter = archive_filter_count(a)) == 0) { goto uncompress_cleanup; } if((fdtmp = mkstemp(tmpfile)) == -1) { perror("mkstemp"); goto uncompress_cleanup; } while((size = archive_read_data(a, buf, sizeof(buf))) > 0) { write(fdtmp, buf, size); } if (size < 0) { fprintf(stderr, "Warning: decompression failed read\n"); goto uncompress_cleanup; } if((ftmp = fdopen(fdtmp, "r")) == NULL) { perror("fdopen"); goto uncompress_cleanup; } rv = ftmp; uncompress_cleanup: rewind(f); if(out != NULL) { for(i = 0; i < nfilter; i++) { fputc(archive_filter_code(a, i), out); } for(i = i % HEADER_PADDING; i < HEADER_PADDING; i++) { fputc(0, out); } } if(fdtmp > 0) close(fdtmp); if(a != NULL) { archive_read_free(a); } return rv; }