diff --git a/setup/extensions.json b/setup/extensions.json index 6b97ea6911..d9a9f682d4 100644 --- a/setup/extensions.json +++ b/setup/extensions.json @@ -199,16 +199,5 @@ "sources": "calibre/devices/mtp/unix/devices.c calibre/devices/mtp/unix/libmtp.c", "headers": "calibre/devices/mtp/unix/devices.h calibre/devices/mtp/unix/upstream/music-players.h calibre/devices/mtp/unix/upstream/device-flags.h", "libraries": "mtp" - }, - { - "name": "unrar", - "sources": "unrar/rar.cpp unrar/strlist.cpp unrar/strfn.cpp unrar/pathfn.cpp unrar/savepos.cpp unrar/smallfn.cpp unrar/global.cpp unrar/file.cpp unrar/filefn.cpp unrar/filcreat.cpp unrar/archive.cpp unrar/arcread.cpp unrar/unicode.cpp unrar/system.cpp unrar/isnt.cpp unrar/crypt.cpp unrar/crc.cpp unrar/rawread.cpp unrar/encname.cpp unrar/resource.cpp unrar/match.cpp unrar/timefn.cpp unrar/rdwrfn.cpp unrar/consio.cpp unrar/options.cpp unrar/ulinks.cpp unrar/errhnd.cpp unrar/rarvm.cpp unrar/secpassword.cpp unrar/rijndael.cpp unrar/getbits.cpp unrar/sha1.cpp unrar/extinfo.cpp unrar/extract.cpp unrar/volume.cpp unrar/list.cpp unrar/find.cpp unrar/unpack.cpp unrar/cmddata.cpp unrar/filestr.cpp unrar/scantree.cpp calibre/utils/unrar.cpp", - "inc_dirs": "unrar", - "defines": "SILENT RARDLL UNRAR _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE", - "windows_defines": "SILENT RARDLL UNRAR", - "haiku_defines": "LITTLE_ENDIAN SILENT RARDLL UNRAR _FILE_OFFSET_BITS=64 _LARGEFILE_SOURCE _BSD_SOURCE", - "haiku_libraries": "bsd", - "optimize_level": 2, - "windows_libraries": "User32 Advapi32 kernel32 Shell32" } ] diff --git a/src/calibre/constants.py b/src/calibre/constants.py index 628fb9383e..dfe1e73b6c 100644 --- a/src/calibre/constants.py +++ b/src/calibre/constants.py @@ -158,7 +158,6 @@ class Plugins(collections.Mapping): 'zlib2', 'html', 'freetype', - 'unrar', 'imageops', 'qt_hack', 'hunspell', diff --git a/src/calibre/ebooks/metadata/archive.py b/src/calibre/ebooks/metadata/archive.py index f5c0b7bed3..bf85e587e5 100644 --- a/src/calibre/ebooks/metadata/archive.py +++ b/src/calibre/ebooks/metadata/archive.py @@ -57,8 +57,7 @@ class ArchiveExtract(FileTypePlugin): zf = ZipFile(archive, 'r') if is_rar: - with open(archive, 'rb') as rf: - fnames = list(names(rf)) + fnames = list(names(archive)) else: fnames = zf.namelist() @@ -94,8 +93,7 @@ class ArchiveExtract(FileTypePlugin): of = self.temporary_file('_archive_extract.'+ext) with closing(of): if is_rar: - with open(archive, 'rb') as f: - data = extract_member(f, match=None, name=fname)[1] + data = extract_member(archive, match=None, name=fname)[1] of.write(data) else: of.write(zf.read(fname)) @@ -162,9 +160,8 @@ def get_comic_metadata(stream, stream_type, series_index='volume'): zf = ZipFile(stream) comment = zf.comment elif stream_type == 'cbr': - from calibre.utils.unrar import RARFile - f = RARFile(stream, get_comment=True) - comment = f.comment + from calibre.utils.unrar import comment as get_comment + comment = get_comment(stream) if comment: import json diff --git a/src/calibre/utils/unrar.cpp b/src/calibre/utils/unrar.cpp deleted file mode 100644 index 625642a776..0000000000 --- a/src/calibre/utils/unrar.cpp +++ /dev/null @@ -1,553 +0,0 @@ -/* - * unrar.cpp - * Copyright (C) 2012 Kovid Goyal - * - * Distributed under terms of the GPL3 license. - */ - -#define _UNICODE -#define UNICODE -#define PY_SSIZE_T_CLEAN -#include - -#ifndef RARDLL // Needed for syntastic -#define RARDLL -#endif - -#include -#include -#include -#include - -static PyObject *UNRARError = NULL; - -#ifndef _MSC_VER -static int wcscpy_s(wchar_t *dest, size_t sz, const wchar_t *src) { - if (dest == NULL || src == NULL) return EINVAL; - if (wcslen(src) >= sz) return ERANGE; - wcscpy(dest, src); - return 0; -} -#endif - -#define STRFY(x) #x -#define STRFY2(x) STRFY(x) -#define NOMEM PyErr_SetString(PyExc_MemoryError, "Out of memory at line number: " STRFY2(__LINE__)) - -static wchar_t *unicode_to_wchar(PyObject *o) { - wchar_t *buf; - Py_ssize_t len; - if (o == NULL) return NULL; - if (!PyUnicode_Check(o)) {PyErr_Format(PyExc_TypeError, "The python object must be a unicode object"); return NULL;} - len = PyUnicode_GET_SIZE(o); - buf = (wchar_t *)calloc(len+2, sizeof(wchar_t)); - if (buf == NULL) { NOMEM; return NULL; } - len = PyUnicode_AsWideChar((PyUnicodeObject*)o, buf, len); - if (len == -1) { free(buf); PyErr_Format(PyExc_TypeError, "Invalid python unicode object."); return NULL; } - return buf; -} - -static PyObject *wchar_to_unicode(const wchar_t *o) { - PyObject *ans; - if (o == NULL) return NULL; - ans = PyUnicode_FromWideChar(o, wcslen(o)); - if (ans == NULL) NOMEM; - return ans; -} - -class PyArchive : public Archive { // {{{ - public: - PyArchive(PyObject *f, wchar_t *name, RAROptions *Cmd) : Archive(Cmd), file(f) { - Py_XINCREF(f); - wcscpy_s(FileNameW, NM, (wcslen(name) < NM-1) ? name : L""); - if (wcstombs(FileName, FileNameW, NM-1) == (size_t)-1) - memcpy(FileName, "", strlen("\0")); - } - - ~PyArchive() { Py_XDECREF(file); } - - virtual bool is_archive() { - return IsArchive(false); - } - - virtual bool IsOpened() { return true; } - - virtual int DirectRead(void *data, size_t size) { - // printf("direct read()\n"); - char *buf; - Py_ssize_t sz = 0; - int ret = 0; - - PyObject *res = PyObject_CallMethod(file, (char*)"read", (char*)"(k)", size); - if (res == NULL) return -1; - - ret = PyBytes_AsStringAndSize(res, &buf, &sz); - if (ret != -1) { - memcpy(data, buf, (size_t)sz); - ret = (int)sz; - } - Py_XDECREF(res); - return ret; - } - - virtual int Read(void *data, size_t size) { - int ret = DirectRead(data, size); - if (ret == -1) { - ErrHandler.ReadError(FileName, FileNameW); - } - return ret; - } - - virtual bool RawSeek(int64 offset, int method) { - // printf("raw seek(%lld, %d)\n", offset, method); - PyObject *res = PyObject_CallMethod(file, (char*)"seek", (char*)"Li", offset, method); - if (res == NULL) return false; - Py_XDECREF(res); - return true; - } - - virtual void Seek(int64 offset, int method) { - if (!RawSeek(offset, method)) - ErrHandler.SeekError(FileName, FileNameW); - } - - virtual bool Close() { return true; } - - virtual int64 Tell() { - // printf("tell()\n"); - PyObject *res = PyObject_CallMethod(file, (char*)"tell", NULL); - if (res == NULL) { - ErrHandler.SeekError(FileName, FileNameW); - } - Py_ssize_t pos = PyInt_AsSsize_t(res); - Py_XDECREF(res); - return (int64)pos; - } - - virtual byte GetByte() { - // printf("get byte()\n"); - byte b = 0; - DirectRead(&b, 1); - return b; - } - - virtual int64 FileLength() { - // printf("file length()\n"); - int64 pos = Tell(); - Seek(0, SEEK_END); - int64 ans = Tell(); - Seek(pos, SEEK_SET); - return ans; - } - - virtual bool IsDevice() { return false; } - - private: - PyObject *file; -}; // }}} - -static -PyMethodDef methods[] = { - - {NULL, NULL, 0, NULL} -}; - -// RARArchive object definition {{{ -typedef struct { - PyObject_HEAD - // Type-specific fields go here. - PyArchive *archive; - PyObject *comment; - int header_size; - RAROptions Cmd; - ComprDataIO DataIO; - Unpack *Unp; - size_t file_count; - -} RARArchive; - -static void -RAR_dealloc(RARArchive* self) { - Py_XDECREF(self->comment); self->comment = NULL; - - if (self->Unp != NULL) { delete self->Unp; self->Unp = NULL; } - - if (self->archive != NULL) { - self->archive->Close(); - delete self->archive; - self->archive = NULL; - } - - self->ob_type->tp_free((PyObject*)self); -} - -static const char* unrar_callback_err = NULL; - -static void handle_rar_error(RAR_EXIT errcode) { - if (PyErr_Occurred()) return; - if (unrar_callback_err != NULL) { - PyErr_SetString(UNRARError, unrar_callback_err); - unrar_callback_err = NULL; - return; - } - - const char *err = "UNKNOWN"; - switch (errcode) { - case RARX_SUCCESS: err = "RARX_SUCCESS"; break; - case RARX_WARNING: err = "RARX_WARNING"; break; - case RARX_FATAL: err = "RARX_FATAL"; break; - case RARX_CRC: err = "RARX_CRC"; break; - case RARX_LOCK: err = "RARX_LOCK"; break; - case RARX_WRITE: err = "RARX_WRITE"; break; - case RARX_OPEN: err = "RARX_OPEN"; break; - case RARX_USERERROR: err = "RARX_USERERROR"; break; - case RARX_MEMORY: err = "RARX_MEMORY"; break; - case RARX_CREATE: err = "RARX_CREATE"; break; - case RARX_NOFILES: err = "RARX_NOFILES"; break; - case RARX_USERBREAK: err = "RARX_USERBREAK"; break; - } - PyErr_Format(UNRARError, "RAR error code: %s", err); -} - -static int CALLBACK callback(UINT msg, LPARAM data, LPARAM p1, LPARAM p2) { - PyObject *c = (PyObject*)data, *ret; - if (msg == UCM_PROCESSDATA) { - ret = PyObject_CallMethod(c, (char*)"handle_data", (char*)"(s#)", (char*)p1, (size_t)p2); - if (ret == NULL) return -1; - Py_DECREF(ret); - return 0; - } else if (msg == UCM_NEEDPASSWORD || msg == UCM_NEEDPASSWORDW) { - unrar_callback_err = "This archive is password protected."; - } else if (msg == UCM_CHANGEVOLUME || msg == UCM_CHANGEVOLUMEW) { - unrar_callback_err = "This is an unsupported multi-volume RAR archive."; - } - return -1; -} - -static int -RAR_init(RARArchive *self, PyObject *args, PyObject *kwds) { - PyObject *file, *name, *get_comment = Py_False, *pycallback; - wchar_t *cname; - - if (!PyArg_ParseTuple(args, "OOO|O", &file, &name, &pycallback, &get_comment)) return -1; - if (!PyObject_HasAttrString(file, "read") || !PyObject_HasAttrString(file, "seek") || !PyObject_HasAttrString(file, "tell")) { - PyErr_SetString(PyExc_TypeError, "file must be a file like object"); - return -1; - } - cname = unicode_to_wchar(name); - if (cname == NULL) return -1; - - self->Cmd.Callback = (UNRARCALLBACK)callback; - self->Cmd.UserData = (LPARAM)pycallback; - - self->archive = new (std::nothrow) PyArchive(file, cname, &self->Cmd); - if (self->archive == NULL) { NOMEM; return -1; } - free(cname); - - self->DataIO.UnpArcSize=self->archive->FileLength(); - self->DataIO.UnpVolume=false; - - self->Unp = new (std::nothrow) Unpack(&self->DataIO); - if (self->Unp == NULL) { NOMEM; return -1; } - self->file_count = 0; - - try { - self->Unp->Init(); - if (!self->archive->is_archive()) { - if (!PyErr_Occurred()) - PyErr_SetString(UNRARError, "Not a RAR archive"); - return -1; - } - - if (PyObject_IsTrue(get_comment)) { - Array cdata; - if (self->archive->GetComment(&cdata, NULL)) { - self->comment = PyBytes_FromStringAndSize((const char*)&cdata[0], cdata.Size()); - if (self->comment == NULL) { NOMEM; return -1; } - } else { - self->comment = Py_None; - Py_INCREF(self->comment); - } - - } else { - self->comment = Py_None; - Py_INCREF(self->comment); - } - - } catch (RAR_EXIT errcode) { - handle_rar_error(errcode); - return -1; - } catch (std::bad_alloc) { - if (!PyErr_Occurred()) - NOMEM; - return -1; - } - - return 0; -} - -// Properties {{{ - -// RARArchive.friendly_name {{{ -static PyObject * -RAR_comment(RARArchive *self, void *closure) { - Py_INCREF(self->comment); return self->comment; -} // }}} - -static PyGetSetDef RAR_getsetters[] = { - {(char *)"comment", - (getter)RAR_comment, NULL, - (char *)"The RAR archive comment or None", - NULL}, - - {NULL} /* Sentinel */ -}; -// }}} - -static PyObject * -RAR_current_item(RARArchive *self, PyObject *args) { - PyObject *filename = Py_None; - try { - self->header_size = (int) self->archive->SearchBlock(FILE_HEAD); - - if (self->header_size <= 0) { - if (self->archive->Volume && self->archive->GetHeaderType() == ENDARC_HEAD && - self->archive->EndArcHead.Flags & EARC_NEXT_VOLUME) { - PyErr_SetString(UNRARError, "This is a multivolume RAR archive. Not supported."); - return NULL; - } - if (self->archive->BrokenFileHeader) { - PyErr_SetString(UNRARError, "This archive has a broken file header."); - return NULL; - } - Py_RETURN_NONE; - } - - if (self->archive->NewLhd.Flags & LHD_SPLIT_BEFORE) { - PyErr_SetString(UNRARError, "This is a split RAR archive. Not supported."); - return NULL; - } - } catch (RAR_EXIT errcode) { - handle_rar_error(errcode); - return NULL; - } catch (std::bad_alloc) { - if (!PyErr_Occurred()) - NOMEM; - return NULL; - } - - FileHeader fh = self->archive->NewLhd; - - if (*(fh.FileNameW)) { - filename = wchar_to_unicode(fh.FileNameW); - if (!filename) return NULL; - } else { - Py_INCREF(filename); - } - PyObject *tret = PyDict_New(); - PyObject *temp = NULL; - if(!tret) goto error; - if (!(temp = Py_BuildValue("s#", fh.FileName, fh.NameSize))) goto error; - if (PyDict_SetItemString(tret, "filename", temp) != 0) goto error; - Py_DECREF(temp); temp = NULL; -#define AVAL(name, code, val) {if (!(temp = Py_BuildValue(code, (val)))) goto error; if (PyDict_SetItemString(tret, name, temp) != 0) goto error; Py_DECREF(temp); temp = NULL;} - AVAL("arcname", "s", self->archive->FileName); - AVAL("filenamew", "N", filename); - AVAL("flags", "H", fh.Flags); - AVAL("pack_size", "I", fh.PackSize); - AVAL("pack_size_high", "I", fh.HighPackSize); - AVAL("unpack_size", "I", fh.UnpSize); - AVAL("unpack_size_high", "I", fh.HighUnpSize); - AVAL("host_os", "b", fh.HostOS); - AVAL("file_crc", "I", fh.FileCRC); - AVAL("file_time", "I", fh.FileTime); - AVAL("unpack_ver", "b", fh.UnpVer); - AVAL("method", "b", fh.Method); - AVAL("file_attr", "I", fh.FileAttr); - AVAL("is_directory", "O", (self->archive->IsArcDir()) ? Py_True : Py_False); - AVAL("is_symlink", "O", (IsLink(fh.FileAttr)) ? Py_True : Py_False); - AVAL("is_label", "O", (self->archive->IsArcLabel()) ? Py_True : Py_False); - AVAL("has_password", "O", ((fh.Flags & LHD_PASSWORD) != 0) ? Py_True : Py_False); - - return tret; -error: - Py_XDECREF(tret); Py_XDECREF(temp); Py_XDECREF(filename); - return NULL; -} - -static File unrar_dummy_output = File(); - -static PyObject * -RAR_process_item(RARArchive *self, PyObject *args) { - PyObject *extract = Py_False; - - if (!PyArg_ParseTuple(args, "|O", &extract)) return NULL; - self->file_count++; - try { - if (PyObject_IsTrue(extract)) { - if ((self->archive->NewLhd.Flags & LHD_PASSWORD) != 0) { - PyErr_SetString(UNRARError, "This file is locked with a password."); - return NULL; - } - if (self->archive->NewLhd.Flags & LHD_SPLIT_AFTER) { - PyErr_SetString(UNRARError, "This file is part of a multivolume RAR archive."); - return NULL; - } - self->DataIO.UnpVolume = false; - self->DataIO.NextVolumeMissing=false; - self->DataIO.CurUnpRead=0; - self->DataIO.CurUnpWrite=0; - self->DataIO.UnpFileCRC=self->archive->OldFormat ? 0 : 0xffffffff; - self->DataIO.PackedCRC=0xffffffff; - // self->DataIO.SetEncryption(0, NULL, NULL, false, self->archive->NewLhd.UnpVer>=36); - self->DataIO.SetPackedSizeToRead(self->archive->NewLhd.FullPackSize); - self->DataIO.SetFiles(self->archive, &unrar_dummy_output); - self->DataIO.SetTestMode(false); - self->DataIO.SetSkipUnpCRC(false); - self->DataIO.SetTestMode(true); // We set this so that the Write method is not called on the output file by UnpWrite() - self->Cmd.DllOpMode = RAR_EXTRACT; - - if (IsLink(self->archive->NewLhd.FileAttr)) { - char LinkTarget[NM]; - int datasz = Min(self->archive->NewLhd.PackSize, NM-1); - self->DataIO.UnpRead((byte *)LinkTarget, datasz); - LinkTarget[datasz]=0; - self->DataIO.UnpWrite((byte*)LinkTarget, datasz); - self->archive->SeekToNext(); - } else if (self->archive->IsArcDir() || self->archive->NewLhd.FullUnpSize < 1) { - self->archive->SeekToNext(); - } else { - // Implementation from the ExtractCurrentFile() method in the unrar source code - if (self->archive->NewLhd.Method == 0x30) { - Array Buffer(0x10000); - int64 DestUnpSize = self->archive->NewLhd.FullUnpSize; - uint Code = 0; - while (true) - { - Code = self->DataIO.UnpRead(&Buffer[0], Buffer.Size()); - if (Code==0 || (int)Code==-1) break; - Code = (Code < DestUnpSize) ? Code:(uint)DestUnpSize; - self->DataIO.UnpWrite(&Buffer[0], Code); - if (DestUnpSize >= 0) DestUnpSize -= Code; - } - } else { - self->Unp->SetDestSize(self->archive->NewLhd.FullUnpSize); - if (self->archive->NewLhd.UnpVer<=15) - self->Unp->DoUnpack(15,self->file_count>1 && self->archive->Solid); - else - self->Unp->DoUnpack(self->archive->NewLhd.UnpVer,(self->archive->NewLhd.Flags & LHD_SOLID)!=0); - } - self->archive->SeekToNext(); - bool ValidCRC = (self->archive->OldFormat && GET_UINT32(self->DataIO.UnpFileCRC)==GET_UINT32(self->archive->NewLhd.FileCRC)) || - (!self->archive->OldFormat && GET_UINT32(self->DataIO.UnpFileCRC)==GET_UINT32(self->archive->NewLhd.FileCRC^0xffffffff)); - if (!ValidCRC) { - PyErr_SetString(UNRARError, "Invalid CRC for item"); - return NULL; - } - // Comes from ProcessFile in dll.cpp - while(self->archive->IsOpened() && self->archive->ReadHeader() != 0 && self->archive->GetHeaderType() == NEWSUB_HEAD) { - // Skip extra file information - self->archive->SeekToNext(); - } - self->archive->Seek(self->archive->CurBlockPos, SEEK_SET); - } - } else { - if (self->archive->Volume && self->archive->GetHeaderType() == FILE_HEAD && self->archive->NewLhd.Flags & LHD_SPLIT_AFTER) { - PyErr_SetString(UNRARError, "This is a split RAR archive. Not supported."); - return NULL; - } - self->archive->SeekToNext(); - } - } catch(RAR_EXIT errcode) { - handle_rar_error(errcode); - return NULL; - } catch (std::bad_alloc) { - if (!PyErr_Occurred()) - NOMEM; - return NULL; - } - Py_RETURN_NONE; -} - -static PyMethodDef RAR_methods[] = { - {"current_item", (PyCFunction)RAR_current_item, METH_VARARGS, - "current_item() -> Return the current item in this RAR file." - }, - - {"process_item", (PyCFunction)RAR_process_item, METH_VARARGS, - "process_item(extract=False) -> Process the current item." - }, - - {NULL} /* Sentinel */ -}; - -static PyTypeObject RARArchiveType = { // {{{ - PyObject_HEAD_INIT(NULL) - 0, /*ob_size*/ - "unrar.RARArchive", /*tp_name*/ - sizeof(RARArchive), /*tp_basicsize*/ - 0, /*tp_itemsize*/ - (destructor)RAR_dealloc, /*tp_dealloc*/ - 0, /*tp_print*/ - 0, /*tp_getattr*/ - 0, /*tp_setattr*/ - 0, /*tp_compare*/ - 0, /*tp_repr*/ - 0, /*tp_as_number*/ - 0, /*tp_as_sequence*/ - 0, /*tp_as_mapping*/ - 0, /*tp_hash */ - 0, /*tp_call*/ - 0, /*tp_str*/ - 0, /*tp_getattro*/ - 0, /*tp_setattro*/ - 0, /*tp_as_buffer*/ - Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, /*tp_flags*/ - "RARArchive", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - RAR_methods, /* tp_methods */ - 0, /* tp_members */ - RAR_getsetters, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - (initproc)RAR_init, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ -}; // }}} - -// }}} End RARArchive - - -CALIBRE_MODINIT_FUNC -initunrar(void) { - PyObject *m; - - RARArchiveType.tp_new = PyType_GenericNew; - if (PyType_Ready(&RARArchiveType) < 0) - return; - - m = Py_InitModule3( - "unrar", methods, - "Support for reading RAR archives" - ); - if (m == NULL) return; - - UNRARError = PyErr_NewException((char*)"unrar.UNRARError", NULL, NULL); - if (UNRARError == NULL) return; - PyModule_AddObject(m, "UNRARError", UNRARError); - - Py_INCREF(&RARArchiveType); - PyModule_AddObject(m, "RARArchive", (PyObject *)&RARArchiveType); - -} - - - diff --git a/src/calibre/utils/unrar.py b/src/calibre/utils/unrar.py index 11e294ef2e..1bb191a496 100644 --- a/src/calibre/utils/unrar.py +++ b/src/calibre/utils/unrar.py @@ -1,205 +1,95 @@ #!/usr/bin/env python2 # vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:fdm=marker:ai -from __future__ import (unicode_literals, division, absolute_import, - print_function) +from __future__ import (unicode_literals, division, absolute_import, print_function) -__license__ = 'GPL v3' +__license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal ' __docformat__ = 'restructuredtext en' -import os, sys, re +import os +import shutil +import re from io import BytesIO -from calibre import force_unicode -from calibre.constants import filesystem_encoding, isosx +from calibre.constants import filesystem_encoding +from calibre.ptempfile import PersistentTemporaryFile, TemporaryDirectory -class UNRARError(Exception): - pass +def as_unicode(x): + if isinstance(x, bytes): + x = x.decode(filesystem_encoding) + return x -class DevNull: - - def write(self, x): - pass - - -class RARStream(object): - - def __init__(self, stream, unrar, get_comment=False): - self.stream = stream - self.unrar = unrar - self._current_cache = None - try: - self.r = unrar.RARArchive(stream, force_unicode( - getattr(stream, 'name', ''), filesystem_encoding), - self, get_comment) - except unrar.UNRARError as e: - raise UNRARError(type(u'')(e)) - self.comment = self.r.comment - - def handle_data(self, raw): - if self._current_dest is not None: - self._current_dest.write(raw) - - def populate_header(self): - c = self._current_cache - if c['filenamew'] is None: - c['filenamew'] = self._decode(c['filename']) - c['filename'] = c.pop('filenamew').replace('\\', '/') - - def _decode(self, raw): - for enc in ('utf-8', 'utf-16le'): - try: - return raw.decode(enc) - except UnicodeDecodeError: - pass - return raw.decode('windows-1252', 'replace') - - @property - def current_item(self): - if self._current_cache is None: - try: - self._current_cache = self.r.current_item() - except self.unrar.UNRARError as e: - raise UNRARError(type(u'')(e)) - if self._current_cache is None: - raise EOFError('End of RAR file') - self.populate_header() - return self._current_cache - - def process_current_item(self, extract_to=None): - self._current_cache = None - self._current_dest = extract_to - try: - ans = self.r.process_item(extract_to is not None) - except self.unrar.UNRARError as e: - raise UNRARError(type(u'')(e)) - return ans - - def test(self, print_names=False): - null = DevNull() - while True: - try: - h = self.current_item - except EOFError: - break - if print_names: - print (h['filename'].encode(sys.stdout.encoding)) - self.process_current_item(null) - - -def RARFile(stream, get_comment=False): - from calibre.constants import plugins - unrar, err = plugins['unrar'] - if err: - raise RuntimeError('Failed to load unrar module with error: %s' - %err) - return RARStream(stream, unrar, get_comment=get_comment) - - -class SaveStream(object): +class StreamAsPath(object): def __init__(self, stream): self.stream = stream def __enter__(self): - self.stream.seek(0) + self.temppath = None + if isinstance(self.stream, basestring): + return as_unicode(self.stream) + name = getattr(self.stream, 'name', None) + if name and os.access(name, os.R_OK): + return as_unicode(name) + pos = self.stream.tell() + with PersistentTemporaryFile('for-unar', 'wb') as f: + shutil.copyfileobj(self.stream, f) + self.stream.seek(pos) + self.temppath = f.name + return as_unicode(f.name) - def __exit__(self, *args): - self.stream.seek(0) - - -def safe_path(base, relpath): - base = os.path.abspath(base) - path = os.path.abspath(os.path.join(base, relpath)) - if (os.path.normcase(path) == os.path.normcase(base) or not - os.path.normcase(path).startswith(os.path.normcase(base))): - return None - return path - - -def is_useful(h): - return not (h['is_label'] or h['is_symlink'] or h['has_password'] or - h['is_directory']) - - -def stream_extract(stream, location): - location = os.path.abspath(location) - if not os.path.exists(location): - os.makedirs(location) - - with SaveStream(stream): - f = RARFile(stream) - while True: + def __exit__(self, *a): + if self.temppath is not None: try: - h = f.current_item - except EOFError: - break - if not is_useful(h): - f.process_current_item() # Skip these - if h['is_directory']: - try: - os.makedirs(safe_path(location, h['filename'])) - except: - # We ignore create directory errors since we dont - # care about missing empty dirs - pass - else: - path = safe_path(location, h['filename']) - if path is not None: - base, fname = os.path.split(path) - if not os.path.exists(base): - os.makedirs(base) - with open(path, 'wb') as dest: - f.process_current_item(dest) + os.remove(self.temppath) + except EnvironmentError: + pass + self.temppath = None -def extract(path, location): - with open(path, 'rb') as stream: - stream_extract(stream, location) +def extract(path_or_stream, location): + from unrardll import extract + with StreamAsPath(path_or_stream) as path: + return extract(path, location) -def names(stream): - with SaveStream(stream): - f = RARFile(stream) - while True: - try: - h = f.current_item - except EOFError: - break - f.process_current_item() - if is_useful(h): - yield h['filename'] +def names(path_or_stream): + from unrardll import names + with StreamAsPath(path_or_stream) as path: + for name in names(path, only_useful=True): + yield name -def extract_member(stream, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), - name=None): +def comment(path_or_stream): + from unrardll import comment + with StreamAsPath(path_or_stream) as path: + return comment(path) - def is_match(fname): + +def extract_member( + path_or_stream, match=re.compile(r'\.(jpg|jpeg|gif|png)\s*$', re.I), name=None): + from unrardll import extract_member + + def is_match(header): + fname = header['filename'] return (name is not None and fname == name) or \ (match is not None and match.search(fname) is not None) - with SaveStream(stream): - f = RARFile(stream) - while True: - try: - h = f.current_item - except EOFError: - break - if (not is_useful(h) or not is_match(h['filename'])): - f.process_current_item() - continue - - et = BytesIO() - f.process_current_item(et) - return h['filename'], et.getvalue() + with StreamAsPath(path_or_stream) as path: + name, data = extract_member(path, is_match) + if name is not None: + return name, data def extract_first_alphabetically(stream): from calibre.libunzip import sort_key - names_ = sorted([x for x in names(stream) if os.path.splitext(x)[1][1:].lower() in - {'png', 'jpg', 'jpeg', 'gif', 'webp'}], key=sort_key) + names_ = sorted([ + x for x in names(stream) + if os.path.splitext(x)[1][1:].lower() in { + 'png', 'jpg', 'jpeg', 'gif', 'webp'}], + key=sort_key) return extract_member(stream, name=names_[0], match=None) @@ -209,79 +99,57 @@ def extract_cover_image(stream): if name_ok(name): return extract_member(stream, name=name, match=None) + # Test normal RAR file {{{ def test_basic(): - stream = BytesIO( - b"Rar!\x1a\x07\x00\xcf\x90s\x00\x00\r\x00\x00\x00\x00\x00\x00\x00\x14\xe7z\x00\x80#\x00\x17\x00\x00\x00\r\x00\x00\x00\x03\xc2\xb3\x96o\x00\x00\x00\x00\x1d3\x03\x00\x00\x00\x00\x00CMT\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe6h\x04\x17\xff\xcd\x0f\xffk9b\x11]^\x80\xd3dt \x90+\x00\x14\x00\x00\x00\x08\x00\x00\x00\x03\xf1\x84\x93\\\xb9]yA\x1d3\t\x00\xa4\x81\x00\x001\\sub-one\x00\xc0\x0c\x00\x8f\xec\x89\xfe.JM\x86\x82\x0c_\xfd\xfd\xd7\x11\x1a\xef@\x9eHt \x80'\x00\x0e\x00\x00\x00\x04\x00\x00\x00\x03\x9f\xa8\x17\xf8\xaf]yA\x1d3\x07\x00\xa4\x81\x00\x00one.txt\x00\x08\xbf\x08\xae\xf3\xca\x87\xfeo\xfe\xd2n\x80-Ht \x82:\x00\x18\x00\x00\x00\x10\x00\x00\x00\x03\xa86\x81\xdf\xf9fyA\x1d3\x1a\x00\xa4\x81\x00\x00\xe8\xaf\xb6\xe6\xaf\x94\xe5\xb1\x81.txt\x00\x8bh\xf6\xd4kA\\.\x00txt\x0c\x00\x8b\xec\x8e\xef\x14\xf6\xe2l\x91\x189\xff\xdf\xfe\xc2\xd3:g\x9a\x19F=cYt \x928\x00\x11\x00\x00\x00\x08\x00\x00\x00\x03\x7f\xd6\xb6\x7f\xeafyA\x1d3\x16\x00\xa4\x81\x00\x00F\xc3\xbc\xc3\x9fe.txt\x00\x01\x00F\xfc\xdfe\x00.txt\x00\xc0 1: - raise ValueError('Leaked %s MB for %d calls'%(b - a, 100)) - # }}} + if set(names(stream)) != { + '1/sub-one', 'one.txt', '2/sub-two.txt', '诶比屁.txt', 'Füße.txt', + 'uncompressed', 'max-compressed'}: + raise ValueError('Name list does not match') + with TemporaryDirectory('test-unrar') as tdir: + extract(stream, tdir) + for name in tdata: + if name not in '1 2 symlink'.split(): + with open(os.path.join(tdir, name), 'rb') as s: + if s.read() != tdata[name]: + raise ValueError('Did not extract %s properly' % name) + do_test(stream) + with PersistentTemporaryFile('test-unrar') as f: + shutil.copyfileobj(stream, f) + with open(f.name, 'rb') as stream: + do_test(stream) + os.remove(f.name) -def test_rar(path): - with open(path, 'rb') as stream: - f = RARFile(stream) - f.test(print_names=True) if __name__ == '__main__': test_basic() diff --git a/src/unrar/UnRAR.vcproj b/src/unrar/UnRAR.vcproj deleted file mode 100644 index da8c21458a..0000000000 --- a/src/unrar/UnRAR.vcproj +++ /dev/null @@ -1,623 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/unrar/UnRARDll.vcproj b/src/unrar/UnRARDll.vcproj deleted file mode 100644 index 4d3b819c4e..0000000000 --- a/src/unrar/UnRARDll.vcproj +++ /dev/null @@ -1,848 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/unrar/acknow.txt b/src/unrar/acknow.txt deleted file mode 100644 index 8ea06e4d39..0000000000 --- a/src/unrar/acknow.txt +++ /dev/null @@ -1,81 +0,0 @@ - ACKNOWLEDGMENTS - -* RAR text compression algorithm is based on Dmitry Shkarin PPMII - and Dmitry Subbotin carryless rangecoder public domain source code. - You may find it in ftp.elf.stuba.sk/pub/pc/pack. - -* RAR encryption includes parts of code from Szymon Stefanek - and Brian Gladman AES implementations also as Steve Reid SHA-1 source. - - --------------------------------------------------------------------------- - Copyright (c) 2002, Dr Brian Gladman < >, Worcester, UK. - All rights reserved. - - LICENSE TERMS - - The free distribution and use of this software in both source and binary - form is allowed (with or without changes) provided that: - - 1. distributions of this source code include the above copyright - notice, this list of conditions and the following disclaimer; - - 2. distributions in binary form include the above copyright - notice, this list of conditions and the following disclaimer - in the documentation and/or other associated materials; - - 3. the copyright holder's name is not used to endorse products - built using this software without specific written permission. - - ALTERNATIVELY, provided that this notice is retained in full, this product - may be distributed under the terms of the GNU General Public License (GPL), - in which case the provisions of the GPL apply INSTEAD OF those given above. - - DISCLAIMER - - This software is provided 'as is' with no explicit or implied warranties - in respect of its properties, including, but not limited to, correctness - and/or fitness for purpose. - --------------------------------------------------------------------------- - - Source code of this package also as other cryptographic technology - and computing project related links are available on Brian Gladman's - web site: http://www.gladman.me.uk - -* RAR uses CRC32 function based on Intel Slicing-by-8 algorithm. - Original Intel Slicing-by-8 code is available here: - - http://sourceforge.net/projects/slicing-by-8/ - - Original Intel Slicing-by-8 code is licensed under BSD License - available at http://www.opensource.org/licenses/bsd-license.html - - Copyright (c) 2004-2006 Intel Corporation. - All Rights Reserved - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer - in the documentation and/or other materials provided with - the distribution. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - -* Useful hints provided by Alexander Khoroshev and Bulat Ziganshin allowed - to significantly improve RAR compression and speed. diff --git a/src/unrar/arccmt.cpp b/src/unrar/arccmt.cpp deleted file mode 100644 index 189fc791e3..0000000000 --- a/src/unrar/arccmt.cpp +++ /dev/null @@ -1,235 +0,0 @@ -bool IsAnsiComment(const char *Data,int Size); - -bool Archive::GetComment(Array *CmtData,Array *CmtDataW) -{ - if (!MainComment) - return(false); - SaveFilePos SavePos(*this); - -#ifndef SFX_MODULE - ushort CmtLength; - if (OldFormat) - { - Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET); - CmtLength=GetByte(); - CmtLength+=(GetByte()<<8); - } - else -#endif - { - if ((NewMhd.Flags & MHD_COMMENT)!=0) - { - // Old style (RAR 2.9) archive comment embedded into the main - // archive header. - Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET); - ReadHeader(); - } - else - { - // Current (RAR 3.0+) version of archive comment. - Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET); - return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0); - } -#ifndef SFX_MODULE - // Old style (RAR 2.9) comment header embedded into the main - // archive header. - if (CommHead.HeadCRC!=HeaderCRC) - { - Log(FileName,St(MLogCommHead)); - Alarm(); - return(false); - } - CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD; -#endif - } -#ifndef SFX_MODULE - if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT)!=0 || !OldFormat && CommHead.Method!=0x30) - { - if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35)) - return(false); - ComprDataIO DataIO; - DataIO.SetTestMode(true); - uint UnpCmtLength; - if (OldFormat) - { -#ifdef RAR_NOCRYPT - return(false); -#else - UnpCmtLength=GetByte(); - UnpCmtLength+=(GetByte()<<8); - CmtLength-=2; - DataIO.SetCmt13Encryption(); -#endif - } - else - UnpCmtLength=CommHead.UnpSize; - DataIO.SetFiles(this,NULL); - DataIO.EnableShowProgress(false); - DataIO.SetPackedSizeToRead(CmtLength); - - Unpack Unpack(&DataIO); - Unpack.Init(); - Unpack.SetDestSize(UnpCmtLength); - Unpack.DoUnpack(CommHead.UnpVer,false); - - if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC) - { - Log(FileName,St(MLogCommBrk)); - Alarm(); - return(false); - } - else - { - byte *UnpData; - size_t UnpDataSize; - DataIO.GetUnpackedData(&UnpData,&UnpDataSize); - CmtData->Alloc(UnpDataSize); - memcpy(&((*CmtData)[0]),UnpData,UnpDataSize); - } - } - else - { - CmtData->Alloc(CmtLength); - - Read(&((*CmtData)[0]),CmtLength); - if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff)) - { - Log(FileName,St(MLogCommBrk)); - Alarm(); - CmtData->Reset(); - return(false); - } - } -#endif -#if defined(_WIN_ALL) && !defined(_WIN_CE) - if (CmtData->Size()>0) - { - size_t CmtSize=CmtData->Size(); - char *DataA=(char *)CmtData->Addr(); - OemToCharBuffA(DataA,DataA,(DWORD)CmtSize); - - if (CmtDataW!=NULL) - { - CmtDataW->Alloc(CmtSize+1); - - // It can cause reallocation, so we should not use 'DataA' variable - // with previosuly saved CmtData->Addr() after Push() call. - CmtData->Push(0); - - CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1); - CmtData->Alloc(CmtSize); - CmtDataW->Alloc(wcslen(CmtDataW->Addr())); - } - } -#endif - return(CmtData->Size()>0); -} - - -size_t Archive::ReadCommentData(Array *CmtData,Array *CmtDataW) -{ - bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE; - if (!ReadSubData(CmtData,NULL)) - return(0); - size_t CmtSize=CmtData->Size(); - if (Unicode) - { - CmtSize/=2; - Array DataW(CmtSize+1); - RawToWide(CmtData->Addr(),DataW.Addr(),CmtSize); - DataW[CmtSize]=0; - size_t DestSize=CmtSize*4; - CmtData->Alloc(DestSize+1); - WideToChar(DataW.Addr(),(char *)CmtData->Addr(),DestSize); - (*CmtData)[DestSize]=0; - CmtSize=strlen((char *)CmtData->Addr()); - CmtData->Alloc(CmtSize); - if (CmtDataW!=NULL) - { - *CmtDataW=DataW; - CmtDataW->Alloc(CmtSize); - } - } - else - if (CmtDataW!=NULL) - { - CmtData->Push(0); - CmtDataW->Alloc(CmtSize+1); - CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1); - CmtData->Alloc(CmtSize); - CmtDataW->Alloc(wcslen(CmtDataW->Addr())); - } - return(CmtSize); -} - - -void Archive::ViewComment() -{ -#ifndef GUI - if (Cmd->DisableComment) - return; - Array CmtBuf; - if (GetComment(&CmtBuf,NULL)) - { - size_t CmtSize=CmtBuf.Size(); - char *ChPtr=(char *)memchr(&CmtBuf[0],0x1A,CmtSize); - if (ChPtr!=NULL) - CmtSize=ChPtr-(char *)&CmtBuf[0]; - mprintf("\n"); - OutComment((char *)&CmtBuf[0],CmtSize); - } -#endif -} - - -#ifndef SFX_MODULE -// Used for archives created by old RAR versions up to and including RAR 2.9. -// New RAR versions store file comments in separate headers and such comments -// are displayed in ListNewSubHeader function. -void Archive::ViewFileComment() -{ - if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat) - return; -#ifndef GUI - mprintf(St(MFileComment)); -#endif - const int MaxSize=0x8000; - Array CmtBuf(MaxSize); - SaveFilePos SavePos(*this); - Seek(CurBlockPos+SIZEOF_NEWLHD+NewLhd.NameSize,SEEK_SET); - int64 SaveCurBlockPos=CurBlockPos; - int64 SaveNextBlockPos=NextBlockPos; - - size_t Size=ReadHeader(); - - CurBlockPos=SaveCurBlockPos; - NextBlockPos=SaveNextBlockPos; - - if (Size<7 || CommHead.HeadType!=COMM_HEAD) - return; - if (CommHead.HeadCRC!=HeaderCRC) - { -#ifndef GUI - Log(FileName,St(MLogCommHead)); -#endif - return; - } - if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || - CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize) - return; - Read(&CmtBuf[0],CommHead.UnpSize); - if (CommHead.CommCRC!=((~CRC(0xffffffff,&CmtBuf[0],CommHead.UnpSize)&0xffff))) - { - Log(FileName,St(MLogBrokFCmt)); - } - else - { - OutComment(&CmtBuf[0],CommHead.UnpSize); -#ifndef GUI - mprintf("\n"); -#endif - } -} -#endif - - diff --git a/src/unrar/archive.cpp b/src/unrar/archive.cpp deleted file mode 100644 index b061e540a4..0000000000 --- a/src/unrar/archive.cpp +++ /dev/null @@ -1,284 +0,0 @@ -#include "rar.hpp" - -#ifndef SHELL_EXT -#include "arccmt.cpp" -#endif - - -Archive::Archive(RAROptions *InitCmd) -{ - Cmd=InitCmd==NULL ? &DummyCmd:InitCmd; - OpenShared=Cmd->OpenShared; - OldFormat=false; - Solid=false; - Volume=false; - MainComment=false; - Locked=false; - Signed=false; - NotFirstVolume=false; - SFXSize=0; - LatestTime.Reset(); - Protected=false; - Encrypted=false; - FailedHeaderDecryption=false; - BrokenFileHeader=false; - LastReadBlock=0; - - CurBlockPos=0; - NextBlockPos=0; - - RecoveryPos=SIZEOF_MARKHEAD; - RecoverySectors=-1; - - memset(&NewMhd,0,sizeof(NewMhd)); - NewMhd.HeadType=MAIN_HEAD; - NewMhd.HeadSize=SIZEOF_NEWMHD; - HeaderCRC=0; - VolWrite=0; - AddingFilesSize=0; - AddingHeadersSize=0; -#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT) - *HeadersSalt=0; - *SubDataSalt=0; -#endif - *FirstVolumeName=0; - *FirstVolumeNameW=0; - - Splitting=false; - NewArchive=false; - - SilentOpen=false; - -} - - - -#ifndef SHELL_EXT -void Archive::CheckArc(bool EnableBroken) -{ - if (!IsArchive(EnableBroken)) - { - Log(FileName,St(MBadArc),FileName); - ErrHandler.Exit(RARX_FATAL); - } -} -#endif - - -#if !defined(SHELL_EXT) && !defined(SFX_MODULE) -void Archive::CheckOpen(const char *Name,const wchar *NameW) -{ - TOpen(Name,NameW); - CheckArc(false); -} -#endif - - -bool Archive::WCheckOpen(const char *Name,const wchar *NameW) -{ - if (!WOpen(Name,NameW)) - return(false); - if (!IsArchive(false)) - { -#ifndef SHELL_EXT - Log(FileName,St(MNotRAR),FileName); -#endif - Close(); - return(false); - } - return(true); -} - - -ARCSIGN_TYPE Archive::IsSignature(const byte *D,size_t Size) -{ - ARCSIGN_TYPE Type=ARCSIGN_NONE; - if (Size>=1 && D[0]==0x52) -#ifndef SFX_MODULE - if (Size>=4 && D[1]==0x45 && D[2]==0x7e && D[3]==0x5e) - Type=ARCSIGN_OLD; - else -#endif - if (Size>=7 && D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07) - { - // We check for non-zero last signature byte, so we can return - // a sensible warning in case we'll want to change the archive - // format sometimes in the future. - Type=D[6]==0 ? ARCSIGN_CURRENT:ARCSIGN_FUTURE; - } - return Type; -} - - -bool Archive::IsArchive(bool EnableBroken) -{ - Encrypted=false; -#ifndef SFX_MODULE - if (IsDevice()) - { -#ifndef SHELL_EXT - Log(FileName,St(MInvalidName),FileName); -#endif - return(false); - } -#endif - if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD) - return(false); - SFXSize=0; - - ARCSIGN_TYPE Type; - if ((Type=IsSignature(MarkHead.Mark,sizeof(MarkHead.Mark)))!=ARCSIGN_NONE) - { - OldFormat=(Type==ARCSIGN_OLD); - if (OldFormat) - Seek(0,SEEK_SET); - } - else - { - Array Buffer(MAXSFXSIZE); - long CurPos=(long)Tell(); - int ReadSize=Read(&Buffer[0],Buffer.Size()-16); - for (int I=0;I0 && CurPos<28 && ReadSize>31) - { - char *D=&Buffer[28-CurPos]; - if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58) - continue; - } - SFXSize=CurPos+I; - Seek(SFXSize,SEEK_SET); - if (!OldFormat) - Read(MarkHead.Mark,SIZEOF_MARKHEAD); - break; - } - if (SFXSize==0) - return false; - } - if (Type==ARCSIGN_FUTURE) - { -#if !defined(SHELL_EXT) && !defined(SFX_MODULE) - Log(FileName,St(MNewRarFormat)); -#endif - return false; - } - ReadHeader(); - SeekToNext(); -#ifndef SFX_MODULE - if (OldFormat) - { - NewMhd.Flags=OldMhd.Flags & 0x3f; - NewMhd.HeadSize=OldMhd.HeadSize; - } - else -#endif - { - if (HeaderCRC!=NewMhd.HeadCRC) - { -#ifndef SHELL_EXT - Log(FileName,St(MLogMainHead)); -#endif - Alarm(); - if (!EnableBroken) - return(false); - } - } - Volume=(NewMhd.Flags & MHD_VOLUME); - Solid=(NewMhd.Flags & MHD_SOLID)!=0; - MainComment=(NewMhd.Flags & MHD_COMMENT)!=0; - Locked=(NewMhd.Flags & MHD_LOCK)!=0; - Signed=(NewMhd.PosAV!=0); - Protected=(NewMhd.Flags & MHD_PROTECT)!=0; - Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0; - - if (NewMhd.EncryptVer>UNP_VER) - { -#ifdef RARDLL - Cmd->DllError=ERAR_UNKNOWN_FORMAT; -#else - ErrHandler.SetErrorCode(RARX_WARNING); - #if !defined(SILENT) && !defined(SFX_MODULE) - Log(FileName,St(MUnknownMeth),FileName); - Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10); - #endif -#endif - return(false); - } -#ifdef RARDLL - // If callback function is not set, we cannot get the password, - // so we skip the initial header processing for encrypted header archive. - // It leads to skipped archive comment, but the rest of archive data - // is processed correctly. - if (Cmd->Callback==NULL) - SilentOpen=true; -#endif - - // If not encrypted, we'll check it below. - NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0; - - if (!SilentOpen || !Encrypted) - { - SaveFilePos SavePos(*this); - int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos; - - NotFirstVolume=false; - while (ReadHeader()!=0) - { - int HeaderType=GetHeaderType(); - if (HeaderType==NEWSUB_HEAD) - { - if (SubHead.CmpName(SUBHEAD_TYPE_CMT)) - MainComment=true; - if ((SubHead.Flags & LHD_SPLIT_BEFORE) || - Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0) - NotFirstVolume=true; - } - else - { - if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 || - Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)) - NotFirstVolume=true; - break; - } - SeekToNext(); - } - CurBlockPos=SaveCurBlockPos; - NextBlockPos=SaveNextBlockPos; - } - if (!Volume || !NotFirstVolume) - { - strcpy(FirstVolumeName,FileName); - wcscpy(FirstVolumeNameW,FileNameW); - } - - return(true); -} - - - - -void Archive::SeekToNext() -{ - Seek(NextBlockPos,SEEK_SET); -} - - -#ifndef SFX_MODULE -int Archive::GetRecoverySize(bool Required) -{ - if (!Protected) - return(0); - if (RecoverySectors!=-1 || !Required) - return(RecoverySectors); - SaveFilePos SavePos(*this); - Seek(SFXSize,SEEK_SET); - SearchSubBlock(SUBHEAD_TYPE_RR); - return(RecoverySectors); -} -#endif - - - - diff --git a/src/unrar/archive.hpp b/src/unrar/archive.hpp deleted file mode 100644 index 58b4cd3efc..0000000000 --- a/src/unrar/archive.hpp +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef _RAR_ARCHIVE_ -#define _RAR_ARCHIVE_ - -class Pack; - -enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4}; - -enum ARCSIGN_TYPE {ARCSIGN_NONE,ARCSIGN_OLD,ARCSIGN_CURRENT,ARCSIGN_FUTURE}; - -class Archive:public File -{ - private: - ARCSIGN_TYPE IsSignature(const byte *D,size_t Size); - void UpdateLatestTime(FileHeader *CurBlock); - void ConvertNameCase(char *Name); - void ConvertNameCase(wchar *Name); - void ConvertUnknownHeader(); - size_t ReadOldHeader(); - void UnexpEndArcMsg(); - -#if !defined(SHELL_EXT) && !defined(RAR_NOCRYPT) - CryptData HeadersCrypt; - byte HeadersSalt[SALT_SIZE]; -#endif -#ifndef SHELL_EXT - ComprDataIO SubDataIO; - byte SubDataSalt[SALT_SIZE]; -#endif - RAROptions *Cmd,DummyCmd; - - MarkHeader MarkHead; - OldMainHeader OldMhd; - - int RecoverySectors; - int64 RecoveryPos; - - bool FailedHeaderDecryption; - - RarTime LatestTime; - int LastReadBlock; - int CurHeaderType; - - bool SilentOpen; - public: - Archive(RAROptions *InitCmd=NULL); - bool IsArchive(bool EnableBroken); - size_t SearchBlock(int BlockType); - size_t SearchSubBlock(const char *Type); - int ReadBlock(int BlockType); - void WriteBlock(int BlockType,BaseBlock *wb=NULL); - int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW); - void SetLhdSize(); - size_t ReadHeader(); - void CheckArc(bool EnableBroken); - void CheckOpen(const char *Name,const wchar *NameW=NULL); - bool WCheckOpen(const char *Name,const wchar *NameW=NULL); - bool GetComment(Array *CmtData,Array *CmtDataW); - void ViewComment(); - void ViewFileComment(); - void SetLatestTime(RarTime *NewTime); - void SeekToNext(); - bool CheckAccess(); - bool IsArcDir(); - bool IsArcLabel(); - void ConvertAttributes(); - int GetRecoverySize(bool Required); - void VolSubtractHeaderSize(size_t SubSize); - void AddSubData(byte *SrcData,size_t DataSize,File *SrcFile,const char *Name,bool AllowSplit); - bool ReadSubData(Array *UnpData,File *DestFile); - int GetHeaderType() {return(CurHeaderType);}; - size_t ReadCommentData(Array *CmtData,Array *CmtDataW); - void WriteCommentData(byte *Data,size_t DataSize,bool FileComment); - RAROptions* GetRAROptions() {return(Cmd);} - void SetSilentOpen(bool Mode) {SilentOpen=Mode;} - - BaseBlock ShortBlock; - MainHeader NewMhd; - FileHeader NewLhd; - EndArcHeader EndArcHead; - SubBlockHeader SubBlockHead; - FileHeader SubHead; - CommentHeader CommHead; - ProtectHeader ProtectHead; - AVHeader AVHead; - SignHeader SignHead; - UnixOwnersHeader UOHead; - MacFInfoHeader MACHead; - EAHeader EAHead; - StreamHeader StreamHead; - - int64 CurBlockPos; - int64 NextBlockPos; - - bool OldFormat; - bool Solid; - bool Volume; - bool MainComment; - bool Locked; - bool Signed; - bool NotFirstVolume; - bool Protected; - bool Encrypted; - size_t SFXSize; - bool BrokenFileHeader; - - bool Splitting; - - ushort HeaderCRC; - - int64 VolWrite; - int64 AddingFilesSize; - size_t AddingHeadersSize; - - bool NewArchive; - - char FirstVolumeName[NM]; - wchar FirstVolumeNameW[NM]; -}; - - -#endif diff --git a/src/unrar/arcread.cpp b/src/unrar/arcread.cpp deleted file mode 100644 index a524a96124..0000000000 --- a/src/unrar/arcread.cpp +++ /dev/null @@ -1,765 +0,0 @@ -#include "rar.hpp" - -size_t Archive::SearchBlock(int BlockType) -{ - size_t Size,Count=0; - while ((Size=ReadHeader())!=0 && - (BlockType==ENDARC_HEAD || GetHeaderType()!=ENDARC_HEAD)) - { - if ((++Count & 127)==0) - Wait(); - if (GetHeaderType()==BlockType) - return(Size); - SeekToNext(); - } - return(0); -} - - -size_t Archive::SearchSubBlock(const char *Type) -{ - size_t Size; - while ((Size=ReadHeader())!=0 && GetHeaderType()!=ENDARC_HEAD) - { - if (GetHeaderType()==NEWSUB_HEAD && SubHead.CmpName(Type)) - return(Size); - SeekToNext(); - } - return(0); -} - - -void Archive::UnexpEndArcMsg() -{ - int64 ArcSize=FileLength(); - if (CurBlockPos>ArcSize || NextBlockPos>ArcSize) - { -#ifndef SHELL_EXT - Log(FileName,St(MLogUnexpEOF)); -#endif - ErrHandler.SetErrorCode(RARX_WARNING); - } -} - - -size_t Archive::ReadHeader() -{ - // Once we failed to decrypt an encrypted block, there is no reason to - // attempt to do it further. We'll never be successful and only generate - // endless errors. - if (FailedHeaderDecryption) - return 0; - - CurBlockPos=Tell(); - -#ifndef SFX_MODULE - if (OldFormat) - return(ReadOldHeader()); -#endif - - RawRead Raw(this); - - bool Decrypt=Encrypted && CurBlockPos>=(int64)SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD; - - if (Decrypt) - { -#if defined(SHELL_EXT) || defined(RAR_NOCRYPT) - return(0); -#else - if (Read(HeadersSalt,SALT_SIZE)!=SALT_SIZE) - { - UnexpEndArcMsg(); - return(0); - } - if (!Cmd->Password.IsSet()) - { -#ifdef RARDLL - if (Cmd->Callback!=NULL) - { - wchar PasswordW[MAXPASSWORD]; - *PasswordW=0; - if (Cmd->Callback(UCM_NEEDPASSWORDW,Cmd->UserData,(LPARAM)PasswordW,ASIZE(PasswordW))==-1) - *PasswordW=0; - if (*PasswordW==0) - { - char PasswordA[MAXPASSWORD]; - *PasswordA=0; - if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1) - *PasswordA=0; - GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW)); - cleandata(PasswordA,sizeof(PasswordA)); - } - Cmd->Password.Set(PasswordW); - cleandata(PasswordW,sizeof(PasswordW)); - } - if (!Cmd->Password.IsSet()) - { - Close(); - Cmd->DllError=ERAR_MISSING_PASSWORD; - ErrHandler.Exit(RARX_USERBREAK); - } -#else - if (!GetPassword(PASSWORD_ARCHIVE,FileName,FileNameW,&Cmd->Password)) - { - Close(); - ErrHandler.Exit(RARX_USERBREAK); - } -#endif - } - HeadersCrypt.SetCryptKeys(&Cmd->Password,HeadersSalt,false,false,NewMhd.EncryptVer>=36); - Raw.SetCrypt(&HeadersCrypt); -#endif - } - - Raw.Read(SIZEOF_SHORTBLOCKHEAD); - if (Raw.Size()==0) - { - UnexpEndArcMsg(); - return(0); - } - - Raw.Get(ShortBlock.HeadCRC); - byte HeadType; - Raw.Get(HeadType); - ShortBlock.HeadType=(HEADER_TYPE)HeadType; - Raw.Get(ShortBlock.Flags); - Raw.Get(ShortBlock.HeadSize); - if (ShortBlock.HeadSizePackSize); - Raw.Get(hd->UnpSize); - Raw.Get(hd->HostOS); - Raw.Get(hd->FileCRC); - Raw.Get(hd->FileTime); - Raw.Get(hd->UnpVer); - Raw.Get(hd->Method); - Raw.Get(hd->NameSize); - Raw.Get(hd->FileAttr); - if (hd->Flags & LHD_LARGE) - { - Raw.Get(hd->HighPackSize); - Raw.Get(hd->HighUnpSize); - } - else - { - hd->HighPackSize=hd->HighUnpSize=0; - if (hd->UnpSize==0xffffffff) - { - // UnpSize equal to 0xffffffff without LHD_LARGE flag indicates - // that we do not know the unpacked file size and must unpack it - // until we find the end of file marker in compressed data. - hd->UnpSize=(uint)(INT64NDF); - hd->HighUnpSize=(uint)(INT64NDF>>32); - } - } - hd->FullPackSize=INT32TO64(hd->HighPackSize,hd->PackSize); - hd->FullUnpSize=INT32TO64(hd->HighUnpSize,hd->UnpSize); - - char FileName[NM*4]; - size_t NameSize=Min(hd->NameSize,sizeof(FileName)-1); - Raw.Get((byte *)FileName,NameSize); - FileName[NameSize]=0; - - strncpyz(hd->FileName,FileName,ASIZE(hd->FileName)); - - if (hd->HeadType==NEWSUB_HEAD) - { - // Let's calculate the size of optional data. - int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD; - if (hd->Flags & LHD_SALT) - DataSize-=SALT_SIZE; - - if (DataSize>0) - { - // Here we read optional additional fields for subheaders. - // They are stored after the file name and before salt. - hd->SubData.Alloc(DataSize); - Raw.Get(&hd->SubData[0],DataSize); - if (hd->CmpName(SUBHEAD_TYPE_RR)) - { - byte *D=&hd->SubData[8]; - RecoverySectors=D[0]+((uint)D[1]<<8)+((uint)D[2]<<16)+((uint)D[3]<<24); - } - } - } - else - if (hd->HeadType==FILE_HEAD) - { - if (hd->Flags & LHD_UNICODE) - { - EncodeFileName NameCoder; - size_t Length=strlen(FileName); - if (Length==hd->NameSize) - { - UtfToWide(FileName,hd->FileNameW,sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0])-1); - WideToChar(hd->FileNameW,hd->FileName,sizeof(hd->FileName)/sizeof(hd->FileName[0])-1); - ExtToInt(hd->FileName,hd->FileName); - } - else - { - Length++; - NameCoder.Decode(FileName,(byte *)FileName+Length, - hd->NameSize-Length,hd->FileNameW, - sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0])); - } - if (*hd->FileNameW==0) - hd->Flags &= ~LHD_UNICODE; - } - else - *hd->FileNameW=0; -#ifndef SFX_MODULE - ConvertNameCase(hd->FileName); - ConvertNameCase(hd->FileNameW); -#endif - ConvertUnknownHeader(); - } - if (hd->Flags & LHD_SALT) - Raw.Get(hd->Salt,SALT_SIZE); - hd->mtime.SetDos(hd->FileTime); - hd->ctime.Reset(); - hd->atime.Reset(); - hd->arctime.Reset(); - if (hd->Flags & LHD_EXTTIME) - { - ushort Flags; - Raw.Get(Flags); - RarTime *tbl[4]; - tbl[0]=&NewLhd.mtime; - tbl[1]=&NewLhd.ctime; - tbl[2]=&NewLhd.atime; - tbl[3]=&NewLhd.arctime; - for (int I=0;I<4;I++) - { - RarTime *CurTime=tbl[I]; - uint rmode=Flags>>(3-I)*4; - if ((rmode & 8)==0) - continue; - if (I!=0) - { - uint DosTime; - Raw.Get(DosTime); - CurTime->SetDos(DosTime); - } - RarLocalTime rlt; - CurTime->GetLocal(&rlt); - if (rmode & 4) - rlt.Second++; - rlt.Reminder=0; - int count=rmode&3; - for (int J=0;JSetLocal(&rlt); - } - } - NextBlockPos+=hd->FullPackSize; - bool CRCProcessedOnly=(hd->Flags & LHD_COMMENT)!=0; - HeaderCRC=~Raw.GetCRC(CRCProcessedOnly)&0xffff; - if (hd->HeadCRC!=HeaderCRC) - { - if (hd->HeadType==NEWSUB_HEAD && strlen(hd->FileName)FileName)-5) - strcat(hd->FileName,"- ???"); - BrokenFileHeader=true; - ErrHandler.SetErrorCode(RARX_WARNING); - - // If we have a broken encrypted header, we do not need to display - // the error message here, because it will be displayed for such - // headers later in this function. Also such headers are unlikely - // to have anything sensible in file name field, so it is useless - // to display the file name. - bool EncBroken=Decrypt && ShortBlock.HeadCRC!=(~Raw.GetCRC(false)&0xffff); - if (!EncBroken) - { -#ifndef SHELL_EXT - Log(Archive::FileName,St(MLogFileHead),IntNameToExt(hd->FileName)); - Alarm(); -#endif - } - } - } - break; -#ifndef SFX_MODULE - case COMM_HEAD: - *(BaseBlock *)&CommHead=ShortBlock; - Raw.Get(CommHead.UnpSize); - Raw.Get(CommHead.UnpVer); - Raw.Get(CommHead.Method); - Raw.Get(CommHead.CommCRC); - break; - case SIGN_HEAD: - *(BaseBlock *)&SignHead=ShortBlock; - Raw.Get(SignHead.CreationTime); - Raw.Get(SignHead.ArcNameSize); - Raw.Get(SignHead.UserNameSize); - break; - case AV_HEAD: - *(BaseBlock *)&AVHead=ShortBlock; - Raw.Get(AVHead.UnpVer); - Raw.Get(AVHead.Method); - Raw.Get(AVHead.AVVer); - Raw.Get(AVHead.AVInfoCRC); - break; - case PROTECT_HEAD: - *(BaseBlock *)&ProtectHead=ShortBlock; - Raw.Get(ProtectHead.DataSize); - Raw.Get(ProtectHead.Version); - Raw.Get(ProtectHead.RecSectors); - Raw.Get(ProtectHead.TotalBlocks); - Raw.Get(ProtectHead.Mark,8); - NextBlockPos+=ProtectHead.DataSize; - RecoverySectors=ProtectHead.RecSectors; - break; - case SUB_HEAD: - *(BaseBlock *)&SubBlockHead=ShortBlock; - Raw.Get(SubBlockHead.DataSize); - NextBlockPos+=SubBlockHead.DataSize; - Raw.Get(SubBlockHead.SubType); - Raw.Get(SubBlockHead.Level); - switch(SubBlockHead.SubType) - { - case UO_HEAD: - *(SubBlockHeader *)&UOHead=SubBlockHead; - Raw.Get(UOHead.OwnerNameSize); - Raw.Get(UOHead.GroupNameSize); - if (UOHead.OwnerNameSize>NM-1) - UOHead.OwnerNameSize=NM-1; - if (UOHead.GroupNameSize>NM-1) - UOHead.GroupNameSize=NM-1; - Raw.Get((byte *)UOHead.OwnerName,UOHead.OwnerNameSize); - Raw.Get((byte *)UOHead.GroupName,UOHead.GroupNameSize); - UOHead.OwnerName[UOHead.OwnerNameSize]=0; - UOHead.GroupName[UOHead.GroupNameSize]=0; - break; - case MAC_HEAD: - *(SubBlockHeader *)&MACHead=SubBlockHead; - Raw.Get(MACHead.fileType); - Raw.Get(MACHead.fileCreator); - break; - case EA_HEAD: - case BEEA_HEAD: - case NTACL_HEAD: - *(SubBlockHeader *)&EAHead=SubBlockHead; - Raw.Get(EAHead.UnpSize); - Raw.Get(EAHead.UnpVer); - Raw.Get(EAHead.Method); - Raw.Get(EAHead.EACRC); - break; - case STREAM_HEAD: - *(SubBlockHeader *)&StreamHead=SubBlockHead; - Raw.Get(StreamHead.UnpSize); - Raw.Get(StreamHead.UnpVer); - Raw.Get(StreamHead.Method); - Raw.Get(StreamHead.StreamCRC); - Raw.Get(StreamHead.StreamNameSize); - if (StreamHead.StreamNameSize>NM-1) - StreamHead.StreamNameSize=NM-1; - Raw.Get((byte *)StreamHead.StreamName,StreamHead.StreamNameSize); - StreamHead.StreamName[StreamHead.StreamNameSize]=0; - break; - } - break; -#endif - default: - if (ShortBlock.Flags & LONG_BLOCK) - { - uint DataSize; - Raw.Get(DataSize); - NextBlockPos+=DataSize; - } - break; - } - HeaderCRC=~Raw.GetCRC(false)&0xffff; - CurHeaderType=ShortBlock.HeadType; - if (Decrypt) - { - NextBlockPos+=Raw.PaddedSize()+SALT_SIZE; - - if (ShortBlock.HeadCRC!=HeaderCRC) - { - bool Recovered=false; - if (ShortBlock.HeadType==ENDARC_HEAD && (EndArcHead.Flags & EARC_REVSPACE)!=0) - { - // Last 7 bytes of recovered volume can contain zeroes, because - // REV files store its own information (volume number, etc.) here. - SaveFilePos SavePos(*this); - int64 Length=Tell(); - Seek(Length-7,SEEK_SET); - Recovered=true; - for (int J=0;J<7;J++) - if (GetByte()!=0) - Recovered=false; - } - if (!Recovered) - { -#ifndef SILENT - Log(FileName,St(MEncrBadCRC),FileName); -#endif -// Close(); - FailedHeaderDecryption=true; - BrokenFileHeader=true; - - ErrHandler.SetErrorCode(RARX_CRC); - return(0); - } - } - } - - if (NextBlockPos<=CurBlockPos) - { -#ifndef SHELL_EXT - Log(FileName,St(MLogFileHead),"???"); -#endif - BrokenFileHeader=true; - ErrHandler.SetErrorCode(RARX_CRC); - return(0); - } - return(Raw.Size()); -} - - -#ifndef SFX_MODULE -size_t Archive::ReadOldHeader() -{ - RawRead Raw(this); - if (CurBlockPos<=(int64)SFXSize) - { - Raw.Read(SIZEOF_OLDMHD); - Raw.Get(OldMhd.Mark,4); - Raw.Get(OldMhd.HeadSize); - Raw.Get(OldMhd.Flags); - NextBlockPos=CurBlockPos+OldMhd.HeadSize; - CurHeaderType=MAIN_HEAD; - } - else - { - OldFileHeader OldLhd; - Raw.Read(SIZEOF_OLDLHD); - NewLhd.HeadType=FILE_HEAD; - Raw.Get(NewLhd.PackSize); - Raw.Get(NewLhd.UnpSize); - Raw.Get(OldLhd.FileCRC); - Raw.Get(NewLhd.HeadSize); - Raw.Get(NewLhd.FileTime); - Raw.Get(OldLhd.FileAttr); - Raw.Get(OldLhd.Flags); - Raw.Get(OldLhd.UnpVer); - Raw.Get(OldLhd.NameSize); - Raw.Get(OldLhd.Method); - - NewLhd.Flags=OldLhd.Flags|LONG_BLOCK; - NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10; - NewLhd.Method=OldLhd.Method+0x30; - NewLhd.NameSize=OldLhd.NameSize; - NewLhd.FileAttr=OldLhd.FileAttr; - NewLhd.FileCRC=OldLhd.FileCRC; - NewLhd.FullPackSize=NewLhd.PackSize; - NewLhd.FullUnpSize=NewLhd.UnpSize; - - NewLhd.mtime.SetDos(NewLhd.FileTime); - NewLhd.ctime.Reset(); - NewLhd.atime.Reset(); - NewLhd.arctime.Reset(); - - Raw.Read(OldLhd.NameSize); - Raw.Get((byte *)NewLhd.FileName,OldLhd.NameSize); - NewLhd.FileName[OldLhd.NameSize]=0; - ConvertNameCase(NewLhd.FileName); - *NewLhd.FileNameW=0; - - if (Raw.Size()!=0) - NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize; - CurHeaderType=FILE_HEAD; - } - return(NextBlockPos>CurBlockPos ? Raw.Size():0); -} -#endif - - -void Archive::ConvertNameCase(char *Name) -{ - if (Cmd->ConvertNames==NAMES_UPPERCASE) - { - IntToExt(Name,Name); - strupper(Name); - ExtToInt(Name,Name); - } - if (Cmd->ConvertNames==NAMES_LOWERCASE) - { - IntToExt(Name,Name); - strlower(Name); - ExtToInt(Name,Name); - } -} - - -#ifndef SFX_MODULE -void Archive::ConvertNameCase(wchar *Name) -{ - if (Cmd->ConvertNames==NAMES_UPPERCASE) - wcsupper(Name); - if (Cmd->ConvertNames==NAMES_LOWERCASE) - wcslower(Name); -} -#endif - - -bool Archive::IsArcDir() -{ - return((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY); -} - - -bool Archive::IsArcLabel() -{ - return(NewLhd.HostOS<=HOST_WIN32 && (NewLhd.FileAttr & 8)); -} - - -void Archive::ConvertAttributes() -{ -#if defined(_WIN_ALL) || defined(_EMX) - switch(NewLhd.HostOS) - { - case HOST_MSDOS: - case HOST_OS2: - case HOST_WIN32: - break; - case HOST_UNIX: - case HOST_BEOS: - if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY) - NewLhd.FileAttr=0x10; - else - NewLhd.FileAttr=0x20; - break; - default: - if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY) - NewLhd.FileAttr=0x10; - else - NewLhd.FileAttr=0x20; - break; - } -#endif -#ifdef _UNIX - // umask defines which permission bits must not be set by default - // when creating a file or directory. The typical default value - // for the process umask is S_IWGRP | S_IWOTH (octal 022), - // resulting in 0644 mode for new files. - static mode_t mask = (mode_t) -1; - - if (mask == (mode_t) -1) - { - // umask call returns the current umask value. Argument (022) is not - // really important here. - mask = umask(022); - - // Restore the original umask value, which was changed to 022 above. - umask(mask); - } - - switch(NewLhd.HostOS) - { - case HOST_MSDOS: - case HOST_OS2: - case HOST_WIN32: - { - // Mapping MSDOS, OS/2 and Windows file attributes to Unix. - - if (NewLhd.FileAttr & 0x10) // FILE_ATTRIBUTE_DIRECTORY - { - // For directories we use 0777 mask. - NewLhd.FileAttr=0777 & ~mask; - } - else - if (NewLhd.FileAttr & 1) // FILE_ATTRIBUTE_READONLY - { - // For read only files we use 0444 mask with 'w' bits turned off. - NewLhd.FileAttr=0444 & ~mask; - } - else - { - // umask does not set +x for regular files, so we use 0666 - // instead of 0777 as for directories. - NewLhd.FileAttr=0666 & ~mask; - } - } - break; - case HOST_UNIX: - case HOST_BEOS: - break; - default: - if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY) - NewLhd.FileAttr=0x41ff & ~mask; - else - NewLhd.FileAttr=0x81b6 & ~mask; - break; - } -#endif -} - - -void Archive::ConvertUnknownHeader() -{ - if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10)) - NewLhd.Flags|=LHD_DIRECTORY; - if (NewLhd.HostOS>=HOST_MAX) - { - if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY) - NewLhd.FileAttr=0x10; - else - NewLhd.FileAttr=0x20; - } - for (char *s=NewLhd.FileName;*s!=0;s=charnext(s)) - { - if (*s=='/' || *s=='\\') - *s=CPATHDIVIDER; -#if defined(_APPLE) && !defined(UNICODE_SUPPORTED) - if ((byte)*s<32 || (byte)*s>127) - *s='_'; -#endif - -#if defined(_WIN_ALL) || defined(_EMX) - // ':' in file names is allowed in Unix, but not in Windows. - // Even worse, file data will be written to NTFS stream on NTFS, - // so automatic name correction on file create error in extraction - // routine does not work. In Windows and DOS versions we better - // replace ':' now. - if (*s==':') - *s='_'; -#endif - - } - - for (wchar *s=NewLhd.FileNameW;*s!=0;s++) - { - if (*s=='/' || *s=='\\') - *s=CPATHDIVIDER; - -#if defined(_WIN_ALL) || defined(_EMX) - // ':' in file names is allowed in Unix, but not in Windows. - // Even worse, file data will be written to NTFS stream on NTFS, - // so automatic name correction on file create error in extraction - // routine does not work. In Windows and DOS versions we better - // replace ':' now. - if (*s==':') - *s='_'; -#endif - } -} - - -#ifndef SHELL_EXT -bool Archive::ReadSubData(Array *UnpData,File *DestFile) -{ - if (HeaderCRC!=SubHead.HeadCRC) - { -#ifndef SHELL_EXT - Log(FileName,St(MSubHeadCorrupt)); -#endif - ErrHandler.SetErrorCode(RARX_CRC); - return(false); - } - if (SubHead.Method<0x30 || SubHead.Method>0x35 || SubHead.UnpVer>/*PACK_VER*/36) - { -#ifndef SHELL_EXT - Log(FileName,St(MSubHeadUnknown)); -#endif - return(false); - } - - if (SubHead.PackSize==0 && (SubHead.Flags & LHD_SPLIT_AFTER)==0) - return(true); - - SubDataIO.Init(); - Unpack Unpack(&SubDataIO); - Unpack.Init(); - - if (DestFile==NULL) - { - UnpData->Alloc(SubHead.UnpSize); - SubDataIO.SetUnpackToMemory(&(*UnpData)[0],SubHead.UnpSize); - } - if (SubHead.Flags & LHD_PASSWORD) - if (Cmd->Password.IsSet()) - SubDataIO.SetEncryption(SubHead.UnpVer,&Cmd->Password, - (SubHead.Flags & LHD_SALT) ? SubHead.Salt:NULL,false, - SubHead.UnpVer>=36); - else - return(false); - SubDataIO.SetPackedSizeToRead(SubHead.PackSize); - SubDataIO.EnableShowProgress(false); - SubDataIO.SetFiles(this,DestFile); - SubDataIO.UnpVolume=(SubHead.Flags & LHD_SPLIT_AFTER)!=0; - SubDataIO.SetSubHeader(&SubHead,NULL); - Unpack.SetDestSize(SubHead.UnpSize); - if (SubHead.Method==0x30) - CmdExtract::UnstoreFile(SubDataIO,SubHead.UnpSize); - else - Unpack.DoUnpack(SubHead.UnpVer,false); - - if (SubHead.FileCRC!=~SubDataIO.UnpFileCRC) - { -#ifndef SHELL_EXT - Log(FileName,St(MSubHeadDataCRC),SubHead.FileName); -#endif - ErrHandler.SetErrorCode(RARX_CRC); - if (UnpData!=NULL) - UnpData->Reset(); - return(false); - } - return(true); -} -#endif diff --git a/src/unrar/array.hpp b/src/unrar/array.hpp deleted file mode 100644 index f3821bc47d..0000000000 --- a/src/unrar/array.hpp +++ /dev/null @@ -1,131 +0,0 @@ -#ifndef _RAR_ARRAY_ -#define _RAR_ARRAY_ - -extern ErrorHandler ErrHandler; - -template class Array -{ - private: - T *Buffer; - size_t BufSize; - size_t AllocSize; - public: - Array(); - Array(size_t Size); - ~Array(); - inline void CleanData(); - inline T& operator [](size_t Item); - inline size_t Size(); // Returns the size in items, not in bytes. - void Add(size_t Items); - void Alloc(size_t Items); - void Reset(); - void SoftReset(); - void operator = (Array &Src); - void Push(T Item); - T* Addr() {return(Buffer);} -}; - -template void Array::CleanData() -{ - Buffer=NULL; - BufSize=0; - AllocSize=0; -} - - -template Array::Array() -{ - CleanData(); -} - - -template Array::Array(size_t Size) -{ - Buffer=(T *)malloc(sizeof(T)*Size); - if (Buffer==NULL && Size!=0) - ErrHandler.MemoryError(); - - AllocSize=BufSize=Size; -} - - -template Array::~Array() -{ - if (Buffer!=NULL) - free(Buffer); -} - - -template inline T& Array::operator [](size_t Item) -{ - return(Buffer[Item]); -} - - -template inline size_t Array::Size() -{ - return(BufSize); -} - - -template void Array::Add(size_t Items) -{ - BufSize+=Items; - if (BufSize>AllocSize) - { - size_t Suggested=AllocSize+AllocSize/4+32; - size_t NewSize=Max(BufSize,Suggested); - - Buffer=(T *)realloc(Buffer,NewSize*sizeof(T)); - if (Buffer==NULL) - ErrHandler.MemoryError(); - AllocSize=NewSize; - } -} - - -template void Array::Alloc(size_t Items) -{ - if (Items>AllocSize) - Add(Items-BufSize); - else - BufSize=Items; -} - - -template void Array::Reset() -{ - if (Buffer!=NULL) - { - free(Buffer); - Buffer=NULL; - } - BufSize=0; - AllocSize=0; -} - - -// Reste buffer size, but preserve already allocated memory if any, -// so we can reuse it without wasting time to allocation. -template void Array::SoftReset() -{ - BufSize=0; -} - - -template void Array::operator =(Array &Src) -{ - Reset(); - Alloc(Src.BufSize); - if (Src.BufSize!=0) - memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T)); -} - - -template void Array::Push(T Item) -{ - Add(1); - (*this)[Size()-1]=Item; -} - -#endif diff --git a/src/unrar/beosea.cpp b/src/unrar/beosea.cpp deleted file mode 100644 index 3b6e862e45..0000000000 --- a/src/unrar/beosea.cpp +++ /dev/null @@ -1,113 +0,0 @@ - - -void ExtractBeEA(Archive &Arc,char *FileName) -{ - if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC) - { - Log(Arc.FileName,St(MEABroken),FileName); - ErrHandler.SetErrorCode(RARX_CRC); - return; - } - if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER) - { - Log(Arc.FileName,St(MEAUnknHeader),FileName); - return; - } - - ComprDataIO DataIO; - Unpack Unpack(&DataIO); - Unpack.Init(); - - Array UnpData(Arc.EAHead.UnpSize); - DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize); - DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize); - DataIO.EnableShowProgress(false); - DataIO.SetFiles(&Arc,NULL); - Unpack.SetDestSize(Arc.EAHead.UnpSize); - Unpack.DoUnpack(Arc.EAHead.UnpVer,false); - - if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC) - { - Log(Arc.FileName,St(MEABroken),FileName); - ErrHandler.SetErrorCode(RARX_CRC); - return; - } - int fd = open(FileName,O_WRONLY); - if (fd==-1) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - return; - } - - int AttrPos=0; - while (AttrPos=sizeof(Name)) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - break; - } - memcpy(Name,CurItem+10,NameSize); - Name[NameSize]=0; - if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - break; - } - AttrPos+=10+NameSize+Size; - } - close(fd); - mprintf(St(MShowEA)); -} - - -void ExtractBeEANew(Archive &Arc,char *FileName) -{ - Array SubData; - if (!Arc.ReadSubData(&SubData,NULL)) - return; - - int fd = open(FileName,O_WRONLY); - if (fd==-1) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - return; - } - - int AttrPos=0; - while (AttrPos=sizeof(Name)) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - break; - } - memcpy(Name,CurItem+10,NameSize); - Name[NameSize]=0; - if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1) - { - Log(Arc.FileName,St(MCannotSetEA),FileName); - ErrHandler.SetErrorCode(RARX_WARNING); - break; - } - AttrPos+=10+NameSize+Size; - } - close(fd); - mprintf(St(MShowEA)); -} - diff --git a/src/unrar/cmddata.cpp b/src/unrar/cmddata.cpp deleted file mode 100644 index e17fa20616..0000000000 --- a/src/unrar/cmddata.cpp +++ /dev/null @@ -1,1431 +0,0 @@ -#include "rar.hpp" - - -CommandData::CommandData() -{ - FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL; - Init(); -} - - -CommandData::~CommandData() -{ - Close(); -} - - -void CommandData::Init() -{ - RAROptions::Init(); - Close(); - - *Command=0; - *CommandW=0; - *ArcName=0; - *ArcNameW=0; - FileLists=false; - NoMoreSwitches=false; - - ListMode=RCLM_AUTO; - - - FileArgs=new StringList; - ExclArgs=new StringList; - InclArgs=new StringList; - StoreArgs=new StringList; - ArcNames=new StringList; -} - - -void CommandData::Close() -{ - delete FileArgs; - delete ExclArgs; - delete InclArgs; - delete StoreArgs; - delete ArcNames; - FileArgs=ExclArgs=InclArgs=StoreArgs=ArcNames=NULL; - NextVolSizes.Reset(); -} - - -#ifdef CUSTOM_CMDLINE_PARSER -// Return the pointer to next position in the string and store dynamically -// allocated command line parameters in Unicode and ASCII in ParW and ParA. -static const wchar *AllocCmdParam(const wchar *CmdLine,wchar **ParW,char **ParA) -{ - const wchar *NextCmd=GetCmdParam(CmdLine,NULL,0); - if (NextCmd==NULL) - return NULL; - size_t ParSize=NextCmd-CmdLine+2; // Parameter size including the trailing zero. - *ParW=(wchar *)malloc(ParSize*sizeof(wchar)); - if (*ParW==NULL) - return NULL; - CmdLine=GetCmdParam(CmdLine,*ParW,ParSize); - size_t ParSizeA=ParSize*2; // One Unicode char can be converted to several MBCS chars. - *ParA=(char *)malloc(ParSizeA); - if (*ParA==NULL) - { - free(*ParW); - return NULL; - } - GetAsciiName(*ParW,*ParA,ParSizeA); - return CmdLine; -} -#endif - - -#ifndef SFX_MODULE -void CommandData::PreprocessCommandLine(int argc, char *argv[]) -{ -#ifdef CUSTOM_CMDLINE_PARSER - // In Windows we may prefer to implement our own command line parser - // to avoid replacing \" by " in standard parser. Such replacing corrupts - // destination paths like "dest path\" in extraction commands. - const wchar *CmdLine=GetCommandLine(); - - wchar *ParW; - char *ParA; - for (bool FirstParam=true;;FirstParam=false) - { - if ((CmdLine=AllocCmdParam(CmdLine,&ParW,&ParA))==NULL) - break; - bool Code=FirstParam ? true:PreprocessSwitch(ParA); - free(ParW); - free(ParA); - if (!Code) - break; - } -#else - for (int I=1;IAddString(Arg,ArgW); - else - { - FindData FileData; - bool Found=FindFile::FastFind(Arg,ArgW,&FileData); - if ((!Found || ListMode==RCLM_ACCEPT_LISTS) && - ListMode!=RCLM_REJECT_LISTS && *Arg=='@' && !IsWildcard(Arg,ArgW)) - { - FileLists=true; - - RAR_CHARSET Charset=FilelistCharset; - -#if defined(_WIN_ALL) && !defined(GUI) - // for compatibility reasons we use OEM encoding - // in Win32 console version by default - - if (Charset==RCH_DEFAULT) - Charset=RCH_OEM; -#endif - - wchar *WideArgName=(ArgW!=NULL && *ArgW!=0 ? ArgW+1:NULL); - ReadTextFile(Arg+1,WideArgName,FileArgs,false,true,Charset,true,true,true); - - } - else - if (Found && FileData.IsDir && Extract && *ExtrPath==0 && *ExtrPathW==0) - { - strncpyz(ExtrPath,Arg,ASIZE(ExtrPath)-1); - AddEndSlash(ExtrPath); - if (ArgW!=NULL) - { - wcsncpyz(ExtrPathW,ArgW,ASIZE(ExtrPathW)-1); - AddEndSlash(ExtrPathW); - } - } - else - FileArgs->AddString(Arg,ArgW); - } - } -} -#endif - - -void CommandData::ParseDone() -{ - if (FileArgs->ItemsCount()==0 && !FileLists) - FileArgs->AddString(MASKALL); - char CmdChar=etoupper(*Command); - bool Extract=CmdChar=='X' || CmdChar=='E' || CmdChar=='P'; - if (Test && Extract) - Test=false; // Switch '-t' is senseless for 'X', 'E', 'P' commands. - BareOutput=(CmdChar=='L' || CmdChar=='V') && Command[1]=='B'; -} - - -#if !defined(SFX_MODULE) && !defined(_WIN_CE) -void CommandData::ParseEnvVar() -{ - char *EnvStr=getenv("RAR"); - if (EnvStr!=NULL) - { - ProcessSwitchesString(EnvStr); - } -} -#endif - - - -#ifndef SFX_MODULE -// Preprocess those parameters, which must be processed before the rest of -// command line. Return 'false' to stop further processing. -bool CommandData::PreprocessSwitch(const char *Switch) -{ - if (IsSwitch(Switch[0])) - { - Switch++; - if (stricomp(Switch,"-")==0) // Switch "--". - return false; - if (stricomp(Switch,"cfg-")==0) - ConfigDisabled=true; -#ifndef GUI - if (strnicomp(Switch,"ilog",4)==0) - { - // Ensure that correct log file name is already set - // if we need to report an error when processing the command line. - ProcessSwitch(Switch); - InitLogOptions(LogName); - } -#endif - if (strnicomp(Switch,"sc",2)==0) - { - // Process -sc before reading any file lists. - ProcessSwitch(Switch); - } - } - return true; -} -#endif - - -#if !defined(GUI) && !defined(SFX_MODULE) -void CommandData::ReadConfig() -{ - StringList List; - if (ReadTextFile(DefConfigName,NULL,&List,true)) - { - char *Str; - while ((Str=List.GetString())!=NULL) - { - while (IsSpace(*Str)) - Str++; - if (strnicomp(Str,"switches=",9)==0) - ProcessSwitchesString(Str+9); - } - } -} -#endif - - -#if !defined(SFX_MODULE) && !defined(_WIN_CE) -void CommandData::ProcessSwitchesString(char *Str) -{ - while (*Str) - { - while (!IsSwitch(*Str) && *Str!=0) - Str++; - if (*Str==0) - break; - char *Next=Str; - while (!(Next[0]==' ' && IsSwitch(Next[1])) && *Next!=0) - Next++; - char NextChar=*Next; - *Next=0; - ProcessSwitch(Str+1); - *Next=NextChar; - Str=Next; - } -} -#endif - - -#if !defined(SFX_MODULE) -void CommandData::ProcessSwitch(const char *Switch,const wchar *SwitchW) -{ - - bool WidePresent=SwitchW!=NULL && *SwitchW!=0; // If 'true', SwitchW is not empty. - - switch(etoupper(Switch[0])) - { - case '@': - ListMode=Switch[1]=='+' ? RCLM_ACCEPT_LISTS:RCLM_REJECT_LISTS; - break; - case 'I': - if (strnicomp(&Switch[1],"LOG",3)==0) - { - strncpyz(LogName,Switch[4] ? Switch+4:DefLogName,ASIZE(LogName)); - break; - } - if (stricomp(&Switch[1],"SND")==0) - { - Sound=true; - break; - } - if (stricomp(&Switch[1],"ERR")==0) - { - MsgStream=MSG_STDERR; - break; - } - if (strnicomp(&Switch[1],"EML",3)==0) - { - strncpyz(EmailTo,Switch[4] ? Switch+4:"@",ASIZE(EmailTo)); - EmailTo[sizeof(EmailTo)-1]=0; - break; - } - if (stricomp(&Switch[1],"NUL")==0) - { - MsgStream=MSG_NULL; - break; - } - if (etoupper(Switch[1])=='D') - { - for (int I=2;Switch[I]!=0;I++) - switch(etoupper(Switch[I])) - { - case 'Q': - MsgStream=MSG_ERRONLY; - break; - case 'C': - DisableCopyright=true; - break; - case 'D': - DisableDone=true; - break; - case 'P': - DisablePercentage=true; - break; - } - break; - } - if (stricomp(&Switch[1],"OFF")==0) - { - Shutdown=true; - break; - } - break; - case 'T': - switch(etoupper(Switch[1])) - { - case 'K': - ArcTime=ARCTIME_KEEP; - break; - case 'L': - ArcTime=ARCTIME_LATEST; - break; - case 'O': - FileTimeBefore.SetAgeText(Switch+2); - break; - case 'N': - FileTimeAfter.SetAgeText(Switch+2); - break; - case 'B': - FileTimeBefore.SetIsoText(Switch+2); - break; - case 'A': - FileTimeAfter.SetIsoText(Switch+2); - break; - case 'S': - { - EXTTIME_MODE Mode=EXTTIME_HIGH3; - bool CommonMode=Switch[2]>='0' && Switch[2]<='4'; - if (CommonMode) - Mode=(EXTTIME_MODE)(Switch[2]-'0'); - if (Switch[2]=='-') - Mode=EXTTIME_NONE; - if (CommonMode || Switch[2]=='-' || Switch[2]=='+' || Switch[2]==0) - xmtime=xctime=xatime=Mode; - else - { - if (Switch[3]>='0' && Switch[3]<='4') - Mode=(EXTTIME_MODE)(Switch[3]-'0'); - if (Switch[3]=='-') - Mode=EXTTIME_NONE; - switch(etoupper(Switch[2])) - { - case 'M': - xmtime=Mode; - break; - case 'C': - xctime=Mode; - break; - case 'A': - xatime=Mode; - break; - case 'R': - xarctime=Mode; - break; - } - } - } - break; - case '-': - Test=false; - break; - case 0: - Test=true; - break; - default: - BadSwitch(Switch); - break; - } - break; - case 'A': - switch(etoupper(Switch[1])) - { - case 'C': - ClearArc=true; - break; - case 'D': - AppendArcNameToPath=true; - break; -#ifndef SFX_MODULE - case 'G': - if (Switch[2]=='-' && Switch[3]==0) - GenerateArcName=0; - else - { - GenerateArcName=true; - strncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask)); - } - break; -#endif - case 'I': - IgnoreGeneralAttr=true; - break; - case 'N': // Reserved for archive name. - break; - case 'O': - AddArcOnly=true; - break; - case 'P': - strcpy(ArcPath,Switch+2); - if (WidePresent) - wcscpy(ArcPathW,SwitchW+2); - break; - case 'S': - SyncFiles=true; - break; - default: - BadSwitch(Switch); - break; - } - break; - case 'D': - if (Switch[2]==0) - switch(etoupper(Switch[1])) - { - case 'S': - DisableSortSolid=true; - break; - case 'H': - OpenShared=true; - break; - case 'F': - DeleteFiles=true; - break; - } - break; - case 'O': - switch(etoupper(Switch[1])) - { - case '+': - Overwrite=OVERWRITE_ALL; - break; - case '-': - Overwrite=OVERWRITE_NONE; - break; - case 0: - Overwrite=OVERWRITE_FORCE_ASK; - break; - case 'R': - Overwrite=OVERWRITE_AUTORENAME; - break; - case 'W': - ProcessOwners=true; - break; -#ifdef SAVE_LINKS - case 'L': - SaveLinks=true; - break; -#endif -#ifdef _WIN_ALL - case 'S': - SaveStreams=true; - break; - case 'C': - SetCompressedAttr=true; - break; -#endif - default : - BadSwitch(Switch); - break; - } - break; - case 'R': - switch(etoupper(Switch[1])) - { - case 0: - Recurse=RECURSE_ALWAYS; - break; - case '-': - Recurse=RECURSE_DISABLE; - break; - case '0': - Recurse=RECURSE_WILDCARDS; - break; -#ifndef _WIN_CE - case 'I': - { - Priority=atoi(Switch+2); - if (Priority<0 || Priority>15) - BadSwitch(Switch); - const char *ChPtr=strchr(Switch+2,':'); - if (ChPtr!=NULL) - { - SleepTime=atoi(ChPtr+1); - if (SleepTime>1000) - BadSwitch(Switch); - InitSystemOptions(SleepTime); - } - SetPriority(Priority); - } - break; -#endif - } - break; - case 'Y': - AllYes=true; - break; - case 'N': - case 'X': - if (Switch[1]!=0) - { - StringList *Args=etoupper(Switch[0])=='N' ? InclArgs:ExclArgs; - if (Switch[1]=='@' && !IsWildcard(Switch)) - { - RAR_CHARSET Charset=FilelistCharset; - -#if defined(_WIN_ALL) && !defined(GUI) - // for compatibility reasons we use OEM encoding - // in Win32 console version by default - - if (Charset==RCH_DEFAULT) - Charset=RCH_OEM; -#endif - - ReadTextFile(Switch+2,NULL,Args,false,true,Charset,true,true,true); - } - else - Args->AddString(Switch+1); - } - break; - case 'E': - switch(etoupper(Switch[1])) - { - case 'P': - switch(Switch[2]) - { - case 0: - ExclPath=EXCL_SKIPWHOLEPATH; - break; - case '1': - ExclPath=EXCL_BASEPATH; - break; - case '2': - ExclPath=EXCL_SAVEFULLPATH; - break; - case '3': - ExclPath=EXCL_ABSPATH; - break; - } - break; - case 'E': - ProcessEA=false; - break; - case 'N': - NoEndBlock=true; - break; - default: - if (Switch[1]=='+') - { - InclFileAttr=GetExclAttr(&Switch[2]); - InclAttrSet=true; - } - else - ExclFileAttr=GetExclAttr(&Switch[1]); - break; - } - break; - case 'P': - if (Switch[1]==0) - { - GetPassword(PASSWORD_GLOBAL,NULL,NULL,&Password); - eprintf("\n"); - } - else - { - wchar PlainPsw[MAXPASSWORD]; - CharToWide(Switch+1,PlainPsw,ASIZE(PlainPsw)); - PlainPsw[ASIZE(PlainPsw)-1]=0; - Password.Set(PlainPsw); - cleandata(PlainPsw,ASIZE(PlainPsw)); - } - break; - case 'H': - if (etoupper(Switch[1])=='P') - { - EncryptHeaders=true; - if (Switch[2]!=0) - { - wchar PlainPsw[MAXPASSWORD]; - CharToWide(Switch+2,PlainPsw,ASIZE(PlainPsw)); - PlainPsw[ASIZE(PlainPsw)-1]=0; - Password.Set(PlainPsw); - cleandata(PlainPsw,ASIZE(PlainPsw)); - } - else - if (!Password.IsSet()) - { - GetPassword(PASSWORD_GLOBAL,NULL,NULL,&Password); - eprintf("\n"); - } - } - break; - case 'Z': - if (Switch[1]==0 && (!WidePresent || SwitchW[1]==0)) - { -#ifndef GUI // stdin is not supported by WinRAR. - // If comment file is not specified, we read data from stdin. - strcpy(CommentFile,"stdin"); -#endif - } - else - { - strncpyz(CommentFile,Switch+1,ASIZE(CommentFile)); - if (WidePresent) - wcsncpyz(CommentFileW,SwitchW+1,ASIZE(CommentFileW)); - } - break; - case 'M': - switch(etoupper(Switch[1])) - { - case 'C': - { - const char *Str=Switch+2; - if (*Str=='-') - for (uint I=0;IAddString(Mask); - if (End==NULL) - break; - Names=End+1; - } - } - break; -#ifdef RAR_SMP - case 'T': - Threads=atoi(Switch+2); - if (Threads>MaxPoolThreads || Threads<1) - BadSwitch(Switch); - else - { - } - break; -#endif - default: - Method=Switch[1]-'0'; - if (Method>5 || Method<0) - BadSwitch(Switch); - break; - } - break; - case 'V': - switch(etoupper(Switch[1])) - { - case 'N': - OldNumbering=true; - break; - case 'P': - VolumePause=true; - break; - case 'E': - if (etoupper(Switch[2])=='R') - VersionControl=atoi(Switch+3)+1; - break; - case '-': - VolSize=0; - break; - default: - VolSize=VOLSIZE_AUTO; // UnRAR -v switch for list command. - break; - } - break; - case 'F': - if (Switch[1]==0) - FreshFiles=true; - else - BadSwitch(Switch); - break; - case 'U': - if (Switch[1]==0) - UpdateFiles=true; - else - BadSwitch(Switch); - break; - case 'W': - strncpyz(TempPath,&Switch[1],ASIZE(TempPath)); - AddEndSlash(TempPath); - break; - case 'S': - if (IsDigit(Switch[1])) - { - Solid|=SOLID_COUNT; - SolidCount=atoi(&Switch[1]); - } - else - switch(etoupper(Switch[1])) - { - case 0: - Solid|=SOLID_NORMAL; - break; - case '-': - Solid=SOLID_NONE; - break; - case 'E': - Solid|=SOLID_FILEEXT; - break; - case 'V': - Solid|=Switch[2]=='-' ? SOLID_VOLUME_DEPENDENT:SOLID_VOLUME_INDEPENDENT; - break; - case 'D': - Solid|=SOLID_VOLUME_DEPENDENT; - break; - case 'L': - if (IsDigit(Switch[2])) - FileSizeLess=atoil(Switch+2); - break; - case 'M': - if (IsDigit(Switch[2])) - FileSizeMore=atoil(Switch+2); - break; - case 'C': - { - // Switch is already found bad, avoid reporting it several times. - bool AlreadyBad=false; - - RAR_CHARSET rch=RCH_DEFAULT; - switch(etoupper(Switch[2])) - { - case 'A': - rch=RCH_ANSI; - break; - case 'O': - rch=RCH_OEM; - break; - case 'U': - rch=RCH_UNICODE; - break; - default : - BadSwitch(Switch); - AlreadyBad=true; - break; - }; - if (!AlreadyBad) - if (Switch[3]==0) - CommentCharset=FilelistCharset=rch; - else - for (int I=3;Switch[I]!=0 && !AlreadyBad;I++) - switch(etoupper(Switch[I])) - { - case 'C': - CommentCharset=rch; - break; - case 'L': - FilelistCharset=rch; - break; - default: - BadSwitch(Switch); - AlreadyBad=true; - break; - } - } - break; - - } - break; - case 'C': - if (Switch[2]==0) - switch(etoupper(Switch[1])) - { - case '-': - DisableComment=true; - break; - case 'U': - ConvertNames=NAMES_UPPERCASE; - break; - case 'L': - ConvertNames=NAMES_LOWERCASE; - break; - } - break; - case 'K': - switch(etoupper(Switch[1])) - { - case 'B': - KeepBroken=true; - break; - case 0: - Lock=true; - break; - } - break; -#ifndef GUI - case '?' : - OutHelp(RARX_SUCCESS); - break; -#endif - default : - BadSwitch(Switch); - break; - } -} -#endif - - -#ifndef SFX_MODULE -void CommandData::BadSwitch(const char *Switch) -{ - mprintf(St(MUnknownOption),Switch); - ErrHandler.Exit(RARX_USERERROR); -} -#endif - - -#ifndef GUI -void CommandData::OutTitle() -{ - if (BareOutput || DisableCopyright) - return; -#if defined(__GNUC__) && defined(SFX_MODULE) - mprintf(St(MCopyrightS)); -#else -#ifndef SILENT - static bool TitleShown=false; - if (TitleShown) - return; - TitleShown=true; - char Version[50]; - int Beta=RARVER_BETA; - if (Beta!=0) - sprintf(Version,"%d.%02d %s %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA); - else - sprintf(Version,"%d.%02d",RARVER_MAJOR,RARVER_MINOR); -#ifdef UNRAR - mprintf(St(MUCopyright),Version,RARVER_YEAR); -#else -#endif -#endif -#endif -} -#endif - - -inline bool CmpMSGID(MSGID i1,MSGID i2) -{ -#ifdef MSGID_INT - return(i1==i2); -#else - // If MSGID is const char*, we cannot compare pointers only. - // Pointers to different instances of same strings can differ, - // so we need to compare complete strings. - return(strcmp(i1,i2)==0); -#endif -} - -void CommandData::OutHelp(RAR_EXIT ExitCode) -{ -#if !defined(GUI) && !defined(SILENT) - OutTitle(); - static MSGID Help[]={ -#ifdef SFX_MODULE - // Console SFX switches definition. - MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV -#elif defined(UNRAR) - // UnRAR switches definition. - MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL, - MCHelpCmdP,MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm, - MCHelpSwAT,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,MCHelpSwAI,MCHelpSwAP, - MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU, - MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR, - MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal, - MCHelpSwO,MCHelpSwOC,MCHelpSwOR,MCHelpSwOW,MCHelpSwP, - MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSL,MCHelpSwSM,MCHelpSwTA, - MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwVUnr, - MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,MCHelpSwY -#else -#endif - }; - - for (int I=0;IItemsCount()==0) - return(false); - if (ExclCheckArgs(InclArgs,Dir,CheckName,false,MATCH_WILDSUBPATH)) - return(false); - return(true); -} - - -bool CommandData::ExclCheckArgs(StringList *Args,bool Dir,char *CheckName,bool CheckFullPath,int MatchMode) -{ - char *Name=ConvertPath(CheckName,NULL); - char FullName[NM]; - char CurMask[NM+1]; // We reserve the space to append "*" to mask. - *FullName=0; - Args->Rewind(); - while (Args->GetString(CurMask,ASIZE(CurMask)-1)) - { - char *LastMaskChar=PointToLastChar(CurMask); - bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only. - - if (Dir) - { - // CheckName is a directory. - if (DirMask) - { - // We process the directory and have the directory exclusion mask. - // So let's convert "mask\" to "mask" and process it normally. - - *LastMaskChar=0; - } - else - { - // If mask has wildcards in name part and does not have the trailing - // '\' character, we cannot use it for directories. - - if (IsWildcard(PointToName(CurMask))) - continue; - } - } - else - { - // If we process a file inside of directory excluded by "dirmask\". - // we want to exclude such file too. So we convert "dirmask\" to - // "dirmask\*". It is important for operations other than archiving. - // When archiving, directory matched by "dirmask\" is excluded - // from further scanning. - - if (DirMask) - strcat(CurMask,"*"); - } - -#ifndef SFX_MODULE - if (CheckFullPath && IsFullPath(CurMask)) - { - // We do not need to do the special "*\" processing here, because - // unlike the "else" part of this "if", now we convert names to full - // format, so they all include the path, which is matched by "*\" - // correctly. Moreover, removing "*\" from mask would break - // the comparison, because now all names have the path. - - if (*FullName==0) - ConvertNameToFull(CheckName,FullName); - if (CmpName(CurMask,FullName,MatchMode)) - return(true); - } - else -#endif - { - char NewName[NM+2],*CurName=Name; - if (CurMask[0]=='*' && IsPathDiv(CurMask[1])) - { - // We want "*\name" to match 'name' not only in subdirectories, - // but also in the current directory. We convert the name - // from 'name' to '.\name' to be matched by "*\" part even if it is - // in current directory. - NewName[0]='.'; - NewName[1]=CPATHDIVIDER; - strncpyz(NewName+2,Name,ASIZE(NewName)-2); - CurName=NewName; - } - - if (CmpName(ConvertPath(CurMask,NULL),CurName,MatchMode)) - return(true); - } - } - return(false); -} - - -#ifndef SFX_MODULE -// Now this function performs only one task and only in Windows version: -// it skips symlinks to directories if -e1024 switch is specified. -// Symlinks are skipped in ScanTree class, so their entire contents -// is skipped too. Without this function we would check the attribute -// only directly before archiving, so we would skip the symlink record, -// but not the contents of symlinked directory. -bool CommandData::ExclDirByAttr(uint FileAttr) -{ -#ifdef _WIN_ALL - if ((FileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0 && - (ExclFileAttr & FILE_ATTRIBUTE_REPARSE_POINT)!=0) - return true; -#endif - return false; -} -#endif - - - - -#ifndef SFX_MODULE -// Return 'true' if we need to exclude the file from processing. -bool CommandData::TimeCheck(RarTime &ft) -{ - if (FileTimeBefore.IsSet() && ft>=FileTimeBefore) - return(true); - if (FileTimeAfter.IsSet() && ft<=FileTimeAfter) - return(true); - return(false); -} -#endif - - -#ifndef SFX_MODULE -// Return 'true' if we need to exclude the file from processing. -bool CommandData::SizeCheck(int64 Size) -{ - if (FileSizeLess!=INT64NDF && Size>=FileSizeLess) - return(true); - if (FileSizeMore!=INT64NDF && Size<=FileSizeMore) - return(true); - return(false); -} -#endif - - - - -int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType) -{ - if (strlen(NewLhd.FileName)>=NM || wcslen(NewLhd.FileNameW)>=NM) - return(0); - bool Dir=(NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY; - if (ExclCheck(NewLhd.FileName,Dir,false,true)) - return(0); -#ifndef SFX_MODULE - if (TimeCheck(NewLhd.mtime)) - return(0); - if ((NewLhd.FileAttr & ExclFileAttr)!=0 || InclAttrSet && (NewLhd.FileAttr & InclFileAttr)==0) - return(0); - if (!Dir && SizeCheck(NewLhd.FullUnpSize)) - return(0); -#endif - char *ArgName; - wchar *ArgNameW; - FileArgs->Rewind(); - for (int StringCount=1;FileArgs->GetString(&ArgName,&ArgNameW);StringCount++) - { -#ifndef SFX_MODULE - bool Unicode=(NewLhd.Flags & LHD_UNICODE) || ArgNameW!=NULL && *ArgNameW!=0; - if (Unicode) - { - wchar NameW[NM],ArgW[NM],*NamePtr=NewLhd.FileNameW; - bool CorrectUnicode=true; - if (ArgNameW==NULL || *ArgNameW==0) - { - if (!CharToWide(ArgName,ArgW) || *ArgW==0) - CorrectUnicode=false; - ArgNameW=ArgW; - } - if ((NewLhd.Flags & LHD_UNICODE)==0) - { - if (!CharToWide(NewLhd.FileName,NameW) || *NameW==0) - CorrectUnicode=false; - NamePtr=NameW; - } - if (CmpName(ArgNameW,NamePtr,MatchType)) - { - if (ExactMatch!=NULL) - *ExactMatch=wcsicompc(ArgNameW,NamePtr)==0; - return(StringCount); - } - if (CorrectUnicode) - continue; - } -#endif - if (CmpName(ArgName,NewLhd.FileName,MatchType)) - { - if (ExactMatch!=NULL) - *ExactMatch=stricompc(ArgName,NewLhd.FileName)==0; - return(StringCount); - } - } - return(0); -} - - -#ifndef GUI -void CommandData::ProcessCommand() -{ -#ifndef SFX_MODULE - - const char *SingleCharCommands="FUADPXETK"; - if (Command[0]!=0 && Command[1]!=0 && strchr(SingleCharCommands,*Command)!=NULL || *ArcName==0) - OutHelp(*Command==0 ? RARX_SUCCESS:RARX_USERERROR); // Return 'success' for 'rar' without parameters. - -#ifdef _UNIX - if (GetExt(ArcName)==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName)))) - strncatz(ArcName,".rar",ASIZE(ArcName)); -#else - if (GetExt(ArcName)==NULL) - strncatz(ArcName,".rar",ASIZE(ArcName)); -#endif - - if (strchr("AFUMD",*Command)==NULL) - { - if (GenerateArcName) - GenerateArchiveName(ArcName,ArcNameW,ASIZE(ArcName),GenerateMask,false); - - StringList ArcMasks; - ArcMasks.AddString(ArcName); - ScanTree Scan(&ArcMasks,Recurse,SaveLinks,SCAN_SKIPDIRS); - FindData FindData; - while (Scan.GetNext(&FindData)==SCAN_SUCCESS) - AddArcName(FindData.Name,FindData.NameW); - } - else - AddArcName(ArcName,NULL); -#endif - - switch(Command[0]) - { - case 'P': - case 'X': - case 'E': - case 'T': - case 'I': - { - CmdExtract Extract; - Extract.DoExtract(this); - } - break; -#ifndef SILENT - case 'V': - case 'L': - ListArchive(this); - break; - default: - OutHelp(RARX_USERERROR); -#endif - } - if (!BareOutput) - mprintf("\n"); -} -#endif - - -void CommandData::AddArcName(const char *Name,const wchar *NameW) -{ - ArcNames->AddString(Name,NameW); -} - - -bool CommandData::GetArcName(char *Name,wchar *NameW,int MaxSize) -{ - if (!ArcNames->GetString(Name,NameW,NM)) - return(false); - return(true); -} - - -bool CommandData::IsSwitch(int Ch) -{ -#if defined(_WIN_ALL) || defined(_EMX) - return(Ch=='-' || Ch=='/'); -#else - return(Ch=='-'); -#endif -} - - -#ifndef SFX_MODULE -uint CommandData::GetExclAttr(const char *Str) -{ - if (IsDigit(*Str)) - return(strtol(Str,NULL,0)); - else - { - uint Attr; - for (Attr=0;*Str;Str++) - switch(etoupper(*Str)) - { -#ifdef _UNIX - case 'D': - Attr|=S_IFDIR; - break; - case 'V': - Attr|=S_IFCHR; - break; -#elif defined(_WIN_ALL) || defined(_EMX) - case 'R': - Attr|=0x1; - break; - case 'H': - Attr|=0x2; - break; - case 'S': - Attr|=0x4; - break; - case 'D': - Attr|=0x10; - break; - case 'A': - Attr|=0x20; - break; -#endif - } - return(Attr); - } -} -#endif - - - - -#ifndef SFX_MODULE -bool CommandData::CheckWinSize() -{ - static int ValidSize[]={ - 0x10000,0x20000,0x40000,0x80000,0x100000,0x200000,0x400000 - }; - for (int I=0;IGetChar()); -} - - -void RangeCoder::InitDecoder(Unpack *UnpackRead) -{ - RangeCoder::UnpackRead=UnpackRead; - - low=code=0; - range=uint(-1); - for (int i=0;i < 4;i++) - code=(code << 8) | GetChar(); -} - - -// (int) cast before "low" added only to suppress compiler warnings. -#define ARI_DEC_NORMALIZE(code,low,range,read) \ -{ \ - while ((low^(low+range))GetChar(); \ - range <<= 8; \ - low <<= 8; \ - } \ -} - - -inline int RangeCoder::GetCurrentCount() -{ - return (code-low)/(range /= SubRange.scale); -} - - -inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT) -{ - return (code-low)/(range >>= SHIFT); -} - - -inline void RangeCoder::Decode() -{ - low += range*SubRange.LowCount; - range *= SubRange.HighCount-SubRange.LowCount; -} diff --git a/src/unrar/coder.hpp b/src/unrar/coder.hpp deleted file mode 100644 index 0c8156c44b..0000000000 --- a/src/unrar/coder.hpp +++ /dev/null @@ -1,25 +0,0 @@ -/**************************************************************************** - * Contents: 'Carryless rangecoder' by Dmitry Subbotin * - ****************************************************************************/ - -const uint TOP=1 << 24, BOT=1 << 15; - - -class RangeCoder -{ - public: - void InitDecoder(Unpack *UnpackRead); - inline int GetCurrentCount(); - inline uint GetCurrentShiftCount(uint SHIFT); - inline void Decode(); - inline void PutChar(unsigned int c); - inline unsigned int GetChar(); - - uint low, code, range; - struct SUBRANGE - { - uint LowCount, HighCount, scale; - } SubRange; - - Unpack *UnpackRead; -}; diff --git a/src/unrar/compress.hpp b/src/unrar/compress.hpp deleted file mode 100644 index 3157e1a3b1..0000000000 --- a/src/unrar/compress.hpp +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef _RAR_COMPRESS_ -#define _RAR_COMPRESS_ - -class ComprDataIO; -class PackingFileTable; - -#define MAX_LZ_MATCH 0x101 - -#define MAXWINSIZE 0x400000 -#define MAXWINMASK (MAXWINSIZE-1) - -#define LOW_DIST_REP_COUNT 16 - -#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */ -#define DC 60 -#define LDC 17 -#define RC 28 -#define HUFF_TABLE_SIZE (NC+DC+RC+LDC) -#define BC 20 - -#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */ -#define DC20 48 -#define RC20 28 -#define BC20 19 -#define MC20 257 - -// Largest alphabet size among all values listed above. -#define LARGEST_TABLE_SIZE 299 - -enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ, - CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA}; - - -enum FilterType { - FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9, - FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA, - FILTER_ITANIUM, FILTER_E8E9V2 -}; - -#endif diff --git a/src/unrar/consio.cpp b/src/unrar/consio.cpp deleted file mode 100644 index 42b72a617f..0000000000 --- a/src/unrar/consio.cpp +++ /dev/null @@ -1,319 +0,0 @@ -#include "rar.hpp" - -#ifndef GUI -#include "log.cpp" -#endif - -static int KbdAnsi(char *Addr,int Size); - -#if !defined(GUI) && !defined(SILENT) -static void RawPrint(char *Msg,MESSAGE_TYPE MessageType); -static byte GetKey(); -#endif - -static MESSAGE_TYPE MsgStream=MSG_STDOUT; -static bool Sound=false; -const int MaxMsgSize=2*NM+2048; - -void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound) -{ - ::MsgStream=MsgStream; - ::Sound=Sound; -} - -#if !defined(GUI) && !defined(SILENT) -void mprintf(const char *fmt,...) -{ - if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY) - return; - char Msg[MaxMsgSize]; - va_list argptr; - va_start(argptr,fmt); - vsnprintf(Msg,ASIZE(Msg),fmt,argptr); - - // Different vsnprintf implementation can return either -1 or >=MaxMsgSize - // if string is truncated. So we do not check exit code and always zero - // terminate the string for safety. It is faster than check for error. - Msg[ASIZE(Msg)-1] = 0; - - RawPrint(Msg,MsgStream); - va_end(argptr); -} -#endif - - -#if !defined(GUI) && !defined(SILENT) -void eprintf(const char *fmt,...) -{ - if (MsgStream==MSG_NULL) - return; - safebuf char Msg[MaxMsgSize]; - va_list argptr; - va_start(argptr,fmt); - vsnprintf(Msg,ASIZE(Msg),fmt,argptr); - - // Different vsnprintf implementation can return either -1 or >=MaxMsgSize - // if string is truncated. So we do not check exit code and always zero - // terminate the string for safety. It is faster than check for error. - Msg[ASIZE(Msg)-1] = 0; - - RawPrint(Msg,MSG_STDERR); - va_end(argptr); -} -#endif - - -#if !defined(GUI) && !defined(SILENT) -void RawPrint(char *Msg,MESSAGE_TYPE MessageType) -{ - File OutFile; - switch(MessageType) - { - case MSG_STDOUT: - OutFile.SetHandleType(FILE_HANDLESTD); - break; - case MSG_STDERR: - case MSG_ERRONLY: - OutFile.SetHandleType(FILE_HANDLEERR); - break; - default: - return; - } -#ifdef _WIN_ALL - CharToOemA(Msg,Msg); - - char OutMsg[MaxMsgSize]; - size_t OutPos=0; - for (size_t I=0;Msg[I]!=0;I++) - { - if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r') && OutPosSet(PlainPsw); - cleandata(PlainPsw,sizeof(PlainPsw)); - break; - } - return(true); -} -#endif - - -#if !defined(GUI) && !defined(SILENT) -byte GetKey() -{ - char Str[80]; - bool EndOfFile; -#if defined(__GNUC__) || defined(sun) - EndOfFile=(fgets(Str,sizeof(Str),stdin)==NULL); -#else - File SrcFile; - SrcFile.SetHandleType(FILE_HANDLESTD); - EndOfFile=(SrcFile.Read(Str,sizeof(Str))==0); -#endif - if (EndOfFile) - { - // Looks like stdin is a null device. We can enter to infinite loop - // calling Ask(), so let's better exit. - ErrHandler.Exit(RARX_USERBREAK); - } - return (byte)Str[0]; -} -#endif - - -#if !defined(GUI) && !defined(SILENT) -int Ask(const char *AskStr) -{ - const int MaxItems=10; - char Item[MaxItems][40]; - int ItemKeyPos[MaxItems],NumItems=0; - - for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_')) - { - char *CurItem=Item[NumItems]; - strncpyz(CurItem,NextItem+1,ASIZE(Item[0])); - char *EndItem=strchr(CurItem,'_'); - if (EndItem!=NULL) - *EndItem=0; - int KeyPos=0,CurKey; - while ((CurKey=CurItem[KeyPos])!=0) - { - bool Found=false; - for (int I=0;I4 ? "\n":" "):", "); - int KeyPos=ItemKeyPos[I]; - for (int J=0;J>1)^0xEDB88320L : (C>>1); - CRCTab[I]=crc_tables[0][I]=C; - } - - for (uint I=0;I<256;I++) // Build additional lookup tables. - { - uint C=crc_tables[0][I]; - for (uint J=1;J<8;J++) - { - C=crc_tables[0][(byte)C]^(C>>8); - crc_tables[J][I]=C; - } - } -} - - -uint CRC(uint StartCRC,const void *Addr,size_t Size) -{ - if (CRCTab[1]==0) - InitCRC(); - byte *Data=(byte *)Addr; - - // Align Data to 8 for better performance. - for (;Size>0 && ((long)Data & 7);Size--,Data++) - StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8); - - for (;Size>=8;Size-=8,Data+=8) - { -#ifdef BIG_ENDIAN - StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24); -#else - StartCRC ^= *(uint32 *) Data; -#endif - StartCRC = crc_tables[7][(byte) StartCRC ] ^ - crc_tables[6][(byte)(StartCRC >> 8) ] ^ - crc_tables[5][(byte)(StartCRC >> 16)] ^ - crc_tables[4][(byte)(StartCRC >> 24)] ^ - crc_tables[3][Data[4]] ^ - crc_tables[2][Data[5]] ^ - crc_tables[1][Data[6]] ^ - crc_tables[0][Data[7]]; - } - - for (;Size>0;Size--,Data++) // Process left data. - StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8); - - return(StartCRC); -} - - -#ifndef SFX_MODULE -// For RAR 1.4 archives in case somebody still has them. -ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size) -{ - byte *Data=(byte *)Addr; - for (size_t I=0;I>15))&0xffff; - } - return(StartCRC); -} -#endif diff --git a/src/unrar/crc.hpp b/src/unrar/crc.hpp deleted file mode 100644 index 196a7e6ab7..0000000000 --- a/src/unrar/crc.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _RAR_CRC_ -#define _RAR_CRC_ - -void InitCRC(); -uint CRC(uint StartCRC,const void *Addr,size_t Size); -ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size); - -#endif diff --git a/src/unrar/crypt.cpp b/src/unrar/crypt.cpp deleted file mode 100644 index 5cc5aefbf2..0000000000 --- a/src/unrar/crypt.cpp +++ /dev/null @@ -1,387 +0,0 @@ -#include "rar.hpp" - -#ifndef SFX_MODULE -extern uint CRCTab[256]; -#endif - -#define NROUNDS 32 - -#define rol(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n)))) -#define ror(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n)))) - -#define substLong(t) ( (uint)SubstTable[(uint)t&255] | \ - ((uint)SubstTable[(int)(t>> 8)&255]<< 8) | \ - ((uint)SubstTable[(int)(t>>16)&255]<<16) | \ - ((uint)SubstTable[(int)(t>>24)&255]<<24) ) - -CryptKeyCacheItem CryptData::Cache[4]; -int CryptData::CachePos=0; - - -#ifndef SFX_MODULE -static byte InitSubstTable[256]={ - 215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42, - 232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137, - 255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6, - 71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235, - 107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36, - 158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251, - 97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11, - 164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51, - 207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7, - 122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80, - 131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129, - 224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10, - 118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108, - 161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225, - 0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52, - 116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84 -}; -#endif - - - -void CryptData::DecryptBlock(byte *Buf,size_t Size) -{ - rin.blockDecrypt(Buf,Size,Buf); -} - - -#ifndef SFX_MODULE -void CryptData::EncryptBlock20(byte *Buf) -{ - uint A,B,C,D,T,TA,TB; -#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT) - A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0]; - B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1]; - C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2]; - D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3]; -#else - uint32 *BufPtr=(uint32 *)Buf; - A=BufPtr[0]^Key[0]; - B=BufPtr[1]^Key[1]; - C=BufPtr[2]^Key[2]; - D=BufPtr[3]^Key[3]; -#endif - for(int I=0;I>8); - Buf[2]=(byte)(C>>16); - Buf[3]=(byte)(C>>24); - D^=Key[1]; - Buf[4]=(byte)D; - Buf[5]=(byte)(D>>8); - Buf[6]=(byte)(D>>16); - Buf[7]=(byte)(D>>24); - A^=Key[2]; - Buf[8]=(byte)A; - Buf[9]=(byte)(A>>8); - Buf[10]=(byte)(A>>16); - Buf[11]=(byte)(A>>24); - B^=Key[3]; - Buf[12]=(byte)B; - Buf[13]=(byte)(B>>8); - Buf[14]=(byte)(B>>16); - Buf[15]=(byte)(B>>24); -#else - BufPtr[0]=C^Key[0]; - BufPtr[1]=D^Key[1]; - BufPtr[2]=A^Key[2]; - BufPtr[3]=B^Key[3]; -#endif - UpdKeys(Buf); -} - - -void CryptData::DecryptBlock20(byte *Buf) -{ - byte InBuf[16]; - uint A,B,C,D,T,TA,TB; -#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT) - A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0]; - B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1]; - C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2]; - D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3]; -#else - uint32 *BufPtr=(uint32 *)Buf; - A=BufPtr[0]^Key[0]; - B=BufPtr[1]^Key[1]; - C=BufPtr[2]^Key[2]; - D=BufPtr[3]^Key[3]; -#endif - memcpy(InBuf,Buf,sizeof(InBuf)); - for(int I=NROUNDS-1;I>=0;I--) - { - T=((C+rol(D,11,32))^Key[I&3]); - TA=A^substLong(T); - T=((D^rol(C,17,32))+Key[I&3]); - TB=B^substLong(T); - A=C; - B=D; - C=TA; - D=TB; - } -#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT) - C^=Key[0]; - Buf[0]=(byte)C; - Buf[1]=(byte)(C>>8); - Buf[2]=(byte)(C>>16); - Buf[3]=(byte)(C>>24); - D^=Key[1]; - Buf[4]=(byte)D; - Buf[5]=(byte)(D>>8); - Buf[6]=(byte)(D>>16); - Buf[7]=(byte)(D>>24); - A^=Key[2]; - Buf[8]=(byte)A; - Buf[9]=(byte)(A>>8); - Buf[10]=(byte)(A>>16); - Buf[11]=(byte)(A>>24); - B^=Key[3]; - Buf[12]=(byte)B; - Buf[13]=(byte)(B>>8); - Buf[14]=(byte)(B>>16); - Buf[15]=(byte)(B>>24); -#else - BufPtr[0]=C^Key[0]; - BufPtr[1]=D^Key[1]; - BufPtr[2]=A^Key[2]; - BufPtr[3]=B^Key[3]; -#endif - UpdKeys(InBuf); -} - - -void CryptData::UpdKeys(byte *Buf) -{ - for (int I=0;I<16;I+=4) - { - Key[0]^=CRCTab[Buf[I]]; - Key[1]^=CRCTab[Buf[I+1]]; - Key[2]^=CRCTab[Buf[I+2]]; - Key[3]^=CRCTab[Buf[I+3]]; - } -} - - -void CryptData::Swap(byte *Ch1,byte *Ch2) -{ - byte Ch=*Ch1; - *Ch1=*Ch2; - *Ch2=Ch; -} -#endif - - -void CryptData::SetCryptKeys(SecPassword *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash) -{ - if (!Password->IsSet()) - return; - wchar PlainPsw[MAXPASSWORD]; - Password->Get(PlainPsw,ASIZE(PlainPsw)); - if (OldOnly) - { -#ifndef SFX_MODULE - if (CRCTab[1]==0) - InitCRC(); - char Psw[MAXPASSWORD]; - memset(Psw,0,sizeof(Psw)); - - // We need to use ASCII password for older encryption algorithms. - WideToChar(PlainPsw,Psw,ASIZE(Psw)); - Psw[ASIZE(Psw)-1]=0; - - size_t PswLength=strlen(Psw); - - SetOldKeys(Psw); - Key[0]=0xD3A3B879L; - Key[1]=0x3F6D12F7L; - Key[2]=0x7515A235L; - Key[3]=0xA4E7F123L; - - memcpy(SubstTable,InitSubstTable,sizeof(SubstTable)); - for (int J=0;J<256;J++) - for (size_t I=0;I>8); - PswNum[2]=(byte)(I>>16); - hash_process( &c, PswNum, 3, HandsOffHash); - if (I%(HashRounds/16)==0) - { - hash_context tempc=c; - uint32 digest[5]; - hash_final( &tempc, digest, HandsOffHash); - AESInit[I/(HashRounds/16)]=(byte)digest[4]; - } - } - uint32 digest[5]; - hash_final( &c, digest, HandsOffHash); - for (int I=0;I<4;I++) - for (int J=0;J<4;J++) - AESKey[I*4+J]=(byte)(digest[I]>>(J*8)); - - Cache[CachePos].Password=*Password; - if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true) - memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE); - Cache[CachePos].HandsOffHash=HandsOffHash; - memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey)); - memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit)); - CachePos=(CachePos+1)%ASIZE(Cache); - - cleandata(RawPsw,sizeof(RawPsw)); - } - rin.init(Encrypt ? Rijndael::Encrypt : Rijndael::Decrypt,AESKey,AESInit); - cleandata(PlainPsw,sizeof(PlainPsw)); -} - - -#ifndef SFX_MODULE -void CryptData::SetOldKeys(const char *Password) -{ - uint PswCRC=CRC(0xffffffff,Password,strlen(Password)); - OldKey[0]=PswCRC&0xffff; - OldKey[1]=(PswCRC>>16)&0xffff; - OldKey[2]=OldKey[3]=0; - PN1=PN2=PN3=0; - byte Ch; - while ((Ch=*Password)!=0) - { - PN1+=Ch; - PN2^=Ch; - PN3+=Ch; - PN3=(byte)rol(PN3,1,8); - OldKey[2]^=Ch^CRCTab[Ch]; - OldKey[3]+=Ch+(CRCTab[Ch]>>16); - Password++; - } -} - - -void CryptData::SetAV15Encryption() -{ - OldKey[0]=0x4765; - OldKey[1]=0x9021; - OldKey[2]=0x7382; - OldKey[3]=0x5215; -} - - -void CryptData::SetCmt13Encryption() -{ - PN1=0; - PN2=7; - PN3=77; -} - - -void CryptData::Crypt(byte *Data,uint Count,int Method) -{ - if (Method==OLD_DECODE) - Decode13(Data,Count); - else - if (Method==OLD_ENCODE) - Encode13(Data,Count); - else - Crypt15(Data,Count); -} - - -void CryptData::Encode13(byte *Data,uint Count) -{ - while (Count--) - { - PN2+=PN3; - PN1+=PN2; - *Data+=PN1; - Data++; - } -} - - -void CryptData::Decode13(byte *Data,uint Count) -{ - while (Count--) - { - PN2+=PN3; - PN1+=PN2; - *Data-=PN1; - Data++; - } -} - - -void CryptData::Crypt15(byte *Data,uint Count) -{ - while (Count--) - { - OldKey[0]+=0x1234; - OldKey[1]^=CRCTab[(OldKey[0] & 0x1fe)>>1]; - OldKey[2]-=CRCTab[(OldKey[0] & 0x1fe)>>1]>>16; - OldKey[0]^=OldKey[2]; - OldKey[3]=ror(OldKey[3]&0xffff,1,16)^OldKey[1]; - OldKey[3]=ror(OldKey[3]&0xffff,1,16); - OldKey[0]^=OldKey[3]; - *Data^=(byte)(OldKey[0]>>8); - Data++; - } -} -#endif - - diff --git a/src/unrar/crypt.hpp b/src/unrar/crypt.hpp deleted file mode 100644 index 96b8a27f13..0000000000 --- a/src/unrar/crypt.hpp +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef _RAR_CRYPT_ -#define _RAR_CRYPT_ - -enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 }; - - -struct CryptKeyCacheItem -{ -#ifndef _SFX_RTL_ - CryptKeyCacheItem() - { - Password.Set(L""); - } - - ~CryptKeyCacheItem() - { - memset(AESKey,0,sizeof(AESKey)); - memset(AESInit,0,sizeof(AESInit)); - memset(&Password,0,sizeof(Password)); - } -#endif - byte AESKey[16],AESInit[16]; - SecPassword Password; - bool SaltPresent; - byte Salt[SALT_SIZE]; - bool HandsOffHash; -}; - -class CryptData -{ - private: - void Encode13(byte *Data,uint Count); - void Decode13(byte *Data,uint Count); - void Crypt15(byte *Data,uint Count); - void UpdKeys(byte *Buf); - void Swap(byte *Ch1,byte *Ch2); - void SetOldKeys(const char *Password); - - Rijndael rin; - - byte SubstTable[256]; - uint Key[4]; - ushort OldKey[4]; - byte PN1,PN2,PN3; - - byte AESKey[16],AESInit[16]; - - static CryptKeyCacheItem Cache[4]; - static int CachePos; - public: - void SetCryptKeys(SecPassword *Password,const byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash); - void SetAV15Encryption(); - void SetCmt13Encryption(); - void EncryptBlock20(byte *Buf); - void DecryptBlock20(byte *Buf); - void EncryptBlock(byte *Buf,size_t Size); - void DecryptBlock(byte *Buf,size_t Size); - void Crypt(byte *Data,uint Count,int Method); - static void SetSalt(byte *Salt,int SaltSize); -}; - -#endif diff --git a/src/unrar/dll.cpp b/src/unrar/dll.cpp deleted file mode 100644 index 535656caf5..0000000000 --- a/src/unrar/dll.cpp +++ /dev/null @@ -1,375 +0,0 @@ -#include "rar.hpp" -#include "dll.hpp" - -static int RarErrorToDll(RAR_EXIT ErrCode); - -struct DataSet -{ - CommandData Cmd; - CmdExtract Extract; - Archive Arc; - int OpenMode; - int HeaderSize; - - DataSet():Arc(&Cmd) {}; -}; - - -HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *r) -{ - RAROpenArchiveDataEx rx; - memset(&rx,0,sizeof(rx)); - rx.ArcName=r->ArcName; - rx.OpenMode=r->OpenMode; - rx.CmtBuf=r->CmtBuf; - rx.CmtBufSize=r->CmtBufSize; - HANDLE hArc=RAROpenArchiveEx(&rx); - r->OpenResult=rx.OpenResult; - r->CmtSize=rx.CmtSize; - r->CmtState=rx.CmtState; - return(hArc); -} - - -HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r) -{ - DataSet *Data=NULL; - try - { - r->OpenResult=0; - Data=new DataSet; - Data->Cmd.DllError=0; - Data->OpenMode=r->OpenMode; - Data->Cmd.FileArgs->AddString("*"); - - char an[NM]; - if (r->ArcName==NULL && r->ArcNameW!=NULL) - { - WideToChar(r->ArcNameW,an,NM); - r->ArcName=an; - } - - Data->Cmd.AddArcName(r->ArcName,r->ArcNameW); - Data->Cmd.Overwrite=OVERWRITE_ALL; - Data->Cmd.VersionControl=1; - - Data->Cmd.Callback=r->Callback; - Data->Cmd.UserData=r->UserData; - - if (!Data->Arc.Open(r->ArcName,r->ArcNameW,0)) - { - r->OpenResult=ERAR_EOPEN; - delete Data; - return(NULL); - } - if (!Data->Arc.IsArchive(false)) - { - r->OpenResult=Data->Cmd.DllError!=0 ? Data->Cmd.DllError:ERAR_BAD_ARCHIVE; - delete Data; - return(NULL); - } - r->Flags=Data->Arc.NewMhd.Flags; - Array CmtData; - if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtData,NULL)) - { - r->Flags|=2; - size_t Size=CmtData.Size()+1; - r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1; - r->CmtSize=(uint)Min(Size,r->CmtBufSize); - memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1); - if (Size<=r->CmtBufSize) - r->CmtBuf[r->CmtSize-1]=0; - } - else - r->CmtState=r->CmtSize=0; - if (Data->Arc.Signed) - r->Flags|=0x20; - Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc); - return((HANDLE)Data); - } - catch (RAR_EXIT ErrCode) - { - if (Data!=NULL && Data->Cmd.DllError!=0) - r->OpenResult=Data->Cmd.DllError; - else - r->OpenResult=RarErrorToDll(ErrCode); - if (Data != NULL) - delete Data; - return(NULL); - } - catch (std::bad_alloc) // Catch 'new' exception. - { - r->OpenResult=ERAR_NO_MEMORY; - if (Data != NULL) - delete Data; - } -} - - -int PASCAL RARCloseArchive(HANDLE hArcData) -{ - DataSet *Data=(DataSet *)hArcData; - bool Success=Data==NULL ? false:Data->Arc.Close(); - delete Data; - return(Success ? 0:ERAR_ECLOSE); -} - - -int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D) -{ - struct RARHeaderDataEx X; - memset(&X,0,sizeof(X)); - - int Code=RARReadHeaderEx(hArcData,&X); - - strncpyz(D->ArcName,X.ArcName,ASIZE(D->ArcName)); - strncpyz(D->FileName,X.FileName,ASIZE(D->FileName)); - D->Flags=X.Flags; - D->PackSize=X.PackSize; - D->UnpSize=X.UnpSize; - D->HostOS=X.HostOS; - D->FileCRC=X.FileCRC; - D->FileTime=X.FileTime; - D->UnpVer=X.UnpVer; - D->Method=X.Method; - D->FileAttr=X.FileAttr; - D->CmtSize=0; - D->CmtState=0; - - return Code; -} - - -int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D) -{ - DataSet *Data=(DataSet *)hArcData; - try - { - if ((Data->HeaderSize=(int)Data->Arc.SearchBlock(FILE_HEAD))<=0) - { - if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD && - (Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)) - if (MergeArchive(Data->Arc,NULL,false,'L')) - { - Data->Extract.SignatureFound=false; - Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); - return(RARReadHeaderEx(hArcData,D)); - } - else - return(ERAR_EOPEN); - return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE); - } - if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)!=0) - { - int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL); - if (Code==0) - return(RARReadHeaderEx(hArcData,D)); - else - return(Code); - } - strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName)); - if (*Data->Arc.FileNameW) - wcsncpy(D->ArcNameW,Data->Arc.FileNameW,ASIZE(D->ArcNameW)); - else - CharToWide(Data->Arc.FileName,D->ArcNameW); - strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName)); - if (*Data->Arc.NewLhd.FileNameW) - wcsncpy(D->FileNameW,Data->Arc.NewLhd.FileNameW,ASIZE(D->FileNameW)); - else - { -#ifdef _WIN_ALL - char AnsiName[NM]; - OemToCharA(Data->Arc.NewLhd.FileName,AnsiName); - if (!CharToWide(AnsiName,D->FileNameW,ASIZE(D->FileNameW))) - *D->FileNameW=0; -#else - if (!CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW,ASIZE(D->FileNameW))) - *D->FileNameW=0; -#endif - } - D->Flags=Data->Arc.NewLhd.Flags; - D->PackSize=Data->Arc.NewLhd.PackSize; - D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize; - D->UnpSize=Data->Arc.NewLhd.UnpSize; - D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize; - D->HostOS=Data->Arc.NewLhd.HostOS; - D->FileCRC=Data->Arc.NewLhd.FileCRC; - D->FileTime=Data->Arc.NewLhd.FileTime; - D->UnpVer=Data->Arc.NewLhd.UnpVer; - D->Method=Data->Arc.NewLhd.Method; - D->FileAttr=Data->Arc.NewLhd.FileAttr; - D->CmtSize=0; - D->CmtState=0; - } - catch (RAR_EXIT ErrCode) - { - return(Data->Cmd.DllError!=0 ? Data->Cmd.DllError:RarErrorToDll(ErrCode)); - } - return(0); -} - - -int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW) -{ - DataSet *Data=(DataSet *)hArcData; - try - { - Data->Cmd.DllError=0; - if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT || - Operation==RAR_SKIP && !Data->Arc.Solid) - { - if (Data->Arc.Volume && - Data->Arc.GetHeaderType()==FILE_HEAD && - (Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0) - if (MergeArchive(Data->Arc,NULL,false,'L')) - { - Data->Extract.SignatureFound=false; - Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); - return(0); - } - else - return(ERAR_EOPEN); - Data->Arc.SeekToNext(); - } - else - { - Data->Cmd.DllOpMode=Operation; - - if (DestPath!=NULL || DestName!=NULL) - { -#ifdef _WIN_ALL - OemToCharA(NullToEmpty(DestPath),Data->Cmd.ExtrPath); -#else - strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath)); -#endif - AddEndSlash(Data->Cmd.ExtrPath); -#ifdef _WIN_ALL - OemToCharA(NullToEmpty(DestName),Data->Cmd.DllDestName); -#else - strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName)); -#endif - } - else - { - *Data->Cmd.ExtrPath=0; - *Data->Cmd.DllDestName=0; - } - - if (DestPathW!=NULL || DestNameW!=NULL) - { - wcsncpy(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2); - AddEndSlash(Data->Cmd.ExtrPathW); - wcsncpy(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1); - - if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0) - WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName); - } - else - { - *Data->Cmd.ExtrPathW=0; - *Data->Cmd.DllDestNameW=0; - } - - strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T"); - Data->Cmd.Test=Operation!=RAR_EXTRACT; - bool Repeat=false; - Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); - - // Now we process extra file information if any. - // - // Archive can be closed if we process volumes, next volume is missing - // and current one is already removed or deleted. So we need to check - // if archive is still open to avoid calling file operations on - // the invalid file handle. Some of our file operations like Seek() - // process such invalid handle correctly, some not. - while (Data->Arc.IsOpened() && Data->Arc.ReadHeader()!=0 && - Data->Arc.GetHeaderType()==NEWSUB_HEAD) - { - Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat); - Data->Arc.SeekToNext(); - } - Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); - } - } - catch (RAR_EXIT ErrCode) - { - return(Data->Cmd.DllError!=0 ? Data->Cmd.DllError:RarErrorToDll(ErrCode)); - } - return(Data->Cmd.DllError); -} - - -int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName) -{ - return(ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL)); -} - - -int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar *DestPath,wchar *DestName) -{ - return(ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName)); -} - - -void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc) -{ - DataSet *Data=(DataSet *)hArcData; - Data->Cmd.ChangeVolProc=ChangeVolProc; -} - - -void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData) -{ - DataSet *Data=(DataSet *)hArcData; - Data->Cmd.Callback=Callback; - Data->Cmd.UserData=UserData; -} - - -void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc) -{ - DataSet *Data=(DataSet *)hArcData; - Data->Cmd.ProcessDataProc=ProcessDataProc; -} - - -#ifndef RAR_NOCRYPT -void PASCAL RARSetPassword(HANDLE hArcData,char *Password) -{ - DataSet *Data=(DataSet *)hArcData; - wchar PasswordW[MAXPASSWORD]; - GetWideName(Password,NULL,PasswordW,ASIZE(PasswordW)); - Data->Cmd.Password.Set(PasswordW); - cleandata(PasswordW,sizeof(PasswordW)); -} -#endif - - -int PASCAL RARGetDllVersion() -{ - return(RAR_DLL_VERSION); -} - - -static int RarErrorToDll(RAR_EXIT ErrCode) -{ - switch(ErrCode) - { - case RARX_FATAL: - return(ERAR_EREAD); - case RARX_CRC: - return(ERAR_BAD_DATA); - case RARX_WRITE: - return(ERAR_EWRITE); - case RARX_OPEN: - return(ERAR_EOPEN); - case RARX_CREATE: - return(ERAR_ECREATE); - case RARX_MEMORY: - return(ERAR_NO_MEMORY); - case RARX_SUCCESS: - return(0); - default: - return(ERAR_UNKNOWN); - } -} diff --git a/src/unrar/dll.def b/src/unrar/dll.def deleted file mode 100644 index 660f69bf6e..0000000000 --- a/src/unrar/dll.def +++ /dev/null @@ -1,12 +0,0 @@ -EXPORTS - RAROpenArchive - RAROpenArchiveEx - RARCloseArchive - RARReadHeader - RARReadHeaderEx - RARProcessFile - RARSetCallback - RARSetChangeVolProc - RARSetProcessDataProc - RARSetPassword - RARGetDllVersion diff --git a/src/unrar/dll.hpp b/src/unrar/dll.hpp deleted file mode 100644 index 1d929becec..0000000000 --- a/src/unrar/dll.hpp +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef _UNRAR_DLL_ -#define _UNRAR_DLL_ - -#pragma pack(1) - -#define ERAR_END_ARCHIVE 10 -#define ERAR_NO_MEMORY 11 -#define ERAR_BAD_DATA 12 -#define ERAR_BAD_ARCHIVE 13 -#define ERAR_UNKNOWN_FORMAT 14 -#define ERAR_EOPEN 15 -#define ERAR_ECREATE 16 -#define ERAR_ECLOSE 17 -#define ERAR_EREAD 18 -#define ERAR_EWRITE 19 -#define ERAR_SMALL_BUF 20 -#define ERAR_UNKNOWN 21 -#define ERAR_MISSING_PASSWORD 22 - -#define RAR_OM_LIST 0 -#define RAR_OM_EXTRACT 1 -#define RAR_OM_LIST_INCSPLIT 2 - -#define RAR_SKIP 0 -#define RAR_TEST 1 -#define RAR_EXTRACT 2 - -#define RAR_VOL_ASK 0 -#define RAR_VOL_NOTIFY 1 - -#define RAR_DLL_VERSION 5 - -#ifdef _UNIX -#define CALLBACK -#define PASCAL -#define LONG long -#define HANDLE void * -#define LPARAM long -#define UINT unsigned int -#endif - -struct RARHeaderData -{ - char ArcName[260]; - char FileName[260]; - unsigned int Flags; - unsigned int PackSize; - unsigned int UnpSize; - unsigned int HostOS; - unsigned int FileCRC; - unsigned int FileTime; - unsigned int UnpVer; - unsigned int Method; - unsigned int FileAttr; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; -}; - - -struct RARHeaderDataEx -{ - char ArcName[1024]; - wchar_t ArcNameW[1024]; - char FileName[1024]; - wchar_t FileNameW[1024]; - unsigned int Flags; - unsigned int PackSize; - unsigned int PackSizeHigh; - unsigned int UnpSize; - unsigned int UnpSizeHigh; - unsigned int HostOS; - unsigned int FileCRC; - unsigned int FileTime; - unsigned int UnpVer; - unsigned int Method; - unsigned int FileAttr; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Reserved[1024]; -}; - - -struct RAROpenArchiveData -{ - char *ArcName; - unsigned int OpenMode; - unsigned int OpenResult; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; -}; - -typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2); - -struct RAROpenArchiveDataEx -{ - char *ArcName; - wchar_t *ArcNameW; - unsigned int OpenMode; - unsigned int OpenResult; - char *CmtBuf; - unsigned int CmtBufSize; - unsigned int CmtSize; - unsigned int CmtState; - unsigned int Flags; - UNRARCALLBACK Callback; - LPARAM UserData; - unsigned int Reserved[28]; -}; - -enum UNRARCALLBACK_MESSAGES { - UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD,UCM_CHANGEVOLUMEW, - UCM_NEEDPASSWORDW -}; - -typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode); -typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size); - -#ifdef __cplusplus -extern "C" { -#endif - -HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData); -HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData); -int PASCAL RARCloseArchive(HANDLE hArcData); -int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData); -int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData); -int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName); -int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName); -void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData); -void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc); -void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc); -void PASCAL RARSetPassword(HANDLE hArcData,char *Password); -int PASCAL RARGetDllVersion(); - -#ifdef __cplusplus -} -#endif - -#pragma pack() - -#endif diff --git a/src/unrar/dll.rc b/src/unrar/dll.rc deleted file mode 100644 index 7a93039ad5..0000000000 --- a/src/unrar/dll.rc +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include - -VS_VERSION_INFO VERSIONINFO -FILEVERSION 4, 20, 100, 526 -PRODUCTVERSION 4, 20, 100, 526 -FILEOS VOS__WINDOWS32 -FILETYPE VFT_APP -{ - BLOCK "StringFileInfo" - { - BLOCK "040904E4" - { - VALUE "CompanyName", "Alexander Roshal\0" - VALUE "ProductName", "RAR decompression library\0" - VALUE "FileDescription", "RAR decompression library\0" - VALUE "FileVersion", "4.20.0\0" - VALUE "ProductVersion", "4.20.0\0" - VALUE "LegalCopyright", "Copyright Alexander Roshal 1993-2012\0" - VALUE "OriginalFilename", "Unrar.dll\0" - } - } - BLOCK "VarFileInfo" - { - VALUE "Translation", 0, 0 - } -} - diff --git a/src/unrar/encname.cpp b/src/unrar/encname.cpp deleted file mode 100644 index 4e42a759bf..0000000000 --- a/src/unrar/encname.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "rar.hpp" - -EncodeFileName::EncodeFileName() -{ - Flags=0; - FlagBits=0; - FlagsPos=0; - DestSize=0; -} - - - - -void EncodeFileName::Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW, - size_t MaxDecSize) -{ - size_t EncPos=0,DecPos=0; - byte HighByte=EncName[EncPos++]; - while (EncPos>6) - { - case 0: - NameW[DecPos++]=EncName[EncPos++]; - break; - case 1: - NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8); - break; - case 2: - NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8); - EncPos+=2; - break; - case 3: - { - int Length=EncName[EncPos++]; - if (Length & 0x80) - { - byte Correction=EncName[EncPos++]; - for (Length=(Length&0x7f)+2;Length>0 && DecPos0 && DecPosMAX_PATH) - { - Log(NULL,St(MMaxPathLimit),MAX_PATH); - } - } -#endif -} - - -void ErrorHandler::ReadErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW) -{ -#ifndef SILENT - ErrMsg(ArcName,St(MErrRead),FileName); - SysErrMsg(); -#endif -} - - -void ErrorHandler::WriteErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW) -{ -#ifndef SILENT - ErrMsg(ArcName,St(MErrWrite),FileName); - SysErrMsg(); -#endif -} - - -void ErrorHandler::Exit(RAR_EXIT ExitCode) -{ -#ifndef SFX_MODULE - Alarm(); -#endif - Throw(ExitCode); -} - - -#ifndef GUI -void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...) -{ - safebuf char Msg[NM+1024]; - va_list argptr; - va_start(argptr,fmt); - vsprintf(Msg,fmt,argptr); - va_end(argptr); -#ifdef _WIN_ALL - if (UserBreak) - Sleep(5000); -#endif - Alarm(); - if (*Msg) - { - Log(ArcName,"\n%s",Msg); - mprintf("\n%s\n",St(MProgAborted)); - } -} -#endif - - -void ErrorHandler::SetErrorCode(RAR_EXIT Code) -{ - switch(Code) - { - case RARX_WARNING: - case RARX_USERBREAK: - if (ExitCode==RARX_SUCCESS) - ExitCode=Code; - break; - case RARX_FATAL: - if (ExitCode==RARX_SUCCESS || ExitCode==RARX_WARNING) - ExitCode=RARX_FATAL; - break; - default: - ExitCode=Code; - break; - } - ErrCount++; -} - - -#if !defined(GUI) && !defined(_SFX_RTL_) -#ifdef _WIN_ALL -BOOL __stdcall ProcessSignal(DWORD SigType) -#else -#if defined(__sun) -extern "C" -#endif -void _stdfunction ProcessSignal(int SigType) -#endif -{ -#ifdef _WIN_ALL - // When a console application is run as a service, this allows the service - // to continue running after the user logs off. - if (SigType==CTRL_LOGOFF_EVENT) - return(TRUE); -#endif - UserBreak=true; - mprintf(St(MBreak)); - for (int I=0;!File::RemoveCreated() && I<3;I++) - { -#ifdef _WIN_ALL - Sleep(100); -#endif - } -#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE) && !defined(RARDLL) - ExtRes.UnloadDLL(); -#endif - exit(RARX_USERBREAK); -#if defined(_WIN_ALL) && !defined(_MSC_VER) - // never reached, just to avoid a compiler warning - return(TRUE); -#endif -} -#endif - - -void ErrorHandler::SetSignalHandlers(bool Enable) -{ - EnableBreak=Enable; -#if !defined(GUI) && !defined(_SFX_RTL_) -#ifdef _WIN_ALL - SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE); -// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN); -#else - signal(SIGINT,Enable ? ProcessSignal:SIG_IGN); - signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN); -#endif -#endif -} - - -void ErrorHandler::Throw(RAR_EXIT Code) -{ - if (Code==RARX_USERBREAK && !EnableBreak) - return; - ErrHandler.SetErrorCode(Code); -#ifdef ALLOW_EXCEPTIONS - throw Code; -#else - File::RemoveCreated(); - exit(Code); -#endif -} - - -void ErrorHandler::SysErrMsg() -{ -#if !defined(SFX_MODULE) && !defined(SILENT) -#ifdef _WIN_ALL - wchar *lpMsgBuf=NULL; - int ErrType=GetLastError(); - if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, - NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR)&lpMsgBuf,0,NULL)) - { - wchar *CurMsg=lpMsgBuf; - while (CurMsg!=NULL) - { - while (*CurMsg=='\r' || *CurMsg=='\n') - CurMsg++; - if (*CurMsg==0) - break; - wchar *EndMsg=wcschr(CurMsg,'\r'); - if (EndMsg==NULL) - EndMsg=wcschr(CurMsg,'\n'); - if (EndMsg!=NULL) - { - *EndMsg=0; - EndMsg++; - } - // We use ASCII for output in Windows console, so let's convert Unicode - // message to single byte. - size_t Length=wcslen(CurMsg)*2; // Must be enough for DBCS characters. - char *MsgA=(char *)malloc(Length+2); - if (MsgA!=NULL) - { - WideToChar(CurMsg,MsgA,Length+1); - MsgA[Length]=0; - Log(NULL,"\n%s",MsgA); - free(MsgA); - } - CurMsg=EndMsg; - } - } - LocalFree( lpMsgBuf ); -#endif - -#if defined(_UNIX) || defined(_EMX) - if (errno!=0) - { - char *err=strerror(errno); - if (err!=NULL) - Log(NULL,"\n%s",err); - } -#endif - -#endif -} - - - - diff --git a/src/unrar/errhnd.hpp b/src/unrar/errhnd.hpp deleted file mode 100644 index ab84e0b546..0000000000 --- a/src/unrar/errhnd.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _RAR_ERRHANDLER_ -#define _RAR_ERRHANDLER_ - -#ifndef SFX_MODULE -#define ALLOW_EXCEPTIONS -#endif - -enum RAR_EXIT // RAR exit code. -{ - RARX_SUCCESS = 0, - RARX_WARNING = 1, - RARX_FATAL = 2, - RARX_CRC = 3, - RARX_LOCK = 4, - RARX_WRITE = 5, - RARX_OPEN = 6, - RARX_USERERROR = 7, - RARX_MEMORY = 8, - RARX_CREATE = 9, - RARX_NOFILES = 10, - RARX_USERBREAK = 255 -}; - -class ErrorHandler -{ - private: - void ErrMsg(const char *ArcName,const char *fmt,...); - - RAR_EXIT ExitCode; - int ErrCount; - bool EnableBreak; - bool Silent; - bool DoShutdown; - public: - ErrorHandler(); - void Clean(); - void MemoryError(); - void OpenError(const char *FileName,const wchar *FileNameW); - void CloseError(const char *FileName,const wchar *FileNameW); - void ReadError(const char *FileName,const wchar *FileNameW); - bool AskRepeatRead(const char *FileName,const wchar *FileNameW); - void WriteError(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW); - void WriteErrorFAT(const char *FileName,const wchar *FileNameW); - bool AskRepeatWrite(const char *FileName,const wchar *FileNameW,bool DiskFull); - void SeekError(const char *FileName,const wchar *FileNameW); - void GeneralErrMsg(const char *Msg); - void MemoryErrorMsg(); - void OpenErrorMsg(const char *FileName,const wchar *FileNameW=NULL); - void OpenErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW); - void CreateErrorMsg(const char *FileName,const wchar *FileNameW=NULL); - void CreateErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW); - void CheckLongPathErrMsg(const char *FileName,const wchar *FileNameW); - void ReadErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW); - void WriteErrorMsg(const char *ArcName,const wchar *ArcNameW,const char *FileName,const wchar *FileNameW); - void Exit(RAR_EXIT ExitCode); - void SetErrorCode(RAR_EXIT Code); - RAR_EXIT GetErrorCode() {return(ExitCode);} - int GetErrorCount() {return(ErrCount);} - void SetSignalHandlers(bool Enable); - void Throw(RAR_EXIT Code); - void SetSilent(bool Mode) {Silent=Mode;}; - void SetShutdown(bool Mode) {DoShutdown=Mode;}; - void SysErrMsg(); -}; - - -#endif diff --git a/src/unrar/extinfo.cpp b/src/unrar/extinfo.cpp deleted file mode 100644 index 538f6a7f36..0000000000 --- a/src/unrar/extinfo.cpp +++ /dev/null @@ -1,76 +0,0 @@ -#include "rar.hpp" - -#ifdef _WIN_ALL -#include "win32acl.cpp" -#include "win32stm.cpp" -#endif -#ifdef _BEOS -#include "beosea.cpp" -#endif -#if defined(_EMX) && !defined(_DJGPP) -#include "os2ea.cpp" -#endif -#ifdef _UNIX -#include "uowners.cpp" -#endif - - - -#ifndef SFX_MODULE -void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW) -{ - switch(Arc.SubBlockHead.SubType) - { -#if defined(_EMX) && !defined(_DJGPP) - case EA_HEAD: - if (Cmd->ProcessEA) - ExtractOS2EA(Arc,Name); - break; -#endif -#ifdef _UNIX - case UO_HEAD: - if (Cmd->ProcessOwners) - ExtractUnixOwner(Arc,Name); - break; -#endif -#ifdef _BEOS - case BEEA_HEAD: - if (Cmd->ProcessEA) - ExtractBeEA(Arc,Name); - break; -#endif -#ifdef _WIN_ALL - case NTACL_HEAD: - if (Cmd->ProcessOwners) - ExtractACL(Arc,Name,NameW); - break; - case STREAM_HEAD: - ExtractStreams(Arc,Name,NameW); - break; -#endif - } -} -#endif - - -void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW) -{ -#if defined(_EMX) && !defined(_DJGPP) - if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_OS2EA)) - ExtractOS2EANew(Arc,Name); -#endif -#ifdef _UNIX - if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER)) - ExtractUnixOwnerNew(Arc,Name); -#endif -#ifdef _BEOS - if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER)) - ExtractUnixOwnerNew(Arc,Name); -#endif -#ifdef _WIN_ALL - if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_ACL)) - ExtractACLNew(Arc,Name,NameW); - if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM)) - ExtractStreamsNew(Arc,Name,NameW); -#endif -} diff --git a/src/unrar/extinfo.hpp b/src/unrar/extinfo.hpp deleted file mode 100644 index db7cea53f8..0000000000 --- a/src/unrar/extinfo.hpp +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef _RAR_EXTINFO_ -#define _RAR_EXTINFO_ - - -void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW); -void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW); - -#endif diff --git a/src/unrar/extract.cpp b/src/unrar/extract.cpp deleted file mode 100644 index ddd71a0386..0000000000 --- a/src/unrar/extract.cpp +++ /dev/null @@ -1,1026 +0,0 @@ -#include "rar.hpp" - -CmdExtract::CmdExtract() -{ - *ArcName=0; - *ArcNameW=0; - - *DestFileName=0; - *DestFileNameW=0; - - TotalFileCount=0; - Password.Set(L""); - Unp=new Unpack(&DataIO); - Unp->Init(); -} - - -CmdExtract::~CmdExtract() -{ - delete Unp; -} - - -void CmdExtract::DoExtract(CommandData *Cmd) -{ - PasswordCancelled=false; - DataIO.SetCurrentCommand(*Cmd->Command); - - FindData FD; - while (Cmd->GetArcName(ArcName,ArcNameW,ASIZE(ArcName))) - if (FindFile::FastFind(ArcName,ArcNameW,&FD)) - DataIO.TotalArcSize+=FD.Size; - - Cmd->ArcNames->Rewind(); - while (Cmd->GetArcName(ArcName,ArcNameW,ASIZE(ArcName))) - { - while (true) - { - SecPassword PrevCmdPassword; - PrevCmdPassword=Cmd->Password; - - EXTRACT_ARC_CODE Code=ExtractArchive(Cmd); - - // Restore Cmd->Password, which could be changed in IsArchive() call - // for next header encrypted archive. - Cmd->Password=PrevCmdPassword; - - if (Code!=EXTRACT_ARC_REPEAT) - break; - } - if (FindFile::FastFind(ArcName,ArcNameW,&FD)) - DataIO.ProcessedArcSize+=FD.Size; - } - - if (TotalFileCount==0 && *Cmd->Command!='I') - { - if (!PasswordCancelled) - { - mprintf(St(MExtrNoFiles)); - } - ErrHandler.SetErrorCode(RARX_NOFILES); - } -#ifndef GUI - else - if (!Cmd->DisableDone) - if (*Cmd->Command=='I') - mprintf(St(MDone)); - else - if (ErrHandler.GetErrorCount()==0) - mprintf(St(MExtrAllOk)); - else - mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount()); -#endif -} - - -void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc) -{ - DataIO.UnpArcSize=Arc.FileLength(); - - FileCount=0; - MatchedArgs=0; -#ifndef SFX_MODULE - FirstFile=true; -#endif - - PasswordAll=(Cmd->Password.IsSet()); - if (PasswordAll) - Password=Cmd->Password; - - DataIO.UnpVolume=false; - - PrevExtracted=false; - SignatureFound=false; - AllMatchesExact=true; - ReconstructDone=false; - AnySolidDataUnpackedWell=false; - - StartTime.SetCurrentTime(); -} - - -EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd) -{ - Archive Arc(Cmd); - if (!Arc.WOpen(ArcName,ArcNameW)) - { - ErrHandler.SetErrorCode(RARX_OPEN); - return(EXTRACT_ARC_NEXT); - } - - if (!Arc.IsArchive(true)) - { -#ifndef GUI - mprintf(St(MNotRAR),ArcName); -#endif - if (CmpExt(ArcName,"rar")) - ErrHandler.SetErrorCode(RARX_WARNING); - return(EXTRACT_ARC_NEXT); - } - - // Archive with corrupt encrypted header can be closed in IsArchive() call. -// if (!Arc.IsOpened()) -// return(EXTRACT_ARC_NEXT); - -#ifndef SFX_MODULE - if (Arc.Volume && Arc.NotFirstVolume) - { - char FirstVolName[NM]; - VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0); - - // If several volume names from same volume set are specified - // and current volume is not first in set and first volume is present - // and specified too, let's skip the current volume. - if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) && - Cmd->ArcNames->Search(FirstVolName,NULL,false)) - return(EXTRACT_ARC_NEXT); - } -#endif - - int64 VolumeSetSize=0; // Total size of volumes after the current volume. - - if (Arc.Volume) - { - // Calculate the total size of all accessible volumes. - // This size is necessary to display the correct total progress indicator. - - char NextName[NM]; - wchar NextNameW[NM]; - - strcpy(NextName,Arc.FileName); - wcscpy(NextNameW,Arc.FileNameW); - - while (true) - { - // First volume is already added to DataIO.TotalArcSize - // in initial TotalArcSize calculation in DoExtract. - // So we skip it and start from second volume. - NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat); - struct FindData FD; - if (FindFile::FastFind(NextName,NextNameW,&FD)) - VolumeSetSize+=FD.Size; - else - break; - } - DataIO.TotalArcSize+=VolumeSetSize; - } - - ExtractArchiveInit(Cmd,Arc); - - if (*Cmd->Command=='T' || *Cmd->Command=='I') - Cmd->Test=true; - - -#ifndef GUI - if (*Cmd->Command=='I') - Cmd->DisablePercentage=true; - else - if (Cmd->Test) - mprintf(St(MExtrTest),ArcName); - else - mprintf(St(MExtracting),ArcName); -#endif - - Arc.ViewComment(); - - // RAR can close a corrupt encrypted archive -// if (!Arc.IsOpened()) -// return(EXTRACT_ARC_NEXT); - - - while (1) - { - size_t Size=Arc.ReadHeader(); - bool Repeat=false; - if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat)) - if (Repeat) - { - // If we started extraction from not first volume and need to - // restart it from first, we must correct DataIO.TotalArcSize - // for correct total progress display. We subtract the size - // of current volume and all volumes after it and add the size - // of new (first) volume. - FindData OldArc,NewArc; - if (FindFile::FastFind(Arc.FileName,Arc.FileNameW,&OldArc) && - FindFile::FastFind(ArcName,ArcNameW,&NewArc)) - DataIO.TotalArcSize-=VolumeSetSize+OldArc.Size-NewArc.Size; - return(EXTRACT_ARC_REPEAT); - } - else - break; - } - - return(EXTRACT_ARC_NEXT); -} - - -bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize,bool &Repeat) -{ - char Command=*Cmd->Command; - if (HeaderSize==0) - if (DataIO.UnpVolume) - { -#ifdef NOVOLUME - return(false); -#else - if (!MergeArchive(Arc,&DataIO,false,Command)) - { - ErrHandler.SetErrorCode(RARX_WARNING); - return(false); - } - SignatureFound=false; -#endif - } - else - return(false); - int HeadType=Arc.GetHeaderType(); - if (HeadType!=FILE_HEAD) - { - if (HeadType==AV_HEAD || HeadType==SIGN_HEAD) - SignatureFound=true; -#if !defined(SFX_MODULE) && !defined(_WIN_CE) - if (HeadType==SUB_HEAD && PrevExtracted) - SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); -#endif - if (HeadType==NEWSUB_HEAD) - { - if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV)) - SignatureFound=true; -#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE) - if (PrevExtracted) - SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL); -#endif - } - if (HeadType==ENDARC_HEAD) - if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME) - { -#ifndef NOVOLUME - if (!MergeArchive(Arc,&DataIO,false,Command)) - { - ErrHandler.SetErrorCode(RARX_WARNING); - return(false); - } - SignatureFound=false; -#endif - Arc.Seek(Arc.CurBlockPos,SEEK_SET); - return(true); - } - else - return(false); - Arc.SeekToNext(); - return(true); - } - PrevExtracted=false; - - if (SignatureFound || - !Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() && - AllMatchesExact) - return(false); - - char ArcFileName[NM]; - IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName); - strcpy(ArcFileName,Arc.NewLhd.FileName); - - wchar ArcFileNameW[NM]; - *ArcFileNameW=0; - - int MatchType=MATCH_WILDSUBPATH; - - bool EqualNames=false; - int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType); - bool ExactMatch=MatchNumber!=0; -#if !defined(SFX_MODULE) && !defined(_WIN_CE) - if (Cmd->ExclPath==EXCL_BASEPATH) - { - *Cmd->ArcPath=0; - if (ExactMatch) - { - Cmd->FileArgs->Rewind(); - if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1)) - *PointToName(Cmd->ArcPath)=0; - } - } -#endif - if (ExactMatch && !EqualNames) - AllMatchesExact=false; - -#ifdef UNICODE_SUPPORTED - bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled(); -#else - bool WideName=false; -#endif - -#ifdef _APPLE - if (WideName) - { - // Prepare UTF-8 name for OS X. Since we are sure that destination - // is UTF-8, we can avoid calling the less reliable WideToChar function. - WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,ASIZE(ArcFileName)); - WideName=false; - } -#endif - - wchar *DestNameW=WideName ? DestFileNameW:NULL; - -#ifdef UNICODE_SUPPORTED - if (WideName) - { - // Prepare the name in single byte native encoding (typically UTF-8 - // for Unix-based systems). Windows does not really need it, - // but Unix system will use this name instead of Unicode. - ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW); - char Name[NM]; - if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name)) - strcpy(ArcFileName,Name); - } -#endif - - ConvertPath(ArcFileName,ArcFileName); - - if (Arc.IsArcLabel()) - return(true); - - if (Arc.NewLhd.Flags & LHD_VERSION) - { - if (Cmd->VersionControl!=1 && !EqualNames) - { - if (Cmd->VersionControl==0) - ExactMatch=false; - int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false); - if (Cmd->VersionControl-1==Version) - ParseVersionFileName(ArcFileName,ArcFileNameW,true); - else - ExactMatch=false; - } - } - else - if (!Arc.IsArcDir() && Cmd->VersionControl>1) - ExactMatch=false; - - Arc.ConvertAttributes(); - -#if !defined(SFX_MODULE) && !defined(RARDLL) - if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 && FirstFile) - { - char CurVolName[NM]; - strcpy(CurVolName,ArcName); - - bool NewNumbering=(Arc.NewMhd.Flags & MHD_NEWNUMBERING)!=0; - VolNameToFirstName(ArcName,ArcName,NewNumbering); - if (*ArcNameW!=0) - VolNameToFirstName(ArcNameW,ArcNameW,NewNumbering); - - if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName,ArcNameW)) - { - // If first volume name does not match the current name and if - // such volume name really exists, let's unpack from this first volume. - Repeat=true; - return(false); - } -#if !defined(RARDLL) && !defined(_WIN_CE) - if (!ReconstructDone) - { - ReconstructDone=true; - - RecVolumes RecVol; - if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true)) - { - Repeat=true; - return(false); - } - } -#endif - strcpy(ArcName,CurVolName); - } -#endif - - DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0; - DataIO.NextVolumeMissing=false; - - Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET); - - bool TestMode=false; - bool ExtrFile=false; - bool SkipSolid=false; - -#ifndef SFX_MODULE - if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0) - { - if (ExactMatch) - { - Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName); -#ifdef RARDLL - Cmd->DllError=ERAR_BAD_DATA; -#endif - ErrHandler.SetErrorCode(RARX_OPEN); - } - ExactMatch=false; - } - - FirstFile=false; -#endif - - if (ExactMatch || (SkipSolid=Arc.Solid)!=0) - { - if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0) -#ifndef RARDLL - if (!Password.IsSet()) -#endif - { -#ifdef RARDLL - if (!Cmd->Password.IsSet()) - { - if (Cmd->Callback!=NULL) - { - wchar PasswordW[MAXPASSWORD]; - *PasswordW=0; - if (Cmd->Callback(UCM_NEEDPASSWORDW,Cmd->UserData,(LPARAM)PasswordW,ASIZE(PasswordW))==-1) - *PasswordW=0; - if (*PasswordW==0) - { - char PasswordA[MAXPASSWORD]; - *PasswordA=0; - if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1) - *PasswordA=0; - GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW)); - cleandata(PasswordA,sizeof(PasswordA)); - } - Cmd->Password.Set(PasswordW); - cleandata(PasswordW,sizeof(PasswordW)); - } - if (!Cmd->Password.IsSet()) - return false; - } - Password=Cmd->Password; - -#else - if (!GetPassword(PASSWORD_FILE,ArcFileName,ArcFileNameW,&Password)) - { - PasswordCancelled=true; - return(false); - } -#endif - } -#if !defined(GUI) && !defined(SILENT) - else - if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0)) - { - eprintf(St(MUseCurPsw),ArcFileName); - switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll))) - { - case -1: - ErrHandler.Exit(RARX_USERBREAK); - case 2: - if (!GetPassword(PASSWORD_FILE,ArcFileName,ArcFileNameW,&Password)) - { - return(false); - } - break; - case 3: - PasswordAll=true; - break; - } - } -#endif - -#ifndef SFX_MODULE - if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0) - WideToChar(Cmd->ExtrPathW,DestFileName); - else -#endif - strcpy(DestFileName,Cmd->ExtrPath); - - -#ifndef SFX_MODULE - if (Cmd->AppendArcNameToPath) - { - strcat(DestFileName,PointToName(Arc.FirstVolumeName)); - SetExt(DestFileName,NULL); - AddEndSlash(DestFileName); - } -#endif - - char *ExtrName=ArcFileName; - - bool EmptyName=false; -#ifndef SFX_MODULE - size_t Length=strlen(Cmd->ArcPath); - if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) && - strlen(ArcFileName)==Length-1) - Length--; - if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0) - { - ExtrName+=Length; - while (*ExtrName==CPATHDIVIDER) - ExtrName++; - if (*ExtrName==0) - EmptyName=true; - } -#endif - - // Use -ep3 only in systems, where disk letters are exist, not in Unix. - bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':'); - - // We do not use any user specified destination paths when extracting - // absolute paths in -ep3 mode. - if (AbsPaths) - *DestFileName=0; - - if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) - strcat(DestFileName,PointToName(ExtrName)); - else - strcat(DestFileName,ExtrName); - - char DiskLetter=etoupper(DestFileName[0]); - - if (AbsPaths) - { - if (DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) && - DiskLetter>='A' && DiskLetter<='Z') - DestFileName[1]=':'; - else - if (DestFileName[0]=='_' && DestFileName[1]=='_') - { - // Convert __server\share to \\server\share. - DestFileName[0]=CPATHDIVIDER; - DestFileName[1]=CPATHDIVIDER; - } - } - -#ifndef SFX_MODULE - if (!WideName && *Cmd->ExtrPathW!=0) - { - DestNameW=DestFileNameW; - WideName=true; - CharToWide(ArcFileName,ArcFileNameW); - } -#endif - - if (WideName) - { - if (*Cmd->ExtrPathW!=0) - wcscpy(DestFileNameW,Cmd->ExtrPathW); - else - CharToWide(Cmd->ExtrPath,DestFileNameW); - -#ifndef SFX_MODULE - if (Cmd->AppendArcNameToPath) - { - wchar FileNameW[NM]; - if (*Arc.FirstVolumeNameW!=0) - wcscpy(FileNameW,Arc.FirstVolumeNameW); - else - CharToWide(Arc.FirstVolumeName,FileNameW); - wcscat(DestFileNameW,PointToName(FileNameW)); - SetExt(DestFileNameW,NULL); - AddEndSlash(DestFileNameW); - } -#endif - wchar *ExtrNameW=ArcFileNameW; -#ifndef SFX_MODULE - if (Length>0) - { - wchar ArcPathW[NM]; - GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW,ASIZE(ArcPathW)); - Length=wcslen(ArcPathW); - } - ExtrNameW+=Length; - while (*ExtrNameW==CPATHDIVIDER) - ExtrNameW++; -#endif - - if (AbsPaths) - *DestFileNameW=0; - - if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) - wcscat(DestFileNameW,PointToName(ExtrNameW)); - else - wcscat(DestFileNameW,ExtrNameW); - - if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2])) - DestFileNameW[1]=':'; - } - else - *DestFileNameW=0; - - ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0; - - if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X')) - { - struct FindData FD; - if (FindFile::FastFind(DestFileName,DestNameW,&FD)) - { - if (FD.mtime >= Arc.NewLhd.mtime) - { - // If directory already exists and its modification time is newer - // than start of extraction, it is likely it was created - // when creating a path to one of already extracted items. - // In such case we'll better update its time even if archived - // directory is older. - - if (!FD.IsDir || FD.mtimeFreshFiles) - ExtrFile=false; - } - - // Skip encrypted file if no password is specified. - if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && !Password.IsSet()) - { - ErrHandler.SetErrorCode(RARX_WARNING); -#ifdef RARDLL - Cmd->DllError=ERAR_MISSING_PASSWORD; -#endif - ExtrFile=false; - } - -#ifdef RARDLL - if (*Cmd->DllDestName) - { - strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName)); - *DestFileNameW=0; - if (Cmd->DllOpMode!=RAR_EXTRACT) - ExtrFile=false; - } - if (*Cmd->DllDestNameW) - { - wcsncpyz(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW)); - DestNameW=DestFileNameW; - if (Cmd->DllOpMode!=RAR_EXTRACT) - ExtrFile=false; - } -#endif - -#ifdef SFX_MODULE - if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) && - Arc.NewLhd.Method!=0x30) -#else - if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER) -#endif - { -#ifndef SILENT - Log(Arc.FileName,St(MUnknownMeth),ArcFileName); -#ifndef SFX_MODULE - Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10); -#endif -#endif - ExtrFile=false; - ErrHandler.SetErrorCode(RARX_WARNING); -#ifdef RARDLL - Cmd->DllError=ERAR_UNKNOWN_FORMAT; -#endif - } - - File CurFile; - - if (!IsLink(Arc.NewLhd.FileAttr)) - if (Arc.IsArcDir()) - { - if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH) - return(true); - if (SkipSolid) - { -#ifndef GUI - mprintf(St(MExtrSkipFile),ArcFileName); -#endif - return(true); - } - TotalFileCount++; - if (Cmd->Test) - { -#ifndef GUI - mprintf(St(MExtrTestFile),ArcFileName); - mprintf(" %s",St(MOk)); -#endif - return(true); - } - MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); - bool DirExist=false; - if (MDCode!=MKDIR_SUCCESS) - { - DirExist=FileExist(DestFileName,DestNameW); - if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW))) - { - // File with name same as this directory exists. Propose user - // to overwrite it. - bool UserReject; - FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime); - DirExist=false; - } - if (!DirExist) - { - CreatePath(DestFileName,DestNameW,true); - MDCode=MakeDir(DestFileName,DestNameW,!Cmd->IgnoreGeneralAttr,Arc.NewLhd.FileAttr); - } - } - if (MDCode==MKDIR_SUCCESS) - { -#ifndef GUI - mprintf(St(MCreatDir),DestFileName); - mprintf(" %s",St(MOk)); -#endif - PrevExtracted=true; - } - else - if (DirExist) - { - if (!Cmd->IgnoreGeneralAttr) - SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr); - PrevExtracted=true; - } - else - { - Log(Arc.FileName,St(MExtrErrMkDir),DestFileName); - ErrHandler.CheckLongPathErrMsg(DestFileName,DestNameW); - ErrHandler.SysErrMsg(); -#ifdef RARDLL - Cmd->DllError=ERAR_ECREATE; -#endif - ErrHandler.SetErrorCode(RARX_CREATE); - } - if (PrevExtracted) - { -#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE) - if (Cmd->SetCompressedAttr && - (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) - SetFileCompression(DestFileName,DestNameW,true); -#endif - SetDirTime(DestFileName,DestNameW, - Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, - Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, - Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); - } - return(true); - } - else - { - if (Cmd->Test && ExtrFile) - TestMode=true; -#if !defined(GUI) && !defined(SFX_MODULE) - if (Command=='P' && ExtrFile) - CurFile.SetHandleType(FILE_HANDLESTD); -#endif - if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test) - { - bool UserReject; - // Specify "write only" mode to avoid OpenIndiana NAS problems - // with SetFileTime and read+write files. - if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime,true)) - { - ExtrFile=false; - if (!UserReject) - { - ErrHandler.CreateErrorMsg(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW); - ErrHandler.SetErrorCode(RARX_CREATE); -#ifdef RARDLL - Cmd->DllError=ERAR_ECREATE; -#endif - if (!IsNameUsable(DestFileName) && (!WideName || !IsNameUsable(DestNameW))) - { - Log(Arc.FileName,St(MCorrectingName)); - char OrigName[ASIZE(DestFileName)]; - wchar OrigNameW[ASIZE(DestFileNameW)]; - strncpyz(OrigName,DestFileName,ASIZE(OrigName)); - wcsncpyz(OrigNameW,NullToEmpty(DestNameW),ASIZE(OrigNameW)); - - MakeNameUsable(DestFileName,true); - - if (WideName) - MakeNameUsable(DestNameW,true); - - CreatePath(DestFileName,DestNameW,true); - if (FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime,true)) - { -#ifndef SFX_MODULE - Log(Arc.FileName,St(MRenaming),OrigName,DestFileName); -#endif - ExtrFile=true; - } - else - ErrHandler.CreateErrorMsg(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW); - } - } - } - } - } - - if (!ExtrFile && Arc.Solid) - { - SkipSolid=true; - TestMode=true; - ExtrFile=true; - - } - if (ExtrFile) - { - - if (!SkipSolid) - { - if (!TestMode && Command!='P' && CurFile.IsDevice()) - { - Log(Arc.FileName,St(MInvalidName),DestFileName); - ErrHandler.WriteError(Arc.FileName,Arc.FileNameW,DestFileName,DestFileNameW); - } - TotalFileCount++; - } - FileCount++; -#ifndef GUI - if (Command!='I') - if (SkipSolid) - mprintf(St(MExtrSkipFile),ArcFileName); - else - switch(Cmd->Test ? 'T':Command) - { - case 'T': - mprintf(St(MExtrTestFile),ArcFileName); - break; -#ifndef SFX_MODULE - case 'P': - mprintf(St(MExtrPrinting),ArcFileName); - break; -#endif - case 'X': - case 'E': - mprintf(St(MExtrFile),DestFileName); - break; - } - if (!Cmd->DisablePercentage) - mprintf(" "); -#endif - DataIO.CurUnpRead=0; - DataIO.CurUnpWrite=0; - DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff; - DataIO.PackedCRC=0xffffffff; - - SecPassword FilePassword; -#ifdef _WIN_ALL - if (Arc.NewLhd.HostOS==HOST_MSDOS/* && Arc.NewLhd.UnpVer<=25*/) - { - // We need the password in OEM encoding if file was encrypted by - // native RAR/DOS (not extender based). Let's make the conversion. - wchar PlainPsw[MAXPASSWORD]; - Password.Get(PlainPsw,ASIZE(PlainPsw)); - char PswA[MAXPASSWORD]; - CharToOemBuffW(PlainPsw,PswA,ASIZE(PswA)); - PswA[ASIZE(PswA)-1]=0; - CharToWide(PswA,PlainPsw,ASIZE(PlainPsw)); - PlainPsw[ASIZE(PlainPsw)-1]=0; - FilePassword.Set(PlainPsw); - cleandata(PlainPsw,sizeof(PlainPsw)); - cleandata(PswA,sizeof(PswA)); - } - else -#endif - FilePassword=Password; - - DataIO.SetEncryption( - (Arc.NewLhd.Flags & LHD_PASSWORD)!=0 ? Arc.NewLhd.UnpVer:0,&FilePassword, - (Arc.NewLhd.Flags & LHD_SALT)!=0 ? Arc.NewLhd.Salt:NULL,false, - Arc.NewLhd.UnpVer>=36); - DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize); - DataIO.SetFiles(&Arc,&CurFile); - DataIO.SetTestMode(TestMode); - DataIO.SetSkipUnpCRC(SkipSolid); -#ifndef _WIN_CE - if (!TestMode && !Arc.BrokenFileHeader && - (Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize && - (Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize)) - CurFile.Prealloc(Arc.NewLhd.FullUnpSize); -#endif - - CurFile.SetAllowDelete(!Cmd->KeepBroken); - - bool LinkCreateMode=!Cmd->Test && !SkipSolid; - if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode)) - PrevExtracted=LinkCreateMode; - else - if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0) - if (Arc.NewLhd.Method==0x30) - UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize); - else - { - Unp->SetDestSize(Arc.NewLhd.FullUnpSize); -#ifndef SFX_MODULE - if (Arc.NewLhd.UnpVer<=15) - Unp->DoUnpack(15,FileCount>1 && Arc.Solid); - else -#endif - Unp->DoUnpack(Arc.NewLhd.UnpVer,(Arc.NewLhd.Flags & LHD_SOLID)!=0); - } - -// if (Arc.IsOpened()) - Arc.SeekToNext(); - - bool ValidCRC=Arc.OldFormat && GET_UINT32(DataIO.UnpFileCRC)==GET_UINT32(Arc.NewLhd.FileCRC) || - !Arc.OldFormat && GET_UINT32(DataIO.UnpFileCRC)==GET_UINT32(Arc.NewLhd.FileCRC^0xffffffff); - - // We set AnySolidDataUnpackedWell to true if we found at least one - // valid non-zero solid file in preceding solid stream. If it is true - // and if current encrypted file is broken, we do not need to hint - // about a wrong password and can report CRC error only. - if ((Arc.NewLhd.Flags & LHD_SOLID)==0) - AnySolidDataUnpackedWell=false; // Reset the flag, because non-solid file is found. - else - if (Arc.NewLhd.Method!=0x30 && Arc.NewLhd.FullUnpSize>0 && ValidCRC) - AnySolidDataUnpackedWell=true; - - bool BrokenFile=false; - if (!SkipSolid) - { - if (ValidCRC) - { -#ifndef GUI - if (Command!='P' && Command!='I') - mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk)); -#endif - } - else - { - if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && !AnySolidDataUnpackedWell) - { - Log(Arc.FileName,St(MEncrBadCRC),ArcFileName); - } - else - { - Log(Arc.FileName,St(MCRCFailed),ArcFileName); - } - BrokenFile=true; - ErrHandler.SetErrorCode(RARX_CRC); -#ifdef RARDLL - // If we already have ERAR_EOPEN as result of missing volume, - // we should not replace it with less precise ERAR_BAD_DATA. - if (Cmd->DllError!=ERAR_EOPEN) - Cmd->DllError=ERAR_BAD_DATA; -#endif - Alarm(); - } - } -#ifndef GUI - else - mprintf("\b\b\b\b\b "); -#endif - - if (!TestMode && (Command=='X' || Command=='E') && - !IsLink(Arc.NewLhd.FileAttr)) - { -#if defined(_WIN_ALL) || defined(_EMX) - if (Cmd->ClearArc) - Arc.NewLhd.FileAttr&=~FA_ARCH; -#endif - if (!BrokenFile || Cmd->KeepBroken) - { - if (BrokenFile) - CurFile.Truncate(); - CurFile.SetOpenFileTime( - Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, - Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime, - Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); - CurFile.Close(); -#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE) - if (Cmd->SetCompressedAttr && - (Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT()) - SetFileCompression(CurFile.FileName,CurFile.FileNameW,true); -#endif - CurFile.SetCloseFileTime( - Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime, - Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime); - if (!Cmd->IgnoreGeneralAttr) - SetFileAttr(CurFile.FileName,CurFile.FileNameW,Arc.NewLhd.FileAttr); - PrevExtracted=true; - } - } - } - } - if (ExactMatch) - MatchedArgs++; - if (DataIO.NextVolumeMissing/* || !Arc.IsOpened()*/) - return(false); - if (!ExtrFile) - if (!Arc.Solid) - Arc.SeekToNext(); - else - if (!SkipSolid) - return(false); - return(true); -} - - -void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize) -{ - Array Buffer(0x10000); - while (1) - { - uint Code=DataIO.UnpRead(&Buffer[0],Buffer.Size()); - if (Code==0 || (int)Code==-1) - break; - Code=Code=0) - DestUnpSize-=Code; - } -} - diff --git a/src/unrar/extract.hpp b/src/unrar/extract.hpp deleted file mode 100644 index 0995e8edae..0000000000 --- a/src/unrar/extract.hpp +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef _RAR_EXTRACT_ -#define _RAR_EXTRACT_ - -enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT}; - -class CmdExtract -{ - private: - EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd); - RarTime StartTime; // time when extraction started - - ComprDataIO DataIO; - Unpack *Unp; - unsigned long TotalFileCount; - - unsigned long FileCount; - unsigned long MatchedArgs; - bool FirstFile; - bool AllMatchesExact; - bool ReconstructDone; - - // If any non-zero solid file was successfully unpacked before current. - // If true and if current encrypted file is broken, obviously - // the password is correct and we can report broken CRC without - // any wrong password hints. - bool AnySolidDataUnpackedWell; - - char ArcName[NM]; - wchar ArcNameW[NM]; - - SecPassword Password; - bool PasswordAll; - bool PrevExtracted; - char DestFileName[NM]; - wchar DestFileNameW[NM]; - bool PasswordCancelled; - public: - CmdExtract(); - ~CmdExtract(); - void DoExtract(CommandData *Cmd); - void ExtractArchiveInit(CommandData *Cmd,Archive &Arc); - bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderSize, - bool &Repeat); - static void UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize); - - bool SignatureFound; -}; - -#endif diff --git a/src/unrar/filcreat.cpp b/src/unrar/filcreat.cpp deleted file mode 100644 index 2bd176f79b..0000000000 --- a/src/unrar/filcreat.cpp +++ /dev/null @@ -1,260 +0,0 @@ -#include "rar.hpp" - -bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW, - OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize, - uint FileTime,bool WriteOnly) -{ - if (UserReject!=NULL) - *UserReject=false; -#if defined(_WIN_ALL) && !defined(_WIN_CE) - bool ShortNameChanged=false; -#endif - while (FileExist(Name,NameW)) - { -#if defined(_WIN_ALL) && !defined(_WIN_CE) - if (!ShortNameChanged) - { - // Avoid the infinite loop if UpdateExistingShortName returns - // the same name. - ShortNameChanged=true; - - // Maybe our long name matches the short name of existing file. - // Let's check if we can change the short name. - wchar WideName[NM]; - GetWideName(Name,NameW,WideName,ASIZE(WideName)); - if (UpdateExistingShortName(WideName)) - { - if (Name!=NULL && *Name!=0) - WideToChar(WideName,Name); - if (NameW!=NULL && *NameW!=0) - wcscpy(NameW,WideName); - continue; - } - } - // Allow short name check again. It is necessary, because rename and - // autorename below can change the name, so we need to check it again. - ShortNameChanged=false; -#endif - if (Mode==OVERWRITE_NONE) - { - if (UserReject!=NULL) - *UserReject=true; - return(false); - } - - // Must be before Cmd->AllYes check or -y switch would override -or. - if (Mode==OVERWRITE_AUTORENAME) - { - if (!GetAutoRenamedName(Name,NameW)) - Mode=OVERWRITE_DEFAULT; - continue; - } - -#ifdef SILENT - Mode=OVERWRITE_ALL; -#endif - - // This check must be after OVERWRITE_AUTORENAME processing or -y switch - // would override -or. - if (Cmd->AllYes || Mode==OVERWRITE_ALL) - break; - - if (Mode==OVERWRITE_DEFAULT || Mode==OVERWRITE_FORCE_ASK) - { - char NewName[NM]; - wchar NewNameW[NM]; - *NewNameW=0; - eprintf(St(MFileExists),Name); - int Choice=Ask(St(MYesNoAllRenQ)); - if (Choice==1) - break; - if (Choice==2) - { - if (UserReject!=NULL) - *UserReject=true; - return(false); - } - if (Choice==3) - { - Cmd->Overwrite=OVERWRITE_ALL; - break; - } - if (Choice==4) - { - if (UserReject!=NULL) - *UserReject=true; - Cmd->Overwrite=OVERWRITE_NONE; - return(false); - } - if (Choice==5) - { -#ifndef GUI - mprintf(St(MAskNewName)); - -#ifdef _WIN_ALL - File SrcFile; - SrcFile.SetHandleType(FILE_HANDLESTD); - int Size=SrcFile.Read(NewName,sizeof(NewName)-1); - NewName[Size]=0; - OemToCharA(NewName,NewName); -#else - if (fgets(NewName,sizeof(NewName),stdin)==NULL) - { - // Process fgets failure as if user answered 'No'. - if (UserReject!=NULL) - *UserReject=true; - return(false); - } -#endif - RemoveLF(NewName); -#endif - if (PointToName(NewName)==NewName) - strcpy(PointToName(Name),NewName); - else - strcpy(Name,NewName); - - if (NameW!=NULL) - if (PointToName(NewNameW)==NewNameW) - wcscpy(PointToName(NameW),NewNameW); - else - wcscpy(NameW,NewNameW); - continue; - } - if (Choice==6) - ErrHandler.Exit(RARX_USERBREAK); - } - } - uint FileMode=WriteOnly ? FMF_WRITE|FMF_SHAREREAD:FMF_UPDATE|FMF_SHAREREAD; - if (NewFile!=NULL && NewFile->Create(Name,NameW,FileMode)) - return(true); - PrepareToDelete(Name,NameW); - CreatePath(Name,NameW,true); - return(NewFile!=NULL ? NewFile->Create(Name,NameW,FileMode):DelFile(Name,NameW)); -} - - -bool GetAutoRenamedName(char *Name,wchar *NameW) -{ - char NewName[NM]; - wchar NewNameW[NM]; - - if (Name!=NULL && strlen(Name)>ASIZE(NewName)-10 || - NameW!=NULL && wcslen(NameW)>ASIZE(NewNameW)-10) - return(false); - char *Ext=NULL; - if (Name!=NULL && *Name!=0) - { - Ext=GetExt(Name); - if (Ext==NULL) - Ext=Name+strlen(Name); - } - wchar *ExtW=NULL; - if (NameW!=NULL && *NameW!=0) - { - ExtW=GetExt(NameW); - if (ExtW==NULL) - ExtW=NameW+wcslen(NameW); - } - *NewName=0; - *NewNameW=0; - for (int FileVer=1;;FileVer++) - { - if (Name!=NULL && *Name!=0) - sprintf(NewName,"%.*s(%d)%s",int(Ext-Name),Name,FileVer,Ext); - if (NameW!=NULL && *NameW!=0) - sprintfw(NewNameW,ASIZE(NewNameW),L"%.*s(%d)%s",int(ExtW-NameW),NameW,FileVer,ExtW); - if (!FileExist(NewName,NewNameW)) - { - if (Name!=NULL && *Name!=0) - strcpy(Name,NewName); - if (NameW!=NULL && *NameW!=0) - wcscpy(NameW,NewNameW); - break; - } - if (FileVer>=1000000) - return(false); - } - return(true); -} - - -#if defined(_WIN_ALL) && !defined(_WIN_CE) -// If we find a file, which short name is equal to 'Name', we try to change -// its short name, while preserving the long name. It helps when unpacking -// an archived file, which long name is equal to short name of already -// existing file. Otherwise we would overwrite the already existing file, -// even though its long name does not match the name of unpacking file. -bool UpdateExistingShortName(wchar *Name) -{ - // 'Name' is the name of file which we want to create. Let's check - // if file with such name is exist. If it does not, we return. - FindData fd; - if (!FindFile::FastFind(NULL,Name,&fd)) - return(false); - - // We continue only if file has a short name, which does not match its - // long name, and this short name is equal to name of file which we need - // to create. - if (*fd.ShortName==0 || wcsicomp(PointToName(fd.NameW),fd.ShortName)==0 || - wcsicomp(PointToName(Name),fd.ShortName)!=0) - return(false); - - // Generate the temporary new name for existing file. - wchar NewName[NM]; - *NewName=0; - for (int I=0;I<10000 && *NewName==0;I+=123) - { - // Here we copy the path part of file to create. We'll make the temporary - // file in the same folder. - wcsncpyz(NewName,Name,ASIZE(NewName)); - - // Here we set the random name part. - sprintfw(PointToName(NewName),ASIZE(NewName),L"rtmp%d",I); - - // If such file is already exist, try next random name. - if (FileExist(NULL,NewName)) - *NewName=0; - } - - // If we could not generate the name not used by any other file, we return. - if (*NewName==0) - return(false); - - // FastFind returns the name without path, but we need the fully qualified - // name for renaming, so we use the path from file to create and long name - // from existing file. - wchar FullName[NM]; - wcsncpyz(FullName,Name,ASIZE(FullName)); - wcscpy(PointToName(FullName),PointToName(fd.NameW)); - - // Rename the existing file to randomly generated name. Normally it changes - // the short name too. - if (!MoveFileW(FullName,NewName)) - return(false); - - // Now we need to create the temporary empty file with same name as - // short name of our already existing file. We do it to occupy its previous - // short name and not allow to use it again when renaming the file back to - // its original long name. - File KeepShortFile; - bool Created=false; - if (!FileExist(NULL,Name)) - Created=KeepShortFile.Create(NULL,Name); - - // Now we rename the existing file from temporary name to original long name. - // Since its previous short name is occupied by another file, it should - // get another short name. - MoveFileW(NewName,FullName); - - if (Created) - { - // Delete the temporary zero length file occupying the short name, - KeepShortFile.Close(); - KeepShortFile.Delete(); - } - // We successfully changed the short name. Maybe sometimes we'll simplify - // this function by use of SetFileShortName Windows API call. - // But SetFileShortName is not available in older Windows. - return(true); -} -#endif diff --git a/src/unrar/filcreat.hpp b/src/unrar/filcreat.hpp deleted file mode 100644 index 7e758bfc7f..0000000000 --- a/src/unrar/filcreat.hpp +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef _RAR_FILECREATE_ -#define _RAR_FILECREATE_ - -bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW, - OVERWRITE_MODE Mode,bool *UserReject,int64 FileSize=INT64NDF, - uint FileTime=0,bool WriteOnly=false); -bool GetAutoRenamedName(char *Name,wchar *NameW); - -#if defined(_WIN_ALL) && !defined(_WIN_CE) -bool UpdateExistingShortName(wchar *Name); -#endif - -#endif diff --git a/src/unrar/file.cpp b/src/unrar/file.cpp deleted file mode 100644 index dcf4e612af..0000000000 --- a/src/unrar/file.cpp +++ /dev/null @@ -1,710 +0,0 @@ -#include "rar.hpp" - -static File *CreatedFiles[256]; -static int RemoveCreatedActive=0; - -File::File() -{ - hFile=BAD_HANDLE; - *FileName=0; - *FileNameW=0; - NewFile=false; - LastWrite=false; - HandleType=FILE_HANDLENORMAL; - SkipClose=false; - IgnoreReadErrors=false; - ErrorType=FILE_SUCCESS; - OpenShared=false; - AllowDelete=true; - CloseCount=0; - AllowExceptions=true; -#ifdef _WIN_ALL - NoSequentialRead=false; - CreateMode=FMF_UNDEFINED; -#endif -} - - -File::~File() -{ - if (hFile!=BAD_HANDLE && !SkipClose) - if (NewFile) - Delete(); - else - Close(); -} - - -void File::operator = (File &SrcFile) -{ - hFile=SrcFile.hFile; - strcpy(FileName,SrcFile.FileName); - NewFile=SrcFile.NewFile; - LastWrite=SrcFile.LastWrite; - HandleType=SrcFile.HandleType; - SrcFile.SkipClose=true; -} - - -bool File::Open(const char *Name,const wchar *NameW,uint Mode) -{ - ErrorType=FILE_SUCCESS; - FileHandle hNewFile; - bool OpenShared=File::OpenShared || (Mode & FMF_OPENSHARED)!=0; - bool UpdateMode=(Mode & FMF_UPDATE)!=0; - bool WriteMode=(Mode & FMF_WRITE)!=0; -#ifdef _WIN_ALL - uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ; - if (UpdateMode) - Access|=GENERIC_WRITE; - uint ShareMode=FILE_SHARE_READ; - if (OpenShared) - ShareMode|=FILE_SHARE_WRITE; - uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN; - if (WinNT() && NameW!=NULL && *NameW!=0) - hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL); - else - hNewFile=CreateFileA(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL); - - if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND) - ErrorType=FILE_NOTFOUND; -#else - int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY); -#ifdef O_BINARY - flags|=O_BINARY; -#if defined(_AIX) && defined(_LARGE_FILE_API) - flags|=O_LARGEFILE; -#endif -#endif -#if defined(_EMX) && !defined(_DJGPP) - int sflags=OpenShared ? SH_DENYNO:SH_DENYWR; - int handle=sopen(Name,flags,sflags); -#else - int handle=open(Name,flags); -#ifdef LOCK_EX - -#ifdef _OSF_SOURCE - extern "C" int flock(int, int); -#endif - - if (!OpenShared && UpdateMode && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1) - { - close(handle); - return(false); - } -#endif -#endif - hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,UpdateMode ? UPDATEBINARY:READBINARY); - if (hNewFile==BAD_HANDLE && errno==ENOENT) - ErrorType=FILE_NOTFOUND; -#endif - NewFile=false; - HandleType=FILE_HANDLENORMAL; - SkipClose=false; - bool Success=hNewFile!=BAD_HANDLE; - if (Success) - { - hFile=hNewFile; - - // We use memove instead of strcpy and wcscpy to avoid problems - // with overlapped buffers. While we do not call this function with - // really overlapped buffers yet, we do call it with Name equal to - // FileName like Arc.Open(Arc.FileName,Arc.FileNameW,...). - if (NameW!=NULL) - memmove(FileNameW,NameW,(wcslen(NameW)+1)*sizeof(*NameW)); - else - *FileNameW=0; - if (Name!=NULL) - memmove(FileName,Name,strlen(Name)+1); - else - WideToChar(NameW,FileName); - AddFileToList(hFile); - } - return(Success); -} - - -#if !defined(SHELL_EXT) && !defined(SFX_MODULE) -void File::TOpen(const char *Name,const wchar *NameW) -{ - if (!WOpen(Name,NameW)) - ErrHandler.Exit(RARX_OPEN); -} -#endif - - -bool File::WOpen(const char *Name,const wchar *NameW) -{ - if (Open(Name,NameW)) - return(true); - ErrHandler.OpenErrorMsg(Name,NameW); - return(false); -} - - -bool File::Create(const char *Name,const wchar *NameW,uint Mode) -{ - // OpenIndiana based NAS and CIFS shares fail to set the file time if file - // was created in read+write mode and some data was written and not flushed - // before SetFileTime call. So we should use the write only mode if we plan - // SetFileTime call and do not need to read from file. - bool WriteMode=(Mode & FMF_WRITE)!=0; - bool ShareRead=(Mode & FMF_SHAREREAD)!=0 || File::OpenShared; -#ifdef _WIN_ALL - CreateMode=Mode; - uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ|GENERIC_WRITE; - DWORD ShareMode=ShareRead ? FILE_SHARE_READ:0; - if (WinNT() && NameW!=NULL && *NameW!=0) - hFile=CreateFileW(NameW,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL); - else - hFile=CreateFileA(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL); -#else - hFile=fopen(Name,WriteMode ? WRITEBINARY:CREATEBINARY); -#endif - NewFile=true; - HandleType=FILE_HANDLENORMAL; - SkipClose=false; - if (NameW!=NULL) - wcscpy(FileNameW,NameW); - else - *FileNameW=0; - if (Name!=NULL) - strcpy(FileName,Name); - else - WideToChar(NameW,FileName); - AddFileToList(hFile); - return(hFile!=BAD_HANDLE); -} - - -void File::AddFileToList(FileHandle hFile) -{ - if (hFile!=BAD_HANDLE) - for (int I=0;ISize && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff) - ErrHandler.WriteErrorFAT(FileName,FileNameW); -#endif - if (ErrHandler.AskRepeatWrite(FileName,FileNameW,false)) - { -#ifndef _WIN_ALL - clearerr(hFile); -#endif - if (Written0) - Seek(Tell()-Written,SEEK_SET); - continue; - } - ErrHandler.WriteError(NULL,NULL,FileName,FileNameW); - } - break; - } - LastWrite=true; -} - - -int File::Read(void *Data,size_t Size) -{ - int64 FilePos=0; // Initialized only to suppress some compilers warning. - - if (IgnoreReadErrors) - FilePos=Tell(); - int ReadSize; - while (true) - { - ReadSize=DirectRead(Data,Size); - if (ReadSize==-1) - { - ErrorType=FILE_READERROR; - if (AllowExceptions) - if (IgnoreReadErrors) - { - ReadSize=0; - for (size_t I=0;IMaxDeviceRead) - Size=MaxDeviceRead; - hFile=GetStdHandle(STD_INPUT_HANDLE); -#else - hFile=stdin; -#endif - } -#endif -#ifdef _WIN_ALL - DWORD Read; - if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL)) - { - if (IsDevice() && Size>MaxDeviceRead) - return(DirectRead(Data,MaxDeviceRead)); - if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE) - return(0); - return(-1); - } - return(Read); -#else - if (LastWrite) - { - fflush(hFile); - LastWrite=false; - } - clearerr(hFile); - size_t ReadSize=fread(Data,1,Size,hFile); - if (ferror(hFile)) - return(-1); - return((int)ReadSize); -#endif -} - - -void File::Seek(int64 Offset,int Method) -{ - if (!RawSeek(Offset,Method) && AllowExceptions) - ErrHandler.SeekError(FileName,FileNameW); -} - - -bool File::RawSeek(int64 Offset,int Method) -{ - if (hFile==BAD_HANDLE) - return(true); - if (Offset<0 && Method!=SEEK_SET) - { - Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset; - Method=SEEK_SET; - } -#ifdef _WIN_ALL - LONG HighDist=(LONG)(Offset>>32); - if (SetFilePointer(hFile,(LONG)Offset,&HighDist,Method)==0xffffffff && - GetLastError()!=NO_ERROR) - return(false); -#else - LastWrite=false; -#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS) - if (fseeko(hFile,Offset,Method)!=0) -#else - if (fseek(hFile,(long)Offset,Method)!=0) -#endif - return(false); -#endif - return(true); -} - - -int64 File::Tell() -{ - if (hFile==BAD_HANDLE) - if (AllowExceptions) - ErrHandler.SeekError(FileName,FileNameW); - else - return(-1); -#ifdef _WIN_ALL - LONG HighDist=0; - uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT); - if (LowDist==0xffffffff && GetLastError()!=NO_ERROR) - if (AllowExceptions) - ErrHandler.SeekError(FileName,FileNameW); - else - return(-1); - return(INT32TO64(HighDist,LowDist)); -#else -#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) - return(ftello(hFile)); -#else - return(ftell(hFile)); -#endif -#endif -} - - -void File::Prealloc(int64 Size) -{ -#ifdef _WIN_ALL - if (RawSeek(Size,SEEK_SET)) - { - Truncate(); - Seek(0,SEEK_SET); - } -#endif - -#if defined(_UNIX) && defined(USE_FALLOCATE) - // fallocate is rather new call. Only latest kernels support it. - // So we are not using it by default yet. - int fd = fileno(hFile); - if (fd >= 0) - fallocate(fd, 0, 0, Size); -#endif -} - - -byte File::GetByte() -{ - byte Byte=0; - Read(&Byte,1); - return(Byte); -} - - -void File::PutByte(byte Byte) -{ - Write(&Byte,1); -} - - -bool File::Truncate() -{ -#ifdef _WIN_ALL - return(SetEndOfFile(hFile)==TRUE); -#else - return(false); -#endif -} - - -void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta) -{ -#ifdef _WIN_ALL - // Workaround for OpenIndiana NAS time bug. If we cannot create a file - // in write only mode, we need to flush the write buffer before calling - // SetFileTime or file time will not be changed. - if (CreateMode!=FMF_UNDEFINED && (CreateMode & FMF_WRITE)==0) - FlushFileBuffers(hFile); - - bool sm=ftm!=NULL && ftm->IsSet(); - bool sc=ftc!=NULL && ftc->IsSet(); - bool sa=fta!=NULL && fta->IsSet(); - FILETIME fm,fc,fa; - if (sm) - ftm->GetWin32(&fm); - if (sc) - ftc->GetWin32(&fc); - if (sa) - fta->GetWin32(&fa); - SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL); -#endif -} - - -void File::SetCloseFileTime(RarTime *ftm,RarTime *fta) -{ -#if defined(_UNIX) || defined(_EMX) - SetCloseFileTimeByName(FileName,ftm,fta); -#endif -} - - -void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta) -{ -#if defined(_UNIX) || defined(_EMX) - bool setm=ftm!=NULL && ftm->IsSet(); - bool seta=fta!=NULL && fta->IsSet(); - if (setm || seta) - { - utimbuf ut; - if (setm) - ut.modtime=ftm->GetUnix(); - else - ut.modtime=fta->GetUnix(); - if (seta) - ut.actime=fta->GetUnix(); - else - ut.actime=ut.modtime; - utime(Name,&ut); - } -#endif -} - - -void File::GetOpenFileTime(RarTime *ft) -{ -#ifdef _WIN_ALL - FILETIME FileTime; - GetFileTime(hFile,NULL,NULL,&FileTime); - *ft=FileTime; -#endif -#if defined(_UNIX) || defined(_EMX) - struct stat st; - fstat(fileno(hFile),&st); - *ft=st.st_mtime; -#endif -} - - -int64 File::FileLength() -{ - SaveFilePos SavePos(*this); - Seek(0,SEEK_END); - return(Tell()); -} - - -void File::SetHandleType(FILE_HANDLETYPE Type) -{ - HandleType=Type; -} - - -bool File::IsDevice() -{ - if (hFile==BAD_HANDLE) - return(false); -#ifdef _WIN_ALL - uint Type=GetFileType(hFile); - return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE); -#else - return(isatty(fileno(hFile))); -#endif -} - - -#ifndef SFX_MODULE -void File::fprintf(const char *fmt,...) -{ - va_list argptr; - va_start(argptr,fmt); - safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024]; - vsprintf(Msg,fmt,argptr); -#ifdef _WIN_ALL - for (int Src=0,Dest=0;;Src++) - { - char CurChar=Msg[Src]; - if (CurChar=='\n') - OutMsg[Dest++]='\r'; - OutMsg[Dest++]=CurChar; - if (CurChar==0) - break; - } -#else - strcpy(OutMsg,Msg); -#endif - Write(OutMsg,strlen(OutMsg)); - va_end(argptr); -} -#endif - - -bool File::RemoveCreated() -{ - RemoveCreatedActive++; - bool RetCode=true; - for (int I=0;ISetExceptions(false); - bool Success; - if (CreatedFiles[I]->NewFile) - Success=CreatedFiles[I]->Delete(); - else - Success=CreatedFiles[I]->Close(); - if (Success) - CreatedFiles[I]=NULL; - else - RetCode=false; - } - RemoveCreatedActive--; - return(RetCode); -} - - -#ifndef SFX_MODULE -int64 File::Copy(File &Dest,int64 Length) -{ - Array Buffer(0x10000); - int64 CopySize=0; - bool CopyAll=(Length==INT64NDF); - - while (CopyAll || Length>0) - { - Wait(); - size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size(); - int ReadSize=Read(&Buffer[0],SizeToRead); - if (ReadSize==0) - break; - Dest.Write(&Buffer[0],ReadSize); - CopySize+=ReadSize; - if (!CopyAll) - Length-=ReadSize; - } - return(CopySize); -} -#endif diff --git a/src/unrar/file.hpp b/src/unrar/file.hpp deleted file mode 100644 index 46fbe61d04..0000000000 --- a/src/unrar/file.hpp +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef _RAR_FILE_ -#define _RAR_FILE_ - -#ifdef _WIN_ALL -typedef HANDLE FileHandle; -#define BAD_HANDLE INVALID_HANDLE_VALUE -#else -typedef FILE* FileHandle; -#define BAD_HANDLE NULL -#endif - -class RAROptions; - -enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR}; - -enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR}; - -struct FileStat -{ - uint FileAttr; - uint FileTime; - int64 FileSize; - bool IsDir; -}; - - -enum FILE_MODE_FLAGS { - // Request read only access to file. Default for Open. - FMF_READ=0, - - // Request both read and write access to file. Default for Create. - FMF_UPDATE=1, - - // Request write only access to file. - FMF_WRITE=2, - - // Open files which are already opened for write by other programs. - FMF_OPENSHARED=4, - - // Provide read access to created file for other programs. - FMF_SHAREREAD=8, - - // Mode flags are not defined yet. - FMF_UNDEFINED=256 -}; - - -class File -{ - private: - void AddFileToList(FileHandle hFile); - - FileHandle hFile; - bool LastWrite; - FILE_HANDLETYPE HandleType; - bool SkipClose; - bool IgnoreReadErrors; - bool NewFile; - bool AllowDelete; - bool AllowExceptions; -#ifdef _WIN_ALL - bool NoSequentialRead; - uint CreateMode; -#endif - protected: - bool OpenShared; // Set by 'Archive' class. - public: - char FileName[NM]; - wchar FileNameW[NM]; - - FILE_ERRORTYPE ErrorType; - - uint CloseCount; - public: - File(); - virtual ~File(); - void operator = (File &SrcFile); - bool Open(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_READ); - void TOpen(const char *Name,const wchar *NameW=NULL); - bool WOpen(const char *Name,const wchar *NameW=NULL); - virtual bool Create(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid - virtual void TCreate(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid - virtual bool WCreate(const char *Name,const wchar *NameW=NULL,uint Mode=FMF_UPDATE|FMF_SHAREREAD); // virtual added by Kovid - virtual bool Close(); // virtual added by Kovid - virtual void Flush(); // virtual added by Kovid - virtual bool Delete(); // virtual added by Kovid - virtual bool Rename(const char *NewName,const wchar *NewNameW=NULL); // virtual added by Kovid - virtual void Write(const void *Data,size_t Size); // virtual added by Kovid - virtual int Read(void *Data,size_t Size); // virtual added by Kovid - virtual int DirectRead(void *Data,size_t Size); // virtual added by Kovid - virtual void Seek(int64 Offset,int Method); // virtual added by Kovid - virtual bool RawSeek(int64 Offset,int Method); // virtual added by Kovid - virtual int64 Tell(); // virtual added by Kovid - virtual void Prealloc(int64 Size); // virtual added by Kovid - virtual byte GetByte(); // virtual added by Kovid - virtual void PutByte(byte Byte); // virtual added by Kovid - virtual bool Truncate(); // virtual added by Kovid - virtual void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL); // virtual added by Kovid - virtual void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL); // virtual added by Kovid - static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta); - virtual void GetOpenFileTime(RarTime *ft); // virtual added by Kovid - virtual bool IsOpened() {return(hFile!=BAD_HANDLE);}; // virtual added by Kovid - virtual int64 FileLength(); // virtual added by Kovid - virtual void SetHandleType(FILE_HANDLETYPE Type); // virtual added by Kovid - virtual FILE_HANDLETYPE GetHandleType() {return(HandleType);}; // virtual added by Kovid - virtual bool IsDevice(); // virtual added by Kovid - virtual void fprintf(const char *fmt,...); // virtual added by Kovid - static bool RemoveCreated(); - virtual FileHandle GetHandle() {return(hFile);}; // virtual added by Kovid - virtual void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;}; // virtual added by Kovid - virtual char *GetName() {return(FileName);} // virtual added by Kovid - virtual int64 Copy(File &Dest,int64 Length=INT64NDF); // virtual added by Kovid - virtual void SetAllowDelete(bool Allow) {AllowDelete=Allow;} // virtual added by Kovid - virtual void SetExceptions(bool Allow) {AllowExceptions=Allow;} // virtual added by Kovid -#ifdef _WIN_ALL - virtual void RemoveSequentialFlag() {NoSequentialRead=true;} // virtual added by Kovid -#endif -}; - -#endif diff --git a/src/unrar/filefn.cpp b/src/unrar/filefn.cpp deleted file mode 100644 index e7cc8fd6b0..0000000000 --- a/src/unrar/filefn.cpp +++ /dev/null @@ -1,564 +0,0 @@ -#include "rar.hpp" - -MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr) -{ -#ifdef _WIN_ALL - BOOL RetCode; - if (WinNT() && NameW!=NULL && *NameW!=0) - RetCode=CreateDirectoryW(NameW,NULL); - else - if (Name!=NULL) - RetCode=CreateDirectoryA(Name,NULL); - else - return(MKDIR_BADPATH); - if (RetCode!=0) // Non-zero return code means success for CreateDirectory. - { - if (SetAttr) - SetFileAttr(Name,NameW,Attr); - return(MKDIR_SUCCESS); - } - int ErrCode=GetLastError(); - if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND) - return(MKDIR_BADPATH); - return(MKDIR_ERROR); -#else - - // No Unicode in the rest of function, so Name must be not NULL. - if (Name==NULL) - return(MKDIR_BADPATH); -#endif - -#ifdef _EMX - #ifdef _DJGPP - if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0) - #else - if (__mkdir(Name)==0) - #endif - { - if (SetAttr) - SetFileAttr(Name,NameW,Attr); - return(MKDIR_SUCCESS); - } - return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); -#endif - -#ifdef _UNIX - mode_t uattr=SetAttr ? (mode_t)Attr:0777; - int ErrCode=mkdir(Name,uattr); - if (ErrCode==-1) - return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR); - return(MKDIR_SUCCESS); -#endif -} - - -bool CreatePath(const char *Path,bool SkipLastName) -{ - if (Path==NULL || *Path==0) - return(false); - -#if defined(_WIN_ALL) || defined(_EMX) - uint DirAttr=0; -#else - uint DirAttr=0777; -#endif - - bool Success=true; - - for (const char *s=Path;*s!=0;s=charnext(s)) - { - if (s-Path>=NM) - break; - - // Process all kinds of path separators, so user can enter Unix style - // path in Windows or Windows in Unix. - if (IsPathDiv(*s)) - { - char DirName[NM]; - strncpy(DirName,Path,s-Path); - DirName[s-Path]=0; - - if (MakeDir(DirName,NULL,true,DirAttr)==MKDIR_SUCCESS) - { -#ifndef GUI - mprintf(St(MCreatDir),DirName); - mprintf(" %s",St(MOk)); -#endif - } - else - Success=false; - } - } - if (!SkipLastName) - if (!IsPathDiv(*PointToLastChar(Path))) - if (MakeDir(Path,NULL,true,DirAttr)!=MKDIR_SUCCESS) - Success=false; - return(Success); -} - - -bool CreatePath(const wchar *Path,bool SkipLastName) -{ - if (Path==NULL || *Path==0) - return(false); - -#if defined(_WIN_ALL) || defined(_EMX) - uint DirAttr=0; -#else - uint DirAttr=0777; -#endif - - bool Success=true; - - for (const wchar *s=Path;*s!=0;s++) - { - if (s-Path>=NM) - break; - - // Process all kinds of path separators, so user can enter Unix style - // path in Windows or Windows in Unix. - if (IsPathDiv(*s)) - { - wchar DirName[NM]; - wcsncpy(DirName,Path,s-Path); - DirName[s-Path]=0; - - if (MakeDir(NULL,DirName,true,DirAttr)==MKDIR_SUCCESS) - { -#ifndef GUI - char DirNameA[NM]; - WideToChar(DirName,DirNameA,ASIZE(DirNameA)); - DirNameA[ASIZE(DirNameA)-1]=0; - mprintf(St(MCreatDir),DirNameA); - mprintf(" %s",St(MOk)); -#endif - } - else - Success=false; - } - } - if (!SkipLastName) - if (!IsPathDiv(*PointToLastChar(Path))) - if (MakeDir(NULL,Path,true,DirAttr)!=MKDIR_SUCCESS) - Success=false; - return(Success); -} - - -bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName) -{ -#ifdef _WIN_ALL - // If we are in Windows, let's try Unicode path first. In Unix we do not - // need it (Unix MakeDir will fails with Unicode only name). - if (PathW!=NULL && *PathW!=0) - return(CreatePath(PathW,SkipLastName)); -#endif - if (Path!=NULL && *Path!=0) - return(CreatePath(Path,SkipLastName)); - return(false); -} - - -void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta) -{ -#ifdef _WIN_ALL - if (!WinNT()) - return; - - bool sm=ftm!=NULL && ftm->IsSet(); - bool sc=ftc!=NULL && ftc->IsSet(); - bool sa=fta!=NULL && fta->IsSet(); - - unsigned int DirAttr=GetFileAttr(Name,NameW); - bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0); - if (ResetAttr) - SetFileAttr(Name,NameW,0); - - wchar DirNameW[NM]; - GetWideName(Name,NameW,DirNameW,ASIZE(DirNameW)); - HANDLE hFile=CreateFileW(DirNameW,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL); - if (hFile==INVALID_HANDLE_VALUE) - return; - FILETIME fm,fc,fa; - if (sm) - ftm->GetWin32(&fm); - if (sc) - ftc->GetWin32(&fc); - if (sa) - fta->GetWin32(&fa); - SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL); - CloseHandle(hFile); - if (ResetAttr) - SetFileAttr(Name,NameW,DirAttr); -#endif -#if defined(_UNIX) || defined(_EMX) - File::SetCloseFileTimeByName(Name,ftm,fta); -#endif -} - - -bool IsRemovable(const char *Name) -{ -#ifdef _WIN_ALL - char Root[NM]; - GetPathRoot(Name,Root); - int Type=GetDriveTypeA(*Root!=0 ? Root:NULL); - return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM); -#elif defined(_EMX) - char Drive=etoupper(Name[0]); - return((Drive=='A' || Drive=='B') && Name[1]==':'); -#else - return(false); -#endif -} - - - - -#ifndef SFX_MODULE -int64 GetFreeDisk(const char *Name) -{ -#ifdef _WIN_ALL - char Root[NM]; - GetPathRoot(Name,Root); - - typedef BOOL (WINAPI *GETDISKFREESPACEEX)( - LPCSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER - ); - static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL; - - if (pGetDiskFreeSpaceEx==NULL) - { - HMODULE hKernel=GetModuleHandleW(L"kernel32.dll"); - if (hKernel!=NULL) - pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA"); - } - if (pGetDiskFreeSpaceEx!=NULL) - { - GetFilePath(Name,Root,ASIZE(Root)); - ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree; - uiUserFree.u.LowPart=uiUserFree.u.HighPart=0; - if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) && - uiUserFree.u.HighPart<=uiTotalFree.u.HighPart) - return(INT32TO64(uiUserFree.u.HighPart,uiUserFree.u.LowPart)); - } - - // We are here if we failed to load GetDiskFreeSpaceExA. - DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters; - if (!GetDiskFreeSpaceA(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters)) - return(1457664); - int64 FreeSize=SectorsPerCluster*BytesPerSector; - FreeSize=FreeSize*FreeClusters; - return(FreeSize); -#elif defined(_BEOS) - char Root[NM]; - GetFilePath(Name,Root,ASIZE(Root)); - dev_t Dev=dev_for_path(*Root ? Root:"."); - if (Dev<0) - return(1457664); - fs_info Info; - if (fs_stat_dev(Dev,&Info)!=0) - return(1457664); - int64 FreeSize=Info.block_size; - FreeSize=FreeSize*Info.free_blocks; - return(FreeSize); -#elif defined(_UNIX) - return(1457664); -#elif defined(_EMX) - int Drive=IsDiskLetter(Name) ? etoupper(Name[0])-'A'+1:0; -#ifndef _DJGPP - if (_osmode == OS2_MODE) - { - FSALLOCATE fsa; - if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0) - return(1457664); - int64 FreeSize=fsa.cSectorUnit*fsa.cbSector; - FreeSize=FreeSize*fsa.cUnitAvail; - return(FreeSize); - } - else -#endif - { - union REGS regs,outregs; - memset(®s,0,sizeof(regs)); - regs.h.ah=0x36; - regs.h.dl=Drive; -#ifdef _DJGPP - int86 (0x21,®s,&outregs); -#else - _int86 (0x21,®s,&outregs); -#endif - if (outregs.x.ax==0xffff) - return(1457664); - int64 FreeSize=outregs.x.ax*outregs.x.cx; - FreeSize=FreeSize*outregs.x.bx; - return(FreeSize); - } -#else - #define DISABLEAUTODETECT - return(1457664); -#endif -} -#endif - - - - - -bool FileExist(const char *Name,const wchar *NameW) -{ -#ifdef _WIN_ALL - if (WinNT() && NameW!=NULL && *NameW!=0) - return(GetFileAttributesW(NameW)!=0xffffffff); - else - return(Name!=NULL && GetFileAttributesA(Name)!=0xffffffff); -#elif defined(ENABLE_ACCESS) - return(access(Name,0)==0); -#else - FindData FD; - return(FindFile::FastFind(Name,NameW,&FD)); -#endif -} - - -bool FileExist(const wchar *Name) -{ - return FileExist(NULL,Name); -} - - -bool WildFileExist(const char *Name,const wchar *NameW) -{ - if (IsWildcard(Name,NameW)) - { - FindFile Find; - Find.SetMask(Name); - Find.SetMaskW(NameW); - FindData fd; - return(Find.Next(&fd)); - } - return(FileExist(Name,NameW)); -} - - -bool IsDir(uint Attr) -{ -#if defined (_WIN_ALL) || defined(_EMX) - return(Attr!=0xffffffff && (Attr & 0x10)!=0); -#endif -#if defined(_UNIX) - return((Attr & 0xF000)==0x4000); -#endif -} - - -bool IsUnreadable(uint Attr) -{ -#if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR) - return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr)); -#endif - return(false); -} - - -bool IsLabel(uint Attr) -{ -#if defined (_WIN_ALL) || defined(_EMX) - return((Attr & 8)!=0); -#else - return(false); -#endif -} - - -bool IsLink(uint Attr) -{ -#ifdef _UNIX - return((Attr & 0xF000)==0xA000); -#else - return(false); -#endif -} - - - - - - -bool IsDeleteAllowed(uint FileAttr) -{ -#if defined(_WIN_ALL) || defined(_EMX) - return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0); -#else - return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR)); -#endif -} - - -void PrepareToDelete(const char *Name,const wchar *NameW) -{ -#if defined(_WIN_ALL) || defined(_EMX) - SetFileAttr(Name,NameW,0); -#endif -#ifdef _UNIX - if (Name!=NULL) - chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR); -#endif -} - - -uint GetFileAttr(const char *Name,const wchar *NameW) -{ -#ifdef _WIN_ALL - if (WinNT() && NameW!=NULL && *NameW!=0) - return(GetFileAttributesW(NameW)); - else - return(GetFileAttributesA(Name)); -#elif defined(_DJGPP) - return(_chmod(Name,0)); -#else - struct stat st; - if (stat(Name,&st)!=0) - return(0); -#ifdef _EMX - return(st.st_attr); -#else - return(st.st_mode); -#endif -#endif -} - - -bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr) -{ - bool Success; -#ifdef _WIN_ALL - if (WinNT() && NameW!=NULL && *NameW!=0) - Success=SetFileAttributesW(NameW,Attr)!=0; - else - if (Name!=NULL) - Success=SetFileAttributesA(Name,Attr)!=0; - else - Success=false; -#elif defined(_DJGPP) - Success=_chmod(Name,1,Attr)!=-1; -#elif defined(_EMX) - Success=__chmod(Name,1,Attr)!=-1; -#elif defined(_UNIX) - Success=chmod(Name,(mode_t)Attr)==0; -#else - Success=false; -#endif - return(Success); -} - - - - -#ifndef SFX_MODULE -uint CalcFileCRC(File *SrcFile,int64 Size,CALCCRC_SHOWMODE ShowMode) -{ - SaveFilePos SavePos(*SrcFile); - const size_t BufSize=0x10000; - Array Data(BufSize); - int64 BlockCount=0; - uint DataCRC=0xffffffff; - -#if !defined(SILENT) && !defined(_WIN_CE) - int64 FileLength=SrcFile->FileLength(); - if (ShowMode!=CALCCRC_SHOWNONE) - { - mprintf(St(MCalcCRC)); - mprintf(" "); - } - -#endif - - SrcFile->Seek(0,SEEK_SET); - while (true) - { - size_t SizeToRead; - if (Size==INT64NDF) // If we process the entire file. - SizeToRead=BufSize; // Then always attempt to read the entire buffer. - else - SizeToRead=(size_t)Min((int64)BufSize,Size); - int ReadSize=SrcFile->Read(&Data[0],SizeToRead); - if (ReadSize==0) - break; - - ++BlockCount; - if ((BlockCount & 15)==0) - { -#if !defined(SILENT) && !defined(_WIN_CE) - if (ShowMode==CALCCRC_SHOWALL) - mprintf("\b\b\b\b%3d%%",ToPercent(BlockCount*int64(BufSize),FileLength)); -#endif - Wait(); - } - DataCRC=CRC(DataCRC,&Data[0],ReadSize); - if (Size!=INT64NDF) - Size-=ReadSize; - } -#if !defined(SILENT) && !defined(_WIN_CE) - if (ShowMode==CALCCRC_SHOWALL) - mprintf("\b\b\b\b "); -#endif - return(DataCRC^0xffffffff); -} -#endif - - -bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW) -{ - return(rename(SrcName,DestName)==0); -} - - -bool DelFile(const char *Name) -{ - return(DelFile(Name,NULL)); -} - - - - -bool DelFile(const char *Name,const wchar *NameW) -{ - return(Name!=NULL && remove(Name)==0); -} - - - - - - - - -#if defined(_WIN_ALL) && !defined(_WIN_CE) && !defined(SFX_MODULE) -bool SetFileCompression(char *Name,wchar *NameW,bool State) -{ - wchar FileNameW[NM]; - GetWideName(Name,NameW,FileNameW,ASIZE(FileNameW)); - HANDLE hFile=CreateFileW(FileNameW,FILE_READ_DATA|FILE_WRITE_DATA, - FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL); - if (hFile==INVALID_HANDLE_VALUE) - return(false); - SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE; - DWORD Result; - int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState, - sizeof(NewState),NULL,0,&Result,NULL); - CloseHandle(hFile); - return(RetCode!=0); -} -#endif - - - - - - - - - diff --git a/src/unrar/filefn.hpp b/src/unrar/filefn.hpp deleted file mode 100644 index bdf193e80d..0000000000 --- a/src/unrar/filefn.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef _RAR_FILEFN_ -#define _RAR_FILEFN_ - -enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH}; - -MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,bool SetAttr,uint Attr); -bool CreatePath(const char *Path,bool SkipLastName); -bool CreatePath(const wchar *Path,bool SkipLastName); -bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName); -void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta); -bool IsRemovable(const char *Name); - -#ifndef SFX_MODULE -int64 GetFreeDisk(const char *Name); -#endif - - -bool FileExist(const char *Name,const wchar *NameW=NULL); -bool FileExist(const wchar *Name); -bool WildFileExist(const char *Name,const wchar *NameW=NULL); -bool IsDir(uint Attr); -bool IsUnreadable(uint Attr); -bool IsLabel(uint Attr); -bool IsLink(uint Attr); -void SetSFXMode(const char *FileName); -void EraseDiskContents(const char *FileName); -bool IsDeleteAllowed(uint FileAttr); -void PrepareToDelete(const char *Name,const wchar *NameW=NULL); -uint GetFileAttr(const char *Name,const wchar *NameW=NULL); -bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr); - -enum CALCCRC_SHOWMODE {CALCCRC_SHOWNONE,CALCCRC_SHOWTEXT,CALCCRC_SHOWALL}; -uint CalcFileCRC(File *SrcFile,int64 Size=INT64NDF,CALCCRC_SHOWMODE ShowMode=CALCCRC_SHOWNONE); - -bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW); -bool DelFile(const char *Name); -bool DelFile(const char *Name,const wchar *NameW); -bool DelDir(const char *Name); -bool DelDir(const char *Name,const wchar *NameW); - -#if defined(_WIN_ALL) && !defined(_WIN_CE) -bool SetFileCompression(char *Name,wchar *NameW,bool State); -#endif - - - - -#endif diff --git a/src/unrar/filestr.cpp b/src/unrar/filestr.cpp deleted file mode 100644 index 49e865b9ae..0000000000 --- a/src/unrar/filestr.cpp +++ /dev/null @@ -1,208 +0,0 @@ -#include "rar.hpp" - -static bool IsUnicode(byte *Data,int Size); - -bool ReadTextFile( - const char *Name, - const wchar *NameW, - StringList *List, - bool Config, - bool AbortOnError, - RAR_CHARSET SrcCharset, - bool Unquote, - bool SkipComments, - bool ExpandEnvStr) -{ - char FileName[NM]; - *FileName=0; - if (Name!=NULL) - if (Config) - GetConfigName(Name,FileName,true); - else - strcpy(FileName,Name); - - wchar FileNameW[NM]; - *FileNameW=0; - -#ifdef _WIN_ALL - if (NameW!=NULL) - if (Config) - GetConfigName(NameW,FileNameW,true); - else - wcscpy(FileNameW,NameW); -#endif - - File SrcFile; - if (FileName!=NULL && *FileName!=0 || FileNameW!=NULL && *FileNameW!=0) - { - bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName,FileNameW):SrcFile.Open(FileName,FileNameW,0); - - if (!OpenCode) - { - if (AbortOnError) - ErrHandler.Exit(RARX_OPEN); - return(false); - } - } - else - SrcFile.SetHandleType(FILE_HANDLESTD); - - unsigned int DataSize=0,ReadSize; - const int ReadBlock=1024; - Array Data(ReadBlock+5); - while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0) - { - DataSize+=ReadSize; - Data.Add(ReadSize); - } - - memset(&Data[DataSize],0,5); - - if (SrcCharset==RCH_UNICODE || - SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize)) - { - // Unicode in native system format, can be more than 2 bytes per character. - Array DataW(Data.Size()/2+1); - for (size_t I=2;I AnsiName; - - while (*CurStr!=0) - { - wchar *NextStr=CurStr,*CmtPtr=NULL; - while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) - { - if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') - { - *NextStr=0; - CmtPtr=NextStr; - } - NextStr++; - } - *NextStr=0; - for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) - { - if (*SpacePtr!=' ' && *SpacePtr!='\t') - break; - *SpacePtr=0; - } - if (*CurStr) - { - // Length and AddSize must be defined as signed, because AddSize - // can be negative. - int Length=(int)wcslen(CurStr); - int AddSize=4*(Length-(int)AnsiName.Size()+1); - - if (AddSize>0) - AnsiName.Add(AddSize); - if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"') - { - CurStr[Length-1]=0; - CurStr++; - } - WideToChar(CurStr,&AnsiName[0],AnsiName.Size()); - - bool Expanded=false; -#if defined(_WIN_ALL) && !defined(_WIN_CE) - if (ExpandEnvStr && *CurStr=='%') - { - // Expanding environment variables in Windows version. - - char ExpName[NM]; - wchar ExpNameW[NM]; - *ExpNameW=0; - int ret,retw=1; - ret=ExpandEnvironmentStringsA(&AnsiName[0],ExpName,ASIZE(ExpName)); - if (ret!=0 && WinNT()) - retw=ExpandEnvironmentStringsW(CurStr,ExpNameW,ASIZE(ExpNameW)); - Expanded=ret!=0 && retAddString(ExpName,ExpNameW); - } -#endif - if (!Expanded) - List->AddString(&AnsiName[0],CurStr); - } - CurStr=NextStr+1; - while (*CurStr=='\r' || *CurStr=='\n') - CurStr++; - } - } - else - { - char *CurStr=&Data[0]; - while (*CurStr!=0) - { - char *NextStr=CurStr,*CmtPtr=NULL; - while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0) - { - if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/') - { - *NextStr=0; - CmtPtr=NextStr; - } - NextStr++; - } - *NextStr=0; - for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--) - { - if (*SpacePtr!=' ' && *SpacePtr!='\t') - break; - *SpacePtr=0; - } - if (*CurStr) - { - if (Unquote && *CurStr=='\"') - { - size_t Length=strlen(CurStr); - if (CurStr[Length-1]=='\"') - { - CurStr[Length-1]=0; - CurStr++; - } - } -#if defined(_WIN_ALL) - if (SrcCharset==RCH_OEM) - OemToCharA(CurStr,CurStr); -#endif - - bool Expanded=false; -#if defined(_WIN_ALL) && !defined(_WIN_CE) - if (ExpandEnvStr && *CurStr=='%') - { - // Expanding environment variables in Windows version. - char ExpName[NM]; - int ret=ExpandEnvironmentStringsA(CurStr,ExpName,ASIZE(ExpName)); - Expanded=ret!=0 && retAddString(ExpName); - } -#endif - if (!Expanded) - List->AddString(CurStr); - } - CurStr=NextStr+1; - while (*CurStr=='\r' || *CurStr=='\n') - CurStr++; - } - } - return(true); -} - - -bool IsUnicode(byte *Data,int Size) -{ - if (Size<4 || Data[0]!=0xff || Data[1]!=0xfe) - return(false); - for (int I=2;IError=false; - if (*FindMask==0) - return(false); -#ifdef _WIN_ALL - if (FirstCall) - { - if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE) - return(false); - } - else - if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE) - return(false); -#else - if (FirstCall) - { - char DirName[NM]; - strcpy(DirName,FindMask); - RemoveNameFromPath(DirName); - if (*DirName==0) - strcpy(DirName,"."); - if ((dirp=opendir(DirName))==NULL) - { - fd->Error=(errno!=ENOENT); - return(false); - } - } - while (1) - { - struct dirent *ent=readdir(dirp); - if (ent==NULL) - return(false); - if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0) - continue; - if (CmpName(FindMask,ent->d_name,MATCH_NAMES)) - { - char FullName[NM]; - strcpy(FullName,FindMask); - *PointToName(FullName)=0; - if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1) - { -#ifndef SILENT - Log(NULL,"\n%s%s",FullName,ent->d_name); - Log(NULL,St(MPathTooLong)); -#endif - return(false); - } - strcat(FullName,ent->d_name); - if (!FastFind(FullName,NULL,fd,GetSymLink)) - { - ErrHandler.OpenErrorMsg(FullName); - continue; - } - strcpy(fd->Name,FullName); - break; - } - } - *fd->NameW=0; -#ifdef _APPLE - if (!LowAscii(fd->Name)) - UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW)); -#elif defined(UNICODE_SUPPORTED) - if (!LowAscii(fd->Name) && UnicodeEnabled()) - CharToWide(fd->Name,fd->NameW); -#endif -#endif - fd->Flags=0; - fd->IsDir=IsDir(fd->FileAttr); - FirstCall=false; - char *Name=PointToName(fd->Name); - if (strcmp(Name,".")==0 || strcmp(Name,"..")==0) - return(Next(fd)); - return(true); -} - - -bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,FindData *fd,bool GetSymLink) -{ - fd->Error=false; -#ifndef _UNIX - if (IsWildcard(FindMask,FindMaskW)) - return(false); -#endif -#ifdef _WIN_ALL - HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd); - if (hFind==INVALID_HANDLE_VALUE) - return(false); - FindClose(hFind); -#else - struct stat st; - if (GetSymLink) - { -#ifdef SAVE_LINKS - if (lstat(FindMask,&st)!=0) -#else - if (stat(FindMask,&st)!=0) -#endif - { - fd->Error=(errno!=ENOENT); - return(false); - } - } - else - if (stat(FindMask,&st)!=0) - { - fd->Error=(errno!=ENOENT); - return(false); - } -#ifdef _DJGPP - fd->FileAttr=_chmod(FindMask,0); -#elif defined(_EMX) - fd->FileAttr=st.st_attr; -#else - fd->FileAttr=st.st_mode; -#endif - fd->IsDir=IsDir(st.st_mode); - fd->Size=st.st_size; - fd->mtime=st.st_mtime; - fd->atime=st.st_atime; - fd->ctime=st.st_ctime; - fd->FileTime=fd->mtime.GetDos(); - strcpy(fd->Name,FindMask); - - *fd->NameW=0; -#ifdef _APPLE - if (!LowAscii(fd->Name)) - UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW)); -#elif defined(UNICODE_SUPPORTED) - if (!LowAscii(fd->Name) && UnicodeEnabled()) - CharToWide(fd->Name,fd->NameW); -#endif -#endif - fd->Flags=0; - fd->IsDir=IsDir(fd->FileAttr); - return(true); -} - - -#ifdef _WIN_ALL -HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,FindData *fd) -{ -#ifndef _WIN_CE - if (WinNT()) -#endif - { - wchar WideMask[NM]; - if (MaskW!=NULL && *MaskW!=0) - wcscpy(WideMask,MaskW); - else - CharToWide(Mask,WideMask); - - WIN32_FIND_DATAW FindData; - if (hFind==INVALID_HANDLE_VALUE) - { - hFind=FindFirstFileW(WideMask,&FindData); - if (hFind==INVALID_HANDLE_VALUE) - { - int SysErr=GetLastError(); - fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND && - SysErr!=ERROR_PATH_NOT_FOUND && - SysErr!=ERROR_NO_MORE_FILES); - } - } - else - if (!FindNextFileW(hFind,&FindData)) - { - hFind=INVALID_HANDLE_VALUE; - fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; - } - - if (hFind!=INVALID_HANDLE_VALUE) - { - wcscpy(fd->NameW,WideMask); - wcscpy(PointToName(fd->NameW),FindData.cFileName); - WideToChar(fd->NameW,fd->Name); - fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow); - fd->FileAttr=FindData.dwFileAttributes; - wcscpy(fd->ShortName,FindData.cAlternateFileName); - fd->ftCreationTime=FindData.ftCreationTime; - fd->ftLastAccessTime=FindData.ftLastAccessTime; - fd->ftLastWriteTime=FindData.ftLastWriteTime; - fd->mtime=FindData.ftLastWriteTime; - fd->ctime=FindData.ftCreationTime; - fd->atime=FindData.ftLastAccessTime; - fd->FileTime=fd->mtime.GetDos(); - -#ifndef _WIN_CE -// if (LowAscii(fd->NameW)) -// *fd->NameW=0; -#endif - } - } -#ifndef _WIN_CE - else - { - char CharMask[NM]; - if (Mask!=NULL && *Mask!=0) - strcpy(CharMask,Mask); - else - WideToChar(MaskW,CharMask); - - WIN32_FIND_DATAA FindData; - if (hFind==INVALID_HANDLE_VALUE) - { - hFind=FindFirstFileA(CharMask,&FindData); - if (hFind==INVALID_HANDLE_VALUE) - { - int SysErr=GetLastError(); - fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND; - } - } - else - if (!FindNextFileA(hFind,&FindData)) - { - hFind=INVALID_HANDLE_VALUE; - fd->Error=GetLastError()!=ERROR_NO_MORE_FILES; - } - - if (hFind!=INVALID_HANDLE_VALUE) - { - strcpy(fd->Name,CharMask); - strcpy(PointToName(fd->Name),FindData.cFileName); - CharToWide(fd->Name,fd->NameW); - fd->Size=INT32TO64(FindData.nFileSizeHigh,FindData.nFileSizeLow); - fd->FileAttr=FindData.dwFileAttributes; - CharToWide(FindData.cAlternateFileName,fd->ShortName); - fd->ftCreationTime=FindData.ftCreationTime; - fd->ftLastAccessTime=FindData.ftLastAccessTime; - fd->ftLastWriteTime=FindData.ftLastWriteTime; - fd->mtime=FindData.ftLastWriteTime; - fd->ctime=FindData.ftCreationTime; - fd->atime=FindData.ftLastAccessTime; - fd->FileTime=fd->mtime.GetDos(); -// if (LowAscii(fd->Name)) -// *fd->NameW=0; - } - } -#endif - fd->Flags=0; - return(hFind); -} -#endif - diff --git a/src/unrar/find.hpp b/src/unrar/find.hpp deleted file mode 100644 index 05f5d7f0e5..0000000000 --- a/src/unrar/find.hpp +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef _RAR_FINDDATA_ -#define _RAR_FINDDATA_ - -enum FINDDATA_FLAGS { - FDDF_SECONDDIR=1 // Second encounter of same directory in SCAN_GETDIRSTWICE ScanTree mode. -}; - -struct FindData -{ - char Name[NM]; - wchar NameW[NM]; - int64 Size; - uint FileAttr; - uint FileTime; - bool IsDir; - RarTime mtime; - RarTime ctime; - RarTime atime; -#ifdef _WIN_ALL - wchar ShortName[NM]; - FILETIME ftCreationTime; - FILETIME ftLastAccessTime; - FILETIME ftLastWriteTime; -#endif - uint Flags; - bool Error; -}; - -class FindFile -{ - private: -#ifdef _WIN_ALL - static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd); -#endif - - char FindMask[NM]; - wchar FindMaskW[NM]; - bool FirstCall; -#ifdef _WIN_ALL - HANDLE hFind; -#else - DIR *dirp; -#endif - public: - FindFile(); - ~FindFile(); - void SetMask(const char *FindMask); - void SetMaskW(const wchar *FindMaskW); - bool Next(FindData *fd,bool GetSymLink=false); - static bool FastFind(const char *FindMask,const wchar *FindMaskW,FindData *fd,bool GetSymLink=false); -}; - -#endif diff --git a/src/unrar/getbits.cpp b/src/unrar/getbits.cpp deleted file mode 100644 index 02b3a0b46b..0000000000 --- a/src/unrar/getbits.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "rar.hpp" - -BitInput::BitInput() -{ - // getbits attempts to read data from InAddr, InAddr+1, InAddr+2 positions. - // So let's allocate two additional bytes for situation, when we need to - // read only 1 byte from the last position of buffer and avoid a crash - // from access to next 2 bytes, which contents we do not need. - size_t BufSize=MAX_SIZE+2; - InBuf=new byte[BufSize]; - - // Ensure that we get predictable results when accessing bytes in area - // not filled with read data. - memset(InBuf,0,BufSize); -} - - -BitInput::~BitInput() -{ - delete[] InBuf; -} - - -void BitInput::faddbits(uint Bits) -{ - // Function wrapped version of inline addbits to save code size. - addbits(Bits); -} - - -uint BitInput::fgetbits() -{ - // Function wrapped version of inline getbits to save code size. - return(getbits()); -} diff --git a/src/unrar/getbits.hpp b/src/unrar/getbits.hpp deleted file mode 100644 index d44fb9f060..0000000000 --- a/src/unrar/getbits.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef _RAR_GETBITS_ -#define _RAR_GETBITS_ - -class BitInput -{ - public: - enum BufferSize {MAX_SIZE=0x8000}; // Size of input buffer. - protected: - int InAddr; // Curent byte position in the buffer. - int InBit; // Current bit position in the current byte. - public: - BitInput(); - ~BitInput(); - - byte *InBuf; // Dynamically allocated input buffer. - - void InitBitInput() - { - InAddr=InBit=0; - } - - // Move forward by 'Bits' bits. - void addbits(uint Bits) - { - Bits+=InBit; - InAddr+=Bits>>3; - InBit=Bits&7; - } - - // Return 16 bits from current position in the buffer. - // Bit at (InAddr,InBit) has the highest position in returning data. - uint getbits() - { - uint BitField=(uint)InBuf[InAddr] << 16; - BitField|=(uint)InBuf[InAddr+1] << 8; - BitField|=(uint)InBuf[InAddr+2]; - BitField >>= (8-InBit); - return(BitField & 0xffff); - } - - void faddbits(uint Bits); - uint fgetbits(); - - // Check if buffer has enough space for IncPtr bytes. Returns 'true' - // if buffer will be overflown. - bool Overflow(uint IncPtr) - { - return(InAddr+IncPtr>=MAX_SIZE); - } -}; -#endif diff --git a/src/unrar/global.cpp b/src/unrar/global.cpp deleted file mode 100644 index 593a057cbf..0000000000 --- a/src/unrar/global.cpp +++ /dev/null @@ -1,4 +0,0 @@ -#define INCLUDEGLOBAL - - -#include "rar.hpp" diff --git a/src/unrar/global.hpp b/src/unrar/global.hpp deleted file mode 100644 index 30eff082a6..0000000000 --- a/src/unrar/global.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _RAR_GLOBAL_ -#define _RAR_GLOBAL_ - -#ifdef INCLUDEGLOBAL - #define EXTVAR -#else - #define EXTVAR extern -#endif - -EXTVAR ErrorHandler ErrHandler; - - - - -#endif diff --git a/src/unrar/headers.hpp b/src/unrar/headers.hpp deleted file mode 100644 index 75343a258e..0000000000 --- a/src/unrar/headers.hpp +++ /dev/null @@ -1,327 +0,0 @@ -#ifndef _RAR_HEADERS_ -#define _RAR_HEADERS_ - -#define SIZEOF_MARKHEAD 7 -#define SIZEOF_OLDMHD 7 -#define SIZEOF_NEWMHD 13 -#define SIZEOF_OLDLHD 21 -#define SIZEOF_NEWLHD 32 -#define SIZEOF_SHORTBLOCKHEAD 7 -#define SIZEOF_LONGBLOCKHEAD 11 -#define SIZEOF_SUBBLOCKHEAD 14 -#define SIZEOF_COMMHEAD 13 -#define SIZEOF_PROTECTHEAD 26 -#define SIZEOF_AVHEAD 14 -#define SIZEOF_SIGNHEAD 15 -#define SIZEOF_UOHEAD 18 -#define SIZEOF_MACHEAD 22 -#define SIZEOF_EAHEAD 24 -#define SIZEOF_BEEAHEAD 24 -#define SIZEOF_STREAMHEAD 26 - -#define PACK_VER 29 -#define PACK_CRYPT_VER 29 -#define UNP_VER 36 -#define CRYPT_VER 29 -#define AV_VER 20 -#define PROTECT_VER 20 - - -#define MHD_VOLUME 0x0001U - -// Old style main archive comment embed into main archive header. Must not -// be used in new archives anymore. Must never be used with MHD_ENCRYPTVER -// or other flags changing the size of main header. RAR expects the fixed -// size of main header preceding the comment if MHD_COMMENT is found. -#define MHD_COMMENT 0x0002U - -#define MHD_LOCK 0x0004U -#define MHD_SOLID 0x0008U -#define MHD_PACK_COMMENT 0x0010U -#define MHD_NEWNUMBERING 0x0010U -#define MHD_AV 0x0020U -#define MHD_PROTECT 0x0040U -#define MHD_PASSWORD 0x0080U -#define MHD_FIRSTVOLUME 0x0100U -#define MHD_ENCRYPTVER 0x0200U - -#define LHD_SPLIT_BEFORE 0x0001U -#define LHD_SPLIT_AFTER 0x0002U -#define LHD_PASSWORD 0x0004U - -// Old style file comment embed into file header. Must not be used -// in new archives anymore. -#define LHD_COMMENT 0x0008U - -#define LHD_SOLID 0x0010U - - -#define LHD_WINDOWMASK 0x00e0U -#define LHD_WINDOW64 0x0000U -#define LHD_WINDOW128 0x0020U -#define LHD_WINDOW256 0x0040U -#define LHD_WINDOW512 0x0060U -#define LHD_WINDOW1024 0x0080U -#define LHD_WINDOW2048 0x00a0U -#define LHD_WINDOW4096 0x00c0U -#define LHD_DIRECTORY 0x00e0U - -#define LHD_LARGE 0x0100U -#define LHD_UNICODE 0x0200U -#define LHD_SALT 0x0400U -#define LHD_VERSION 0x0800U -#define LHD_EXTTIME 0x1000U -#define LHD_EXTAREA 0x2000U - -#define SKIP_IF_UNKNOWN 0x4000U -#define LONG_BLOCK 0x8000U - -#define EARC_NEXT_VOLUME 0x0001U // Not last volume. -#define EARC_DATACRC 0x0002U // Store CRC32 of RAR archive (now is used only in volumes). -#define EARC_REVSPACE 0x0004U // Reserve space for end of REV file 7 byte record. -#define EARC_VOLNUMBER 0x0008U // Store a number of current volume. - -enum HEADER_TYPE { - MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76, - SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a, - ENDARC_HEAD=0x7b -}; - -enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103, - NTACL_HEAD=0x104,STREAM_HEAD=0x105 }; - -enum HOST_SYSTEM { - HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4, - HOST_BEOS=5,HOST_MAX -}; - -#define SUBHEAD_TYPE_CMT "CMT" -#define SUBHEAD_TYPE_ACL "ACL" -#define SUBHEAD_TYPE_STREAM "STM" -#define SUBHEAD_TYPE_UOWNER "UOW" -#define SUBHEAD_TYPE_AV "AV" -#define SUBHEAD_TYPE_RR "RR" -#define SUBHEAD_TYPE_OS2EA "EA2" -#define SUBHEAD_TYPE_BEOSEA "EABE" - -/* new file inherits a subblock when updating a host file */ -#define SUBHEAD_FLAGS_INHERITED 0x80000000 - -#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001 - -struct OldMainHeader -{ - byte Mark[4]; - ushort HeadSize; - byte Flags; -}; - - -struct OldFileHeader -{ - uint PackSize; - uint UnpSize; - ushort FileCRC; - ushort HeadSize; - uint FileTime; - byte FileAttr; - byte Flags; - byte UnpVer; - byte NameSize; - byte Method; -}; - - -struct MarkHeader -{ - byte Mark[7]; -}; - - -struct BaseBlock -{ - ushort HeadCRC; - HEADER_TYPE HeadType; // 1 byte. - ushort Flags; - ushort HeadSize; - - bool IsSubBlock() - { - if (HeadType==SUB_HEAD) - return(true); - if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0) - return(true); - return(false); - } -}; - -struct BlockHeader:BaseBlock -{ - union { - uint DataSize; - uint PackSize; - }; -}; - - -struct MainHeader:BaseBlock -{ - ushort HighPosAV; - uint PosAV; - byte EncryptVer; -}; - - -#define SALT_SIZE 8 - -struct FileHeader:BlockHeader -{ - uint UnpSize; - byte HostOS; - uint FileCRC; - uint FileTime; - byte UnpVer; - byte Method; - ushort NameSize; - union { - uint FileAttr; - uint SubFlags; - }; -/* optional */ - uint HighPackSize; - uint HighUnpSize; -/* names */ - char FileName[NM]; - wchar FileNameW[NM]; -/* optional */ - Array SubData; - byte Salt[SALT_SIZE]; - - RarTime mtime; - RarTime ctime; - RarTime atime; - RarTime arctime; -/* dummy */ - int64 FullPackSize; - int64 FullUnpSize; - - void Clear(size_t SubDataSize) - { - SubData.Alloc(SubDataSize); - Flags=LONG_BLOCK; - SubFlags=0; - } - - bool CmpName(const char *Name) - { - return(strcmp(FileName,Name)==0); - } - - FileHeader& operator = (FileHeader &hd) - { - SubData.Reset(); - memcpy(this,&hd,sizeof(*this)); - SubData.CleanData(); - SubData=hd.SubData; - return(*this); - } -}; - - -struct EndArcHeader:BaseBlock -{ - // Optional CRC32 of entire archive up to start of EndArcHeader block. - // Present if EARC_DATACRC flag is set. - uint ArcDataCRC; - - // Optional number of current volume. - // Present if EARC_VOLNUMBER flag is set. - ushort VolNumber; - - // 7 additional zero bytes can be stored here if EARC_REVSPACE is set. -}; - - -// SubBlockHeader and its successors were used in RAR 2.x format. -// RAR 3.x uses FileHeader with NEWSUB_HEAD HeadType for subblocks. -struct SubBlockHeader:BlockHeader -{ - ushort SubType; - byte Level; -}; - - -struct CommentHeader:BaseBlock -{ - ushort UnpSize; - byte UnpVer; - byte Method; - ushort CommCRC; -}; - - -struct ProtectHeader:BlockHeader -{ - byte Version; - ushort RecSectors; - uint TotalBlocks; - byte Mark[8]; -}; - - -struct AVHeader:BaseBlock -{ - byte UnpVer; - byte Method; - byte AVVer; - uint AVInfoCRC; -}; - - -struct SignHeader:BaseBlock -{ - uint CreationTime; - ushort ArcNameSize; - ushort UserNameSize; -}; - - -struct UnixOwnersHeader:SubBlockHeader -{ - ushort OwnerNameSize; - ushort GroupNameSize; -/* dummy */ - char OwnerName[NM]; - char GroupName[NM]; -}; - - -struct EAHeader:SubBlockHeader -{ - uint UnpSize; - byte UnpVer; - byte Method; - uint EACRC; -}; - - -struct StreamHeader:SubBlockHeader -{ - uint UnpSize; - byte UnpVer; - byte Method; - uint StreamCRC; - ushort StreamNameSize; -/* dummy */ - byte StreamName[NM]; -}; - - -struct MacFInfoHeader:SubBlockHeader -{ - uint fileType; - uint fileCreator; -}; - - -#endif diff --git a/src/unrar/isnt.cpp b/src/unrar/isnt.cpp deleted file mode 100644 index 53c722ab42..0000000000 --- a/src/unrar/isnt.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include "rar.hpp" - -#ifdef _WIN_ALL -DWORD WinNT() -{ - static int dwPlatformId=-1; - static DWORD dwMajorVersion,dwMinorVersion; - if (dwPlatformId==-1) - { - OSVERSIONINFO WinVer; - WinVer.dwOSVersionInfoSize=sizeof(WinVer); - GetVersionEx(&WinVer); - dwPlatformId=WinVer.dwPlatformId; - dwMajorVersion=WinVer.dwMajorVersion; - dwMinorVersion=WinVer.dwMinorVersion; - } - DWORD Result=0; - if (dwPlatformId==VER_PLATFORM_WIN32_NT) - Result=dwMajorVersion*0x100+dwMinorVersion; - - - return(Result); -} -#endif diff --git a/src/unrar/isnt.hpp b/src/unrar/isnt.hpp deleted file mode 100644 index 520ac8ad7d..0000000000 --- a/src/unrar/isnt.hpp +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef _RAR_ISNT_ -#define _RAR_ISNT_ - -enum WINNT_VERSION { - WNT_NONE=0,WNT_NT351=0x0333,WNT_NT4=0x0400,WNT_W2000=0x0500, - WNT_WXP=0x0501,WNT_W2003=0x0502,WNT_VISTA=0x0600,WNT_W7=0x0601 -}; - -DWORD WinNT(); - -#endif diff --git a/src/unrar/license.txt b/src/unrar/license.txt deleted file mode 100644 index 0811276a13..0000000000 --- a/src/unrar/license.txt +++ /dev/null @@ -1,42 +0,0 @@ - ****** ***** ****** UnRAR - free utility for RAR archives - ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ****** ******* ****** License for use and distribution of - ** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ** ** ** ** ** ** FREE portable version - ~~~~~~~~~~~~~~~~~~~~~ - - The source code of UnRAR utility is freeware. This means: - - 1. All copyrights to RAR and the utility UnRAR are exclusively - owned by the author - Alexander Roshal. - - 2. UnRAR source code may be used in any software to handle - RAR archives without limitations free of charge, but cannot be - used to develop RAR (WinRAR) compatible archiver and to - re-create RAR compression algorithm, which is proprietary. - Distribution of modified UnRAR source code in separate form - or as a part of other software is permitted, provided that - full text of this paragraph, starting from "UnRAR source code" - words, is included in license, or in documentation if license - is not available, and in source code comments of resulting package. - - 3. The UnRAR utility may be freely distributed. It is allowed - to distribute UnRAR inside of other software packages. - - 4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS". - NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT - YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS, - DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING - OR MISUSING THIS SOFTWARE. - - 5. Installing and using the UnRAR utility signifies acceptance of - these terms and conditions of the license. - - 6. If you don't agree with terms of the license you must remove - UnRAR files from your storage devices and cease to use the - utility. - - Thank you for your interest in RAR and UnRAR. - - - Alexander L. Roshal diff --git a/src/unrar/list.cpp b/src/unrar/list.cpp deleted file mode 100644 index 000e92d3f8..0000000000 --- a/src/unrar/list.cpp +++ /dev/null @@ -1,391 +0,0 @@ -#include "rar.hpp" - -static void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare); -static void ListSymLink(Archive &Arc); -static void ListFileAttr(uint A,int HostOS); -static void ListOldSubHeader(Archive &Arc); -static void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical); - -void ListArchive(CommandData *Cmd) -{ - int64 SumPackSize=0,SumUnpSize=0; - uint ArcCount=0,SumFileCount=0; - bool Technical=(Cmd->Command[1]=='T'); - bool Bare=(Cmd->Command[1]=='B'); - bool Verbose=(*Cmd->Command=='V'); - - char ArcName[NM]; - wchar ArcNameW[NM]; - - while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName))) - { - Archive Arc(Cmd); -#ifdef _WIN_ALL - Arc.RemoveSequentialFlag(); -#endif - if (!Arc.WOpen(ArcName,ArcNameW)) - continue; - bool FileMatched=true; - while (1) - { - int64 TotalPackSize=0,TotalUnpSize=0; - uint FileCount=0; - if (Arc.IsArchive(true)) - { -// if (!Arc.IsOpened()) -// break; - bool TitleShown=false; - if (!Bare) - { - Arc.ViewComment(); - mprintf("\n"); - if (Arc.Solid) - mprintf(St(MListSolid)); - if (Arc.SFXSize>0) - mprintf(St(MListSFX)); - if (Arc.Volume) - if (Arc.Solid) - mprintf(St(MListVol1)); - else - mprintf(St(MListVol2)); - else - if (Arc.Solid) - mprintf(St(MListArc1)); - else - mprintf(St(MListArc2)); - mprintf(" %s\n",Arc.FileName); - if (Technical) - { - if (Arc.Protected) - mprintf(St(MListRecRec)); - if (Arc.Locked) - mprintf(St(MListLock)); - } - } - while(Arc.ReadHeader()>0) - { - int HeaderType=Arc.GetHeaderType(); - if (HeaderType==ENDARC_HEAD) - break; - switch(HeaderType) - { - case FILE_HEAD: - IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName); - FileMatched=Cmd->IsProcessFile(Arc.NewLhd)!=0; - if (FileMatched) - { - ListFileHeader(Arc.NewLhd,Verbose,Technical,TitleShown,Bare); - if (!(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)) - { - TotalUnpSize+=Arc.NewLhd.FullUnpSize; - FileCount++; - } - TotalPackSize+=Arc.NewLhd.FullPackSize; - if (Technical) - ListSymLink(Arc); -#ifndef SFX_MODULE - if (Verbose) - Arc.ViewFileComment(); -#endif - } - break; -#ifndef SFX_MODULE - case SUB_HEAD: - if (Technical && FileMatched && !Bare) - ListOldSubHeader(Arc); - break; -#endif - case NEWSUB_HEAD: - if (FileMatched && !Bare) - { - if (Technical) - ListFileHeader(Arc.SubHead,Verbose,true,TitleShown,false); - ListNewSubHeader(Cmd,Arc,Technical); - } - break; - } - Arc.SeekToNext(); - } - if (!Bare) - if (TitleShown) - { - mprintf("\n"); - for (int I=0;I<79;I++) - mprintf("-"); - char UnpSizeText[20]; - itoa(TotalUnpSize,UnpSizeText); - - char PackSizeText[20]; - itoa(TotalPackSize,PackSizeText); - - mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText, - PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize)); - SumFileCount+=FileCount; - SumUnpSize+=TotalUnpSize; - SumPackSize+=TotalPackSize; -#ifndef SFX_MODULE - if (Arc.EndArcHead.Flags & EARC_VOLNUMBER) - { - mprintf(" "); - mprintf(St(MVolumeNumber),Arc.EndArcHead.VolNumber+1); - } -#endif - mprintf("\n"); - } - else - mprintf(St(MListNoFiles)); - - ArcCount++; - -#ifndef NOVOLUME - if (Cmd->VolSize!=0 && ((Arc.NewLhd.Flags & LHD_SPLIT_AFTER) || - Arc.GetHeaderType()==ENDARC_HEAD && - (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)!=0) && - MergeArchive(Arc,NULL,false,*Cmd->Command)) - { - Arc.Seek(0,SEEK_SET); - } - else -#endif - break; - } - else - { - if (Cmd->ArcNames->ItemsCount()<2 && !Bare) - mprintf(St(MNotRAR),Arc.FileName); - break; - } - } - } - if (ArcCount>1 && !Bare) - { - char UnpSizeText[20],PackSizeText[20]; - itoa(SumUnpSize,UnpSizeText); - itoa(SumPackSize,PackSizeText); - mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText, - PackSizeText,ToPercentUnlim(SumPackSize,SumUnpSize)); - } -} - - -void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare) -{ - if (!Bare) - { - if (!TitleShown) - { - if (Verbose) - mprintf(St(MListPathComm)); - else - mprintf(St(MListName)); - mprintf(St(MListTitle)); - if (Technical) - mprintf(St(MListTechTitle)); - for (int I=0;I<79;I++) - mprintf("-"); - TitleShown=true; - } - - if (hd.HeadType==NEWSUB_HEAD) - mprintf(St(MSubHeadType),hd.FileName); - - mprintf("\n%c",(hd.Flags & LHD_PASSWORD) ? '*' : ' '); - } - - char *Name=hd.FileName; - -#ifdef UNICODE_SUPPORTED - char ConvertedName[NM]; - if ((hd.Flags & LHD_UNICODE)!=0 && *hd.FileNameW!=0 && UnicodeEnabled()) - { - if (WideToChar(hd.FileNameW,ConvertedName) && *ConvertedName!=0) - Name=ConvertedName; - } -#endif - - if (Bare) - { - mprintf("%s\n",Verbose ? Name:PointToName(Name)); - return; - } - - if (Verbose) - mprintf("%s\n%12s ",Name,""); - else - mprintf("%-12s",PointToName(Name)); - - char UnpSizeText[20],PackSizeText[20]; - if (hd.FullUnpSize==INT64NDF) - strcpy(UnpSizeText,"?"); - else - itoa(hd.FullUnpSize,UnpSizeText); - itoa(hd.FullPackSize,PackSizeText); - - mprintf(" %8s %8s ",UnpSizeText,PackSizeText); - - if ((hd.Flags & LHD_SPLIT_BEFORE) && (hd.Flags & LHD_SPLIT_AFTER)) - mprintf(" <->"); - else - if (hd.Flags & LHD_SPLIT_BEFORE) - mprintf(" <--"); - else - if (hd.Flags & LHD_SPLIT_AFTER) - mprintf(" -->"); - else - mprintf("%3d%%",ToPercentUnlim(hd.FullPackSize,hd.FullUnpSize)); - - char DateStr[50]; - hd.mtime.GetText(DateStr,false); - mprintf(" %s ",DateStr); - - if (hd.HeadType==NEWSUB_HEAD) - mprintf(" %c....B ",(hd.SubFlags & SUBHEAD_FLAGS_INHERITED) ? 'I' : '.'); - else - ListFileAttr(hd.FileAttr,hd.HostOS); - - mprintf(" %8.8X",hd.FileCRC); - mprintf(" m%d",hd.Method-0x30); - if ((hd.Flags & LHD_WINDOWMASK)<=6*32) - mprintf("%c",((hd.Flags&LHD_WINDOWMASK)>>5)+'a'); - else - mprintf(" "); - mprintf(" %d.%d",hd.UnpVer/10,hd.UnpVer%10); - - static const char *RarOS[]={ - "DOS","OS/2","Windows","Unix","Mac OS","BeOS","WinCE","","","" - }; - - if (Technical) - mprintf("\n%22s %8s %4s", - (hd.HostOS",FileName); - } - else - { - // Link data are encrypted. We would need to ask for password - // and initialize decryption routine to display the link target. - mprintf("\n%22s %s","-->","*<-?->"); - } -} - - -void ListFileAttr(uint A,int HostOS) -{ - switch(HostOS) - { - case HOST_MSDOS: - case HOST_OS2: - case HOST_WIN32: - case HOST_MACOS: - mprintf(" %c%c%c%c%c%c%c ", - (A & 0x08) ? 'V' : '.', - (A & 0x10) ? 'D' : '.', - (A & 0x01) ? 'R' : '.', - (A & 0x02) ? 'H' : '.', - (A & 0x04) ? 'S' : '.', - (A & 0x20) ? 'A' : '.', - (A & 0x800) ? 'C' : '.'); - break; - case HOST_UNIX: - case HOST_BEOS: - switch (A & 0xF000) - { - case 0x4000: - mprintf("d"); - break; - case 0xA000: - mprintf("l"); - break; - default: - mprintf("-"); - break; - } - mprintf("%c%c%c%c%c%c%c%c%c", - (A & 0x0100) ? 'r' : '-', - (A & 0x0080) ? 'w' : '-', - (A & 0x0040) ? ((A & 0x0800) ? 's':'x'):((A & 0x0800) ? 'S':'-'), - (A & 0x0020) ? 'r' : '-', - (A & 0x0010) ? 'w' : '-', - (A & 0x0008) ? ((A & 0x0400) ? 's':'x'):((A & 0x0400) ? 'S':'-'), - (A & 0x0004) ? 'r' : '-', - (A & 0x0002) ? 'w' : '-', - (A & 0x0001) ? 'x' : '-'); - break; - } -} - - -#ifndef SFX_MODULE -void ListOldSubHeader(Archive &Arc) -{ - switch(Arc.SubBlockHead.SubType) - { - case EA_HEAD: - mprintf(St(MListEAHead)); - break; - case UO_HEAD: - mprintf(St(MListUOHead),Arc.UOHead.OwnerName,Arc.UOHead.GroupName); - break; - case MAC_HEAD: - mprintf(St(MListMACHead1),Arc.MACHead.fileType>>24,Arc.MACHead.fileType>>16,Arc.MACHead.fileType>>8,Arc.MACHead.fileType); - mprintf(St(MListMACHead2),Arc.MACHead.fileCreator>>24,Arc.MACHead.fileCreator>>16,Arc.MACHead.fileCreator>>8,Arc.MACHead.fileCreator); - break; - case BEEA_HEAD: - mprintf(St(MListBeEAHead)); - break; - case NTACL_HEAD: - mprintf(St(MListNTACLHead)); - break; - case STREAM_HEAD: - mprintf(St(MListStrmHead),Arc.StreamHead.StreamName); - break; - default: - mprintf(St(MListUnkHead),Arc.SubBlockHead.SubType); - break; - } -} -#endif - - -void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical) -{ - if (Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) && - (Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment) - { - Array CmtData; - size_t ReadSize=Arc.ReadCommentData(&CmtData,NULL); - if (ReadSize!=0) - { - mprintf(St(MFileComment)); - OutComment((char *)&CmtData[0],ReadSize); - } - } - if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM) && - (Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0) - { - size_t DestSize=Arc.SubHead.SubData.Size()/2; - wchar DestNameW[NM]; - char DestName[NM]; - if (DestSize - - " -#define MUNRARTitle1 "\nUsage: unrar - - " -#define MRARTitle2 "\n <@listfiles...> " -#define MCHelpCmd "\n\n" -#define MCHelpCmdA "\n a Add files to archive" -#define MCHelpCmdC "\n c Add archive comment" -#define MCHelpCmdCF "\n cf Add files comment" -#define MCHelpCmdCH "\n ch Change archive parameters" -#define MCHelpCmdCW "\n cw Write archive comment to file" -#define MCHelpCmdD "\n d Delete files from archive" -#define MCHelpCmdE "\n e Extract files to current directory" -#define MCHelpCmdF "\n f Freshen files in archive" -#define MCHelpCmdI "\n i[par]= Find string in archives" -#define MCHelpCmdK "\n k Lock archive" -#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]" -#define MCHelpCmdM "\n m[f] Move to archive [files only]" -#define MCHelpCmdP "\n p Print file to stdout" -#define MCHelpCmdR "\n r Repair archive" -#define MCHelpCmdRC "\n rc Reconstruct missing volumes" -#define MCHelpCmdRN "\n rn Rename archived files" -#define MCHelpCmdRR "\n rr[N] Add data recovery record" -#define MCHelpCmdRV "\n rv[N] Create recovery volumes" -#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX" -#define MCHelpCmdT "\n t Test archive files" -#define MCHelpCmdU "\n u Update files in archive" -#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]" -#define MCHelpCmdX "\n x Extract files with full path" -#define MCHelpSw "\n\n" -#define MCHelpSwm "\n - Stop switches scanning" -#define MCHelpSwAT "\n @[+] Disable [enable] file lists" -#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction" -#define MCHelpSwAD "\n ad Append archive name to destination path" -#define MCHelpSwAG "\n ag[format] Generate archive name using the current date" -#define MCHelpSwAI "\n ai Ignore file attributes" -#define MCHelpSwAO "\n ao Add files with Archive attribute set" -#define MCHelpSwAP "\n ap Set path inside archive" -#define MCHelpSwAS "\n as Synchronize archive contents" -#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)" -#define MCHelpSwAVm "\n av- Disable authenticity verification check" -#define MCHelpSwCm "\n c- Disable comments show" -#define MCHelpSwCFGm "\n cfg- Disable read configuration" -#define MCHelpSwCL "\n cl Convert names to lower case" -#define MCHelpSwCU "\n cu Convert names to upper case" -#define MCHelpSwDF "\n df Delete files after archiving" -#define MCHelpSwDH "\n dh Open shared files" -#define MCHelpSwDR "\n dr Delete files to Recycle Bin" -#define MCHelpSwDS "\n ds Disable name sort for solid archive" -#define MCHelpSwDW "\n dw Wipe files after archiving" -#define MCHelpSwEa "\n e[+] Set file exclude and include attributes" -#define MCHelpSwED "\n ed Do not add empty directories" -#define MCHelpSwEE "\n ee Do not save and extract extended attributes" -#define MCHelpSwEN "\n en Do not put 'end of archive' block" -#define MCHelpSwEP "\n ep Exclude paths from names" -#define MCHelpSwEP1 "\n ep1 Exclude base directory from names" -#define MCHelpSwEP2 "\n ep2 Expand paths to full" -#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter" -#define MCHelpSwF "\n f Freshen files" -#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers" -#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages" -#define MCHelpSwIEML "\n ieml[addr] Send archive by email" -#define MCHelpSwIERR "\n ierr Send all messages to stderr" -#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)" -#define MCHelpSwINUL "\n inul Disable all messages" -#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation" -#define MCHelpSwISND "\n isnd Enable sound" -#define MCHelpSwK "\n k Lock archive" -#define MCHelpSwKB "\n kb Keep broken extracted files" -#define MCHelpSwLog "\n log[f][=name] Write names to log file" -#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)" -#define MCHelpSwMC "\n mc Set advanced compression parameters" -#define MCHelpSwMD "\n md Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)" -#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store" -#define MCHelpSwMT "\n mt Set the number of threads" -#define MCHelpSwN "\n n Include only specified file" -#define MCHelpSwNa "\n n@ Read file names to include from stdin" -#define MCHelpSwNal "\n n@ Include files listed in specified list file" -#define MCHelpSwO "\n o[+|-] Set the overwrite mode" -#define MCHelpSwOC "\n oc Set NTFS Compressed attribute" -#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file" -#define MCHelpSwOR "\n or Rename files automatically" -#define MCHelpSwOS "\n os Save NTFS streams" -#define MCHelpSwOW "\n ow Save or restore file owner and group" -#define MCHelpSwP "\n p[password] Set password" -#define MCHelpSwPm "\n p- Do not query password" -#define MCHelpSwR "\n r Recurse subdirectories" -#define MCHelpSwRm "\n r- Disable recursion" -#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only" -#define MCHelpSwRI "\n ri

[:] Set priority (0-default,1-min..15-max) and sleep time in ms" -#define MCHelpSwRR "\n rr[N] Add data recovery record" -#define MCHelpSwRV "\n rv[N] Create recovery volumes" -#define MCHelpSwS "\n s[,v[-],e] Create solid archive" -#define MCHelpSwSm "\n s- Disable solid archiving" -#define MCHelpSwSC "\n sc[obj] Specify the character set" -#define MCHelpSwSFX "\n sfx[name] Create SFX archive" -#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)" -#define MCHelpSwSL "\n sl Process files with size less than specified" -#define MCHelpSwSM "\n sm Process files with size more than specified" -#define MCHelpSwT "\n t Test files after archiving" -#define MCHelpSwTK "\n tk Keep original archive time" -#define MCHelpSwTL "\n tl Set archive time to latest file" -#define MCHelpSwTN "\n tn