po: Update German programs translation
[dpkg.git] / src / split / split.c
blobb4d3aee5ebd7f5f559adfd2ce2d038571abfa724
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)
103 ohshit(_("unable to parse timestamp '%.255s'"), value);
104 else if (errno != 0)
105 ohshite(_("unable to parse timestamp '%.255s'"), value);
107 return timestamp;
110 /* Cleanup filename for use in crippled msdos systems. */
111 static char *
112 clean_msdos_filename(char *filename)
114 char *d, *s;
116 for (s = d = filename; *s; d++, s++) {
117 if (*s == '+')
118 *d = 'x';
119 else if (c_isupper(*s))
120 *d = c_tolower(*s);
121 else if (c_islower(*s) || c_isdigit(*s))
122 *d = *s;
123 else
124 s++;
127 return filename;
130 static int
131 mksplit(const char *file_src, const char *prefix, off_t maxpartsize,
132 bool msdos)
134 struct pkginfo *pkg;
135 struct dpkg_error err;
136 int fd_src;
137 struct stat st;
138 intmax_t timestamp;
139 const char *timestamp_str;
140 const char *version;
141 char hash[MD5HASHLEN + 1];
142 int nparts, curpart;
143 off_t partsize;
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);
151 if (fd_src < 0)
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"),
160 file_src, err.str);
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);
169 else
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);
182 if (msdos) {
183 char *t;
185 t = m_strdup(prefix);
186 prefixdir = m_strdup(dirname(t));
187 free(t);
189 msdos_prefix = m_strdup(path_basename(prefix));
190 prefix = clean_msdos_filename(msdos_prefix);
193 for (curpart = 1; curpart <= nparts; curpart++) {
194 struct dpkg_ar *ar;
196 /* Generate output filename. */
197 if (msdos) {
198 char *refname;
199 int prefix_max;
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);
205 free(refname);
206 } else {
207 varbuf_set_fmt(&file_dst, "%s.%dof%d" DEBEXT,
208 prefix, curpart, nparts);
211 if (curpart == nparts)
212 cur_partsize = last_partsize;
213 else
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);
244 dpkg_ar_close(ar);
246 printf("%d ", curpart);
249 varbuf_destroy(&file_dst);
250 varbuf_destroy(&partname);
251 varbuf_destroy(&partmagic);
253 free(prefixdir);
254 free(msdos_prefix);
256 close(fd_src);
258 printf(_("done\n"));
260 return 0;
264 do_split(const char *const *argv)
266 const char *sourcefile, *prefix;
268 sourcefile = *argv++;
269 if (!sourcefile)
270 badusage(_("--split needs a source filename argument"));
271 prefix = *argv++;
272 if (prefix && *argv)
273 badusage(_("--split takes at most a source filename and destination prefix"));
274 if (!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);
285 return 0;