2 * dpkg-split - splitting and joining of multipart *.deb archives
3 * split.c - splitting archives
5 * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 * Copyright © 2008-2015 Guillem Jover <guillem@debian.org>
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
25 #include <sys/types.h>
40 #include <dpkg/i18n.h>
41 #include <dpkg/c-ctype.h>
42 #include <dpkg/dpkg.h>
43 #include <dpkg/dpkg-db.h>
44 #include <dpkg/parsedump.h>
45 #include <dpkg/path.h>
46 #include <dpkg/string.h>
47 #include <dpkg/subproc.h>
48 #include <dpkg/buffer.h>
50 #include <dpkg/options.h>
52 #include "dpkg-split.h"
55 * Parse the control file from a .deb package into a struct pkginfo.
57 static struct pkginfo *
58 deb_parse_control(const char *filename)
60 struct parsedb_state *ps;
69 /* Child writes to pipe. */
74 execlp(BACKEND, BACKEND, "--info", filename, "control", NULL);
75 ohshite(_("unable to execute %s (%s)"),
76 _("package field value extraction"), BACKEND);
80 /* Parent reads from pipe. */
81 ps = parsedb_new(_("<dpkg-deb --info pipe>"), p[0], pdb_parse_binary);
83 parsedb_parse(ps, &pkg);
88 subproc_reap(pid, _("package field value extraction"), SUBPROC_NOPIPE);
94 parse_timestamp(const char *value)
100 timestamp = strtol(value, &end, 10);
101 if (value == end || *end || errno != 0)
102 ohshite(_("unable to parse timestamp '%.255s'"), value);
107 /* Cleanup filename for use in crippled msdos systems. */
109 clean_msdos_filename(char *filename)
113 for (s = d = filename; *s; d++, s++) {
116 else if (c_isupper(*s))
118 else if (c_islower(*s) || c_isdigit(*s))
128 mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
132 struct dpkg_error err;
136 const char *timestamp_str;
138 char hash[MD5HASHLEN + 1];
141 off_t cur_partsize, last_partsize;
142 char *prefixdir = NULL, *msdos_prefix = NULL;
143 struct varbuf file_dst = VARBUF_INIT;
144 struct varbuf partmagic = VARBUF_INIT;
145 struct varbuf partname = VARBUF_INIT;
147 fd_src = open(file_src, O_RDONLY);
149 ohshite(_("unable to open source file '%.250s'"), file_src);
150 if (fstat(fd_src, &st))
151 ohshite(_("unable to fstat source file"));
152 if (!S_ISREG(st.st_mode))
153 ohshit(_("source file '%.250s' not a plain file"), file_src);
155 if (fd_md5(fd_src, hash, -1, &err) < 0)
156 ohshit(_("cannot compute MD5 hash for file '%s': %s"),
158 lseek(fd_src, 0, SEEK_SET);
160 pkg = deb_parse_control(file_src);
161 version = versiondescribe(&pkg->available.version, vdew_nonambig);
163 timestamp_str = getenv("SOURCE_DATE_EPOCH");
165 timestamp = parse_timestamp(timestamp_str);
167 timestamp = time(NULL);
169 partsize = maxpartsize - HEADERALLOWANCE;
170 last_partsize = st.st_size % partsize;
171 if (last_partsize == 0)
172 last_partsize = partsize;
173 nparts = (st.st_size + partsize - 1) / partsize;
175 printf(P_("Splitting package %s into %d part: ",
176 "Splitting package %s into %d parts: ", nparts),
177 pkg->set->name, nparts);
182 t = m_strdup(prefix);
183 prefixdir = m_strdup(dirname(t));
186 msdos_prefix = m_strdup(path_basename(prefix));
187 prefix = clean_msdos_filename(msdos_prefix);
190 for (curpart = 1; curpart <= nparts; curpart++) {
193 varbuf_reset(&file_dst);
194 /* Generate output filename. */
199 refname = str_fmt("%dof%d", curpart, nparts);
200 prefix_max = max(8 - strlen(refname), 0);
201 varbuf_printf(&file_dst, "%s/%.*s%.8s.deb",
202 prefixdir, prefix_max, prefix, refname);
205 varbuf_printf(&file_dst, "%s.%dof%d.deb",
206 prefix, curpart, nparts);
209 if (curpart == nparts)
210 cur_partsize = last_partsize;
212 cur_partsize = partsize;
214 if (cur_partsize > maxpartsize) {
215 ohshit(_("header is too long, making part too long; "
216 "the package name or version\n"
217 "numbers must be extraordinarily long, "
218 "or something; giving up"));
221 /* Split the data. */
222 ar = dpkg_ar_create(file_dst.buf, 0644);
223 dpkg_ar_set_mtime(ar, timestamp);
225 /* Write the ar header. */
226 dpkg_ar_put_magic(ar);
228 /* Write the debian-split part. */
229 varbuf_printf(&partmagic,
230 "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n",
231 SPLITVERSION, pkg->set->name, version, hash,
232 (intmax_t)st.st_size, (intmax_t)partsize,
233 curpart, nparts, pkg->available.arch->name);
234 dpkg_ar_member_put_mem(ar, PARTMAGIC,
235 partmagic.buf, partmagic.used);
236 varbuf_reset(&partmagic);
238 /* Write the data part. */
239 varbuf_printf(&partname, "data.%d", curpart);
240 dpkg_ar_member_put_file(ar, partname.buf,
241 fd_src, cur_partsize);
242 varbuf_reset(&partname);
246 printf("%d ", curpart);
249 varbuf_destroy(&file_dst);
250 varbuf_destroy(&partname);
251 varbuf_destroy(&partmagic);
264 do_split(const char *const *argv)
266 const char *sourcefile, *prefix;
268 sourcefile = *argv++;
270 badusage(_("--split needs a source filename argument"));
273 badusage(_("--split takes at most a source filename and destination prefix"));
275 size_t sourcefile_len = strlen(sourcefile);
277 if (str_match_end(sourcefile, DEBEXT))
278 sourcefile_len -= strlen(DEBEXT);
280 prefix = nfstrnsave(sourcefile, sourcefile_len);
283 mksplit(sourcefile, prefix, opt_maxpartsize, opt_msdos);