---
dpkg-deb/build.c | 346 ++++++++++++++++++++++++++++++++----------------------
1 file changed, 207 insertions(+), 139 deletions(-)
diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c
index 348e01e..703136a 100644
--- a/dpkg-deb/build.c
+++ b/dpkg-deb/build.c
@@ -382,79 +382,39 @@ pkg_get_pathname(const char *dir, struct pkginfo *pkg)
return path;
}
-/**
- * Overly complex function that builds a .deb file.
- */
-int
-do_build(const char *const *argv)
+static void
+compress_control_tar(int input_fd, int gzfd)
{
- struct dpkg_error err;
- const char *debar, *dir;
- bool subdir;
- char *tfbuf;
- int arfd;
- int p1[2], p2[2], p3[2], gzfd;
- pid_t c1,c2,c3;
- struct file_info *fi;
- struct file_info *symlist = NULL;
- struct file_info *symlist_end = NULL;
+ pid_t c;
- /* Decode our arguments. */
- dir = *argv++;
- if (!dir)
- badusage(_("--%s needs a <directory> argument"), cipaction->olong);
- subdir = false;
- debar = *argv++;
- if (debar != NULL) {
- struct stat debarstab;
-
- if (*argv)
- badusage(_("--%s takes at most two arguments"), cipaction->olong);
+ /* And run gzip to compress our control archive. */
+ c = subproc_fork();
+ if (!c) {
+ struct compress_params params;
- if (stat(debar, &debarstab)) {
- if (errno != ENOENT)
- ohshite(_("unable to check for existence of archive `%.250s'"), debar);
- } else if (S_ISDIR(debarstab.st_mode)) {
- subdir = true;
- }
- } else {
- char *m;
+ params.type = compressor_type_gzip;
+ params.strategy = compressor_strategy_none;
+ params.level = 9;
- m= m_malloc(strlen(dir) + sizeof(DEBEXT));
- strcpy(m, dir);
- path_trim_slash_slashdot(m);
- strcat(m, DEBEXT);
- debar= m;
+ compress_filter(¶ms, input_fd, gzfd, _("compressing control member"));
+ exit(0);
}
+ close(input_fd);
+ subproc_wait_check(c, "gzip -9c", 0);
+}
- /* Perform some sanity checks on the to-be-build package. */
- if (nocheckflag) {
- if (subdir)
- ohshit(_("target is directory - cannot skip control file check"));
- warning(_("not checking contents of control area"));
- printf(_("dpkg-deb: building an unknown package in '%s'.\n"), debar);
- } else {
- struct pkginfo *pkg;
-
- pkg = check_new_pkg(dir);
- if (subdir)
- debar = pkg_get_pathname(debar, pkg);
- printf(_("dpkg-deb: building package `%s' in `%s'.\n"),
- pkg->set->name, debar);
- }
- m_output(stdout, _("<standard output>"));
+static void
+create_control_tar(const char *dir, int gzfd)
+{
+ int p[2];
+ pid_t c;
- /* Now that we have verified everything its time to actually
- * build something. Let's start by making the ar-wrapper. */
- arfd = creat(debar, 0644);
- if (arfd < 0)
- ohshite(_("unable to create `%.255s'"), debar);
/* Fork a tar to package the control-section of the package. */
unsetenv("TAR_OPTIONS");
- m_pipe(p1);
- c1 = subproc_fork();
- if (!c1) {
- m_dup2(p1[1],1); close(p1[0]); close(p1[1]);
+ m_pipe(p);
+ c = subproc_fork();
+ if (!c) {
+ m_dup2(p[1], 1); close(p[0]); close(p[1]);
if (chdir(dir))
ohshite(_("failed to chdir to `%.255s'"), dir);
if (chdir(BUILDCONTROLDIR))
@@ -462,88 +422,85 @@ do_build(const char *const *argv)
execlp(TAR, "tar", "-cf", "-", "--format=gnu", ".", NULL);
ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
}
- close(p1[1]);
+ close(p[1]);
+
+ compress_control_tar(p[0], gzfd);
+ subproc_wait_check(c, "tar -cf", 0);
+}
+
+static void
+write_format_zero_deb_header(const char *debar, int arfd, int gzfd)
+{
+ struct dpkg_error err;
+ struct stat controlstab;
+ char versionbuf[40];
+
+ if (fstat(gzfd, &controlstab))
+ ohshite(_("failed to stat temporary file (%s)"), _("control member"));
+ sprintf(versionbuf, "%-8s\n%jd\n", OLDARCHIVEVERSION,
+ (intmax_t)controlstab.st_size);
+ if (fd_write(arfd, versionbuf, strlen(versionbuf)) < 0)
+ ohshite(_("error writing `%s'"), debar);
+ if (fd_fd_copy(gzfd, arfd, -1, &err) < 0)
+ ohshit(_("cannot copy '%s' into archive '%s': %s"), _("control member"),
+ debar, err.str);
+}
+
+static void
+write_deb_header(const char *debar, int arfd, int gzfd)
+{
+ const char deb_magic[] = ARCHIVEVERSION "\n";
+
+ /* Ensure that we start at the beginning */
+ if (lseek(gzfd, 0, SEEK_SET))
+ ohshite(_("failed to rewind temporary file (%s)"), _("control member"));
+
+ if (deb_format.major == 0) {
+ write_format_zero_deb_header(debar, arfd, gzfd);
+ return;
+ }
+
+ dpkg_ar_put_magic(debar, arfd);
+ dpkg_ar_member_put_mem(debar, arfd, DEBMAGIC, deb_magic, strlen(deb_magic));
+ dpkg_ar_member_put_file(debar, arfd, ADMINMEMBER, gzfd, -1);
+}
+
+static int
+setup_temp_gz(char const * target_name)
+{
+ char *tfbuf;
+ int gzfd;
+
/* Create a temporary file to store the control data in. Immediately
* unlink our temporary file so others can't mess with it. */
tfbuf = path_make_temp_template("dpkg-deb");
gzfd = mkstemp(tfbuf);
if (gzfd == -1)
- ohshite(_("failed to make temporary file (%s)"), _("control member"));
+ ohshite(_("failed to make temporary file (%s)"), target_name);
/* Make sure it's gone, the fd will remain until we close it. */
if (unlink(tfbuf))
- ohshit(_("failed to unlink temporary file (%s), %s"), _("control member"),
+ ohshit(_("failed to unlink temporary file (%s), %s"), target_name,
tfbuf);
free(tfbuf);
+ return gzfd;
+}
- /* And run gzip to compress our control archive. */
- c2 = subproc_fork();
- if (!c2) {
- struct compress_params params;
-
- params.type = compressor_type_gzip;
- params.strategy = compressor_strategy_none;
- params.level = 9;
-
- compress_filter(¶ms, p1[0], gzfd, _("compressing control member"));
- exit(0);
- }
- close(p1[0]);
- subproc_wait_check(c2, "gzip -9c", 0);
- subproc_wait_check(c1, "tar -cf", 0);
-
- if (lseek(gzfd, 0, SEEK_SET))
- ohshite(_("failed to rewind temporary file (%s)"), _("control member"));
-
- /* We have our first file for the ar-archive. Write a header for it
- * to the package and insert it. */
- if (deb_format.major == 0) {
- struct stat controlstab;
- char versionbuf[40];
-
- if (fstat(gzfd, &controlstab))
- ohshite(_("failed to stat temporary file (%s)"), _("control member"));
- sprintf(versionbuf, "%-8s\n%jd\n", OLDARCHIVEVERSION,
- (intmax_t)controlstab.st_size);
- if (fd_write(arfd, versionbuf, strlen(versionbuf)) < 0)
- ohshite(_("error writing `%s'"), debar);
- if (fd_fd_copy(gzfd, arfd, -1, &err) < 0)
- ohshit(_("cannot copy '%s' into archive '%s': %s"), _("control member"),
- debar, err.str);
- } else {
- const char deb_magic[] = ARCHIVEVERSION "\n";
-
- dpkg_ar_put_magic(debar, arfd);
- dpkg_ar_member_put_mem(debar, arfd, DEBMAGIC, deb_magic, strlen(deb_magic));
- dpkg_ar_member_put_file(debar, arfd, ADMINMEMBER, gzfd, -1);
- }
- close(gzfd);
+static void
+create_data_tar(const char *dir, int gzfd)
+{
+ int p1[2], p2[2], p3[2];
+ pid_t c1, c2, c3;
+ struct file_info *fi;
+ struct file_info *symlist = NULL;
+ struct file_info *symlist_end = NULL;
- /* Control is done, now we need to archive the data. */
- if (deb_format.major == 0) {
- /* In old format, the data member is just concatenated after the
- * control member, so we do not need a temporary file and can use
- * the compression file descriptor. */
- gzfd = arfd;
- } else {
- /* Start by creating a new temporary file. Immediately unlink the
- * temporary file so others can't mess with it. */
- tfbuf = path_make_temp_template("dpkg-deb");
- gzfd = mkstemp(tfbuf);
- if (gzfd == -1)
- ohshite(_("failed to make temporary file (%s)"), _("data member"));
- /* Make sure it's gone, the fd will remain until we close it. */
- if (unlink(tfbuf))
- ohshit(_("failed to unlink temporary file (%s), %s"), _("data member"),
- tfbuf);
- free(tfbuf);
- }
/* Fork off a tar. We will feed it a list of filenames on stdin later. */
m_pipe(p1);
m_pipe(p2);
c1 = subproc_fork();
if (!c1) {
- m_dup2(p1[0],0); close(p1[0]); close(p1[1]);
- m_dup2(p2[1],1); close(p2[0]); close(p2[1]);
+ m_dup2(p1[0], 0); close(p1[0]); close(p1[1]);
+ m_dup2(p2[1], 1); close(p2[0]); close(p2[1]);
if (chdir(dir))
ohshite(_("failed to chdir to `%.255s'"), dir);
execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "-T", "-", "--no-recursion", NULL);
@@ -565,7 +522,7 @@ do_build(const char *const *argv)
m_pipe(p3);
c3 = subproc_fork();
if (!c3) {
- m_dup2(p3[1],1); close(p3[0]); close(p3[1]);
+ m_dup2(p3[1], 1); close(p3[0]); close(p3[1]);
if (chdir(dir))
ohshite(_("failed to chdir to `%.255s'"), dir);
execlp(FIND, "find", ".", "-path", "./" BUILDCONTROLDIR, "-prune", "-o",
@@ -595,17 +552,128 @@ do_build(const char *const *argv)
file_info_list_free(symlist);
subproc_wait_check(c2, _("<compress> from tar -cf"), 0);
subproc_wait_check(c1, "tar -cf", 0);
- /* Okay, we have data.tar as well now, add it to the ar wrapper. */
- if (deb_format.major == 2) {
- char datamember[16 + 1];
+}
- sprintf(datamember, "%s%s", DATAMEMBER,
- compressor_get_extension(compress_params.type));
+static void
+write_data_tar(const char *debar, int arfd, int gzfd)
+{
+ char datamember[16 + 1];
+
+ sprintf(datamember, "%s%s", DATAMEMBER,
+ compressor_get_extension(compress_params.type));
+
+ if (lseek(gzfd, 0, SEEK_SET))
+ ohshite(_("failed to rewind temporary file (%s)"), _("data member"));
- if (lseek(gzfd, 0, SEEK_SET))
- ohshite(_("failed to rewind temporary file (%s)"), _("data member"));
+ dpkg_ar_member_put_file(debar, arfd, datamember, gzfd, -1);
+}
- dpkg_ar_member_put_file(debar, arfd, datamember, gzfd, -1);
+static void
+decode_arguments(const char *const *argv, const char **dir, bool *subdir, const char **debar)
+{
+ *dir = *argv++;
+ if (!*dir)
+ badusage(_("--%s needs a <directory> argument"), cipaction->olong);
+ *subdir = false;
+ *debar = *argv++;
+ if (*debar != NULL) {
+ struct stat debarstab;
+
+ if (*argv)
+ badusage(_("--%s takes at most two arguments"), cipaction->olong);
+
+ if (stat(*debar, &debarstab)) {
+ if (errno != ENOENT)
+ ohshite(_("unable to check for existence of archive `%.250s'"), *debar);
+ } else if (S_ISDIR(debarstab.st_mode)) {
+ *subdir = true;
+ }
+ } else {
+ char *m;
+
+ m = m_malloc(strlen(*dir) + sizeof(DEBEXT));
+ strcpy(m, *dir);
+ path_trim_slash_slashdot(m);
+ strcat(m, DEBEXT);
+ *debar = m;
+ }
+}
+
+static void
+check_build_sanity(const char *dir, bool subdir, const char **debar)
+{
+ if (nocheckflag) {
+ if (subdir)
+ ohshit(_("target is directory - cannot skip control file check"));
+ warning(_("not checking contents of control area"));
+ printf(_("dpkg-deb: building an unknown package in '%s'.\n"), *debar);
+ } else {
+ struct pkginfo *pkg;
+
+ pkg = check_new_pkg(dir);
+ if (subdir)
+ *debar = pkg_get_pathname(*debar, pkg);
+ printf(_("dpkg-deb: building package `%s' in `%s'.\n"),
+ pkg->set->name, *debar);
+ }
+ m_output(stdout, _("<standard output>")); // XXX-lunar: what is this for?
+}
+
+static int
+initialize_ar(const char *debar)
+{
+ int arfd;
+
+ arfd = creat(debar, 0644);
+ if (arfd < 0)
+ ohshite(_("unable to create `%.255s'"), debar);
+ return arfd;
+}
+
+/**
+ * Overly complex function that builds a .deb file.
+ */
+int
+do_build(const char *const *argv)
+{
+ const char *debar, *dir;
+ bool subdir;
+ int arfd;
+ int gzfd;
+
+ /* Decode our arguments. */
+ decode_arguments(argv, &dir, &subdir, &debar);
+
+ /* Perform some sanity checks on the to-be-build package. */
+ check_build_sanity(dir, subdir, &debar);
+
+ /* Now that we have verified everything its time to actually
+ * build something. Let's start by making the ar-wrapper. */
+ arfd = initialize_ar(debar);
+
+ gzfd = setup_temp_gz(_("control member"));
+
+ create_control_tar(dir, gzfd);
+
+ /* We have our first file for the ar-archive. Write a header for it
+ * to the package and insert it. */
+ write_deb_header(debar, arfd, gzfd);
+
+ close(gzfd);
+
+ /* Control is done, now we need to archive the data. */
+ if (deb_format.major == 0) {
+ /* In old format, the data member is just concatenated after the
+ * control member, so we do not need a temporary file and can use
+ * the compression file descriptor. */
+ gzfd = arfd;
+ } else {
+ gzfd = setup_temp_gz(_("data member"));
+ }
+ create_data_tar(dir, gzfd);
+ /* Okay, we have data.tar as well now, add it to the ar wrapper. */
+ if (deb_format.major == 2) {
+ write_data_tar(debar, arfd, gzfd);
}
if (fsync(arfd))
ohshite(_("unable to sync file '%s'"), debar);
--
Lunar .''`.
lunar@debian.org : :Ⓐ : # apt-get install anarchism
`. `'`
`-
Attachment:
signature.asc
Description: Digital signature