ADDED utils/ofzip/GZIPArchive.h Index: utils/ofzip/GZIPArchive.h ================================================================== --- utils/ofzip/GZIPArchive.h +++ utils/ofzip/GZIPArchive.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#import "OFGZIPStream.h" + +#import "Archive.h" + +@interface GZIPArchive: OFObject +{ + OFGZIPStream *_stream; +} +@end ADDED utils/ofzip/GZIPArchive.m Index: utils/ofzip/GZIPArchive.m ================================================================== --- utils/ofzip/GZIPArchive.m +++ utils/ofzip/GZIPArchive.m @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE.QPL included in + * the packaging of this file. + * + * Alternatively, it may be distributed under the terms of the GNU General + * Public License, either version 2 or 3, which can be found in the file + * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this + * file. + */ + +#include "config.h" + +#import "OFApplication.h" +#import "OFStdIOStream.h" + +#import "GZIPArchive.h" +#import "OFZIP.h" + +static OFZIP *app; + +@implementation GZIPArchive ++ (void)initialize +{ + if (self == [GZIPArchive class]) + app = [[OFApplication sharedApplication] delegate]; +} + ++ (instancetype)archiveWithFile: (OFFile*)file +{ + return [[[self alloc] initWithFile: file] autorelease]; +} + +- initWithFile: (OFFile*)file +{ + self = [super init]; + + @try { + _stream = [[OFGZIPStream alloc] initWithStream: file]; + } @catch (id e) { + [self release]; + @throw e; + } + + return self; +} + +- (void)dealloc +{ + [_stream release]; + + [super dealloc]; +} + +- (void)listFiles +{ + [of_stderr writeLine: @"Cannot list files of a .gz archive!"]; + app->_exitStatus = 1; +} + +- (void)extractFiles: (OFArray OF_GENERIC(OFString*)*)files +{ + OFString *fileName; + OFFile *output; + + if ([files count] != 0) { + [of_stderr writeLine: + @"Cannot extract a specific file of a .gz archive!"]; + app->_exitStatus = 1; + return; + } + + fileName = [[app->_archivePath lastPathComponent] + stringByDeletingPathExtension]; + + if (app->_outputLevel >= 0) + [of_stdout writeFormat: @"Extracting %@...", fileName]; + + if (![app shouldExtractFile: fileName + outFileName: fileName]) + return; + + output = [OFFile fileWithPath: fileName + mode: @"wb"]; + /* TODO: Copy permissions */ + + while (![_stream isAtEndOfStream]) { + ssize_t length = [app copyBlockFromStream: _stream + toStream: output + fileName: fileName]; + + if (length < 0) { + app->_exitStatus = 1; + return; + } + } + + if (app->_outputLevel >= 0) + [of_stdout writeFormat: @"\rExtracting %@... done\n", fileName]; +} +@end Index: utils/ofzip/Makefile ================================================================== --- utils/ofzip/Makefile +++ utils/ofzip/Makefile @@ -1,9 +1,10 @@ include ../../extra.mk PROG = ofzip${PROG_SUFFIX} -SRCS = OFZIP.m \ +SRCS = GZIPArchive.m \ + OFZIP.m \ ZIPArchive.m include ../../buildsys.mk ${PROG}: ${LIBOBJFW_DEP_LVL2} Index: utils/ofzip/OFZIP.h ================================================================== --- utils/ofzip/OFZIP.h +++ utils/ofzip/OFZIP.h @@ -13,18 +13,20 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFObject.h" +#import "OFString.h" #import "Archive.h" @interface OFZIP: OFObject { int8_t _override; @public int8_t _outputLevel; + OFString *_archivePath; int _exitStatus; } - (id )openArchiveWithPath: (OFString*)path; - (bool)shouldExtractFile: (OFString*)fileName Index: utils/ofzip/OFZIP.m ================================================================== --- utils/ofzip/OFZIP.m +++ utils/ofzip/OFZIP.m @@ -25,10 +25,11 @@ #import "OFOptionsParser.h" #import "OFStdIOStream.h" #import "OFZIP.h" #import "ZIPArchive.h" +#import "GZIPArchive.h" #import "OFCreateDirectoryFailedException.h" #import "OFInvalidFormatException.h" #import "OFOpenItemFailedException.h" #import "OFReadFailedException.h" @@ -197,10 +198,13 @@ - (id )openArchiveWithPath: (OFString*)path { OFFile *file; id archive; + [_archivePath release]; + _archivePath = [path copy]; + @try { file = [OFFile fileWithPath: path mode: @"rb"]; } @catch (OFOpenItemFailedException *e) { [of_stderr writeFormat: @"Failed to open file %@: %s\n", @@ -207,11 +211,14 @@ [e path], strerror([e errNo])]; [OFApplication terminateWithStatus: 1]; } @try { - archive = [ZIPArchive archiveWithFile: file]; + if ([path hasSuffix: @".gz"]) + archive = [GZIPArchive archiveWithFile: file]; + else + archive = [ZIPArchive archiveWithFile: file]; } @catch (OFReadFailedException *e) { [of_stderr writeFormat: @"Failed to read file %@: %s\n", path, strerror([e errNo])]; [OFApplication terminateWithStatus: 1]; } @catch (OFInvalidFormatException *e) {