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>
41 #include <dpkg/i18n.h>
42 #include <dpkg/c-ctype.h>
43 #include <dpkg/dpkg.h>
44 #include <dpkg/dpkg-db.h>
45 #include <dpkg/parsedump.h>
46 #include <dpkg/path.h>
47 #include <dpkg/string.h>
48 #include <dpkg/subproc.h>
49 #include <dpkg/buffer.h>
51 #include <dpkg/options.h>
53 #include "dpkg-split.h"
56 * Parse the control file from a .deb package into a struct pkginfo.
58 static struct pkginfo
*
59 deb_parse_control(const char *filename
)
61 struct parsedb_state
*ps
;
70 /* Child writes to pipe. */
75 execlp(BACKEND
, BACKEND
, "--info", filename
, "control", NULL
);
76 ohshite(_("unable to execute %s (%s)"),
77 _("package field value extraction"), BACKEND
);
81 /* Parent reads from pipe. */
82 ps
= parsedb_new(_("<dpkg-deb --info pipe>"), p
[0], pdb_parse_binary
);
84 parsedb_parse(ps
, &pkg
);
89 subproc_reap(pid
, _("package field value extraction"), SUBPROC_NOPIPE
);
95 parse_timestamp(const char *value
)
101 timestamp
= strtoimax(value
, &end
, 10);
102 if (value
== end
|| *end
)
103 ohshit(_("unable to parse timestamp '%.255s'"), value
);
105 ohshite(_("unable to parse timestamp '%.255s'"), value
);
110 /* Cleanup filename for use in crippled msdos systems. */
112 clean_msdos_filename(char *filename
)
116 for (s
= d
= filename
; *s
; d
++, s
++) {
119 else if (c_isupper(*s
))
121 else if (c_islower(*s
) || c_isdigit(*s
))
131 mksplit(const char *file_src
, const char *prefix
, off_t maxpartsize
,
135 struct dpkg_error err
;
139 const char *timestamp_str
;
141 char hash
[MD5HASHLEN
+ 1];
144 off_t cur_partsize
, last_partsize
;
145 char *prefixdir
= NULL
, *msdos_prefix
= NULL
;
146 struct varbuf file_dst
= VARBUF_INIT
;
147 struct varbuf partmagic
= VARBUF_INIT
;
148 struct varbuf partname
= VARBUF_INIT
;
150 fd_src
= open(file_src
, O_RDONLY
);
152 ohshite(_("unable to open source file '%.250s'"), file_src
);
153 if (fstat(fd_src
, &st
))
154 ohshite(_("unable to fstat source file"));
155 if (!S_ISREG(st
.st_mode
))
156 ohshit(_("source file '%.250s' not a plain file"), file_src
);
158 if (fd_md5(fd_src
, hash
, -1, &err
) < 0)
159 ohshit(_("cannot compute MD5 digest for file '%s': %s"),
161 lseek(fd_src
, 0, SEEK_SET
);
163 pkg
= deb_parse_control(file_src
);
164 version
= versiondescribe(&pkg
->available
.version
, vdew_nonambig
);
166 timestamp_str
= getenv("SOURCE_DATE_EPOCH");
167 if (str_is_set(timestamp_str
))
168 timestamp
= parse_timestamp(timestamp_str
);
170 timestamp
= time(NULL
);
172 partsize
= maxpartsize
- HEADERALLOWANCE
;
173 last_partsize
= st
.st_size
% partsize
;
174 if (last_partsize
== 0)
175 last_partsize
= partsize
;
176 nparts
= (st
.st_size
+ partsize
- 1) / partsize
;
178 printf(P_("Splitting package %s into %d part: ",
179 "Splitting package %s into %d parts: ", nparts
),
180 pkg
->set
->name
, nparts
);
185 t
= m_strdup(prefix
);
186 prefixdir
= m_strdup(dirname(t
));
189 msdos_prefix
= m_strdup(path_basename(prefix
));
190 prefix
= clean_msdos_filename(msdos_prefix
);
193 for (curpart
= 1; curpart
<= nparts
; curpart
++) {
196 /* Generate output filename. */
201 refname
= str_fmt("%dof%d", curpart
, nparts
);
202 prefix_max
= max(8 - strlen(refname
), 0);
203 varbuf_set_fmt(&file_dst
, "%s/%.*s%.8s" DEBEXT
,
204 prefixdir
, prefix_max
, prefix
, refname
);
207 varbuf_set_fmt(&file_dst
, "%s.%dof%d" DEBEXT
,
208 prefix
, curpart
, nparts
);
211 if (curpart
== nparts
)
212 cur_partsize
= last_partsize
;
214 cur_partsize
= partsize
;
216 if (cur_partsize
> maxpartsize
) {
217 ohshit(_("header is too long, making part too long; "
218 "the package name or version\n"
219 "numbers must be extraordinarily long, "
220 "or something; giving up"));
223 /* Split the data. */
224 ar
= dpkg_ar_create(file_dst
.buf
, 0644);
225 dpkg_ar_set_mtime(ar
, timestamp
);
227 /* Write the ar header. */
228 dpkg_ar_put_magic(ar
);
230 /* Write the debian-split part. */
231 varbuf_set_fmt(&partmagic
,
232 "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n",
233 SPLITVERSION
, pkg
->set
->name
, version
, hash
,
234 (intmax_t)st
.st_size
, (intmax_t)partsize
,
235 curpart
, nparts
, pkg
->available
.arch
->name
);
236 dpkg_ar_member_put_mem(ar
, PARTMAGIC
,
237 partmagic
.buf
, partmagic
.used
);
239 /* Write the data part. */
240 varbuf_set_fmt(&partname
, "data.%d", curpart
);
241 dpkg_ar_member_put_file(ar
, partname
.buf
,
242 fd_src
, cur_partsize
);
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
);