diff --git a/src/tracker-extract/tracker-extract-ps.c b/src/tracker-extract/tracker-extract-ps.c index 9d32116..da7a861 100644 --- a/src/tracker-extract/tracker-extract-ps.c +++ b/src/tracker-extract/tracker-extract-ps.c @@ -29,6 +29,23 @@ #include #include + + +#include +#include +#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__) +# include +# include +# define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) +#else +# define SET_BINARY_MODE(file) +#endif +#define CHUNK 16384 +int inf(FILE *source, FILE *dest); +void zerr(int ret); + + + #include "tracker-extract.h" #if !HAVE_GETLINE @@ -267,3 +284,138 @@ tracker_extract_ps (gchar *filename, GHashTable *metadata) close (fd); } } + + +void +tracker_extract_ps_gz (gchar *filename, GHashTable *metadata) +{ + gint fd; + gint fdz; + FILE *fz; + FILE *f; + +#if defined(__linux__) + if ((fdz = g_open (filename, (O_RDONLY | O_NOATIME))) == -1) { +#else + if ((fdz = g_open (filename, O_RDONLY)) == -1) { +#endif + return; + } + + GError * error = NULL; + gchar * gunzipped = NULL; + fd = g_file_open_tmp ("tracker-extract-ps-gunzipped.XXXXXX", &gunzipped, &error); + + if (error) { + g_error_free (error); + return; + } + + if ((fz = fdopen (fdz, "r"))) { + if ((f = fdopen (fd, "w"))) { + int status = inf (fz, f); + if (status == Z_OK) + tracker_extract_ps (gunzipped, metadata); + else + zerr (status); + fclose (f); + } + fclose (fz); + } + + close (fdz); + close (fd); + + g_unlink (gunzipped); +} + + +/* Decompress from file source to file dest until stream ends or EOF. + * inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be + * allocated for processing, Z_DATA_ERROR if the deflate data is + * invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and + * the version of the library linked do not match, or Z_ERRNO if there + * is an error reading or writing the files. */ +int inf(FILE *source, FILE *dest) +{ + int ret; + unsigned have; + z_stream strm; + unsigned char in[CHUNK]; + unsigned char out[CHUNK]; + + /* allocate inflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + strm.avail_in = 0; + strm.next_in = Z_NULL; + ret = inflateInit(&strm); + if (ret != Z_OK) + return ret; + + /* decompress until deflate stream ends or end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK, source); + if (ferror(source)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + if (strm.avail_in == 0) + break; + strm.next_in = in; + + /* run inflate() on input until output buffer not full */ + do { + strm.avail_out = CHUNK; + strm.next_out = out; + ret = inflate(&strm, Z_NO_FLUSH); + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ + switch (ret) { + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + case Z_DATA_ERROR: + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; + } + have = CHUNK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)inflateEnd(&strm); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* done when inflate() says it's done */ + } while (ret != Z_STREAM_END); + + /* clean up and return */ + (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; +} + +/* report a zlib or i/o error */ +void zerr(int ret) +{ + fputs("zpipe: ", stderr); + switch (ret) { + case Z_ERRNO: + if (ferror(stdin)) + fputs("error reading stdin\n", stderr); + if (ferror(stdout)) + fputs("error writing stdout\n", stderr); + break; + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); + } +} + diff --git a/src/tracker-extract/tracker-extract.c b/src/tracker-extract/tracker-extract.c index 413f76f..2849726 100644 --- a/src/tracker-extract/tracker-extract.c +++ b/src/tracker-extract/tracker-extract.c @@ -65,6 +65,7 @@ void tracker_extract_mplayer (gchar *, GHashTable *); void tracker_extract_totem (gchar *, GHashTable *); void tracker_extract_oasis (gchar *, GHashTable *); void tracker_extract_ps (gchar *, GHashTable *); +void tracker_extract_ps_gz (gchar *, GHashTable *); #ifdef HAVE_LIBXML2 void tracker_extract_html (gchar *, GHashTable *); #endif @@ -102,6 +103,7 @@ void tracker_extract_xine (gchar *, GHashTable *); MimeToExtractor extractors[] = { /* Document extractors */ { "application/vnd.oasis.opendocument.*", tracker_extract_oasis }, + { "application/x-gzpostscript", tracker_extract_ps_gz }, { "application/postscript", tracker_extract_ps }, #ifdef HAVE_LIBXML2 { "text/html", tracker_extract_html },