mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-07-01 01:29:43 +00:00
Use zlib instead of fork/exec gzip executable
* Now all disk images are saved gzipped
This commit is contained in:
parent
e6ee8db900
commit
f5c8df9a4a
|
@ -77,10 +77,10 @@ bin_PROGRAMS = xapple2-80col
|
||||||
|
|
||||||
|
|
||||||
EXTRA_xapple2_80col_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
EXTRA_xapple2_80col_SOURCES = debugger.c opcodes.c debug.c joystick.c
|
||||||
xapple2_80col_SOURCES = cpu.S memory.S glue.S keys.c prefs.c disk.c font.c cpu-supp.c misc.c win-shim.c soundcore.c soundcore-openal.c alhelpers.c speaker.c AY8910.c mockingboard.c interface.c timing.c
|
xapple2_80col_SOURCES = cpu.S memory.S glue.S keys.c prefs.c disk.c font.c cpu-supp.c misc.c win-shim.c soundcore.c soundcore-openal.c alhelpers.c speaker.c AY8910.c mockingboard.c interface.c timing.c zlib-helpers.c
|
||||||
|
|
||||||
|
|
||||||
xapple2_80col_LDADD = joystick.o vidsup-80.o xvideo-80.o display-80.o -L/usr/lib/i386-linux-gnu -lX11 -lXext -lrt -lopenal -lpthread
|
xapple2_80col_LDADD = joystick.o vidsup-80.o xvideo-80.o display-80.o -L/usr/lib/i386-linux-gnu -L/lib/i386-linux-gnu -lX11 -lXext -lrt -lopenal -lpthread -lz
|
||||||
|
|
||||||
xapple2_80col_DEPENDENCIES = joystick.o vidsup-80.o xvideo-80.o display-80.o
|
xapple2_80col_DEPENDENCIES = joystick.o vidsup-80.o xvideo-80.o display-80.o
|
||||||
|
|
||||||
|
@ -105,7 +105,7 @@ X_CFLAGS =
|
||||||
X_LIBS =
|
X_LIBS =
|
||||||
X_EXTRA_LIBS =
|
X_EXTRA_LIBS =
|
||||||
X_PRE_LIBS = -lSM -lICE
|
X_PRE_LIBS = -lSM -lICE
|
||||||
xapple2_80col_OBJECTS = cpu.o memory.o glue.o keys.o prefs.o disk.o debugger.o opcodes.o debug.o font.o cpu-supp.o misc.o AY8910.o mockingboard.o win-shim.o soundcore.o soundcore-openal.o alhelpers.o speaker.o interface.o timing.o
|
xapple2_80col_OBJECTS = cpu.o memory.o glue.o keys.o prefs.o disk.o debugger.o opcodes.o debug.o font.o cpu-supp.o misc.o AY8910.o mockingboard.o win-shim.o soundcore.o soundcore-openal.o alhelpers.o speaker.o interface.o timing.o zlib-helpers.o
|
||||||
xapple2_80col_LDFLAGS =
|
xapple2_80col_LDFLAGS =
|
||||||
genfont_SOURCES = genfont.c
|
genfont_SOURCES = genfont.c
|
||||||
genfont_OBJECTS = genfont.o
|
genfont_OBJECTS = genfont.o
|
||||||
|
|
56
src/disk.c
56
src/disk.c
|
@ -14,20 +14,17 @@
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
#include <assert.h>
|
|
||||||
|
|
||||||
#include "disk.h"
|
#include "disk.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "glue.h"
|
#include "glue.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
|
#include "keys.h"
|
||||||
|
#include "interface.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "zlib-helpers.h"
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#define PHASE_BYTES 3328
|
#define PHASE_BYTES 3328
|
||||||
|
|
||||||
|
@ -95,32 +92,37 @@ void c_init_6()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
/* -------------------------------------------------------------------------
|
||||||
c_eject_6() - assumes privileged access to image file (to re-gzip)
|
c_eject_6() - ejects/gzips image file
|
||||||
------------------------------------------------------------------------- */
|
------------------------------------------------------------------------- */
|
||||||
|
|
||||||
void c_eject_6(int drive) {
|
void c_eject_6(int drive) {
|
||||||
pid_t pid;
|
int ch = -1;
|
||||||
|
|
||||||
|
#define ZLIB_SUBMENU_H 7
|
||||||
|
#define ZLIB_SUBMENU_W 40
|
||||||
|
char zlibmenu[ZLIB_SUBMENU_H][ZLIB_SUBMENU_W+1] =
|
||||||
|
//1. 5. 10. 15. 20. 25. 30. 35. 40.
|
||||||
|
{ "||||||||||||||||||||||||||||||||||||||||",
|
||||||
|
"| |",
|
||||||
|
"| An error occurred when attempting to |",
|
||||||
|
"| compress a disk image: |",
|
||||||
|
"| |",
|
||||||
|
"| |",
|
||||||
|
"||||||||||||||||||||||||||||||||||||||||" };
|
||||||
|
|
||||||
if (disk6.disk[drive].compressed)
|
if (disk6.disk[drive].compressed)
|
||||||
{
|
{
|
||||||
/* gzip the last disk if it was compressed_6 */
|
// foo.dsk -> foo.dsk.gz
|
||||||
if ((pid = fork())) /* parent process */
|
const char* const err = def(disk6.disk[drive].file_name, Z_DEFAULT_COMPRESSION);
|
||||||
{ /* privileged mode - gzip in place */
|
if (err)
|
||||||
waitpid(pid, NULL, 0);
|
{
|
||||||
}
|
snprintf(&zlibmenu[4][2], 37, "%s", err);
|
||||||
else
|
c_interface_print_submenu_centered(zlibmenu[0], ZLIB_SUBMENU_W, ZLIB_SUBMENU_H);
|
||||||
if (!pid) /* child process */
|
while ((ch = c_mygetch(1)) == -1) { }
|
||||||
{ /* privileged mode - gzip in place */
|
|
||||||
if (execl("/bin/gzip", "/bin/gzip",
|
|
||||||
disk6.disk[drive].file_name, NULL) == -1)
|
|
||||||
{
|
|
||||||
perror("Problem exec'ing /bin/gzip");
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
perror("Problem calling fork" );
|
unlink(disk6.disk[drive].file_name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +156,6 @@ int c_new_diskette_6(int drive, char *file_name, int cmpr, int nib, int force) {
|
||||||
disk6.disk[drive].fp = NULL;
|
disk6.disk[drive].fp = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set to users privilege level for disk access */
|
|
||||||
|
|
||||||
if (stat(disk6.disk[drive].file_name, &buf) < 0)
|
if (stat(disk6.disk[drive].file_name, &buf) < 0)
|
||||||
{
|
{
|
||||||
disk6.disk[drive].fp = NULL;
|
disk6.disk[drive].fp = NULL;
|
||||||
|
|
|
@ -16,6 +16,9 @@
|
||||||
|
|
||||||
|
|
||||||
#ifndef A2_DISK_H
|
#ifndef A2_DISK_H
|
||||||
|
#define A2_DISK_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
struct diskette
|
struct diskette
|
||||||
{
|
{
|
||||||
|
@ -64,5 +67,4 @@ disk_write_latch(),
|
||||||
disk_read_prepare_in(),
|
disk_read_prepare_in(),
|
||||||
disk_read_prepare_out();
|
disk_read_prepare_out();
|
||||||
|
|
||||||
#define A2_DISK_H
|
|
||||||
#endif
|
#endif
|
||||||
|
|
151
src/interface.c
151
src/interface.c
|
@ -24,6 +24,9 @@
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "prefs.h"
|
#include "prefs.h"
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
#include "zlib-helpers.h"
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
#define MOUSETEXT_BEGIN 0x90
|
#define MOUSETEXT_BEGIN 0x90
|
||||||
|
|
||||||
|
@ -556,27 +559,21 @@ void c_interface_select_diskette( int drive )
|
||||||
}
|
}
|
||||||
while (ch == -1);
|
while (ch == -1);
|
||||||
|
|
||||||
if (ch == kUP) /* Arrow up */
|
if (ch == kUP)
|
||||||
{
|
{
|
||||||
if (curpos > 0)
|
if (curpos > 0)
|
||||||
{
|
{
|
||||||
curpos--;
|
curpos--;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (ch == kDOWN) /* Arrow down */
|
else if (ch == kDOWN)
|
||||||
{
|
{
|
||||||
if (curpos < entries - 1)
|
if (curpos < entries - 1)
|
||||||
{
|
{
|
||||||
curpos++;
|
curpos++;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (ch == kPGDN) /* Page down */
|
else if (ch == kPGDN)
|
||||||
{
|
{
|
||||||
curpos += 16;
|
curpos += 16;
|
||||||
if (curpos > entries - 1)
|
if (curpos > entries - 1)
|
||||||
|
@ -584,7 +581,7 @@ void c_interface_select_diskette( int drive )
|
||||||
curpos = entries - 1;
|
curpos = entries - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ch == kPGUP) /* Page up */
|
else if (ch == kPGUP)
|
||||||
{
|
{
|
||||||
curpos -= 16;
|
curpos -= 16;
|
||||||
if (curpos < 0)
|
if (curpos < 0)
|
||||||
|
@ -592,15 +589,15 @@ void c_interface_select_diskette( int drive )
|
||||||
curpos = 0;
|
curpos = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (ch == kHOME) /* Home */
|
else if (ch == kHOME)
|
||||||
{
|
{
|
||||||
curpos = 0;
|
curpos = 0;
|
||||||
}
|
}
|
||||||
else if (ch == kEND) /* End */
|
else if (ch == kEND)
|
||||||
{
|
{
|
||||||
curpos = entries - 1;
|
curpos = entries - 1;
|
||||||
}
|
}
|
||||||
else if (ch == kESC) /* ESC */
|
else if (ch == kESC)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -635,7 +632,7 @@ void c_interface_select_diskette( int drive )
|
||||||
|
|
||||||
c_interface_print_screen( screen );
|
c_interface_print_screen( screen );
|
||||||
}
|
}
|
||||||
else if ((ch == 13) || (toupper(ch) == 'W')) /* Return */
|
else if ((ch == 13) || (toupper(ch) == 'W'))
|
||||||
{
|
{
|
||||||
#define PERM_SUBMENU_H 5
|
#define PERM_SUBMENU_H 5
|
||||||
#define PERM_SUBMENU_W 40
|
#define PERM_SUBMENU_W 40
|
||||||
|
@ -647,7 +644,7 @@ void c_interface_select_diskette( int drive )
|
||||||
"| |",
|
"| |",
|
||||||
"||||||||||||||||||||||||||||||||||||||||" };
|
"||||||||||||||||||||||||||||||||||||||||" };
|
||||||
|
|
||||||
int len, cmpr = 0;
|
int len;
|
||||||
|
|
||||||
snprintf(temp, TEMPSIZE, "%s/%s",
|
snprintf(temp, TEMPSIZE, "%s/%s",
|
||||||
disk_path, namelist[ curpos ]->d_name );
|
disk_path, namelist[ curpos ]->d_name );
|
||||||
|
@ -678,6 +675,7 @@ void c_interface_select_diskette( int drive )
|
||||||
|
|
||||||
/* eject the disk and start over */
|
/* eject the disk and start over */
|
||||||
c_eject_6(drive);
|
c_eject_6(drive);
|
||||||
|
c_interface_print_screen( screen );
|
||||||
|
|
||||||
nextdir = true;
|
nextdir = true;
|
||||||
break;
|
break;
|
||||||
|
@ -689,7 +687,7 @@ void c_interface_select_diskette( int drive )
|
||||||
{
|
{
|
||||||
if (toupper(ch) == 'W')
|
if (toupper(ch) == 'W')
|
||||||
{
|
{
|
||||||
continue; /* can't protect this */
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((disk_path[len-1]) == '/')
|
if ((disk_path[len-1]) == '/')
|
||||||
|
@ -714,108 +712,45 @@ void c_interface_select_diskette( int drive )
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define ZLIB_SUBMENU_H 7
|
||||||
|
#define ZLIB_SUBMENU_W 40
|
||||||
|
char zlibmenu[ZLIB_SUBMENU_H][ZLIB_SUBMENU_W+1] =
|
||||||
|
//1. 5. 10. 15. 20. 25. 30. 35. 40.
|
||||||
|
{ "||||||||||||||||||||||||||||||||||||||||",
|
||||||
|
"| |",
|
||||||
|
"| An error occurred when attempting to |",
|
||||||
|
"| uncompress a disk image: |",
|
||||||
|
"| |",
|
||||||
|
"| |",
|
||||||
|
"||||||||||||||||||||||||||||||||||||||||" };
|
||||||
|
#define SHOW_ZLIB_ERROR() \
|
||||||
|
c_interface_print_submenu_centered(zlibmenu[0], ZLIB_SUBMENU_W, ZLIB_SUBMENU_H); \
|
||||||
|
while ((ch = c_mygetch(1)) == -1) { } \
|
||||||
|
c_interface_print_screen( screen );
|
||||||
|
|
||||||
/* uncompress the gziped disk */
|
/* uncompress the gziped disk */
|
||||||
if (c_interface_is_gz(temp))
|
if (c_interface_is_gz(temp))
|
||||||
{
|
{
|
||||||
if ((pid = fork())) /* parent process */
|
const char* const err = inf(temp); // foo.dsk.gz -> foo.dsk
|
||||||
|
if (err)
|
||||||
{
|
{
|
||||||
c_interface_print( 1, 21, 0,
|
snprintf(&zlibmenu[4][2], 37, "%s", err);
|
||||||
" Uncompressing... " );
|
SHOW_ZLIB_ERROR();
|
||||||
c_interface_print( 1, 22, 0,
|
|
||||||
" " );
|
|
||||||
if (waitpid(pid, NULL, 0) == -1)
|
|
||||||
{
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Problem gunzip'ing " );
|
|
||||||
c_interface_print( 1, 22, 0,
|
|
||||||
" " );
|
|
||||||
c_usleep();
|
|
||||||
c_mygetch(1);
|
|
||||||
c_interface_redo_diskette_bottom();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!pid) /* child process */
|
|
||||||
{ /* privileged mode - gzip in place */
|
|
||||||
if (execl("/bin/gzip", "/bin/gzip",
|
|
||||||
"-d", temp, NULL) == -1)
|
|
||||||
{
|
|
||||||
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
|
|
||||||
perror("\tproblem");
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Problem exec'ing /bin/gzip -d " );
|
|
||||||
c_interface_print( 1, 22, 0, temp);
|
|
||||||
c_usleep();
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Cannot fork! " );
|
|
||||||
c_interface_print( 1, 22, 0, temp);
|
|
||||||
c_usleep();
|
|
||||||
c_mygetch(1);
|
|
||||||
c_interface_redo_diskette_bottom();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (unlink(temp)) // temporarily remove .gz file
|
||||||
c_interface_cut_gz( temp );
|
|
||||||
cmpr = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* gzip the last disk */
|
|
||||||
if (disk6.disk[drive].compressed)
|
|
||||||
{
|
|
||||||
/* gzip the last disk if it was compressed_6 */
|
|
||||||
|
|
||||||
if ((pid = fork())) /* parent process */
|
|
||||||
{ /* privileged mode - gzip in place */
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Compressing old diskette... " );
|
|
||||||
c_interface_print( 1, 22, 0,
|
|
||||||
" " );
|
|
||||||
if (waitpid(pid, NULL, 0) == -1)
|
|
||||||
{
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Problem gzip'ing " );
|
|
||||||
c_interface_print( 1, 22, 0,
|
|
||||||
" " );
|
|
||||||
c_usleep();
|
|
||||||
c_mygetch(1);
|
|
||||||
c_interface_redo_diskette_bottom();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (!pid) /* child process */
|
|
||||||
{ /* privileged mode - gzip in place */
|
|
||||||
if (execl("/bin/gzip", "/bin/gzip",
|
|
||||||
disk6.disk[drive].file_name, NULL) == -1)
|
|
||||||
{
|
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Problem exec'ing /bin/gzip " );
|
|
||||||
c_interface_print( 1, 22, 0, temp);
|
|
||||||
c_usleep();
|
|
||||||
exit(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
snprintf(temp, TEMPSIZE, "%s", sys_errlist[errno]);
|
ERRLOG("OOPS, cannot unlink %s", temp);
|
||||||
c_interface_print( 1, 21, 0,
|
|
||||||
" Cannot fork! " );
|
|
||||||
c_interface_print( 1, 22, 0, temp);
|
|
||||||
c_usleep();
|
|
||||||
c_mygetch(1);
|
|
||||||
c_interface_redo_diskette_bottom();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c_interface_cut_gz(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now try to change the disk */
|
c_eject_6(drive);
|
||||||
|
c_interface_print_screen( screen );
|
||||||
|
|
||||||
if (c_new_diskette_6(
|
if (c_new_diskette_6(
|
||||||
drive, temp, cmpr, c_interface_is_nibblized(temp),
|
drive, temp, 1, c_interface_is_nibblized(temp),
|
||||||
(toupper(ch) != 'W')))
|
(toupper(ch) != 'W')))
|
||||||
{
|
{
|
||||||
c_interface_print_submenu_centered(protmenu[0], PERM_SUBMENU_W, PERM_SUBMENU_H);
|
c_interface_print_submenu_centered(protmenu[0], PERM_SUBMENU_W, PERM_SUBMENU_H);
|
||||||
|
@ -1546,7 +1481,9 @@ void c_interface_parameters()
|
||||||
if (ch == 'Y')
|
if (ch == 'Y')
|
||||||
{
|
{
|
||||||
c_eject_6( 0 );
|
c_eject_6( 0 );
|
||||||
|
c_interface_print_screen( screen );
|
||||||
c_eject_6( 1 );
|
c_eject_6( 1 );
|
||||||
|
c_interface_print_screen( screen );
|
||||||
#ifdef PC_JOYSTICK
|
#ifdef PC_JOYSTICK
|
||||||
c_close_joystick();
|
c_close_joystick();
|
||||||
#endif
|
#endif
|
||||||
|
|
286
src/zlib-helpers.c
Normal file
286
src/zlib-helpers.c
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
/*
|
||||||
|
* Apple // emulator for *nix
|
||||||
|
*
|
||||||
|
* This software package is subject to the GNU General Public License
|
||||||
|
* version 2 or later (your choice) as published by the Free Software
|
||||||
|
* Foundation.
|
||||||
|
*
|
||||||
|
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* zpipe.c: example of proper use of zlib's inflate() and deflate()
|
||||||
|
Not copyrighted -- provided to the public domain
|
||||||
|
Version 1.4 11 December 2005 Mark Adler */
|
||||||
|
|
||||||
|
/* Version history:
|
||||||
|
1.0 30 Oct 2004 First version
|
||||||
|
1.1 8 Nov 2004 Add void casting for unused return values
|
||||||
|
Use switch statement for inflate() return values
|
||||||
|
1.2 9 Nov 2004 Add assertions to document zlib guarantees
|
||||||
|
1.3 6 Apr 2005 Remove incorrect assertion in inf()
|
||||||
|
1.4 11 Dec 2005 Add hack to avoid MSDOS end-of-line conversions
|
||||||
|
Avoid some compiler warnings for input and output buffers
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
#include "zlib-helpers.h"
|
||||||
|
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
#define CHUNK 16384
|
||||||
|
#define UNKNOWN_ERR 42
|
||||||
|
|
||||||
|
/* report a zlib or i/o error */
|
||||||
|
static const char* const zerr(int ret, FILE *in, FILE *out)
|
||||||
|
{
|
||||||
|
switch (ret) {
|
||||||
|
case Z_ERRNO:
|
||||||
|
if (in && ferror(in))
|
||||||
|
{
|
||||||
|
return "error reading";
|
||||||
|
}
|
||||||
|
if (out && ferror(out))
|
||||||
|
{
|
||||||
|
return "error writing";
|
||||||
|
}
|
||||||
|
ERRLOG("Unknown zerr...");
|
||||||
|
case Z_OK:
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case Z_STREAM_ERROR:
|
||||||
|
return "invalid compression level";
|
||||||
|
|
||||||
|
case Z_DATA_ERROR:
|
||||||
|
return "invalid/incomplete deflate data";
|
||||||
|
|
||||||
|
case Z_MEM_ERROR:
|
||||||
|
return "out of memory";
|
||||||
|
|
||||||
|
case Z_VERSION_ERROR:
|
||||||
|
return "zlib version mismatch!";
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "general zlib error";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Compress from file source to file dest until EOF on source.
|
||||||
|
def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
|
||||||
|
allocated for processing, Z_STREAM_ERROR if an invalid compression
|
||||||
|
level is supplied, 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. */
|
||||||
|
const char* const def(const char* const src, const int level)
|
||||||
|
{
|
||||||
|
FILE *source = NULL;
|
||||||
|
FILE *dest = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (src == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
|
||||||
|
source = fopen(src, "r");
|
||||||
|
if (source == NULL) {
|
||||||
|
ERRLOG("Cannot open file '%s' for reading", src);
|
||||||
|
ret = UNKNOWN_ERR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
char dst[TEMPSIZE];
|
||||||
|
snprintf(dst, TEMPSIZE-1, "%s%s", src, ".gz");
|
||||||
|
FILE *dest = fopen(dst, "w+");
|
||||||
|
|
||||||
|
if (dest == NULL) {
|
||||||
|
ERRLOG("Cannot open file '%s' for writing", dst);
|
||||||
|
ret = UNKNOWN_ERR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int flush;
|
||||||
|
unsigned have;
|
||||||
|
z_stream strm;
|
||||||
|
unsigned char in[CHUNK];
|
||||||
|
unsigned char out[CHUNK];
|
||||||
|
|
||||||
|
/* allocate deflate state */
|
||||||
|
strm.zalloc = Z_NULL;
|
||||||
|
strm.zfree = Z_NULL;
|
||||||
|
strm.opaque = Z_NULL;
|
||||||
|
ret = deflateInit(&strm, level);
|
||||||
|
if (ret != Z_OK) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compress until end of file */
|
||||||
|
do {
|
||||||
|
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||||
|
if (ferror(source)) {
|
||||||
|
(void)deflateEnd(&strm);
|
||||||
|
ret = Z_ERRNO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
|
||||||
|
strm.next_in = in;
|
||||||
|
|
||||||
|
/* run deflate() on input until output buffer not full, finish
|
||||||
|
compression if all of source has been read in */
|
||||||
|
do {
|
||||||
|
strm.avail_out = CHUNK;
|
||||||
|
strm.next_out = out;
|
||||||
|
ret = deflate(&strm, flush); /* no bad return value */
|
||||||
|
assert(ret != Z_STREAM_ERROR); /* state not clobbered */
|
||||||
|
have = CHUNK - strm.avail_out;
|
||||||
|
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||||
|
(void)deflateEnd(&strm);
|
||||||
|
ret = Z_ERRNO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (strm.avail_out == 0);
|
||||||
|
assert(strm.avail_in == 0); /* all input will be used */
|
||||||
|
|
||||||
|
/* done when last data in file processed */
|
||||||
|
} while (flush != Z_FINISH);
|
||||||
|
assert(ret == Z_STREAM_END); /* stream will be complete */
|
||||||
|
|
||||||
|
(void)deflateEnd(&strm);
|
||||||
|
ret = Z_OK;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
const char* const err = zerr(ret, source, dest);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
fclose(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(dest);
|
||||||
|
|
||||||
|
if (dest) {
|
||||||
|
fclose(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
const char* const inf(const char* const src)
|
||||||
|
{
|
||||||
|
FILE *source = NULL;
|
||||||
|
FILE *dest = NULL;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (src == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
FILE *source = fopen(src, "r");
|
||||||
|
if (source == NULL) {
|
||||||
|
ERRLOG("Cannot open file '%s' for reading", src);
|
||||||
|
ret = UNKNOWN_ERR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int len = strlen(src);
|
||||||
|
char dst[TEMPSIZE];
|
||||||
|
snprintf(dst, TEMPSIZE-1, "%s", src);
|
||||||
|
assert(dst[len-3] == '.');
|
||||||
|
assert(dst[len-2] == 'g');
|
||||||
|
assert(dst[len-1] == 'z');
|
||||||
|
dst[len-3] = '\0';
|
||||||
|
|
||||||
|
FILE *dest = fopen(dst, "w+");
|
||||||
|
if (dest == NULL) {
|
||||||
|
ERRLOG("Cannot open file '%s' for writing", dst);
|
||||||
|
ret = UNKNOWN_ERR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* decompress until deflate stream ends or end of file */
|
||||||
|
do {
|
||||||
|
strm.avail_in = fread(in, 1, CHUNK, source);
|
||||||
|
if (ferror(source)) {
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
ret = Z_ERRNO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
have = CHUNK - strm.avail_out;
|
||||||
|
if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
ret = Z_ERRNO;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (strm.avail_out == 0);
|
||||||
|
|
||||||
|
/* done when inflate() says it's done */
|
||||||
|
} while (ret != Z_STREAM_END);
|
||||||
|
|
||||||
|
/* clean up and return */
|
||||||
|
(void)inflateEnd(&strm);
|
||||||
|
ret = Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
|
||||||
|
} while (0);
|
||||||
|
|
||||||
|
const char* const err = zerr(ret, source, dest);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
|
||||||
|
if (source) {
|
||||||
|
fclose(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
fflush(dest);
|
||||||
|
|
||||||
|
if (dest) {
|
||||||
|
fclose(dest);
|
||||||
|
}
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
9
src/zlib-helpers.h
Normal file
9
src/zlib-helpers.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef _ZLIB_HELPERS_H_
|
||||||
|
#define _ZLIB_HELPERS_H_
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
const char* const inf(const char* const source); // source : foo.dsk.gz --> foo.dsk
|
||||||
|
const char* const def(const char* const source, const int level); // source : foo.dsk --> foo.dsk.gz
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user