penk@1599: "{ Package: 'stx:libtool2' }" penk@1599: penk@1599: Object subclass:#Archiver penk@1599: instanceVariableNames:'process temporaryDirectory fileName outStream errorStream penk@1599: synchron' penk@1599: classVariableNames:'' penk@1599: poolDictionaries:'' penk@1599: category:'System-Support-FileFormats' penk@1599: ! penk@1599: penk@1599: Archiver subclass:#GZipArchive penk@1599: instanceVariableNames:'' penk@1599: classVariableNames:'' penk@1599: poolDictionaries:'' penk@1599: privateIn:Archiver penk@1599: ! penk@1599: penk@1599: Archiver subclass:#TarArchive penk@1599: instanceVariableNames:'fileName' penk@1599: classVariableNames:'' penk@1599: poolDictionaries:'' penk@1599: privateIn:Archiver penk@1599: ! penk@1599: penk@1599: Archiver subclass:#TarGZipArchive penk@1599: instanceVariableNames:'tarArchiver tarFile' penk@1599: classVariableNames:'' penk@1599: poolDictionaries:'' penk@1599: privateIn:Archiver penk@1599: ! penk@1599: penk@1599: penk@1599: !Archiver class methodsFor:'instance creation'! penk@1599: penk@1599: with:aFilename penk@1599: penk@1599: | instance | penk@1599: penk@1599: instance := self new. penk@1599: instance fileName:aFilename. penk@1599: ^ instance penk@1599: ! ! penk@1599: penk@1599: !Archiver class methodsFor:'classAccess'! penk@1599: penk@1599: gzipArchive penk@1599: penk@1599: ^ GZipArchive penk@1599: ! penk@1599: penk@1599: tarArchive penk@1599: penk@1599: ^ TarArchive penk@1599: ! penk@1599: penk@1599: tarGZipArchive penk@1599: penk@1599: ^ TarGZipArchive penk@1599: ! ! penk@1599: penk@1599: !Archiver class methodsFor:'common options'! penk@1599: penk@1599: MinusSign penk@1599: penk@1599: ^ $- penk@1599: ! penk@1599: penk@1599: PipeSign penk@1599: penk@1599: ^ $> penk@1599: ! ! penk@1599: penk@1599: !Archiver methodsFor:'accessing'! penk@1599: penk@1599: errorStream penk@1599: "return the value of the instance variable 'errorStream' (automatically generated)" penk@1599: penk@1599: ^ errorStream penk@1599: ! penk@1599: penk@1599: errorStream:something penk@1599: "set the value of the instance variable 'errorStream' (automatically generated)" penk@1599: penk@1599: errorStream := something. penk@1599: ! penk@1599: penk@1599: fileName penk@1599: "return the value of the instance variable 'fileName' (automatically generated)" penk@1599: penk@1599: ^ fileName penk@1599: ! penk@1599: penk@1599: fileName:something penk@1599: "set the value of the instance variable 'fileName' (automatically generated)" penk@1599: penk@1599: fileName := something. penk@1599: ! penk@1599: penk@1599: outStream penk@1599: "return the value of the instance variable 'outStream' (automatically generated)" penk@1599: penk@1599: ^ outStream penk@1599: ! penk@1599: penk@1599: outStream:something penk@1599: "set the value of the instance variable 'outStream' (automatically generated)" penk@1599: penk@1599: outStream := something. penk@1599: ! penk@1599: penk@1599: process penk@1599: "return the value of the instance variable 'process' (automatically generated)" penk@1599: penk@1599: ^ process penk@1599: ! penk@1599: penk@1599: process:something penk@1599: "set the value of the instance variable 'process' (automatically generated)" penk@1599: penk@1599: process := something. penk@1599: ! penk@1599: penk@1599: synchron penk@1599: "return the value of the instance variable 'synchron' (automatically generated)" penk@1599: penk@1599: ^ synchron penk@1599: ! penk@1599: penk@1599: synchron:something penk@1599: "set the value of the instance variable 'synchron' (automatically generated)" penk@1599: penk@1599: synchron := something. penk@1599: ! penk@1599: penk@1599: temporaryDirectory penk@1599: "return the value of the instance variable 'temporaryDirectory' (automatically generated)" penk@1599: penk@1599: temporaryDirectory isNil ifTrue:[ penk@1599: temporaryDirectory := Filename newTemporary. penk@1599: temporaryDirectory makeDirectory. penk@1599: ]. penk@1599: ^ temporaryDirectory penk@1599: ! ! penk@1599: penk@1599: !Archiver methodsFor:'actions'! penk@1599: penk@1599: addFilesToArchiv:colOfFiles penk@1599: penk@1599: self subclassResponsibility. penk@1599: ! penk@1599: penk@1599: extractTo:aColOfFiles penk@1599: penk@1599: self subclassResponsibility. penk@1599: ! penk@1599: penk@1599: listFilesFromArchiv penk@1599: penk@1599: self subclassResponsibility. penk@1599: ! penk@1599: penk@1599: removeFilesFromArchiv:aColOfFiles penk@1599: penk@1599: self subclassResponsibility. penk@1599: ! ! penk@1599: penk@1599: !Archiver methodsFor:'actions private'! penk@1599: penk@1599: removeTemporaryDirectory penk@1599: penk@1599: | tmp | penk@1599: penk@1599: temporaryDirectory notNil ifTrue:[ penk@1599: tmp := self temporaryDirectory. penk@1599: (FileDirectory directoryNamed:(tmp directory)) removeDirectory:tmp baseName. penk@1599: temporaryDirectory := nil. penk@1599: ]. penk@1599: ! penk@1599: penk@1599: stopProcess penk@1599: penk@1599: process notNil ifTrue:[ penk@1599: process terminateWithAllSubprocesses. penk@1599: process waitUntilTerminated. penk@1599: ]. penk@1599: ! ! penk@1599: penk@1599: !Archiver methodsFor:'command execution'! penk@1599: penk@1599: executeCommand:cmd directory:aDirectory penk@1599: penk@1599: penk@1599: synchron isNil ifTrue:[synchron := true]. penk@1599: synchron ifTrue:[ penk@1599: OperatingSystem penk@1599: executeCommand:cmd penk@1599: inputFrom:nil penk@1599: outputTo:outStream penk@1599: errorTo:errorStream penk@1599: inDirectory:aDirectory penk@1599: lineWise:true penk@1599: onError:[:status| false]. penk@1599: ] ifFalse:[ penk@1599: process := Process for:[ penk@1599: [ penk@1599: OperatingSystem penk@1599: executeCommand:cmd penk@1599: inputFrom:nil penk@1599: outputTo:outStream penk@1599: errorTo:errorStream penk@1599: inDirectory:aDirectory penk@1599: lineWise:true penk@1599: onError:[:status| false]. penk@1599: ] penk@1599: valueNowOrOnUnwindDo:[ penk@1599: process := nil. penk@1599: ]. penk@1599: penk@1599: ] priority:(Processor systemBackgroundPriority). penk@1599: process name:('ArchivFileCommand command >', cmd). penk@1599: process resume. penk@1599: ] penk@1599: ! penk@1599: penk@1599: outStream:aOutStream errorStream:aErrorStream penk@1599: penk@1599: outStream := aOutStream. penk@1599: errorStream := aErrorStream. penk@1599: ! penk@1599: penk@1599: outStream:aOutStream errorStream:aErrorStream synchron:aBoolean penk@1599: penk@1599: outStream := aOutStream. penk@1599: errorStream := aErrorStream. penk@1599: synchron := aBoolean penk@1599: ! ! penk@1599: penk@1599: !Archiver methodsFor:'initialization & release'! penk@1599: penk@1599: release penk@1599: penk@1599: self stopProcess. penk@1599: self removeTemporaryDirectory. penk@1599: ! ! penk@1599: penk@1599: !Archiver::GZipArchive class methodsFor:'zip archiv command options'! penk@1599: penk@1599: GZipArchivFileOption penk@1599: ^ 'f' penk@1599: ! penk@1599: penk@1599: GZipArchivUnzipCommand penk@1599: ^ 'gunzip' penk@1599: ! penk@1599: penk@1599: GZipArchivWriteToStdioOption penk@1599: ^ 'c' penk@1599: ! penk@1599: penk@1599: GZipArchivZipCommand penk@1599: ^ 'gzip' penk@1599: ! ! penk@1599: penk@1599: !Archiver::GZipArchive methodsFor:'actions'! penk@1599: penk@1599: unzipTo:aDirectory penk@1599: penk@1599: | cmd file newFile| penk@1599: penk@1599: (aDirectory exists not) ifTrue:[ penk@1599: DialogBox warn:'cant unzip to not existing directory ', aDirectory asString. penk@1599: ]. penk@1599: (aDirectory isDirectory not) ifTrue:[ penk@1599: DialogBox warn:'cant unzip to file ', aDirectory asString. penk@1599: ]. penk@1599: file := self fileName. penk@1599: (file directory asString = aDirectory asString) ifFalse:[ penk@1599: file copyTo:(aDirectory construct:(file baseName)). penk@1599: ]. penk@1599: newFile := aDirectory construct:(file baseName). penk@1599: cmd := self getUnzipCommandForFile:newFile. penk@1599: self executeCommand:cmd directory:aDirectory. penk@1599: ! penk@1599: penk@1599: zipFile:aFile to:newFile penk@1599: penk@1599: | cmd directory| penk@1599: penk@1599: directory := newFile directory. penk@1599: (directory exists not) ifTrue:[ penk@1599: DialogBox warn:'cant unzip to not existing directory ', directory asString. penk@1599: ]. penk@1599: (directory isDirectory not) ifTrue:[ penk@1599: DialogBox warn:'cant unzip to file ', directory asString. penk@1599: ]. penk@1599: cmd := self getZipCommandForFile:aFile to:newFile. penk@1599: self executeCommand:cmd directory:directory. penk@1599: newFile exists ifTrue:[ penk@1599: self fileName:newFile. penk@1599: ]. penk@1599: ! ! penk@1599: penk@1599: !Archiver::GZipArchive methodsFor:'command strings'! penk@1599: penk@1599: getUnzipCommand penk@1599: penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class GZipArchivUnzipCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self fileName baseName. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getUnzipCommandForFile:aFileName penk@1599: penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class GZipArchivUnzipCommand. penk@1599: stream space. penk@1599: stream nextPutAll:aFileName asString. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getZipCommandForFile:aFileName penk@1599: penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class GZipArchivZipCommand. penk@1599: stream space. penk@1599: stream nextPutAll:aFileName asString. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getZipCommandForFile:aFile to:newFile penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class GZipArchivZipCommand. penk@1599: stream space. penk@1599: stream nextPut:self class MinusSign. penk@1599: stream nextPutAll:self class GZipArchivWriteToStdioOption. penk@1599: stream space. penk@1599: stream nextPutAll:aFile asString. penk@1599: stream space. penk@1599: stream nextPut:self class PipeSign. penk@1599: stream space. penk@1599: stream nextPutAll:newFile asString. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarArchive class methodsFor:'command strings'! penk@1599: penk@1599: TarArchivAddOption penk@1599: ^ 'r' penk@1599: ! penk@1599: penk@1599: TarArchivCommand penk@1599: ^ 'tar' penk@1599: ! penk@1599: penk@1599: TarArchivDeleteOption penk@1599: ^ '--delete' penk@1599: ! penk@1599: penk@1599: TarArchivFileOption penk@1599: ^ 'f' penk@1599: ! penk@1599: penk@1599: TarArchivListContentsOption penk@1599: ^ 't' penk@1599: ! penk@1599: penk@1599: TarArchivListOptions penk@1599: ^ self TarArchivListContentsOption , self TarArchivVerboseOption penk@1599: , self TarArchivFileOption penk@1599: ! penk@1599: penk@1599: TarArchivListZippedOptions penk@1599: ^ self TarArchivListContentsOption , self TarArchivVerboseOption penk@1599: , self TarArchivFileOption , self TarArchivZipOption penk@1599: ! penk@1599: penk@1599: TarArchivUnpackInDirectoryOption penk@1599: ^ '-C ' penk@1599: ! penk@1599: penk@1599: TarArchivUnpackOption penk@1599: ^ 'x' penk@1599: ! penk@1599: penk@1599: TarArchivVerboseOption penk@1599: ^ 'v' penk@1599: ! penk@1599: penk@1599: TarArchivZipOption penk@1599: ^ 'z' penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarArchive methodsFor:'actions'! penk@1599: penk@1599: addFilesToArchiv:colOfFiles penk@1599: penk@1599: | cmd tempDir archivFile archivInTemp| penk@1599: penk@1599: tempDir := self temporaryDirectory. penk@1599: archivFile := self fileName. penk@1599: archivInTemp := tempDir construct:(archivFile baseName). penk@1599: "/ copy files to be added to tempDir penk@1599: colOfFiles do:[ :file | penk@1599: file recursiveCopyTo:(tempDir construct:(file baseName)) penk@1599: ]. penk@1599: penk@1599: "/ copy tar archiv to tempDir penk@1599: archivFile copyTo:archivInTemp. penk@1599: penk@1599: "/ addFiles to the tar archive penk@1599: cmd := self getAddFilesToTarArchiveCommandForArchiv:archivInTemp with:colOfFiles. penk@1599: self executeCommand:cmd directory:tempDir. penk@1599: penk@1599: "/ copy tar archiv back penk@1599: archivInTemp copyTo:(self fileName). penk@1599: ! penk@1599: penk@1599: extractTo:aDirectory penk@1599: penk@1599: ^ self extractTo:aDirectory with:nil penk@1599: ! penk@1599: penk@1599: extractTo:aDirectory with:files penk@1599: penk@1599: |execDir cmd| penk@1599: penk@1599: execDir := self fileName directory. penk@1599: cmd := self getExtractSelectedFilesCommandForDirectory:aDirectory withSelection:files. penk@1599: self executeCommand:cmd directory:execDir. penk@1599: ! penk@1599: penk@1599: extractWithOutDirectoryTo:aDirectory with:files penk@1599: penk@1599: |execDir tempDir tempFile| penk@1599: penk@1599: execDir := self fileName directory. penk@1599: tempDir := self temporaryDirectory. penk@1599: self extractTo:tempDir with:files. penk@1599: files do:[ : aFileString | penk@1599: tempFile := self temporaryDirectory construct:aFileString. penk@1599: tempFile exists ifTrue:[ penk@1599: tempFile recursiveCopyTo:(aDirectory construct:(aFileString fileName asFilename baseName)). penk@1599: ]. penk@1599: ]. penk@1599: ! penk@1599: penk@1599: listFilesFromArchiv penk@1599: penk@1599: self listFilesFromArchiv:nil penk@1599: ! penk@1599: penk@1599: listFilesFromArchiv:newColOfFiles penk@1599: penk@1599: | cmd dir| penk@1599: penk@1599: self fileName isNil ifTrue:[ ^ self]. penk@1599: dir := self fileName directory. penk@1599: cmd := self getFileListFromArchivCommand:newColOfFiles. penk@1599: self executeCommand:cmd directory:dir penk@1599: ! penk@1599: penk@1599: removeFilesFromArchiv:aColOfFiles penk@1599: penk@1599: |cmd| penk@1599: penk@1599: cmd := self getRemoveFilesFromTarArchivFor:aColOfFiles. penk@1599: self executeCommand:cmd directory:(self fileName directory). penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarArchive methodsFor:'command strings'! penk@1599: penk@1599: getAddFilesToTarArchiveCommand:aColOfFiles penk@1599: |filename cmd stream| penk@1599: penk@1599: filename := self fileName. penk@1599: filename exists ifTrue:[ penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class TarArchivCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivAddOption. penk@1599: stream nextPutAll:self class TarArchivFileOption. penk@1599: stream space. penk@1599: stream nextPutAll:filename asString. penk@1599: aColOfFiles do:[:el | penk@1599: stream space. penk@1599: stream nextPutAll:(el asString) penk@1599: ]. penk@1599: cmd := stream contents penk@1599: ]. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getAddFilesToTarArchiveCommandForArchiv:archivFile with:aColOfFiles penk@1599: | cmd stream| penk@1599: penk@1599: archivFile exists ifTrue:[ penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class TarArchivCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivAddOption. penk@1599: stream nextPutAll:self class TarArchivFileOption. penk@1599: stream space. penk@1599: stream nextPutAll:archivFile asString. penk@1599: aColOfFiles do:[:el | penk@1599: stream space. penk@1599: stream nextPutAll:(el baseName) penk@1599: ]. penk@1599: cmd := stream contents penk@1599: ]. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getExtractSelectedFilesCommandForDirectory:dir withSelection:sel penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class TarArchivCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivUnpackOption. penk@1599: stream nextPutAll:self class TarArchivFileOption. penk@1599: stream space. penk@1599: stream nextPutAll:self fileName asString. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivUnpackInDirectoryOption. penk@1599: stream space. penk@1599: stream nextPutAll:dir asString. penk@1599: sel notNil ifTrue:[ penk@1599: sel do:[:el | penk@1599: stream space. penk@1599: stream nextPutAll:(el fileName asString) penk@1599: ]. penk@1599: ]. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getFileListFromArchivCommand:aColOfFiles penk@1599: penk@1599: | stream cmd| penk@1599: penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class TarArchivCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivListOptions. penk@1599: stream space. penk@1599: stream nextPutAll:self fileName baseName. penk@1599: aColOfFiles notNil ifTrue:[ penk@1599: aColOfFiles do:[:el | penk@1599: stream space. penk@1599: stream nextPutAll:(el baseName) penk@1599: ] penk@1599: ]. penk@1599: cmd := stream contents. penk@1599: stream close. penk@1599: ^ cmd penk@1599: ! penk@1599: penk@1599: getRemoveFilesFromTarArchivFor:sel penk@1599: | stream filename| penk@1599: penk@1599: filename := self fileName. penk@1599: filename exists ifTrue:[ penk@1599: stream := WriteStream on:''. penk@1599: stream nextPutAll:self class TarArchivCommand. penk@1599: stream space. penk@1599: stream nextPutAll:self class TarArchivDeleteOption. penk@1599: stream space. penk@1599: stream nextPut:self class MinusSign. penk@1599: stream nextPutAll:self class TarArchivFileOption. penk@1599: stream space. penk@1599: stream nextPutAll:filename asString. penk@1599: sel do:[:el | penk@1599: stream space. penk@1599: stream nextPutAll:el penk@1599: ]. penk@1599: ^ stream contents penk@1599: ] penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarGZipArchive methodsFor:'accessing'! penk@1599: penk@1599: fileName:aFile penk@1599: penk@1599: | tempDir file gzipArchiver suffix| penk@1599: penk@1599: super fileName:aFile. penk@1599: " unzip file in tempDirectory and do all the things with tar file " penk@1599: tempDir := self temporaryDirectory. penk@1599: gzipArchiver := Archiver::GZipArchive with:(self fileName). penk@1599: gzipArchiver unzipTo:tempDir. penk@1599: suffix := self fileName suffix. penk@1599: file := self fileName withoutSuffix. penk@1599: file := file baseName. penk@1599: suffix = 'tgz' ifTrue:[ penk@1599: file := file , '.tar' penk@1599: ]. penk@1599: tarFile := self temporaryDirectory construct:file. penk@1599: tarArchiver := TarArchive with:tarFile. penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarGZipArchive methodsFor:'actions'! penk@1599: penk@1599: addFilesToArchiv:colOfFiles penk@1599: penk@1599: self setCommandOptions. penk@1599: tarArchiver addFilesToArchiv:colOfFiles. penk@1599: self synchronize. penk@1599: ! penk@1599: penk@1599: extractTo:aDirectory penk@1599: penk@1599: self extractTo:aDirectory with:nil. penk@1599: ! penk@1599: penk@1599: extractTo:aDirectory with:col penk@1599: penk@1599: self setCommandOptions. penk@1599: tarArchiver extractTo:aDirectory with:col. penk@1599: ! penk@1599: penk@1599: extractWithOutDirectoryTo:aDirectory with:files penk@1599: penk@1599: self setCommandOptions. penk@1599: tarArchiver extractWithOutDirectoryTo:aDirectory with:files. penk@1599: ! penk@1599: penk@1599: listFilesFromArchiv penk@1599: penk@1599: self listFilesFromArchiv:nil penk@1599: ! penk@1599: penk@1599: listFilesFromArchiv:newColOfFiles penk@1599: penk@1599: self setCommandOptions. penk@1599: ^ tarArchiver listFilesFromArchiv:newColOfFiles. penk@1599: ! penk@1599: penk@1599: removeFilesFromArchiv:aColOfFiles penk@1599: penk@1599: self setCommandOptions. penk@1599: tarArchiver removeFilesFromArchiv:aColOfFiles. penk@1599: self synchronize. penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarGZipArchive methodsFor:'actions private'! penk@1599: penk@1599: setCommandOptions penk@1599: penk@1599: tarArchiver outStream:(self outStream). penk@1599: tarArchiver errorStream:(self errorStream). penk@1599: tarArchiver synchron:(self synchron). penk@1599: ! penk@1599: penk@1599: synchronize penk@1599: penk@1599: |gzipArchiver| penk@1599: penk@1599: gzipArchiver := GZipArchive with:nil. penk@1599: gzipArchiver zipFile:(tarArchiver fileName) to:(self fileName). penk@1599: ! ! penk@1599: penk@1599: !Archiver::TarGZipArchive methodsFor:'initialization & release'! penk@1599: penk@1599: release penk@1599: penk@1599: super release. penk@1599: tarArchiver release. penk@1599: ! ! penk@1599: penk@1599: !Archiver class methodsFor:'documentation'! penk@1599: penk@1599: version penk@1599: ^ '$Header$' penk@1599: ! !