--- 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