Branch data Line data Source code
1 : : /*
2 : : * dpkg-split - splitting and joining of multipart *.deb archives
3 : : * join.c - joining
4 : : *
5 : : * Copyright © 1995 Ian Jackson <ijackson@chiark.greenend.org.uk>
6 : : *
7 : : * This is free software; you can redistribute it and/or modify
8 : : * it under the terms of the GNU General Public License as published by
9 : : * the Free Software Foundation; either version 2 of the License, or
10 : : * (at your option) any later version.
11 : : *
12 : : * This is distributed in the hope that it will be useful,
13 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : : * GNU General Public License for more details.
16 : : *
17 : : * You should have received a copy of the GNU General Public License
18 : : * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 : : */
20 : :
21 : : #include <config.h>
22 : : #include <compat.h>
23 : :
24 : : #include <limits.h>
25 : : #include <string.h>
26 : : #include <fcntl.h>
27 : : #include <unistd.h>
28 : : #include <stdlib.h>
29 : : #include <stdio.h>
30 : :
31 : : #include <dpkg/i18n.h>
32 : : #include <dpkg/dpkg.h>
33 : : #include <dpkg/dpkg-db.h>
34 : : #include <dpkg/buffer.h>
35 : : #include <dpkg/options.h>
36 : :
37 : : #include "dpkg-split.h"
38 : :
39 : 1 : void reassemble(struct partinfo **partlist, const char *outputfile) {
40 : : struct dpkg_error err;
41 : : int fd_out, fd_in;
42 : : int i;
43 : :
44 : 1 : printf(P_("Putting package %s together from %d part: ",
45 : : "Putting package %s together from %d parts: ",
46 : : partlist[0]->maxpartn),
47 : 1 : partlist[0]->package,partlist[0]->maxpartn);
48 : :
49 : 1 : fd_out = creat(outputfile, 0644);
50 [ - + ]: 1 : if (fd_out < 0)
51 : 0 : ohshite(_("unable to open output file '%.250s'"), outputfile);
52 [ + + ]: 11 : for (i=0; i<partlist[0]->maxpartn; i++) {
53 : 10 : struct partinfo *pi = partlist[i];
54 : :
55 : 10 : fd_in = open(pi->filename, O_RDONLY);
56 [ - + ]: 10 : if (fd_in < 0)
57 : 0 : ohshite(_("unable to (re)open input part file '%.250s'"), pi->filename);
58 [ - + ]: 10 : if (fd_skip(fd_in, pi->headerlen, &err) < 0)
59 : 0 : ohshit(_("cannot skip split package header for '%s': %s"), pi->filename,
60 : : err.str);
61 [ - + ]: 10 : if (fd_fd_copy(fd_in, fd_out, pi->thispartlen, &err) < 0)
62 : 0 : ohshit(_("cannot append split package part '%s' to '%s': %s"),
63 : : pi->filename, outputfile, err.str);
64 : 10 : close(fd_in);
65 : :
66 : 10 : printf("%d ", i + 1);
67 : : }
68 [ - + ]: 1 : if (fsync(fd_out))
69 : 0 : ohshite(_("unable to sync file '%s'"), outputfile);
70 [ - + ]: 1 : if (close(fd_out))
71 : 0 : ohshite(_("unable to close file '%s'"), outputfile);
72 : :
73 : 1 : printf(_("done\n"));
74 : 1 : }
75 : :
76 : :
77 : 10 : void addtopartlist(struct partinfo **partlist,
78 : : struct partinfo *pi, struct partinfo *refi) {
79 : : int i;
80 : :
81 [ + - ]: 10 : if (strcmp(pi->package,refi->package) ||
82 [ + - ]: 10 : strcmp(pi->version,refi->version) ||
83 [ + - ]: 10 : strcmp(pi->md5sum,refi->md5sum) ||
84 [ + - ]: 10 : pi->orglength != refi->orglength ||
85 [ + - ]: 10 : pi->maxpartn != refi->maxpartn ||
86 [ - + ]: 10 : pi->maxpartlen != refi->maxpartlen) {
87 : 0 : print_info(pi);
88 : 0 : print_info(refi);
89 : 0 : ohshit(_("files '%.250s' and '%.250s' are not parts of the same file"),
90 : : pi->filename,refi->filename);
91 : : }
92 : 10 : i= pi->thispartn-1;
93 [ - + ]: 10 : if (partlist[i])
94 : 0 : ohshit(_("there are several versions of part %d - at least '%.250s' and '%.250s'"),
95 : 0 : pi->thispartn, pi->filename, partlist[i]->filename);
96 : 10 : partlist[i]= pi;
97 : 10 : }
98 : :
99 : : int
100 : 1 : do_join(const char *const *argv)
101 : : {
102 : : const char *thisarg;
103 : 1 : struct partqueue *queue = NULL;
104 : : struct partqueue *pq;
105 : : struct partinfo *refi, **partlist;
106 : : int i;
107 : :
108 [ - + ]: 1 : if (!*argv)
109 : 0 : badusage(_("--%s requires one or more part file arguments"),
110 : 0 : cipaction->olong);
111 [ + + ]: 11 : while ((thisarg= *argv++)) {
112 : 10 : pq = nfmalloc(sizeof(*pq));
113 : :
114 : 10 : mustgetpartinfo(thisarg,&pq->info);
115 : :
116 : 10 : pq->nextinqueue= queue;
117 : 10 : queue= pq;
118 : : }
119 : 1 : refi= NULL;
120 [ + + ]: 11 : for (pq= queue; pq; pq= pq->nextinqueue)
121 [ + + + + ]: 10 : if (!refi || pq->info.thispartn < refi->thispartn) refi= &pq->info;
122 [ - + ]: 1 : if (refi == NULL)
123 : 0 : internerr("empty deb part queue");
124 : :
125 : 1 : partlist = nfmalloc(sizeof(*partlist) * refi->maxpartn);
126 [ + + ]: 11 : for (i = 0; i < refi->maxpartn; i++)
127 : 10 : partlist[i] = NULL;
128 [ + + ]: 11 : for (pq= queue; pq; pq= pq->nextinqueue) {
129 : 10 : struct partinfo *pi = &pq->info;
130 : :
131 : 10 : addtopartlist(partlist,pi,refi);
132 : : }
133 [ + + ]: 11 : for (i=0; i<refi->maxpartn; i++) {
134 [ - + ]: 10 : if (!partlist[i]) ohshit(_("part %d is missing"),i+1);
135 : : }
136 [ - + ]: 1 : if (!opt_outputfile) {
137 : : char *p;
138 : :
139 : 0 : p= nfmalloc(strlen(refi->package)+1+strlen(refi->version)+sizeof(DEBEXT));
140 : 0 : strcpy(p,refi->package);
141 : 0 : strcat(p, "_");
142 : 0 : strcat(p,refi->version);
143 : 0 : strcat(p, "_");
144 [ # # ]: 0 : strcat(p, refi->arch ? refi->arch : "unknown");
145 : 0 : strcat(p,DEBEXT);
146 : 0 : opt_outputfile = p;
147 : : }
148 : 1 : reassemble(partlist, opt_outputfile);
149 : :
150 : 1 : return 0;
151 : : }
|