summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/CPack/cmCPackDebGenerator.cxx290
1 files changed, 19 insertions, 271 deletions
diff --git a/Source/CPack/cmCPackDebGenerator.cxx b/Source/CPack/cmCPackDebGenerator.cxx
index 01306e2..18d559e 100644
--- a/Source/CPack/cmCPackDebGenerator.cxx
+++ b/Source/CPack/cmCPackDebGenerator.cxx
@@ -12,23 +12,12 @@
#include "cm_sys_stat.h"
#include "cmsys/Glob.hxx"
-#include <limits.h>
#include <map>
#include <ostream>
#include <set>
-#include <stdio.h>
#include <string.h>
#include <utility>
-// NOTE:
-// A debian package .deb is simply an 'ar' archive. The only subtle difference
-// is that debian uses the BSD ar style archive whereas most Linux distro have
-// a GNU ar.
-// See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
-// Therefore we provide our own implementation of a BSD-ar:
-static int ar_append(const char* archive,
- const std::vector<std::string>& files);
-
cmCPackDebGenerator::cmCPackDebGenerator()
{
}
@@ -672,23 +661,25 @@ int cmCPackDebGenerator::createDeb()
}
// ar -r your-package-name.deb debian-binary control.tar.* data.tar.*
- // since debian packages require BSD ar (most Linux distros and even
- // FreeBSD and NetBSD ship GNU ar) we use a copy of OpenBSD ar here.
- std::vector<std::string> arFiles;
- std::string topLevelString = strGenWDIR + "/";
- arFiles.push_back(topLevelString + "debian-binary");
- arFiles.push_back(topLevelString + "control.tar.gz");
- arFiles.push_back(topLevelString + "data.tar" + compression_suffix);
- std::string outputFileName = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
- outputFileName += "/";
- outputFileName += this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
- int res = ar_append(outputFileName.c_str(), arFiles);
- if (res != 0) {
- std::string tmpFile =
- this->GetOption("GEN_CPACK_TEMPORARY_PACKAGE_FILE_NAME");
- tmpFile += "/Deb.log";
- cmGeneratedFileStream ofs(tmpFile.c_str());
- ofs << "# Problem creating archive using: " << res << std::endl;
+ // A debian package .deb is simply an 'ar' archive. The only subtle
+ // difference is that debian uses the BSD ar style archive whereas most
+ // Linux distro have a GNU ar.
+ // See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=161593 for more info
+ std::string const outputDir = this->GetOption("CPACK_TOPLEVEL_DIRECTORY");
+ std::string const outputName = this->GetOption("GEN_CPACK_OUTPUT_FILE_NAME");
+ std::string const outputPath = outputDir + "/" + outputName;
+ std::string const tlDir = strGenWDIR + "/";
+ cmGeneratedFileStream debStream;
+ debStream.Open(outputPath.c_str(), false, true);
+ cmArchiveWrite deb(debStream, cmArchiveWrite::CompressNone, "arbsd");
+ if (!deb.Add(tlDir + "debian-binary", tlDir.length()) ||
+ !deb.Add(tlDir + "control.tar.gz", tlDir.length()) ||
+ !deb.Add(tlDir + "data.tar" + compression_suffix, tlDir.length())) {
+ cmCPackLogger(cmCPackLog::LOG_ERROR, "Error creating debian package:"
+ << std::endl
+ << "#top level directory: " << outputDir << std::endl
+ << "#file: " << outputName << std::endl
+ << "#error:" << deb.GetError() << std::endl);
return 0;
}
return 1;
@@ -718,246 +709,3 @@ std::string cmCPackDebGenerator::GetComponentInstallDirNameSuffix(
}
return componentName;
}
-
-// The following code is taken from OpenBSD ar:
-// http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ar/
-// It has been slightly modified:
-// -return error codes instead exit() in functions
-// -use the stdio file I/O functions instead the file descriptor based ones
-// -merged into one cxx file
-// -no additional options supported
-// The coding style hasn't been modified.
-
-/*-
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Hugh Smith at The University of Guelph.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- * 3. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
- */
-
-#define ARMAG "!<arch>\n" /* ar "magic number" */
-#define SARMAG 8 /* strlen(ARMAG); */
-
-#define AR_EFMT1 "#1/" /* extended format #1 */
-#define ARFMAG "`\n"
-
-/* Header format strings. */
-#define HDR1 "%s%-13d%-12ld%-6u%-6u%-8o%-10lld%2s"
-#define HDR2 "%-16.16s%-12ld%-6u%-6u%-8o%-10lld%2s"
-
-struct ar_hdr
-{
- char ar_name[16]; /* name */
- char ar_date[12]; /* modification time */
- char ar_uid[6]; /* user id */
- char ar_gid[6]; /* group id */
- char ar_mode[8]; /* octal file permissions */
- char ar_size[10]; /* size in bytes */
- char ar_fmag[2]; /* consistency check */
-};
-
-/* Set up file copy. */
-#define SETCF(from, fromname, to, toname, pad) \
- { \
- cf.rFile = from; \
- cf.rname = fromname; \
- cf.wFile = to; \
- cf.wname = toname; \
- cf.flags = pad; \
- }
-
-/* File copy structure. */
-typedef struct
-{
- FILE* rFile; /* read file descriptor */
- const char* rname; /* read name */
- FILE* wFile; /* write file descriptor */
- const char* wname; /* write name */
-#define NOPAD 0x00 /* don't pad */
-#define WPAD 0x02 /* pad on writes */
- unsigned int flags; /* pad flags */
-} CF;
-
-/* misc.c */
-
-static const char* ar_rname(const char* path)
-{
- const char* ind = strrchr(path, '/');
- return (ind) ? ind + 1 : path;
-}
-
-/* archive.c */
-
-typedef struct ar_hdr HDR;
-static char ar_hb[sizeof(HDR) + 1]; /* real header */
-
-static size_t ar_already_written;
-
-/* copy_ar --
- * Copy size bytes from one file to another - taking care to handle the
- * extra byte (for odd size files) when reading archives and writing an
- * extra byte if necessary when adding files to archive. The length of
- * the object is the long name plus the object itself; the variable
- * already_written gets set if a long name was written.
- *
- * The padding is really unnecessary, and is almost certainly a remnant
- * of early archive formats where the header included binary data which
- * a PDP-11 required to start on an even byte boundary. (Or, perhaps,
- * because 16-bit word addressed copies were faster?) Anyhow, it should
- * have been ripped out long ago.
- */
-static int copy_ar(CF* cfp, off_t size)
-{
- static char pad = '\n';
- off_t sz = size;
- size_t nr, nw;
- char buf[8 * 1024];
-
- if (sz == 0) {
- return 0;
- }
-
- FILE* from = cfp->rFile;
- FILE* to = cfp->wFile;
- while (sz &&
- (nr = fread(buf, 1, sz < static_cast<off_t>(sizeof(buf))
- ? static_cast<size_t>(sz)
- : sizeof(buf),
- from)) > 0) {
- sz -= static_cast<off_t>(nr);
- for (size_t off = 0; off < nr; nr -= off, off += nw) {
- if ((nw = fwrite(buf + off, 1, nr, to)) < nr) {
- return -1;
- }
- }
- }
- if (sz) {
- return -2;
- }
-
- if (cfp->flags & WPAD && (size + ar_already_written) & 1 &&
- fwrite(&pad, 1, 1, to) != 1) {
- return -4;
- }
-
- return 0;
-}
-
-/* put_arobj -- Write an archive member to a file. */
-static int put_arobj(CF* cfp, struct stat* sb)
-{
- int result = 0;
-
- /* If passed an sb structure, reading a file from disk. Get stat(2)
- * information, build a name and construct a header. (Files are named
- * by their last component in the archive.) */
- const char* name = ar_rname(cfp->rname);
- (void)stat(cfp->rname, sb);
-
- /* If not truncating names and the name is too long or contains
- * a space, use extended format 1. */
- size_t lname = strlen(name);
- uid_t uid = sb->st_uid;
- gid_t gid = sb->st_gid;
- if (uid > USHRT_MAX) {
- uid = USHRT_MAX;
- }
- if (gid > USHRT_MAX) {
- gid = USHRT_MAX;
- }
- if (lname > sizeof(ar_hdr().ar_name) || strchr(name, ' ')) {
- (void)sprintf(ar_hb, HDR1, AR_EFMT1, (int)lname, (long int)sb->st_mtime,
- (unsigned)uid, (unsigned)gid, (unsigned)sb->st_mode,
- (long long)sb->st_size + lname, ARFMAG);
- } else {
- lname = 0;
- (void)sprintf(ar_hb, HDR2, name, (long int)sb->st_mtime, (unsigned)uid,
- (unsigned)gid, (unsigned)sb->st_mode, (long long)sb->st_size,
- ARFMAG);
- }
- off_t size = sb->st_size;
-
- if (fwrite(ar_hb, 1, sizeof(HDR), cfp->wFile) != sizeof(HDR)) {
- return -1;
- }
-
- if (lname) {
- if (fwrite(name, 1, lname, cfp->wFile) != lname) {
- return -2;
- }
- ar_already_written = lname;
- }
- result = copy_ar(cfp, size);
- ar_already_written = 0;
- return result;
-}
-
-/* append.c */
-
-/* append --
- * Append files to the archive - modifies original archive or creates
- * a new archive if named archive does not exist.
- */
-static int ar_append(const char* archive,
- const std::vector<std::string>& files)
-{
- int eval = 0;
- FILE* aFile = cmSystemTools::Fopen(archive, "wb+");
- if (aFile != nullptr) {
- fwrite(ARMAG, SARMAG, 1, aFile);
- if (fseek(aFile, 0, SEEK_END) != -1) {
- CF cf;
- struct stat sb;
- /* Read from disk, write to an archive; pad on write. */
- SETCF(nullptr, nullptr, aFile, archive, WPAD);
- for (std::vector<std::string>::const_iterator fileIt = files.begin();
- fileIt != files.end(); ++fileIt) {
- const char* filename = fileIt->c_str();
- FILE* file = cmSystemTools::Fopen(filename, "rb");
- if (file == nullptr) {
- eval = -1;
- continue;
- }
- cf.rFile = file;
- cf.rname = filename;
- int result = put_arobj(&cf, &sb);
- (void)fclose(file);
- if (result != 0) {
- eval = -2;
- break;
- }
- }
- } else {
- eval = -3;
- }
- fclose(aFile);
- } else {
- eval = -4;
- }
- return eval;
-}