libdpkg: Deindent an else clause
[dpkg.git] / src / split / split.c
blob771de626cd3d2d16a0fdcf1fc333b0318b81cc44
1 /*
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/>.
22 #include <config.h>
23 #include <compat.h>
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <sys/wait.h>
29 #include <errno.h>
30 #include <limits.h>
31 #include <inttypes.h>
32 #include <fcntl.h>
33 #include <libgen.h>
34 #include <string.h>
35 #include <time.h>
36 #include <unistd.h>
37 #include <stdint.h>
38 #include <stdlib.h>
39 #include <stdio.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>
50 #include <dpkg/ar.h>
51 #include <dpkg/options.h>
53 #include "dpkg-split.h"
55 /**
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;
62 struct pkginfo *pkg;
63 pid_t pid;
64 int p[2];
66 m_pipe(p);
68 pid = subproc_fork();
69 if (pid == 0) {
70 /* Child writes to pipe. */
71 m_dup2(p[1], 1);
72 close(p[0]);
73 close(p[1]);
75 execlp(BACKEND, BACKEND, "--info", filename, "control", NULL);
76 ohshite(_("unable to execute %s (%s)"),
77 _("package field value extraction"), BACKEND);
79 close(p[1]);
81 /* Parent reads from pipe. */
82 ps = parsedb_new(_("<dpkg-deb --info pipe>"), p[0], pdb_parse_binary);
83 parsedb_load(ps);
84 parsedb_parse(ps, &pkg);
85 parsedb_close(ps);
87 close(p[0]);
89 subproc_reap(pid, _("package field value extraction"), SUBPROC_NOPIPE);
91 return pkg;
94 static intmax_t
95 parse_timestamp(const char *value)
97 intmax_t timestamp;
98 char *end;
100 errno = 0;
101 timestamp = strtoimax(value, &end, 10);
102 if (value == end || *end || errno != 0)
103 ohshite(_("unable to parse timestamp '%.255s'"), value);
105 return timestamp;
108 /* Cleanup filename for use in crippled msdos systems. */
109 static char *
110 clean_msdos_filename(char *filename)
112 char *d, *s;
114 for (s = d = filename; *s; d++, s++) {
115 if (*s == '+')
116 *d = 'x';
117 else if (c_isupper(*s))
118 *d = c_tolower(*s);
119 else if (c_islower(*s) || c_isdigit(*s))
120 *d = *s;
121 else
122 s++;
125 return filename;
128 static int
129 mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
130 bool msdos)
132 struct pkginfo *pkg;
133 struct dpkg_error err;
134 int fd_src;
135 struct stat st;
136 intmax_t timestamp;
137 const char *timestamp_str;
138 const char *version;
139 char hash[MD5HASHLEN + 1];
140 int nparts, curpart;
141 off_t partsize;
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);
149 if (fd_src < 0)
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"),
158 file_src, err.str);
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");
165 if (timestamp_str)
166 timestamp = parse_timestamp(timestamp_str);
167 else
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);
180 if (msdos) {
181 char *t;
183 t = m_strdup(prefix);
184 prefixdir = m_strdup(dirname(t));
185 free(t);
187 msdos_prefix = m_strdup(path_basename(prefix));
188 prefix = clean_msdos_filename(msdos_prefix);
191 for (curpart = 1; curpart <= nparts; curpart++) {
192 struct dpkg_ar *ar;
194 varbuf_reset(&file_dst);
195 /* Generate output filename. */
196 if (msdos) {
197 char *refname;
198 int prefix_max;
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);
204 free(refname);
205 } else {
206 varbuf_printf(&file_dst, "%s.%dof%d" DEBEXT,
207 prefix, curpart, nparts);
210 if (curpart == nparts)
211 cur_partsize = last_partsize;
212 else
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);
245 dpkg_ar_close(ar);
247 printf("%d ", curpart);
250 varbuf_destroy(&file_dst);
251 varbuf_destroy(&partname);
252 varbuf_destroy(&partmagic);
254 free(prefixdir);
255 free(msdos_prefix);
257 close(fd_src);
259 printf(_("done\n"));
261 return 0;
265 do_split(const char *const *argv)
267 const char *sourcefile, *prefix;
269 sourcefile = *argv++;
270 if (!sourcefile)
271 badusage(_("--split needs a source filename argument"));
272 prefix = *argv++;
273 if (prefix && *argv)
274 badusage(_("--split takes at most a source filename and destination prefix"));
275 if (!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);
286 return 0;