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
|| errno
!= 0)
103 ohshite(_("unable to parse timestamp '%.255s'"), value
);
108 /* Cleanup filename for use in crippled msdos systems. */
110 clean_msdos_filename(char *filename
)
114 for (s
= d
= filename
; *s
; d
++, s
++) {
117 else if (c_isupper(*s
))
119 else if (c_islower(*s
) || c_isdigit(*s
))
129 mksplit(const char *file_src
, const char *prefix
, off_t maxpartsize
,
133 struct dpkg_error err
;
137 const char *timestamp_str
;
139 char hash
[MD5HASHLEN
+ 1];
142 off_t cur_partsize
, last_partsize
;
143 char *prefixdir
= NULL
, *msdos_prefix
= NULL
;
144 struct varbuf file_dst
= VARBUF_INIT
;
145 struct varbuf partmagic
= VARBUF_INIT
;
146 struct varbuf partname
= VARBUF_INIT
;
148 fd_src
= open(file_src
, O_RDONLY
);
150 ohshite(_("unable to open source file '%.250s'"), file_src
);
151 if (fstat(fd_src
, &st
))
152 ohshite(_("unable to fstat source file"));
153 if (!S_ISREG(st
.st_mode
))
154 ohshit(_("source file '%.250s' not a plain file"), file_src
);
156 if (fd_md5(fd_src
, hash
, -1, &err
) < 0)
157 ohshit(_("cannot compute MD5 digest for file '%s': %s"),
159 lseek(fd_src
, 0, SEEK_SET
);
161 pkg
= deb_parse_control(file_src
);
162 version
= versiondescribe(&pkg
->available
.version
, vdew_nonambig
);
164 timestamp_str
= getenv("SOURCE_DATE_EPOCH");
166 timestamp
= parse_timestamp(timestamp_str
);
168 timestamp
= time(NULL
);
170 partsize
= maxpartsize
- HEADERALLOWANCE
;
171 last_partsize
= st
.st_size
% partsize
;
172 if (last_partsize
== 0)
173 last_partsize
= partsize
;
174 nparts
= (st
.st_size
+ partsize
- 1) / partsize
;
176 printf(P_("Splitting package %s into %d part: ",
177 "Splitting package %s into %d parts: ", nparts
),
178 pkg
->set
->name
, nparts
);
183 t
= m_strdup(prefix
);
184 prefixdir
= m_strdup(dirname(t
));
187 msdos_prefix
= m_strdup(path_basename(prefix
));
188 prefix
= clean_msdos_filename(msdos_prefix
);
191 for (curpart
= 1; curpart
<= nparts
; curpart
++) {
194 varbuf_reset(&file_dst
);
195 /* Generate output filename. */
200 refname
= str_fmt("%dof%d", curpart
, nparts
);
201 prefix_max
= max(8 - strlen(refname
), 0);
202 varbuf_printf(&file_dst
, "%s/%.*s%.8s" DEBEXT
,
203 prefixdir
, prefix_max
, prefix
, refname
);
206 varbuf_printf(&file_dst
, "%s.%dof%d" DEBEXT
,
207 prefix
, curpart
, nparts
);
210 if (curpart
== nparts
)
211 cur_partsize
= last_partsize
;
213 cur_partsize
= partsize
;
215 if (cur_partsize
> maxpartsize
) {
216 ohshit(_("header is too long, making part too long; "
217 "the package name or version\n"
218 "numbers must be extraordinarily long, "
219 "or something; giving up"));
222 /* Split the data. */
223 ar
= dpkg_ar_create(file_dst
.buf
, 0644);
224 dpkg_ar_set_mtime(ar
, timestamp
);
226 /* Write the ar header. */
227 dpkg_ar_put_magic(ar
);
229 /* Write the debian-split part. */
230 varbuf_printf(&partmagic
,
231 "%s\n%s\n%s\n%s\n%jd\n%jd\n%d/%d\n%s\n",
232 SPLITVERSION
, pkg
->set
->name
, version
, hash
,
233 (intmax_t)st
.st_size
, (intmax_t)partsize
,
234 curpart
, nparts
, pkg
->available
.arch
->name
);
235 dpkg_ar_member_put_mem(ar
, PARTMAGIC
,
236 partmagic
.buf
, partmagic
.used
);
237 varbuf_reset(&partmagic
);
239 /* Write the data part. */
240 varbuf_printf(&partname
, "data.%d", curpart
);
241 dpkg_ar_member_put_file(ar
, partname
.buf
,
242 fd_src
, cur_partsize
);
243 varbuf_reset(&partname
);
247 printf("%d ", curpart
);
250 varbuf_destroy(&file_dst
);
251 varbuf_destroy(&partname
);
252 varbuf_destroy(&partmagic
);
265 do_split(const char *const *argv
)
267 const char *sourcefile
, *prefix
;
269 sourcefile
= *argv
++;
271 badusage(_("--split needs a source filename argument"));
274 badusage(_("--split takes at most a source filename and destination prefix"));
276 size_t sourcefile_len
= strlen(sourcefile
);
278 if (str_match_end(sourcefile
, DEBEXT
))
279 sourcefile_len
-= strlen(DEBEXT
);
281 prefix
= nfstrnsave(sourcefile
, sourcefile_len
);
284 mksplit(sourcefile
, prefix
, opt_maxpartsize
, opt_msdos
);