~ubuntu-branches/ubuntu/raring/reprepro/raring

« back to all changes in this revision

Viewing changes to extractcontrol.c

  • Committer: Bazaar Package Importer
  • Author(s): Bernhard R. Link
  • Date: 2011-05-05 16:34:23 UTC
  • mfrom: (21.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110505163423-x49kbdijyoubai4x
Tags: 4.6.0-1
* new release
- general cleanup
- new FilterSrcList
* increase Standards-Version, no changes needed

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
        int pipe1[2];
44
44
        int pipe2[2];
45
45
        int ret;
46
 
        pid_t ar,tar,pid;
 
46
        pid_t ar, tar, pid;
47
47
        int status;
48
48
        char *controlchunk;
49
49
 
50
 
        retvalue result,r;
 
50
        retvalue result, r;
51
51
 
52
52
        result = RET_OK;
53
53
 
54
54
        ret = pipe(pipe1);
55
 
        if( ret < 0 ) {
 
55
        if (ret < 0) {
56
56
                int e = errno;
57
57
                fprintf(stderr, "Error %d creating pipe: %s\n", e, strerror(e));
58
58
                return RET_ERRNO(e);
59
59
        }
60
60
 
61
61
        ret = pipe(pipe2);
62
 
        if( ret < 0 ) {
 
62
        if (ret < 0) {
63
63
                int e = errno;
64
 
                close(pipe1[0]);close(pipe1[1]);
 
64
                close(pipe1[0]); close(pipe1[1]);
65
65
                fprintf(stderr, "Error %d creating pipe: %s\n", e, strerror(e));
66
66
                return RET_ERRNO(e);
67
67
        }
68
68
 
69
69
        ar = fork();
70
 
        if( ar < 0 ) {
 
70
        if (ar < 0) {
71
71
                int e = errno;
72
72
                fprintf(stderr, "Error %d forking: %s\n", e, strerror(e));
73
73
                result = RET_ERRNO(e);
74
 
                close(pipe1[0]);close(pipe1[1]);
75
 
                close(pipe2[0]);close(pipe2[1]);
 
74
                close(pipe1[0]); close(pipe1[1]);
 
75
                close(pipe2[0]); close(pipe2[1]);
76
76
                return result;
77
77
        }
78
78
 
79
 
        if( ar == 0 ) {
 
79
        if (ar == 0) {
80
80
                int e;
81
81
                /* calling ar */
82
 
                if( dup2(pipe1[1],1) < 0 )
 
82
                if (dup2(pipe1[1], 1) < 0)
83
83
                        exit(255);
84
 
                close(pipe1[0]);close(pipe1[1]);
85
 
                close(pipe2[0]);close(pipe2[1]);
 
84
                close(pipe1[0]); close(pipe1[1]);
 
85
                close(pipe2[0]); close(pipe2[1]);
86
86
                //TODO without explicit path
87
87
                ret = execl("/usr/bin/ar",
88
88
                                "ar", "p", debfile, "control.tar.gz",
94
94
        }
95
95
 
96
96
        tar = fork();
97
 
        if( tar < 0 ) {
 
97
        if (tar < 0) {
98
98
                int e = errno;
99
99
                result = RET_ERRNO(e);
100
100
                fprintf(stderr, "Error %d forking: %s\n", e, strerror(e));
101
 
                close(pipe1[0]);close(pipe1[1]);
102
 
                close(pipe2[0]);close(pipe2[1]);
 
101
                close(pipe1[0]); close(pipe1[1]);
 
102
                close(pipe2[0]); close(pipe2[1]);
103
103
                tar = -1;
104
 
        } else if( tar == 0 ) {
 
104
        } else if (tar == 0) {
105
105
                int e;
106
106
                /* calling tar */
107
 
                if( dup2(pipe1[0],0) < 0 )
108
 
                        exit(255);
109
 
                if( dup2(pipe2[1],1) < 0 )
110
 
                        exit(255);
111
 
                close(pipe1[0]);close(pipe1[1]);
112
 
                close(pipe2[0]);close(pipe2[1]);
 
107
                if (dup2(pipe1[0], 0) < 0)
 
108
                        exit(255);
 
109
                if (dup2(pipe2[1], 1) < 0)
 
110
                        exit(255);
 
111
                close(pipe1[0]); close(pipe1[1]);
 
112
                close(pipe2[0]); close(pipe2[1]);
113
113
                //TODO without explicit path
114
114
                execl("/bin/tar", "tar", "-xOzf", "-",
115
115
                                brokentar?"control":"./control",
127
127
        controlchunk = NULL;
128
128
 
129
129
        /* read data: */
130
 
        if( RET_IS_OK(result) ) {
 
130
        if (RET_IS_OK(result)) {
131
131
                size_t len; char *afterchanges;
132
132
 
133
133
                r = readtextfilefd(pipe2[0],
134
134
                                brokentar?
135
 
                                "output from ar p <debfile> control.tar.gz | tar -XOzf - control":
136
 
                                "output from ar p <debfile> control.tar.gz | tar -XOzf - ./control",
 
135
"output from ar p <debfile> control.tar.gz | tar -XOzf - control":
 
136
"output from ar p <debfile> control.tar.gz | tar -XOzf - ./control",
137
137
                                &controlchunk, NULL);
138
 
                if( RET_IS_OK(r) ) {
139
 
                        len = chunk_extract(controlchunk, controlchunk, &afterchanges);
140
 
                        if( len == 0 )
 
138
                if (RET_IS_OK(r)) {
 
139
                        len = chunk_extract(controlchunk, controlchunk,
 
140
                                        &afterchanges);
 
141
                        if (len == 0)
141
142
                                r = RET_NOTHING;
142
 
                        if( *afterchanges != '\0' ) {
 
143
                        if (*afterchanges != '\0') {
143
144
                                fprintf(stderr,
144
145
"Unexpected emtpy line in control information within '%s'\n"
145
146
"(obtained via 'ar p %s control.tar.gz | tar -XOzf - %scontrol')\n",
150
151
                                r = RET_ERROR;
151
152
                        }
152
153
                }
153
 
                if( r == RET_NOTHING ) {
 
154
                if (r == RET_NOTHING) {
154
155
                        free(controlchunk);
155
156
                        controlchunk = NULL;
156
 
                        fprintf(stderr, "No control information found in .deb!\n");
157
 
                        /* only report error now if we haven't try everything yet */
158
 
                        if( brokentar )
 
157
                        fprintf(stderr,
 
158
"No control information found in .deb!\n");
 
159
                        /* only report error now,
 
160
                         * if we haven't try everything yet */
 
161
                        if (brokentar)
159
162
                                r = RET_ERROR_MISSING;
160
163
                }
161
 
                RET_UPDATE(result,r);
 
164
                RET_UPDATE(result, r);
162
165
 
163
166
        }
164
167
 
165
 
        while( ar != -1 || tar != -1 ) {
 
168
        while (ar != -1 || tar != -1) {
166
169
                pid=wait(&status);
167
 
                if( pid < 0 ) {
168
 
                        if( errno != EINTR )
169
 
                                RET_UPDATE(result,RET_ERRNO(errno));
 
170
                if (pid < 0) {
 
171
                        if (errno != EINTR)
 
172
                                RET_UPDATE(result, RET_ERRNO(errno));
170
173
                } else {
171
 
                        if( pid == ar ) {
 
174
                        if (pid == ar) {
172
175
                                ar = -1;
173
 
                                if( !WIFEXITED(status) ) {
174
 
                                        fprintf(stderr,"Ar exited unnaturally!\n");
 
176
                                if (!WIFEXITED(status)) {
 
177
                                        fprintf(stderr,
 
178
"Ar exited unnaturally!\n");
175
179
                                        result = RET_ERROR;
176
 
                                } else if( WEXITSTATUS(status) != 0) {
177
 
                                        fprintf(stderr,"Error from ar for '%s': %d\n",
178
 
                                                        debfile, WEXITSTATUS(status));
 
180
                                } else if (WEXITSTATUS(status) != 0) {
 
181
                                        fprintf(stderr,
 
182
"Error from ar for '%s': %d\n", debfile, WEXITSTATUS(status));
179
183
                                        result = RET_ERROR;
180
184
                                }
181
 
                        } else if( pid == tar ) {
 
185
                        } else if (pid == tar) {
182
186
                                tar = -1;
183
 
                                if( !WIFEXITED(status) ) {
184
 
                                        fprintf(stderr,"Tar exited unnaturally!\n");
 
187
                                if (!WIFEXITED(status)) {
 
188
                                        fprintf(stderr,
 
189
"Tar exited unnaturally!\n");
185
190
                                        result = RET_ERROR;
186
 
                                } else if( !brokentar && WEXITSTATUS(status) == 2 ) {
187
 
                                        if( RET_IS_OK(result) )
 
191
                                } else if (!brokentar && WEXITSTATUS(status) == 2) {
 
192
                                        if (RET_IS_OK(result))
188
193
                                                result = RET_NOTHING;
189
 
                                } else if( WEXITSTATUS(status) != 0 ) {
190
 
                                        fprintf(stderr,"Error from tar for control.tar.gz within '%s': %d\n",
 
194
                                } else if (WEXITSTATUS(status) != 0) {
 
195
                                        fprintf(stderr,
 
196
"Error from tar for control.tar.gz within '%s': %d\n",
191
197
                                                        debfile,
192
198
                                                        WEXITSTATUS(status));
193
199
                                        result = RET_ERROR;
194
200
                                }
195
201
                        } else {
196
202
                                // WTH?
197
 
                                fprintf(stderr,"Who is %d, and why does this bother me?\n",(int)pid);
 
203
                                fprintf(stderr,
 
204
"Who is %d, and why does this bother me?\n", (int)pid);
198
205
                        }
199
206
                }
200
207
 
201
208
        }
202
 
        if( RET_IS_OK(result) ) {
203
 
                if( controlchunk == NULL )
 
209
        if (RET_IS_OK(result)) {
 
210
                if (controlchunk == NULL)
204
211
                        /* we got not data but tar gave not error.. */
205
212
                        return RET_ERROR_MISSING;
206
213
                else
210
217
        return result;
211
218
}
212
219
 
213
 
retvalue extractcontrol(char **control,const char *debfile) {
 
220
retvalue extractcontrol(char **control, const char *debfile) {
214
221
        retvalue r;
215
222
 
216
223
        r = try_extractcontrol(control, debfile, false);
217
 
        if( r != RET_NOTHING )
 
224
        if (r != RET_NOTHING)
218
225
                return r;
219
226
        /* perhaps the control.tar.gz is packaged by hand wrongly,
220
227
         * try again: */
221
228
        r = try_extractcontrol(control, debfile, true);
222
 
        if( RET_IS_OK(r) ) {
223
 
                fprintf(stderr, "WARNING: '%s' contains a broken/unusual control.tar.gz.\n"
224
 
                                "reprepro was able to work around this but other tools or versions might not.\n", debfile);
 
229
        if (RET_IS_OK(r)) {
 
230
                fprintf(stderr,
 
231
"WARNING: '%s' contains a broken/unusual control.tar.gz.\n"
 
232
"reprepro was able to work around this but other tools or versions might not.\n",
 
233
                                debfile);
225
234
        }
226
 
        assert( r != RET_NOTHING );
 
235
        assert (r != RET_NOTHING);
227
236
        return r;
228
237
}
229
238
 
230
239
retvalue getfilelist(/*@out@*/char **filelist, /*@out@*/size_t *size, const char *debfile) {
231
 
        fprintf(stderr, "Extraction of file list without libarchive currently not implemented.\n");
 
240
        fprintf(stderr,
 
241
"Extraction of file list without libarchive currently not implemented.\n");
232
242
        return RET_ERROR;
233
243
#if 0
234
244
        int pipe1[2];
235
245
        int pipe2[2];
236
246
        int ret;
237
 
        pid_t ar,tar,pid;
 
247
        pid_t ar, tar, pid;
238
248
        int status;
239
249
        struct filelistcompressor c;
240
250
        size_t last = 0;
242
252
 
243
253
#error this still needs to be reimplemented...
244
254
        result = filelistcompressor_setup(&c);
245
 
        if( RET_WAS_ERROR(result) )
 
255
        if (RET_WAS_ERROR(result))
246
256
                return result;
247
257
 
248
258
        result = RET_OK;
249
259
 
250
260
        ret = pipe(pipe1);
251
 
        if( ret < 0 ) {
 
261
        if (ret < 0) {
252
262
                int e = errno;
253
263
                fprintf(stderr, "Error %d creating pipe: %s\n", e, strerror(e));
254
264
                filelistcompressor_cancel(&c);
256
266
        }
257
267
 
258
268
        ret = pipe(pipe2);
259
 
        if( ret < 0 ) {
 
269
        if (ret < 0) {
260
270
                int e = errno;
261
271
                fprintf(stderr, "Error %d creating pipe: %s\n", e, strerror(e));
262
 
                close(pipe1[0]);close(pipe1[1]);
 
272
                close(pipe1[0]); close(pipe1[1]);
263
273
                filelistcompressor_cancel(&c);
264
274
                return RET_ERRNO(e);
265
275
        }
266
276
 
267
277
        ar = fork();
268
 
        if( ar < 0 ) {
 
278
        if (ar < 0) {
269
279
                int e = errno;
270
280
                fprintf(stderr, "Error %d forking: %s\n", e, strerror(e));
271
281
                result = RET_ERRNO(e);
272
 
                close(pipe1[0]);close(pipe1[1]);
273
 
                close(pipe2[0]);close(pipe2[1]);
 
282
                close(pipe1[0]); close(pipe1[1]);
 
283
                close(pipe2[0]); close(pipe2[1]);
274
284
                filelistcompressor_cancel(&c);
275
285
                return result;
276
286
        }
277
287
 
278
 
        if( ar == 0 ) {
 
288
        if (ar == 0) {
279
289
                int e;
280
290
                /* calling ar */
281
 
                if( dup2(pipe1[1],1) < 0 )
 
291
                if (dup2(pipe1[1], 1) < 0)
282
292
                        exit(255);
283
 
                close(pipe1[0]);close(pipe1[1]);
284
 
                close(pipe2[0]);close(pipe2[1]);
 
293
                close(pipe1[0]); close(pipe1[1]);
 
294
                close(pipe2[0]); close(pipe2[1]);
285
295
                //TODO without explicit path
286
296
                ret = execl("/usr/bin/ar",
287
297
                                "ar", "p", debfile, "data.tar.gz",
293
303
        }
294
304
 
295
305
        tar = fork();
296
 
        if( tar < 0 ) {
 
306
        if (tar < 0) {
297
307
                int e = errno;
298
308
                result = RET_ERRNO(e);
299
309
                fprintf(stderr, "Error %d forking: %s\n", e, strerror(e));
300
 
                close(pipe1[0]);close(pipe1[1]);
301
 
                close(pipe2[0]);close(pipe2[1]);
 
310
                close(pipe1[0]); close(pipe1[1]);
 
311
                close(pipe2[0]); close(pipe2[1]);
302
312
                tar = -1;
303
 
        } else if( tar == 0 ) {
 
313
        } else if (tar == 0) {
304
314
                int e;
305
315
                /* calling tar */
306
 
                if( dup2(pipe1[0],0) < 0 )
307
 
                        exit(255);
308
 
                if( dup2(pipe2[1],1) < 0 )
309
 
                        exit(255);
310
 
                close(pipe1[0]);close(pipe1[1]);
311
 
                close(pipe2[0]);close(pipe2[1]);
 
316
                if (dup2(pipe1[0], 0) < 0)
 
317
                        exit(255);
 
318
                if (dup2(pipe2[1], 1) < 0)
 
319
                        exit(255);
 
320
                close(pipe1[0]); close(pipe1[1]);
 
321
                close(pipe2[0]); close(pipe2[1]);
312
322
                //TODO without explicit path
313
323
                execl("/bin/tar", "tar", "-tzf", "-", ENDOFARGUMENTS);
314
324
                e = errno;
318
328
 
319
329
        }
320
330
 
321
 
        close(pipe1[0]);close(pipe1[1]);
 
331
        close(pipe1[0]); close(pipe1[1]);
322
332
        close(pipe2[1]);
323
333
 
324
334
        /* read data: */
325
 
        if( RET_IS_OK(result) ) do {
 
335
        if (RET_IS_OK(result)) do {
326
336
                ssize_t bytes_read;
327
337
                size_t ignore;
328
338
 
329
 
                if( listsize <= len + 512 ) {
 
339
                if (listsize <= len + 512) {
330
340
                        char *n;
331
341
 
332
342
                        listsize = len + 1024;
333
343
                        n = realloc(list, listsize);
334
 
                        if( n == NULL ) {
 
344
                        if (FAILEDTOALLOC(n)) {
335
345
                                result = RET_ERROR_OOM;
336
346
                                break;
337
347
                        }
340
350
 
341
351
                ignore = 0;
342
352
                bytes_read = read(pipe2[0], list+len, listsize-len-1);
343
 
                if( bytes_read < 0 ) {
 
353
                if (bytes_read < 0) {
344
354
                        int e = errno;
345
355
                        fprintf(stderr, "Error %d reading from pipe: %s\n",
346
356
                                        e, strerror(e));
347
357
                        result = RET_ERRNO(e);
348
358
                        break;
349
 
                } else if( bytes_read == 0 )
 
359
                } else if (bytes_read == 0)
350
360
                        break;
351
 
                else while( bytes_read > 0 ) {
352
 
                        if( list[len] == '\0' ) {
 
361
                else while (bytes_read > 0) {
 
362
                        if (list[len] == '\0') {
353
363
                                fprintf(stderr,
354
364
"Unexpected NUL character from tar while getting file list from %s!\n", debfile);
355
365
                                result = RET_ERROR;
356
366
                                break;
357
 
                        } else if( list[len] == '\n' ) {
358
 
                                if( len > last+ignore && list[len-1] != '/' ) {
 
367
                        } else if (list[len] == '\n') {
 
368
                                if (len > last+ignore && list[len-1] != '/') {
359
369
                                        list[len] = '\0';
360
370
                                        len++;
361
371
                                        bytes_read--;
367
377
                                        bytes_read--;
368
378
                                        ignore = len-last;
369
379
                                }
370
 
                        } else if( list[len] == '.' && len == last+ignore ) {
 
380
                        } else if (list[len] == '.' && len == last+ignore) {
371
381
                                len++; ignore++;
372
382
                                bytes_read--;
373
 
                        } else if( list[len] == '/' && len == last+ignore ) {
 
383
                        } else if (list[len] == '/' && len == last+ignore) {
374
384
                                len++; ignore++;
375
385
                                bytes_read--;
376
386
                        } else {
378
388
                                bytes_read--;
379
389
                        }
380
390
                }
381
 
                if( ignore > 0 ) {
382
 
                        if( len <= last+ignore )
 
391
                if (ignore > 0) {
 
392
                        if (len <= last+ignore)
383
393
                                len = last;
384
394
                        else {
385
395
                                memmove(list+last, list+last+ignore,
387
397
                                len -= ignore;
388
398
                        }
389
399
                }
390
 
        } while( true );
391
 
        if( len != last ) {
 
400
        } while (true);
 
401
        if (len != last) {
392
402
                fprintf(stderr,
393
403
"WARNING: unterminated output from tar pipe while extracting file list of %s\n", debfile);
394
404
                list[len] = '\0';
396
406
                                list+last);
397
407
                result = RET_ERROR;
398
408
        } else {
399
 
                char *n = realloc(list,len+1);
400
 
                if( n == NULL )
 
409
                char *n = realloc(list, len+1);
 
410
                if (FAILEDTOALLOC(n))
401
411
                        result = RET_ERROR_OOM;
402
412
                else {
403
413
                        list = n;
406
416
        }
407
417
        close(pipe2[0]);
408
418
 
409
 
        while( ar != -1 || tar != -1 ) {
 
419
        while (ar != -1 || tar != -1) {
410
420
                pid=wait(&status);
411
 
                if( pid < 0 ) {
412
 
                        if( errno != EINTR )
413
 
                                RET_UPDATE(result,RET_ERRNO(errno));
 
421
                if (pid < 0) {
 
422
                        if (errno != EINTR)
 
423
                                RET_UPDATE(result, RET_ERRNO(errno));
414
424
                } else {
415
 
                        if( pid == ar ) {
 
425
                        if (pid == ar) {
416
426
                                ar = -1;
417
 
                                if( !WIFEXITED(status) ||
 
427
                                if (!WIFEXITED(status) ||
418
428
                                                WEXITSTATUS(status) != 0) {
419
 
                                        fprintf(stderr,"Error from ar for '%s': %d\n",
420
 
                                                        debfile,
421
 
                                                        WEXITSTATUS(status));
 
429
                                        fprintf(stderr,
 
430
"Error from ar for '%s': %d\n", debfile, WEXITSTATUS(status));
422
431
                                        result = RET_ERROR;
423
432
                                }
424
 
                        } else if( pid == tar ) {
 
433
                        } else if (pid == tar) {
425
434
                                tar = -1;
426
 
                                if( !WIFEXITED(status) ||
427
 
                                                WEXITSTATUS(status) != 0 ) {
428
 
                                        fprintf(stderr,"Error from tar for data.tar.gz within '%s': %d\n",
 
435
                                if (!WIFEXITED(status) ||
 
436
                                                WEXITSTATUS(status) != 0) {
 
437
                                        fprintf(stderr,
 
438
"Error from tar for data.tar.gz within '%s': %d\n",
429
439
                                                        debfile,
430
440
                                                        WEXITSTATUS(status));
431
441
                                        result = RET_ERROR;
432
442
                                }
433
443
                        } else {
434
444
                                // WTH?
435
 
                                fprintf(stderr,"Who is %d, and why does this bother me?\n",pid);
 
445
                                fprintf(stderr,
 
446
"Who is %d, and why does this bother me?\n", pid);
436
447
                        }
437
448
                }
438
449
        }
439
 
        if( RET_IS_OK(result) )
 
450
        if (RET_IS_OK(result))
440
451
                return filelistcompressor_finish(&c, filelist);
441
452
        else
442
453
                filelistcompressor_cancel(&c);