[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Reimplement mksplit.pl in C



[ I subscribed to the list, thanks for the Cc:'s ]

On Sat, Apr 03, 2010 at 12:20:52PM -0600, Marcelo E. Magallon wrote:

>  The two cases I can think of are splitting an archive that
>  splits to a single piece, splitting to multiple pieces and
>  some failure cases.

 Right now I do something like:

     cat test.deb |
     build-tree/dpkg-split/mksplit test.deb 1024 test 4608 2048 no
     cp test.deb test.deb.orig
     dpkg-split -j test*.deb
     cmp test.deb test.deb.orig && echo OK

 but not much more.

 I did some refactoring, and reused a couple of bits of libdpkg.
 I was hoping for libdpkg to have something like:

    package = get_deb_field("my_package.deb", "Package");

 but I didn't find it.  Did I miss it?  Is there something close
 to that?

 Anyways, the updated patches are attached.

 Marcelo
>From 40cbd26e938f3ffda58803c6e25d6e4c9a836b96 Mon Sep 17 00:00:00 2001
From: Marcelo E. Magallon <marcelo.magallon@gmail.com>
Date: Fri, 2 Apr 2010 22:27:50 -0600
Subject: [PATCH 1/5] Reimplement mksplit in C

My original intention was to do without some of the pipes, but for the
initial implementation this is just a translation of the original Perl
program into C, without much in the way of optimization.  It produces
the same output and exits in the same way as the original program (mod
exit status probably).

The reimplementation can use some refactoring love.
---
 dpkg-split/Makefile.am |   12 ++-
 dpkg-split/mksplit.c   |  279 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 288 insertions(+), 3 deletions(-)
 create mode 100644 dpkg-split/mksplit.c

diff --git a/dpkg-split/Makefile.am b/dpkg-split/Makefile.am
index 6f6043c..3ea9d00 100644
--- a/dpkg-split/Makefile.am
+++ b/dpkg-split/Makefile.am
@@ -24,10 +24,16 @@ dpkg_split_LDADD = \
 	../lib/compat/libcompat.a \
 	$(LIBINTL)
 
+mksplit_SOURCES = \
+	mksplit.c
 
-pkglib_SCRIPTS = mksplit
-EXTRA_DIST = mksplit.pl
-CLEANFILES = $(pkglib_SCRIPTS)
+mksplit_LDADD = \
+	../lib/dpkg/libdpkg.a \
+	../lib/compat/libcompat.a \
+	$(LIBINTL)
+
+pkglib_PROGRAMS = mksplit
+CLEANFILES = $(pkglib_PROGRAMS)
 
 
 do_perl_subst = $(AM_V_GEN) sed -e "s:^\#![:space:]*/usr/bin/perl:\#!$(PERL):"
diff --git a/dpkg-split/mksplit.c b/dpkg-split/mksplit.c
new file mode 100644
index 0000000..5ca34d6
--- /dev/null
+++ b/dpkg-split/mksplit.c
@@ -0,0 +1,279 @@
+/* This program is only supposed to be called by dpkg-split.
+ * Its arguments are:
+ * <sourcefile> <partsize> <prefix> <totalsize> <partsizeallow> <msdostruncyesno>
+ * Stdin is also redirected from the source archive by dpkg-split.
+ *
+ * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ * Copyright © 2010 Marcelo E. Magallon <mmagallo@debian.org>
+ *
+ * This is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <limits.h>
+#include <error.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#define MSDOS_PATH_MAX 10
+
+void checked_free(void *ptr)
+{
+    if (ptr) free(ptr);
+}
+
+void add(FILE *stream, char* id, char* data, size_t len)
+{
+    time_t current_time;
+
+    current_time = time(NULL);
+    fprintf(stream, "%-16s%-12d0     0     100644  %-10d%c\n",
+            id, (int)current_time, (int)len, 0140);
+    fwrite(data, 1, len, stream);
+    fprintf(stream, "%s", (len & 1) ? "\n" : "");
+}
+
+char* output(char *cmd)
+{
+    FILE * file = NULL;
+    int len = getpagesize();
+    char *result = (char *)malloc(len);
+    char *p = result;
+
+    if (result == NULL)
+        goto error_out;
+
+    if ((file = popen(cmd, "r")) == NULL)
+        goto error_out;
+
+    while (len > 0 && !feof(file))
+    {
+        int n;
+        n = fread(p, 1, len, file);
+        if (ferror(file))
+            goto error_out;
+        p += n;
+        len -= n;
+    }
+    goto out;
+
+error_out:
+    if (result)
+    {
+        free(result);
+        result = NULL;
+    }
+
+out:
+    if (file)
+        pclose(file);
+    return result;
+}
+
+char* get_field(char *filename, char *field)
+{
+    char *result;
+    char cmd[PATH_MAX];
+    sprintf(cmd, "dpkg-deb --field %s %s", filename, field);
+
+    result = output(cmd);
+    if (result)
+    {
+        char *p;
+        for (p = result + strlen(result) - 1; p >= result && isspace(*p); --p)
+            *p = 0;
+    }
+
+    return result;
+}
+
+char* get_md5sum(char *filename)
+{
+    char *result;
+    char cmd[PATH_MAX];
+    sprintf(cmd, "md5sum <%s", filename);
+
+    result = output(cmd);
+    if (result)
+    {
+        char *p;
+        for(p = result; *p && *p != ' '; ++p);
+        if (*p) *p = 0;
+    }
+
+    return result;
+}
+
+int main(int argc, char* argv[])
+{
+    char *sourcefile;
+    char *prefix;
+    char basename[PATH_MAX];
+    char *prefixdir = NULL;
+    char *cleanprefix = NULL;
+    char *package = NULL;
+    char *myversion = "2.1";
+    char *version = NULL;
+    char *revision = NULL;
+    char *csum = NULL;
+    char *data = NULL;
+    int partsize;
+    int orgsize;
+    size_t partsizeallow;
+    int msdos; /* yes = true, anything else = false */
+    int nparts;
+    int startat;
+    int showpartnum = 1;
+
+    if (argc != 7)
+        error(1, 0, "bad invocation\n");
+
+    sourcefile = argv[1];
+    partsize = atoi(argv[2]);
+    prefix = argv[3];
+    orgsize = atoi(argv[4]);
+    partsizeallow = (size_t)atoi(argv[5]);
+    msdos = strcmp(argv[6], "yes") == 0 ? 1 : 0;
+
+    package = get_field(sourcefile, "Package");
+    version = get_field(sourcefile, "Version");
+    revision = get_field(sourcefile, "Package_Revision");
+
+    if (version && revision && strlen(revision) > 0)
+    {
+        int n = strlen(version) + 1 + strlen(revision) + 1;
+        char *tmp = (char *)malloc(n*sizeof(char));
+        sprintf(tmp, "%s-%s", version, revision);
+        free(version);
+        version = tmp;
+    }
+
+    csum = get_md5sum(sourcefile);
+    nparts=(orgsize+partsize-1)/partsize;
+
+    printf("Splitting package %s into %d parts: ", package, nparts);
+
+    if (msdos)
+    {
+        char *p, *q;
+        prefixdir = strdup(prefix);
+        p = strrchr(prefixdir, '/');
+        if (p)
+        {
+            ++p;
+            cleanprefix = strdup(p);
+            *p = 0;
+        }
+        else
+        {
+            cleanprefix = strdup(prefix);
+            *prefixdir = 0;
+        }
+
+        for(p = q = cleanprefix; *p; ++p)
+        {
+            if (*p == '+')
+                *q++ = *p = 'x';
+            else if (isupper(*p))
+                *q++ = *p = tolower(*p);
+            else if (islower(*p) || isdigit(*p))
+                *q++ = *p;
+        }
+
+        *q = 0;
+    }
+
+    data = malloc(partsize);
+
+    for(startat = 0; startat < orgsize; startat += partsize)
+    {
+        char tmp[17];
+        char dsp[1024];
+        FILE *output;
+        size_t thispartreallen;
+
+        if (msdos)
+        {
+            int len;
+            char *p = basename;
+            len = snprintf(basename, MSDOS_PATH_MAX,
+                    "%dof%d", showpartnum, nparts);
+            p += snprintf(p, PATH_MAX, "%s/", prefixdir);
+            p += snprintf(p, MSDOS_PATH_MAX - len, "%s", cleanprefix);
+            snprintf(p, PATH_MAX - (p - basename),
+                    "%dof%d.deb", showpartnum, nparts);
+        }
+        else
+        {
+            snprintf(basename, PATH_MAX, "%s.%dof%d.deb",
+                    prefix, showpartnum, nparts);
+        }
+
+        output = fopen(basename, "w");
+
+        if (!output)
+        {
+            error(1, errno, "open %s", basename);
+        }
+
+        fprintf(output, "!<arch>\n");
+        printf("%d ", showpartnum);
+
+        snprintf(dsp, sizeof(dsp)/sizeof(*dsp),
+                 "%s\n"
+                 "%s\n"
+                 "%s\n"
+                 "%s\n"
+                 "%d\n"
+                 "%d\n"
+                 "%d/%d\n",
+                 myversion, package, version, csum, orgsize, partsize,
+                 showpartnum, nparts);
+        add(output, "debian-split", dsp, strlen(dsp));
+
+        thispartreallen = fread(data, 1, partsize, stdin);
+
+        snprintf(tmp, sizeof(tmp)/sizeof(*tmp), "data.%d", showpartnum);
+        add(output, tmp, data, thispartreallen);
+
+        if (thispartreallen > partsizeallow)
+        {
+            error(1, 0,
+                    "Header is too long, making part too long.  "
+                    "Your package name or version\n"
+                    "numbers must be extraordinarily long, or something.  "
+                    "Giving up.\n");
+        }
+
+        fclose(output);
+
+        ++showpartnum;
+    }
+
+    printf("done\n");
+
+    checked_free(data);
+    checked_free(prefixdir);
+    checked_free(cleanprefix);
+    checked_free(package);
+    checked_free(version);
+    checked_free(revision);
+    checked_free(csum);
+
+    return 0;
+}
-- 
1.7.0.3

>From fb9b2618645b04afb3f0563be1d56eaa4d0a8f45 Mon Sep 17 00:00:00 2001
From: Marcelo E. Magallon <marcelo.magallon@gmail.com>
Date: Sun, 4 Apr 2010 18:00:47 -0600
Subject: [PATCH 2/5] Add cislower and cisupper

Along the same vein as the already present functions, cislower(c) and
cisupper(c) consider only C-locale ranges.
---
 lib/dpkg/dpkg.h  |    2 ++
 lib/dpkg/utils.c |   10 +++++++++-
 2 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/lib/dpkg/dpkg.h b/lib/dpkg/dpkg.h
index 7f94417..c89017b 100644
--- a/lib/dpkg/dpkg.h
+++ b/lib/dpkg/dpkg.h
@@ -182,6 +182,8 @@ void m_output(FILE *f, const char *name);
 /*** from utils.c ***/
 
 int cisdigit(int c);
+int cislower(int c);
+int cisupper(int c);
 int cisalpha(int c);
 int cisspace(int c);
 
diff --git a/lib/dpkg/utils.c b/lib/dpkg/utils.c
index 178cb42..be017d2 100644
--- a/lib/dpkg/utils.c
+++ b/lib/dpkg/utils.c
@@ -33,8 +33,16 @@ int cisdigit(int c) {
 	return (c>='0') && (c<='9');
 }
 
+int cislower(int c) {
+	return (c>='a') && (c<='z');
+}
+
+int cisupper(int c) {
+	return (c>='A') && (c<='Z');
+}
+
 int cisalpha(int c) {
-	return ((c>='a') && (c<='z')) || ((c>='A') && (c<='Z'));
+	return (cislower(c) || cisupper(c));
 }
 
 int
-- 
1.7.0.3

>From 302b83a117721230ef9d48fe2e9d2146309bb3fd Mon Sep 17 00:00:00 2001
From: Marcelo E. Magallon <marcelo.magallon@gmail.com>
Date: Sun, 4 Apr 2010 18:03:33 -0600
Subject: [PATCH 3/5] Refactor the original mksplit implementation

Collect self-contained functionality in functions and clean up the
implementation a little bit.
---
 dpkg-split/mksplit.c |  300 ++++++++++++++++++++++++++++++++++++--------------
 1 files changed, 215 insertions(+), 85 deletions(-)

diff --git a/dpkg-split/mksplit.c b/dpkg-split/mksplit.c
index 5ca34d6..ed13e05 100644
--- a/dpkg-split/mksplit.c
+++ b/dpkg-split/mksplit.c
@@ -20,6 +20,7 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <stdlib.h>
 #include <time.h>
@@ -29,8 +30,14 @@
 #include <ctype.h>
 #include <errno.h>
 #include <unistd.h>
+#include "dpkg/dpkg.h"
 
-#define MSDOS_PATH_MAX 10
+/* 8 + '.' + 3 + terminating null */
+#define MSDOS_PATH_MAX 13
+
+#define ID_LEN 16
+
+const char thisname[]= "mksplit";
 
 void checked_free(void *ptr)
 {
@@ -42,35 +49,51 @@ void add(FILE *stream, char* id, char* data, size_t len)
     time_t current_time;
 
     current_time = time(NULL);
-    fprintf(stream, "%-16s%-12d0     0     100644  %-10d%c\n",
-            id, (int)current_time, (int)len, 0140);
+    fprintf(stream, "%-*s%-12d0     0     100644  %-10d%c\n",
+            ID_LEN, id, (int)current_time, (int)len, 0140);
     fwrite(data, 1, len, stream);
     fprintf(stream, "%s", (len & 1) ? "\n" : "");
 }
 
+/**
+ * Drain a stream, reading at most size bytes from it
+ *
+ * @param stream
+ * @param buf the preallocated buffer used to store the data
+ * @param size the size of the buffer
+ *
+ * @return the total number of bytes read or -1 on error
+ */
+int drain(FILE *stream, char *buf, size_t size)
+{
+    char *p = buf;
+
+    while (size > 0 && !feof(stream))
+    {
+        int n = fread(p, 1, size, stream);
+        if (ferror(stream))
+            return -1;
+        p += n;
+        size -= n;
+    }
+
+    return (size_t)(p - buf);
+}
+
 char* output(char *cmd)
 {
     FILE * file = NULL;
+    char *result = NULL;
     int len = getpagesize();
-    char *result = (char *)malloc(len);
-    char *p = result;
 
-    if (result == NULL)
+    if ((result = (char *)malloc(len)) == NULL)
         goto error_out;
 
     if ((file = popen(cmd, "r")) == NULL)
         goto error_out;
 
-    while (len > 0 && !feof(file))
-    {
-        int n;
-        n = fread(p, 1, len, file);
-        if (ferror(file))
-            goto error_out;
-        p += n;
-        len -= n;
-    }
-    goto out;
+    if (drain(file, result, len) >= 0)
+        goto out;
 
 error_out:
     if (result)
@@ -113,28 +136,179 @@ char* get_md5sum(char *filename)
     {
         char *p;
         for(p = result; *p && *p != ' '; ++p);
-        if (*p) *p = 0;
+        *p = 0;
     }
 
     return result;
 }
 
+/**
+ * Extract the filename from the given path
+ *
+ * @param path
+ *
+ * @return the filename component of path.  If path does not contain a /
+ * returns a newly allocated string with a copy of the original path.
+ */
+char* dbasename(char *filename)
+{
+    char *p = strrchr(filename, '/');
+    return p ? strdup(++p) : strdup(filename);
+}
+
+/**
+ * Extract the directory name from the given path
+ *
+ * @param path
+ *
+ * @return a newly allocated string with the directory component of
+ * path, including a trailing / or an empty string if the path does not
+ * contain a /
+ */
+char* ddirname(char *path)
+{
+    char *p = strrchr(path, '/');
+    return p ? strndup(path, (size_t)(++p - path)) : strdup("");
+}
+
+int minimum(int a, int b)
+{
+    return a < b ? a : b;
+}
+
+int maximum(int a, int b)
+{
+    return a > b ? a : b;
+}
+
+/**
+ * Make a MSDOS-friendly name
+ *
+ * @param filename the filename to modify
+ *
+ * @return the original parameter
+ *
+ * Modifies a filename in place, possibly making it shorter in the
+ * process.
+ *
+ * Every '+' in the input is replaced by an 'x'.
+ * Uppercase letters are replaced by their lowercase versions.
+ * Lowercase letters and digits are preserved.
+ * Anything else is discarded.
+ */
+char* msdosize(char *filename)
+{
+    if (filename != NULL)
+    {
+        char *p, *q;
+
+        for(p = q = filename; *p; ++p)
+        {
+            if (*p == '+')
+                *q++ = *p = 'x';
+            else if (cisupper(*p))
+                *q++ = *p = tolower(*p);
+            else if (cislower(*p) || cisdigit(*p))
+                *q++ = *p;
+        }
+
+        *q = 0;
+    }
+
+    return filename;
+}
+
+char * deb_get_version(char *filename)
+{
+    char *version, *revision;
+
+    version = get_field(filename, "Version");
+    revision = get_field(filename, "Package_Revision");
+
+    if (version && revision && strlen(revision) > 0)
+    {
+        /* version-revision plus terminating null */
+        int n = strlen(version) + 1 + strlen(revision) + 1;
+        char *tmp = (char *)malloc(n*sizeof(char));
+        sprintf(tmp, "%s-%s", version, revision);
+        free(version);
+        version = tmp;
+    }
+
+    checked_free(revision);
+
+    return version;
+}
+
+/**
+ * Create a filename for part i
+ *
+ * @param buf the buffer with the new name
+ * @param size the size of the buffer, in bytes
+ * @param prefix a string to be prepended as is to the new name
+ * @param name the original name of the file
+ * @param i the index of the current part
+ * @param total the total number of parts
+ *
+ * @return nothing
+ *
+ * If "name" is null then a simple name is generated using the
+ * template "<prefix>.<i>of<total>.deb".  Otherwise this function
+ * tries to generate a name that will fit within the 8+3
+ * character limit of MSDOS.  When USE_ORIGINAL_MKSPLIT_FILENAMES
+ * is defined, this fails miserably if the total number of parts
+ * is larger than 999.
+ */
+void make_name(
+        char *buf, size_t size,
+        char *prefix, char *name,
+        int i, int total)
+{
+    memset(buf, 0, size);
+    if (name != NULL)
+    {
+        int l;
+        /* required chars not counting terminating null */
+#if defined(USE_ORIGINAL_MKSPLIT_FILENAMES)
+        int req = snprintf(buf, MSDOS_PATH_MAX, "%dof%d.deb", i, total);
+#else
+        int req = snprintf(buf, size, "%d", total);
+#endif
+        int n = snprintf(buf, size, "%s", prefix);
+        size -= n;
+        l = MSDOS_PATH_MAX - 1 - req;
+        l = minimum(l, strlen(name));
+        l = minimum(l, size-1);
+        l = maximum(l, 0);
+        strncpy(buf+n, name, l);
+        n += l;
+        size -= l;
+#if defined(USE_ORIGINAL_MKSPLIT_FILENAMES)
+        snprintf(buf+n, size, "%dof%d.deb", i, total);
+#else
+        snprintf(buf+n, size, "%0*d.deb", req, i);
+#endif
+    }
+    else
+    {
+        snprintf(buf, size, "%s.%dof%d.deb", prefix, i, total);
+    }
+}
+
 int main(int argc, char* argv[])
 {
     char *sourcefile;
     char *prefix;
-    char basename[PATH_MAX];
     char *prefixdir = NULL;
     char *cleanprefix = NULL;
     char *package = NULL;
     char *myversion = "2.1";
     char *version = NULL;
-    char *revision = NULL;
     char *csum = NULL;
     char *data = NULL;
     int partsize;
     int orgsize;
-    size_t partsizeallow;
+    int partsizeallow;
     int msdos; /* yes = true, anything else = false */
     int nparts;
     int startat;
@@ -147,21 +321,12 @@ int main(int argc, char* argv[])
     partsize = atoi(argv[2]);
     prefix = argv[3];
     orgsize = atoi(argv[4]);
-    partsizeallow = (size_t)atoi(argv[5]);
+    partsizeallow = atoi(argv[5]);
     msdos = strcmp(argv[6], "yes") == 0 ? 1 : 0;
+    msdos = 1;
 
     package = get_field(sourcefile, "Package");
-    version = get_field(sourcefile, "Version");
-    revision = get_field(sourcefile, "Package_Revision");
-
-    if (version && revision && strlen(revision) > 0)
-    {
-        int n = strlen(version) + 1 + strlen(revision) + 1;
-        char *tmp = (char *)malloc(n*sizeof(char));
-        sprintf(tmp, "%s-%s", version, revision);
-        free(version);
-        version = tmp;
-    }
+    version = deb_get_version(sourcefile);
 
     csum = get_md5sum(sourcefile);
     nparts=(orgsize+partsize-1)/partsize;
@@ -170,66 +335,31 @@ int main(int argc, char* argv[])
 
     if (msdos)
     {
-        char *p, *q;
+        prefixdir = ddirname(prefix);
+        cleanprefix = msdosize(dbasename(prefix));
+    }
+    else
+    {
         prefixdir = strdup(prefix);
-        p = strrchr(prefixdir, '/');
-        if (p)
-        {
-            ++p;
-            cleanprefix = strdup(p);
-            *p = 0;
-        }
-        else
-        {
-            cleanprefix = strdup(prefix);
-            *prefixdir = 0;
-        }
-
-        for(p = q = cleanprefix; *p; ++p)
-        {
-            if (*p == '+')
-                *q++ = *p = 'x';
-            else if (isupper(*p))
-                *q++ = *p = tolower(*p);
-            else if (islower(*p) || isdigit(*p))
-                *q++ = *p;
-        }
-
-        *q = 0;
     }
 
     data = malloc(partsize);
 
     for(startat = 0; startat < orgsize; startat += partsize)
     {
-        char tmp[17];
+        char partname[PATH_MAX];
+        char id[ID_LEN+1];
         char dsp[1024];
         FILE *output;
-        size_t thispartreallen;
+        int thispartreallen;
 
-        if (msdos)
-        {
-            int len;
-            char *p = basename;
-            len = snprintf(basename, MSDOS_PATH_MAX,
-                    "%dof%d", showpartnum, nparts);
-            p += snprintf(p, PATH_MAX, "%s/", prefixdir);
-            p += snprintf(p, MSDOS_PATH_MAX - len, "%s", cleanprefix);
-            snprintf(p, PATH_MAX - (p - basename),
-                    "%dof%d.deb", showpartnum, nparts);
-        }
-        else
-        {
-            snprintf(basename, PATH_MAX, "%s.%dof%d.deb",
-                    prefix, showpartnum, nparts);
-        }
+        make_name(partname, sizeof(partname)/sizeof(*partname),
+                prefixdir, cleanprefix, showpartnum, nparts);
 
-        output = fopen(basename, "w");
+        output = fopen(partname, "w");
 
         if (!output)
-        {
-            error(1, errno, "open %s", basename);
-        }
+            error(1, errno, "open %s", partname);
 
         fprintf(output, "!<arch>\n");
         printf("%d ", showpartnum);
@@ -246,19 +376,20 @@ int main(int argc, char* argv[])
                  showpartnum, nparts);
         add(output, "debian-split", dsp, strlen(dsp));
 
-        thispartreallen = fread(data, 1, partsize, stdin);
+        thispartreallen = drain(stdin, data, partsize);
+        if (thispartreallen < 0)
+            /* The original implementation didn't do this */
+            error(1, errno, "Failed to read data from stdin.");
 
-        snprintf(tmp, sizeof(tmp)/sizeof(*tmp), "data.%d", showpartnum);
-        add(output, tmp, data, thispartreallen);
+        snprintf(id, sizeof(id)/sizeof(*id), "data.%d", showpartnum);
+        add(output, id, data, thispartreallen);
 
         if (thispartreallen > partsizeallow)
-        {
             error(1, 0,
                     "Header is too long, making part too long.  "
                     "Your package name or version\n"
                     "numbers must be extraordinarily long, or something.  "
                     "Giving up.\n");
-        }
 
         fclose(output);
 
@@ -272,7 +403,6 @@ int main(int argc, char* argv[])
     checked_free(cleanprefix);
     checked_free(package);
     checked_free(version);
-    checked_free(revision);
     checked_free(csum);
 
     return 0;
-- 
1.7.0.3

>From 1b3fc7a66d8335110c5f090ecd69043427ea6e4e Mon Sep 17 00:00:00 2001
From: Marcelo E. Magallon <marcelo.magallon@gmail.com>
Date: Sun, 4 Apr 2010 18:38:53 -0600
Subject: [PATCH 4/5] Use libdpkg to compute md5sum

---
 dpkg-split/mksplit.c |   20 +++++++++++++-------
 1 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/dpkg-split/mksplit.c b/dpkg-split/mksplit.c
index ed13e05..1a566ea 100644
--- a/dpkg-split/mksplit.c
+++ b/dpkg-split/mksplit.c
@@ -31,6 +31,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include "dpkg/dpkg.h"
+#include "dpkg/buffer.h"
 
 /* 8 + '.' + 3 + terminating null */
 #define MSDOS_PATH_MAX 13
@@ -128,15 +129,20 @@ char* get_field(char *filename, char *field)
 char* get_md5sum(char *filename)
 {
     char *result;
-    char cmd[PATH_MAX];
-    sprintf(cmd, "md5sum <%s", filename);
+    char hash[MD5HASHLEN+1];
+    FILE *h;
 
-    result = output(cmd);
-    if (result)
+    h = fopen(filename, "r");
+
+    if (h)
     {
-        char *p;
-        for(p = result; *p && *p != ' '; ++p);
-        *p = 0;
+        stream_md5(h, hash, -1, "md5hash");
+        fclose(h);
+        result = strdup(hash);
+    }
+    else
+    {
+        result = NULL;
     }
 
     return result;
-- 
1.7.0.3

>From 8d77dee2c4d6d29112458c96a6cb25769617a2bd Mon Sep 17 00:00:00 2001
From: Marcelo E. Magallon <marcelo.magallon@gmail.com>
Date: Sun, 4 Apr 2010 20:58:20 -0600
Subject: [PATCH 5/5] Use DEBEXT from dpkg.h

---
 dpkg-split/mksplit.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/dpkg-split/mksplit.c b/dpkg-split/mksplit.c
index 1a566ea..cca4311 100644
--- a/dpkg-split/mksplit.c
+++ b/dpkg-split/mksplit.c
@@ -276,7 +276,7 @@ void make_name(
         int l;
         /* required chars not counting terminating null */
 #if defined(USE_ORIGINAL_MKSPLIT_FILENAMES)
-        int req = snprintf(buf, MSDOS_PATH_MAX, "%dof%d.deb", i, total);
+        int req = snprintf(buf, MSDOS_PATH_MAX, "%dof%d" DEBEXT, i, total);
 #else
         int req = snprintf(buf, size, "%d", total);
 #endif
@@ -290,14 +290,14 @@ void make_name(
         n += l;
         size -= l;
 #if defined(USE_ORIGINAL_MKSPLIT_FILENAMES)
-        snprintf(buf+n, size, "%dof%d.deb", i, total);
+        snprintf(buf+n, size, "%dof%d" DEBEXT, i, total);
 #else
-        snprintf(buf+n, size, "%0*d.deb", req, i);
+        snprintf(buf+n, size, "%0*d" DEBEXT, req, i);
 #endif
     }
     else
     {
-        snprintf(buf, size, "%s.%dof%d.deb", prefix, i, total);
+        snprintf(buf, size, "%s.%dof%d" DEBEXT, prefix, i, total);
     }
 }
 
-- 
1.7.0.3


Reply to: