diff options
Diffstat (limited to 'src/archive')
-rw-r--r-- | src/archive/bz2_archive_plugin.c (renamed from src/archive/bz2_plugin.c) | 174 | ||||
-rw-r--r-- | src/archive/bz2_archive_plugin.h | 25 | ||||
-rw-r--r-- | src/archive/iso9660_archive_plugin.c (renamed from src/archive/iso_plugin.c) | 107 | ||||
-rw-r--r-- | src/archive/iso9660_archive_plugin.h | 25 | ||||
-rw-r--r-- | src/archive/zzip_archive_plugin.c (renamed from src/archive/zip_plugin.c) | 104 | ||||
-rw-r--r-- | src/archive/zzip_archive_plugin.h | 25 |
6 files changed, 288 insertions, 172 deletions
diff --git a/src/archive/bz2_plugin.c b/src/archive/bz2_archive_plugin.c index 0ef042e90..b3a9027af 100644 --- a/src/archive/bz2_plugin.c +++ b/src/archive/bz2_archive_plugin.c @@ -21,9 +21,10 @@ * single bz2 archive handling (requires libbz2) */ +#include "config.h" +#include "archive/bz2_archive_plugin.h" #include "archive_api.h" #include "input_plugin.h" -#include "config.h" #include <stdint.h> #include <stddef.h> @@ -32,30 +33,40 @@ #include <bzlib.h> #ifdef HAVE_OLDER_BZIP2 -#define BZ2_bzDecompressInit bzDecompressInit -#define BZ2_bzDecompress bzDecompress +#define BZ2_bzDecompressInit bzDecompressInit +#define BZ2_bzDecompress bzDecompress #endif #define BZ_BUFSIZE 5000 -typedef struct { - char *name; - bool reset; +struct bz2_archive_file { + struct archive_file base; + + char *name; + bool reset; struct input_stream istream; - int last_bz_result; - int last_parent_result; - bz_stream bzstream; - char *buffer; -} bz2_context; + bool eof; + + bz_stream bzstream; + char *buffer; +}; static const struct input_plugin bz2_inputplugin; +static inline GQuark +bz2_quark(void) +{ + return g_quark_from_static_string("bz2"); +} + /* single archive handling allocation helpers */ static bool -bz2_alloc(bz2_context *data) +bz2_alloc(struct bz2_archive_file *data, GError **error_r) { + int ret; + data->bzstream.bzalloc = NULL; data->bzstream.bzfree = NULL; data->bzstream.opaque = NULL; @@ -64,19 +75,21 @@ bz2_alloc(bz2_context *data) data->bzstream.next_in = (void *) data->buffer; data->bzstream.avail_in = 0; - if (BZ2_bzDecompressInit(&data->bzstream, 0, 0) != BZ_OK) { + ret = BZ2_bzDecompressInit(&data->bzstream, 0, 0); + if (ret != BZ_OK) { g_free(data->buffer); g_free(data); + + g_set_error(error_r, bz2_quark(), ret, + "BZ2_bzDecompressInit() has failed"); return false; } - data->last_bz_result = BZ_OK; - data->last_parent_result = 0; return true; } static void -bz2_destroy(bz2_context *data) +bz2_destroy(struct bz2_archive_file *data) { BZ2_bzDecompressEnd(&data->bzstream); g_free(data->buffer); @@ -85,61 +98,56 @@ bz2_destroy(bz2_context *data) /* archive open && listing routine */ static struct archive_file * -bz2_open(char * pathname) +bz2_open(const char *pathname, GError **error_r) { - bz2_context *context; - char *name; + struct bz2_archive_file *context; int len; - context = g_malloc(sizeof(bz2_context)); - if (!context) { - return NULL; - } + context = g_malloc(sizeof(*context)); + archive_file_init(&context->base, &bz2_archive_plugin); + //open archive - if (!input_stream_open(&context->istream, pathname)) { - g_warning("failed to open an bzip2 archive %s\n",pathname); - g_free(context); - return NULL; - } - //capture filename - name = strrchr(pathname, '/'); - if (name == NULL) { - g_warning("failed to get bzip2 name from %s\n",pathname); + if (!input_stream_open(&context->istream, pathname, error_r)) { g_free(context); return NULL; } - context->name = g_strdup(name+1); + + context->name = g_path_get_basename(pathname); + //remove suffix len = strlen(context->name); if (len > 4) { - context->name[len-4] = 0; //remove .bz2 suffix + context->name[len - 4] = 0; //remove .bz2 suffix } - return (struct archive_file *) context; + + return &context->base; } static void bz2_scan_reset(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; context->reset = true; } static char * bz2_scan_next(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; char *name = NULL; + if (context->reset) { name = context->name; context->reset = false; } + return name; } static void bz2_close(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; g_free(context->name); @@ -151,35 +159,36 @@ bz2_close(struct archive_file *file) static bool bz2_open_stream(struct archive_file *file, struct input_stream *is, - G_GNUC_UNUSED const char *path) + G_GNUC_UNUSED const char *path, GError **error_r) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; + //setup file ops is->plugin = &bz2_inputplugin; //insert back reference is->data = context; is->seekable = false; - if (!bz2_alloc(context)) { - g_warning("alloc bz2 failed\n"); + if (!bz2_alloc(context, error_r)) return false; - } + + context->eof = false; + return true; } static void bz2_is_close(struct input_stream *is) { - bz2_context *context = (bz2_context *) is->data; + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; bz2_destroy(context); is->data = NULL; bz2_close((struct archive_file *)context); } -static int -bz2_fillbuffer(bz2_context *context, - size_t numBytes) +static bool +bz2_fillbuffer(struct bz2_archive_file *context, GError **error_r) { size_t count; bz_stream *bzstream; @@ -187,76 +196,65 @@ bz2_fillbuffer(bz2_context *context, bzstream = &context->bzstream; if (bzstream->avail_in > 0) - return 0; + return true; count = input_stream_read(&context->istream, - context->buffer, BZ_BUFSIZE); - - if (count == 0) { - if (bzstream->avail_out == numBytes) - return -1; - if (!input_stream_eof(&context->istream)) - context->last_parent_result = 1; - } else { - bzstream->next_in = context->buffer; - bzstream->avail_in = count; - } + context->buffer, BZ_BUFSIZE, + error_r); + if (count == 0) + return false; - return 0; + bzstream->next_in = context->buffer; + bzstream->avail_in = count; + return true; } static size_t -bz2_is_read(struct input_stream *is, void *ptr, size_t size) +bz2_is_read(struct input_stream *is, void *ptr, size_t length, + GError **error_r) { - bz2_context *context = (bz2_context *) is->data; + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; bz_stream *bzstream; int bz_result; - size_t numBytes = size; - size_t bytesRead = 0; + size_t nbytes = 0; - if (context->last_bz_result != BZ_OK) - return 0; - if (context->last_parent_result != 0) + if (context->eof) return 0; bzstream = &context->bzstream; bzstream->next_out = ptr; - bzstream->avail_out = numBytes; + bzstream->avail_out = length; - while (bzstream->avail_out != 0) { - if (bz2_fillbuffer(context, numBytes) != 0) - break; + do { + if (!bz2_fillbuffer(context, error_r)) + return 0; bz_result = BZ2_bzDecompress(bzstream); - if (context->last_bz_result != BZ_OK - && bzstream->avail_out == numBytes) { - context->last_bz_result = bz_result; + if (bz_result == BZ_STREAM_END) { + context->eof = true; break; } - if (bz_result == BZ_STREAM_END) { - context->last_bz_result = bz_result; - break; + if (bz_result != BZ_OK) { + g_set_error(error_r, bz2_quark(), bz_result, + "BZ2_bzDecompress() has failed"); + return 0; } - } + } while (bzstream->avail_out == length); - bytesRead = numBytes - bzstream->avail_out; - is->offset += bytesRead; + nbytes = length - bzstream->avail_out; + is->offset += nbytes; - return bytesRead; + return nbytes; } static bool bz2_is_eof(struct input_stream *is) { - bz2_context *context = (bz2_context *) is->data; - - if (context->last_bz_result == BZ_STREAM_END) { - return true; - } + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; - return false; + return context->eof; } /* exported structures */ @@ -272,7 +270,7 @@ static const struct input_plugin bz2_inputplugin = { .eof = bz2_is_eof, }; -const struct archive_plugin bz2_plugin = { +const struct archive_plugin bz2_archive_plugin = { .name = "bz2", .open = bz2_open, .scan_reset = bz2_scan_reset, diff --git a/src/archive/bz2_archive_plugin.h b/src/archive/bz2_archive_plugin.h new file mode 100644 index 000000000..42b0c48ed --- /dev/null +++ b/src/archive/bz2_archive_plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_BZ2_H +#define MPD_ARCHIVE_BZ2_H + +extern const struct archive_plugin bz2_archive_plugin; + +#endif diff --git a/src/archive/iso_plugin.c b/src/archive/iso9660_archive_plugin.c index 9063af0fc..780268df8 100644 --- a/src/archive/iso_plugin.c +++ b/src/archive/iso9660_archive_plugin.c @@ -21,6 +21,8 @@ * iso archive handling (requires cdio, and iso9660) */ +#include "config.h" +#include "archive/iso9660_archive_plugin.h" #include "archive_api.h" #include "input_plugin.h" @@ -32,21 +34,29 @@ #define CEILING(x, y) ((x+(y-1))/y) -typedef struct { +struct iso9660_archive_file { + struct archive_file base; + iso9660_t *iso; iso9660_stat_t *statbuf; size_t cur_ofs; size_t max_blocks; GSList *list; GSList *iter; -} iso_context; +}; + +static const struct input_plugin iso9660_input_plugin; -static const struct input_plugin iso_inputplugin; +static inline GQuark +iso9660_quark(void) +{ + return g_quark_from_static_string("iso9660"); +} /* archive open && listing routine */ static void -listdir_recur(const char *psz_path, iso_context *context) +listdir_recur(const char *psz_path, struct iso9660_archive_file *context) { iso9660_t *iso = context->iso; CdioList_t *entlist; @@ -80,36 +90,44 @@ listdir_recur(const char *psz_path, iso_context *context) } static struct archive_file * -iso_open(char * pathname) +iso9660_archive_open(const char *pathname, GError **error_r) { - iso_context *context = g_malloc(sizeof(iso_context)); + struct iso9660_archive_file *context = + g_new(struct iso9660_archive_file, 1); + + archive_file_init(&context->base, &iso9660_archive_plugin); context->list = NULL; /* open archive */ context->iso = iso9660_open (pathname); if (context->iso == NULL) { - g_warning("iso %s open failed\n", pathname); + g_set_error(error_r, iso9660_quark(), 0, + "Failed to open ISO9660 file %s", pathname); return NULL; } listdir_recur("/", context); - return (struct archive_file *)context; + return &context->base; } static void -iso_scan_reset(struct archive_file *file) +iso9660_archive_scan_reset(struct archive_file *file) { - iso_context *context = (iso_context *) file; + struct iso9660_archive_file *context = + (struct iso9660_archive_file *)file; + //reset iterator context->iter = context->list; } static char * -iso_scan_next(struct archive_file *file) +iso9660_archive_scan_next(struct archive_file *file) { - iso_context *context = (iso_context *) file; + struct iso9660_archive_file *context = + (struct iso9660_archive_file *)file; + char *data = NULL; if (context->iter != NULL) { ///fetch data and goto next @@ -120,9 +138,11 @@ iso_scan_next(struct archive_file *file) } static void -iso_close(struct archive_file *file) +iso9660_archive_close(struct archive_file *file) { - iso_context *context = (iso_context *) file; + struct iso9660_archive_file *context = + (struct iso9660_archive_file *)file; + GSList *tmp; if (context->list) { //free list @@ -139,12 +159,14 @@ iso_close(struct archive_file *file) /* single archive handling */ static bool -iso_open_stream(struct archive_file *file, struct input_stream *is, - const char *pathname) +iso9660_archive_open_stream(struct archive_file *file, struct input_stream *is, + const char *pathname, GError **error_r) { - iso_context *context = (iso_context *) file; + struct iso9660_archive_file *context = + (struct iso9660_archive_file *)file; + //setup file ops - is->plugin = &iso_inputplugin; + is->plugin = &iso9660_input_plugin; //insert back reference is->data = context; //we are not seekable @@ -153,7 +175,8 @@ iso_open_stream(struct archive_file *file, struct input_stream *is, context->statbuf = iso9660_ifs_stat_translate (context->iso, pathname); if (context->statbuf == NULL) { - g_warning("file %s not found in iso\n", pathname); + g_set_error(error_r, iso9660_quark(), 0, + "not found in the ISO file: %s", pathname); return false; } context->cur_ofs = 0; @@ -162,19 +185,19 @@ iso_open_stream(struct archive_file *file, struct input_stream *is, } static void -iso_is_close(struct input_stream *is) +iso9660_input_close(struct input_stream *is) { - iso_context *context = (iso_context *) is->data; + struct iso9660_archive_file *context = is->data; g_free(context->statbuf); - iso_close((struct archive_file *)context); + iso9660_archive_close((struct archive_file *)context); } static size_t -iso_is_read(struct input_stream *is, void *ptr, size_t size) +iso9660_input_read(struct input_stream *is, void *ptr, size_t size, GError **error_r) { - iso_context *context = (iso_context *) is->data; + struct iso9660_archive_file *context = (struct iso9660_archive_file *) is->data; int toread, readed = 0; int no_blocks, cur_block; size_t left_bytes = context->statbuf->size - context->cur_ofs; @@ -196,9 +219,10 @@ iso_is_read(struct input_stream *is, void *ptr, size_t size) context->statbuf->lsn + cur_block, no_blocks); if (readed != no_blocks * ISO_BLOCKSIZE) { - g_warning("error reading ISO file at lsn %lu\n", - (long unsigned int) cur_block ); - return -1; + g_set_error(error_r, iso9660_quark(), 0, + "error reading ISO file at lsn %lu", + (long unsigned int) cur_block); + return 0; } if (left_bytes < size) { readed = left_bytes; @@ -209,31 +233,32 @@ iso_is_read(struct input_stream *is, void *ptr, size_t size) } static bool -iso_is_eof(struct input_stream *is) +iso9660_input_eof(struct input_stream *is) { - iso_context *context = (iso_context *) is->data; + struct iso9660_archive_file *context = is->data; + return (context->cur_ofs == context->statbuf->size); } /* exported structures */ -static const char *const iso_extensions[] = { +static const char *const iso9660_archive_extensions[] = { "iso", NULL }; -static const struct input_plugin iso_inputplugin = { - .close = iso_is_close, - .read = iso_is_read, - .eof = iso_is_eof, +static const struct input_plugin iso9660_input_plugin = { + .close = iso9660_input_close, + .read = iso9660_input_read, + .eof = iso9660_input_eof, }; -const struct archive_plugin iso_plugin = { +const struct archive_plugin iso9660_archive_plugin = { .name = "iso", - .open = iso_open, - .scan_reset = iso_scan_reset, - .scan_next = iso_scan_next, - .open_stream = iso_open_stream, - .close = iso_close, - .suffixes = iso_extensions + .open = iso9660_archive_open, + .scan_reset = iso9660_archive_scan_reset, + .scan_next = iso9660_archive_scan_next, + .open_stream = iso9660_archive_open_stream, + .close = iso9660_archive_close, + .suffixes = iso9660_archive_extensions }; diff --git a/src/archive/iso9660_archive_plugin.h b/src/archive/iso9660_archive_plugin.h new file mode 100644 index 000000000..21730c537 --- /dev/null +++ b/src/archive/iso9660_archive_plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_ISO9660_H +#define MPD_ARCHIVE_ISO9660_H + +extern const struct archive_plugin iso9660_archive_plugin; + +#endif diff --git a/src/archive/zip_plugin.c b/src/archive/zzip_archive_plugin.c index 243d46418..43c880aab 100644 --- a/src/archive/zip_plugin.c +++ b/src/archive/zzip_archive_plugin.c @@ -21,6 +21,8 @@ * zip archive handling (requires zziplib) */ +#include "config.h" +#include "archive/zzip_archive_plugin.h" #include "archive_api.h" #include "archive_api.h" #include "input_plugin.h" @@ -29,29 +31,40 @@ #include <glib.h> #include <string.h> -typedef struct { +struct zzip_archive { + struct archive_file base; + ZZIP_DIR *dir; ZZIP_FILE *file; size_t length; GSList *list; GSList *iter; -} zip_context; +}; + +static const struct input_plugin zzip_input_plugin; -static const struct input_plugin zip_inputplugin; +static inline GQuark +zzip_quark(void) +{ + return g_quark_from_static_string("zzip"); +} /* archive open && listing routine */ static struct archive_file * -zip_open(char * pathname) +zzip_archive_open(const char *pathname, GError **error_r) { - zip_context *context = g_malloc(sizeof(zip_context)); + struct zzip_archive *context = g_malloc(sizeof(*context)); ZZIP_DIRENT dirent; + archive_file_init(&context->base, &zzip_archive_plugin); + // open archive context->list = NULL; context->dir = zzip_dir_open(pathname, NULL); if (context->dir == NULL) { - g_warning("zipfile %s open failed\n", pathname); + g_set_error(error_r, zzip_quark(), 0, + "Failed to open ZIP file %s", pathname); return NULL; } @@ -63,21 +76,21 @@ zip_open(char * pathname) } } - return (struct archive_file *)context; + return &context->base; } static void -zip_scan_reset(struct archive_file *file) +zzip_archive_scan_reset(struct archive_file *file) { - zip_context *context = (zip_context *) file; + struct zzip_archive *context = (struct zzip_archive *) file; //reset iterator context->iter = context->list; } static char * -zip_scan_next(struct archive_file *file) +zzip_archive_scan_next(struct archive_file *file) { - zip_context *context = (zip_context *) file; + struct zzip_archive *context = (struct zzip_archive *) file; char *data = NULL; if (context->iter != NULL) { ///fetch data and goto next @@ -88,9 +101,9 @@ zip_scan_next(struct archive_file *file) } static void -zip_close(struct archive_file *file) +zzip_archive_close(struct archive_file *file) { - zip_context *context = (zip_context *) file; + struct zzip_archive *context = (struct zzip_archive *) file; if (context->list) { //free list for (GSList *tmp = context->list; tmp != NULL; tmp = g_slist_next(tmp)) @@ -106,14 +119,14 @@ zip_close(struct archive_file *file) /* single archive handling */ static bool -zip_open_stream(struct archive_file *file, struct input_stream *is, - const char *pathname) +zzip_archive_open_stream(struct archive_file *file, struct input_stream *is, + const char *pathname, GError **error_r) { - zip_context *context = (zip_context *) file; + struct zzip_archive *context = (struct zzip_archive *) file; ZZIP_STAT z_stat; //setup file ops - is->plugin = &zip_inputplugin; + is->plugin = &zzip_input_plugin; //insert back reference is->data = context; //we are seekable (but its not recommendent to do so) @@ -121,7 +134,8 @@ zip_open_stream(struct archive_file *file, struct input_stream *is, context->file = zzip_file_open(context->dir, pathname, 0); if (!context->file) { - g_warning("file %s not found in the zipfile\n", pathname); + g_set_error(error_r, zzip_quark(), 0, + "not found in the ZIP file: %s", pathname); return false; } zzip_file_stat(context->file, &z_stat); @@ -130,41 +144,45 @@ zip_open_stream(struct archive_file *file, struct input_stream *is, } static void -zip_is_close(struct input_stream *is) +zzip_input_close(struct input_stream *is) { - zip_context *context = (zip_context *) is->data; + struct zzip_archive *context = (struct zzip_archive *) is->data; zzip_file_close (context->file); - zip_close((struct archive_file *)context); + zzip_archive_close((struct archive_file *)context); } static size_t -zip_is_read(struct input_stream *is, void *ptr, size_t size) +zzip_input_read(struct input_stream *is, void *ptr, size_t size, + GError **error_r) { - zip_context *context = (zip_context *) is->data; + struct zzip_archive *context = (struct zzip_archive *) is->data; int ret; ret = zzip_file_read(context->file, ptr, size); if (ret < 0) { - g_warning("error %d reading zipfile\n", ret); + g_set_error(error_r, zzip_quark(), ret, + "zzip_file_read() has failed"); return 0; } return ret; } static bool -zip_is_eof(struct input_stream *is) +zzip_input_eof(struct input_stream *is) { - zip_context *context = (zip_context *) is->data; + struct zzip_archive *context = (struct zzip_archive *) is->data; return ((size_t) zzip_tell(context->file) == context->length); } static bool -zip_is_seek(G_GNUC_UNUSED struct input_stream *is, - G_GNUC_UNUSED off_t offset, G_GNUC_UNUSED int whence) +zzip_input_seek(struct input_stream *is, + goffset offset, int whence, GError **error_r) { - zip_context *context = (zip_context *) is->data; + struct zzip_archive *context = (struct zzip_archive *) is->data; zzip_off_t ofs = zzip_seek(context->file, offset, whence); if (ofs != -1) { + g_set_error(error_r, zzip_quark(), ofs, + "zzip_seek() has failed"); is->offset = ofs; return true; } @@ -173,24 +191,24 @@ zip_is_seek(G_GNUC_UNUSED struct input_stream *is, /* exported structures */ -static const char *const zip_extensions[] = { +static const char *const zzip_archive_extensions[] = { "zip", NULL }; -static const struct input_plugin zip_inputplugin = { - .close = zip_is_close, - .read = zip_is_read, - .eof = zip_is_eof, - .seek = zip_is_seek, +static const struct input_plugin zzip_input_plugin = { + .close = zzip_input_close, + .read = zzip_input_read, + .eof = zzip_input_eof, + .seek = zzip_input_seek, }; -const struct archive_plugin zip_plugin = { - .name = "zip", - .open = zip_open, - .scan_reset = zip_scan_reset, - .scan_next = zip_scan_next, - .open_stream = zip_open_stream, - .close = zip_close, - .suffixes = zip_extensions +const struct archive_plugin zzip_archive_plugin = { + .name = "zzip", + .open = zzip_archive_open, + .scan_reset = zzip_archive_scan_reset, + .scan_next = zzip_archive_scan_next, + .open_stream = zzip_archive_open_stream, + .close = zzip_archive_close, + .suffixes = zzip_archive_extensions }; diff --git a/src/archive/zzip_archive_plugin.h b/src/archive/zzip_archive_plugin.h new file mode 100644 index 000000000..07a8a2eca --- /dev/null +++ b/src/archive/zzip_archive_plugin.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2003-2009 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_ARCHIVE_ZZIP_H +#define MPD_ARCHIVE_ZZIP_H + +extern const struct archive_plugin zzip_archive_plugin; + +#endif |