X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/2eb37f730d29c1edd3e3339930f12c3c2d2635b3..74a8f67d96591cec101def2a7d47c64072aff7fd:/src/common/tarstrm.cpp diff --git a/src/common/tarstrm.cpp b/src/common/tarstrm.cpp index 32b55f3a7b..9a6d851a0e 100644 --- a/src/common/tarstrm.cpp +++ b/src/common/tarstrm.cpp @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: tarstrm.cpp +// Name: src/common/tarstrm.cpp // Purpose: Streams for Tar files // Author: Mike Wetherell // RCS-ID: $Id$ @@ -26,7 +26,7 @@ #include "wx/buffer.h" #include "wx/datetime.h" -#include "wx/ptr_scpd.h" +#include "wx/scopedptr.h" #include "wx/filename.h" #include "wx/thread.h" @@ -104,9 +104,9 @@ wxTarClassFactory::wxTarClassFactory() const wxChar * const * wxTarClassFactory::GetProtocols(wxStreamProtocolType type) const { - static const wxChar *protocols[] = { _T("tar"), NULL }; - static const wxChar *mimetypes[] = { _T("application/x-tar"), NULL }; - static const wxChar *fileexts[] = { _T(".tar"), NULL }; + static const wxChar *protocols[] = { wxT("tar"), NULL }; + static const wxChar *mimetypes[] = { wxT("application/x-tar"), NULL }; + static const wxChar *fileexts[] = { wxT(".tar"), NULL }; static const wxChar *empty[] = { NULL }; switch (type) { @@ -161,23 +161,23 @@ wxDEFINE_SCOPED_PTR_TYPE(wxTarHeaderBlock) // A table giving the field names and offsets in a tar header block const wxTarField wxTarHeaderBlock::fields[] = { - { _T("name"), 0 }, // 100 - { _T("mode"), 100 }, // 8 - { _T("uid"), 108 }, // 8 - { _T("gid"), 116 }, // 8 - { _T("size"), 124 }, // 12 - { _T("mtime"), 136 }, // 12 - { _T("chksum"), 148 }, // 8 - { _T("typeflag"), 156 }, // 1 - { _T("linkname"), 157 }, // 100 - { _T("magic"), 257 }, // 6 - { _T("version"), 263 }, // 2 - { _T("uname"), 265 }, // 32 - { _T("gname"), 297 }, // 32 - { _T("devmajor"), 329 }, // 8 - { _T("devminor"), 337 }, // 8 - { _T("prefix"), 345 }, // 155 - { _T("unused"), 500 }, // 12 + { wxT("name"), 0 }, // 100 + { wxT("mode"), 100 }, // 8 + { wxT("uid"), 108 }, // 8 + { wxT("gid"), 116 }, // 8 + { wxT("size"), 124 }, // 12 + { wxT("mtime"), 136 }, // 12 + { wxT("chksum"), 148 }, // 8 + { wxT("typeflag"), 156 }, // 1 + { wxT("linkname"), 157 }, // 100 + { wxT("magic"), 257 }, // 6 + { wxT("version"), 263 }, // 2 + { wxT("uname"), 265 }, // 32 + { wxT("gname"), 297 }, // 32 + { wxT("devmajor"), 329 }, // 8 + { wxT("devminor"), 337 }, // 8 + { wxT("prefix"), 345 }, // 155 + { wxT("unused"), 500 }, // 12 { NULL, TAR_BLOCKSIZE } }; @@ -362,7 +362,8 @@ static wxString wxTarUserName(int uid) wxCharBuffer buf(bufsize); struct passwd pw; - if (getpwuid_r(uid, &pw, buf.data(), bufsize, &ppw) == 0) + memset(&pw, 0, sizeof(pw)); + if (getpwuid_r(uid, &pw, buf.data(), bufsize, &ppw) == 0 && pw.pw_name) return wxString(pw.pw_name, wxConvLibc); #else if ((ppw = getpwuid(uid)) != NULL) @@ -384,7 +385,8 @@ static wxString wxTarGroupName(int gid) wxCharBuffer buf(bufsize); struct group gr; - if (getgrgid_r(gid, &gr, buf.data(), bufsize, &pgr) == 0) + memset(&gr, 0, sizeof(gr)); + if (getgrgid_r(gid, &gr, buf.data(), bufsize, &pgr) == 0 && gr.gr_name) return wxString(gr.gr_name, wxConvLibc); #else if ((pgr = getgrgid(gid)) != NULL) @@ -537,15 +539,15 @@ wxString wxTarEntry::GetName(wxPathFormat format /*=wxPATH_NATIVE*/) const switch (wxFileName::GetFormat(format)) { case wxPATH_DOS: { - wxString name(isDir ? m_Name + _T("\\") : m_Name); + wxString name(isDir ? m_Name + wxT("\\") : m_Name); for (size_t i = 0; i < name.length(); i++) - if (name[i] == _T('/')) - name[i] = _T('\\'); + if (name[i] == wxT('/')) + name[i] = wxT('\\'); return name; } case wxPATH_UNIX: - return isDir ? m_Name + _T("/") : m_Name; + return isDir ? m_Name + wxT("/") : m_Name; default: ; @@ -592,9 +594,9 @@ wxString wxTarEntry::GetInternalName(const wxString& name, while (!internal.empty() && *internal.begin() == '/') internal.erase(0, 1); - while (!internal.empty() && internal.compare(0, 2, _T("./")) == 0) + while (!internal.empty() && internal.compare(0, 2, wxT("./")) == 0) internal.erase(0, 2); - if (internal == _T(".") || internal == _T("..")) + if (internal == wxT(".") || internal == wxT("..")) internal = wxEmptyString; return internal; @@ -693,9 +695,9 @@ wxTarEntry *wxTarInputStream::GetNextEntry() entry->SetOffset(m_offset); - entry->SetDateTime(GetHeaderDate(_T("mtime"))); - entry->SetAccessTime(GetHeaderDate(_T("atime"))); - entry->SetCreateTime(GetHeaderDate(_T("ctime"))); + entry->SetDateTime(GetHeaderDate(wxT("mtime"))); + entry->SetAccessTime(GetHeaderDate(wxT("atime"))); + entry->SetCreateTime(GetHeaderDate(wxT("ctime"))); entry->SetTypeFlag(*m_hdr->Get(TAR_TYPEFLAG)); bool isDir = entry->IsDir(); @@ -791,7 +793,9 @@ wxStreamError wxTarInputStream::ReadHeaders() while (!done) { m_hdr->Read(*m_parent_i_stream); if (m_parent_i_stream->Eof()) + { wxLogError(_("incomplete header block in tar")); + } if (!*m_parent_i_stream) return wxSTREAM_READ_ERROR; m_offset += TAR_BLOCKSIZE; @@ -864,7 +868,7 @@ wxString wxTarInputStream::GetHeaderPath() const { wxString path; - if ((path = GetExtendedHeader(_T("path"))) != wxEmptyString) + if ((path = GetExtendedHeader(wxT("path"))) != wxEmptyString) return path; path = wxString(m_hdr->Get(TAR_NAME), GetConv()); @@ -872,7 +876,7 @@ wxString wxTarInputStream::GetHeaderPath() const return path; const char *prefix = m_hdr->Get(TAR_PREFIX); - return *prefix ? wxString(prefix, GetConv()) + _T("/") + path : path; + return *prefix ? wxString(prefix, GetConv()) + wxT("/") + path : path; } wxDateTime wxTarInputStream::GetHeaderDate(const wxString& key) const @@ -886,7 +890,7 @@ wxDateTime wxTarInputStream::GetHeaderDate(const wxString& key) const return ll; } - if (key == _T("mtime")) + if (key == wxT("mtime")) return wxLongLong(m_hdr->GetOctal(TAR_MTIME)) * 1000L; return wxDateTime(); @@ -943,7 +947,7 @@ bool wxTarInputStream::ReadExtendedHeader(wxTarHeaderRecords*& recs) size_t recPos, recSize; bool ok = true; - for (recPos = 0; recPos < len; recPos += recSize) { + for (recPos = 0; recPos < len && ok; recPos += recSize) { char *pRec = buf.data() + recPos; char *p = pRec; @@ -1038,7 +1042,9 @@ size_t wxTarInputStream::OnSysRead(void *buffer, size_t size) } else if (!m_parent_i_stream->IsOk()) { // any other error will have been reported by the underlying stream if (m_parent_i_stream->Eof()) + { wxLogError(_("unexpected end of file")); + } m_lasterror = wxSTREAM_READ_ERROR; } @@ -1237,11 +1243,11 @@ bool wxTarOutputStream::WriteHeaders(wxTarEntry& entry) entry.SetSize(0); m_large = !SetHeaderNumber(TAR_SIZE, entry.GetSize()); - SetHeaderDate(_T("mtime"), entry.GetDateTime()); + SetHeaderDate(wxT("mtime"), entry.GetDateTime()); if (entry.GetAccessTime().IsValid()) - SetHeaderDate(_T("atime"), entry.GetAccessTime()); + SetHeaderDate(wxT("atime"), entry.GetAccessTime()); if (entry.GetCreateTime().IsValid()) - SetHeaderDate(_T("ctime"), entry.GetCreateTime()); + SetHeaderDate(wxT("ctime"), entry.GetCreateTime()); *m_hdr->Get(TAR_TYPEFLAG) = char(entry.GetTypeFlag()); @@ -1276,7 +1282,7 @@ bool wxTarOutputStream::WriteHeaders(wxTarEntry& entry) // an old tar that doesn't understand extended headers will // extract it as a file, so give these fields reasonable values // so that the user will have access to read and remove it. - m_hdr2->SetPath(PaxHeaderPath(_T("%d/PaxHeaders.%p/%f"), + m_hdr2->SetPath(PaxHeaderPath(wxT("%d/PaxHeaders.%p/%f"), entry.GetName(wxPATH_UNIX)), GetConv()); m_hdr2->SetOctal(TAR_MODE, 0600); strcpy(m_hdr2->Get(TAR_UID), m_hdr->Get(TAR_UID)); @@ -1301,6 +1307,11 @@ bool wxTarOutputStream::WriteHeaders(wxTarEntry& entry) m_tarsize += rounded; *m_extendedHdr = 0; + + // update m_headpos which is used to seek back to fix up the file + // length if it is not known in advance + if (m_tarstart != wxInvalidOffset) + m_headpos = m_tarstart + m_tarsize; } // if don't have extended headers just report error @@ -1321,12 +1332,12 @@ bool wxTarOutputStream::WriteHeaders(wxTarEntry& entry) wxString wxTarOutputStream::PaxHeaderPath(const wxString& format, const wxString& path) { - wxString d = path.BeforeLast(_T('/')); - wxString f = path.AfterLast(_T('/')); + wxString d = path.BeforeLast(wxT('/')); + wxString f = path.AfterLast(wxT('/')); wxString ret; if (d.empty()) - d = _T("."); + d = wxT("."); ret.reserve(format.length() + path.length() + 16); @@ -1342,7 +1353,7 @@ wxString wxTarOutputStream::PaxHeaderPath(const wxString& format, case 'd': ret << d; break; case 'f': ret << f; break; case 'p': ret << wxGetProcessId(); break; - case '%': ret << _T("%"); break; + case '%': ret << wxT("%"); break; } begin = end + 2; } @@ -1387,7 +1398,7 @@ bool wxTarOutputStream::ModifyHeader() void wxTarOutputStream::SetHeaderPath(const wxString& name) { if (!m_hdr->SetPath(name, GetConv()) || (m_pax && !name.IsAscii())) - SetExtendedHeader(_T("path"), name); + SetExtendedHeader(wxT("path"), name); } bool wxTarOutputStream::SetHeaderNumber(int id, wxTarNumber n) @@ -1413,13 +1424,13 @@ void wxTarOutputStream::SetHeaderDate(const wxString& key, wxLongLong ll = datetime.IsValid() ? datetime.GetValue() : wxLongLong(0); wxLongLong secs = ll / 1000L; - if (key != _T("mtime") + if (key != wxT("mtime") || !m_hdr->SetOctal(TAR_MTIME, wxTarNumber(secs.GetValue())) || secs <= 0 || secs >= 0x7fffffff) { wxString str; if (ll >= LONG_MIN && ll <= LONG_MAX) { - str.Printf(_T("%g"), ll.ToLong() / 1000.0); + str.Printf(wxT("%g"), ll.ToLong() / 1000.0); } else { str = ll.ToString(); str.insert(str.end() - 3, '.'); @@ -1481,7 +1492,7 @@ void wxTarOutputStream::SetExtendedHeader(const wxString& key, else { // if not pax then make a list of fields to report as errors if (!m_badfit.empty()) - m_badfit += _T(", "); + m_badfit += wxT(", "); m_badfit += key; } }