204
/* Overly complex function that builds a .deb file
206
void do_build(const char *const *argv) {
207
static const char *const maintainerscripts[]= {
208
PREINSTFILE, POSTINSTFILE, PRERMFILE, POSTRMFILE, NULL
212
const char *debar, *directory, *const *mscriptp, *versionstring, *arch;
169
static const char *const maintainerscripts[] = {
178
* Check control directory and file permissions.
181
check_file_perms(const char *dir)
183
struct varbuf path = VARBUF_INIT;
184
const char *const *mscriptp;
185
struct stat mscriptstab;
187
varbuf_printf(&path, "%s/%s/", dir, BUILDCONTROLDIR);
188
if (lstat(path.buf, &mscriptstab))
189
ohshite(_("unable to stat control directory"));
190
if (!S_ISDIR(mscriptstab.st_mode))
191
ohshit(_("control directory is not a directory"));
192
if ((mscriptstab.st_mode & 07757) != 0755)
193
ohshit(_("control directory has bad permissions %03lo "
194
"(must be >=0755 and <=0775)"),
195
(unsigned long)(mscriptstab.st_mode & 07777));
197
for (mscriptp = maintainerscripts; *mscriptp; mscriptp++) {
199
varbuf_printf(&path, "%s/%s/%s", dir, BUILDCONTROLDIR, *mscriptp);
200
if (!lstat(path.buf, &mscriptstab)) {
201
if (S_ISLNK(mscriptstab.st_mode))
203
if (!S_ISREG(mscriptstab.st_mode))
204
ohshit(_("maintainer script `%.50s' is not a plain file or symlink"),
206
if ((mscriptstab.st_mode & 07557) != 0555)
207
ohshit(_("maintainer script `%.50s' has bad permissions %03lo "
208
"(must be >=0555 and <=0775)"),
209
*mscriptp, (unsigned long)(mscriptstab.st_mode & 07777));
210
} else if (errno != ENOENT) {
211
ohshite(_("maintainer script `%.50s' is not stattable"), *mscriptp);
215
varbuf_destroy(&path);
219
* Check if conffiles contains sane information.
222
check_conffiles(const char *dir)
225
struct varbuf controlfile = VARBUF_INIT;
226
char conffilename[MAXCONFFILENAME + 1];
227
struct file_info *conffiles_head = NULL;
228
struct file_info *conffiles_tail = NULL;
230
varbuf_printf(&controlfile, "%s/%s/%s", dir, BUILDCONTROLDIR, CONFFILESFILE);
232
cf = fopen(controlfile.buf, "r");
237
ohshite(_("error opening conffiles file"));
240
while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) {
241
struct stat controlstab;
244
n = strlen(conffilename);
246
ohshite(_("empty string from fgets reading conffiles"));
248
if (conffilename[n - 1] != '\n') {
251
warning(_("conffile name '%.50s...' is too long, or missing final newline"),
253
while ((c = getc(cf)) != EOF && c != '\n');
258
conffilename[n - 1] = '\0';
259
varbuf_reset(&controlfile);
260
varbuf_printf(&controlfile, "%s/%s", dir, conffilename);
261
if (lstat(controlfile.buf, &controlstab)) {
262
if (errno == ENOENT) {
263
if ((n > 1) && isspace(conffilename[n - 2]))
264
warning(_("conffile filename '%s' contains trailing white spaces"),
266
ohshit(_("conffile `%.250s' does not appear in package"), conffilename);
268
ohshite(_("conffile `%.250s' is not stattable"), conffilename);
269
} else if (!S_ISREG(controlstab.st_mode)) {
270
warning(_("conffile '%s' is not a plain file"), conffilename);
273
if (file_info_find_name(conffiles_head, conffilename)) {
274
warning(_("conffile name '%s' is duplicated"), conffilename);
276
struct file_info *conffile;
278
conffile = file_info_new(conffilename);
279
file_info_list_append(&conffiles_head, &conffiles_tail, conffile);
283
file_info_list_free(conffiles_head);
284
varbuf_destroy(&controlfile);
287
ohshite(_("error reading conffiles file"));
291
static const char *arbitrary_fields[] = {
296
"Installer-Menu-Item",
302
static const char private_prefix[] = "Private-";
305
known_arbitrary_field(const struct arbitraryfield *field)
309
/* Always accept fields starting with a private field prefix. */
310
if (strncasecmp(field->name, private_prefix, strlen(private_prefix)) == 0)
313
for (known = arbitrary_fields; *known; known++)
314
if (strcasecmp(field->name, *known) == 0)
321
* Perform some sanity checks on the to-be-built package.
323
* @return The pkginfo struct from the parsed control file.
325
static struct pkginfo *
326
check_new_pkg(const char *dir)
329
struct arbitraryfield *field;
333
/* Start by reading in the control file so we can check its contents. */
334
m_asprintf(&controlfile, "%s/%s/%s", dir, BUILDCONTROLDIR, CONTROLFILE);
335
parsedb(controlfile, pdb_recordavailable | pdb_rejectstatus, &pkg);
337
if (strspn(pkg->name, "abcdefghijklmnopqrstuvwxyz0123456789+-.") !=
339
ohshit(_("package name has characters that aren't lowercase alphanums or `-+.'"));
340
if (pkg->priority == pri_other)
341
warning(_("'%s' contains user-defined Priority value '%s'"),
342
controlfile, pkg->otherpriority);
343
for (field = pkg->available.arbs; field; field = field->next) {
344
if (known_arbitrary_field(field))
347
warning(_("'%s' contains user-defined field '%s'"), controlfile,
353
check_file_perms(dir);
354
check_conffiles(dir);
356
warns = warning_get_count();
358
warning(P_("ignoring %d warning about the control file(s)\n",
359
"ignoring %d warnings about the control file(s)\n", warns),
366
* Generate the pathname for the to-be-built package.
368
* @return The pathname for the package being built.
371
pkg_get_pathname(const char *dir, struct pkginfo *pkg)
374
const char *versionstring, *arch_sep;
376
versionstring = versiondescribe(&pkg->available.version, vdew_never);
377
arch_sep = pkg->available.arch[0] == '\0' ? "" : "_";
378
m_asprintf(&path, "%s/%s_%s%s%s%s", dir, pkg->name, versionstring,
379
arch_sep, pkg->available.arch, DEBEXT);
385
* Overly complex function that builds a .deb file.
388
do_build(const char *const *argv)
390
const char *debar, *dir;
214
char *controlfile, *tfbuf;
215
struct pkginfo *checkedinfo;
216
struct arbitraryfield *field;
218
int p1[2], p2[2], p3[2], warns, n, c, gzfd;
394
int p1[2], p2[2], p3[2], gzfd;
220
struct stat controlstab, mscriptstab, debarstab;
221
char conffilename[MAXCONFFILENAME+1];
222
396
struct file_info *fi;
223
397
struct file_info *symlist = NULL;
224
398
struct file_info *symlist_end = NULL;
226
/* Decode our arguments */
400
/* Decode our arguments. */
229
403
badusage(_("--%s needs a <directory> argument"), cipaction->olong);
232
406
if (debar != NULL) {
407
struct stat debarstab;
233
409
if (*argv) badusage(_("--build takes at most two arguments"));
235
if (stat(debar,&debarstab)) {
237
ohshite(_("unable to check for existence of archive `%.250s'"),debar);
238
} else if (S_ISDIR(debarstab.st_mode)) {
411
if (stat(debar, &debarstab)) {
413
ohshite(_("unable to check for existence of archive `%.250s'"), debar);
414
} else if (S_ISDIR(debarstab.st_mode)) {
243
m= m_malloc(strlen(directory) + sizeof(DEBEXT));
244
strcpy(m, directory);
245
path_rtrim_slash_slashdot(m);
420
m= m_malloc(strlen(dir) + sizeof(DEBEXT));
422
path_trim_slash_slashdot(m);
246
423
strcat(m, DEBEXT);
250
/* Perform some sanity checks on the to-be-build package.
427
/* Perform some sanity checks on the to-be-build package. */
252
428
if (nocheckflag) {
254
430
ohshit(_("target is directory - cannot skip control file check"));
255
431
warning(_("not checking contents of control area."));
256
432
printf(_("dpkg-deb: building an unknown package in '%s'.\n"), debar);
258
controlfile= m_malloc(strlen(directory) + sizeof(BUILDCONTROLDIR) +
259
sizeof(CONTROLFILE) + sizeof(CONFFILESFILE) +
260
sizeof(POSTINSTFILE) + sizeof(PREINSTFILE) +
261
sizeof(POSTRMFILE) + sizeof(PRERMFILE) +
262
MAXCONFFILENAME + 5);
263
/* Lets start by reading in the control-file so we can check its contents */
264
strcpy(controlfile, directory);
265
strcat(controlfile, "/" BUILDCONTROLDIR "/" CONTROLFILE);
267
parsedb(controlfile, pdb_recordavailable|pdb_rejectstatus,
268
&checkedinfo, stderr, &warns);
269
if (strspn(checkedinfo->name,
270
"abcdefghijklmnopqrstuvwxyz0123456789+-.")
271
!= strlen(checkedinfo->name))
272
ohshit(_("package name has characters that aren't lowercase alphanums or `-+.'"));
273
if (checkedinfo->priority == pri_other) {
274
warning(_("'%s' contains user-defined Priority value '%s'"),
275
controlfile, checkedinfo->otherpriority);
278
for (field= checkedinfo->available.arbs; field; field= field->next) {
279
if (known_arbitrary_field(field))
282
warning(_("'%s' contains user-defined field '%s'"),
283
controlfile, field->name);
288
versionstring= versiondescribe(&checkedinfo->available.version,vdew_never);
289
arch= checkedinfo->available.architecture; if (!arch) arch= "";
290
m= m_malloc(sizeof(DEBEXT)+1+strlen(debar)+1+strlen(checkedinfo->name)+
291
strlen(versionstring)+1+strlen(arch));
292
sprintf(m,"%s/%s_%s%s%s" DEBEXT,debar,checkedinfo->name,versionstring,
293
arch[0] ? "_" : "", arch);
296
printf(_("dpkg-deb: building package `%s' in `%s'.\n"), checkedinfo->name, debar);
298
/* Check file permissions */
299
strcpy(controlfile, directory);
300
strcat(controlfile, "/" BUILDCONTROLDIR "/");
301
if (lstat(controlfile, &mscriptstab))
302
ohshite(_("unable to stat control directory"));
303
if (!S_ISDIR(mscriptstab.st_mode))
304
ohshit(_("control directory is not a directory"));
305
if ((mscriptstab.st_mode & 07757) != 0755)
306
ohshit(_("control directory has bad permissions %03lo (must be >=0755 "
307
"and <=0775)"), (unsigned long)(mscriptstab.st_mode & 07777));
309
for (mscriptp= maintainerscripts; *mscriptp; mscriptp++) {
310
strcpy(controlfile, directory);
311
strcat(controlfile, "/" BUILDCONTROLDIR "/");
312
strcat(controlfile, *mscriptp);
314
if (!lstat(controlfile,&mscriptstab)) {
315
if (S_ISLNK(mscriptstab.st_mode)) continue;
316
if (!S_ISREG(mscriptstab.st_mode))
317
ohshit(_("maintainer script `%.50s' is not a plain file or symlink"),*mscriptp);
318
if ((mscriptstab.st_mode & 07557) != 0555)
319
ohshit(_("maintainer script `%.50s' has bad permissions %03lo "
320
"(must be >=0555 and <=0775)"),
321
*mscriptp, (unsigned long)(mscriptstab.st_mode & 07777));
322
} else if (errno != ENOENT) {
323
ohshite(_("maintainer script `%.50s' is not stattable"),*mscriptp);
327
/* Check if conffiles contains sane information */
328
strcpy(controlfile, directory);
329
strcat(controlfile, "/" BUILDCONTROLDIR "/" CONFFILESFILE);
330
if ((cf= fopen(controlfile,"r"))) {
331
struct file_info *conffiles_head = NULL;
332
struct file_info *conffiles_tail = NULL;
334
while (fgets(conffilename,MAXCONFFILENAME+1,cf)) {
335
n= strlen(conffilename);
336
if (!n) ohshite(_("empty string from fgets reading conffiles"));
337
if (conffilename[n-1] != '\n') {
338
warning(_("conffile name '%.50s...' is too long, or missing final newline"),
341
while ((c= getc(cf)) != EOF && c != '\n');
344
conffilename[n - 1] = '\0';
345
strcpy(controlfile, directory);
346
strcat(controlfile, "/");
347
strcat(controlfile, conffilename);
348
if (lstat(controlfile,&controlstab)) {
349
if (errno == ENOENT) {
350
if((n > 1) && isspace(conffilename[n-2]))
351
warning(_("conffile filename '%s' contains trailing white spaces"),
353
ohshit(_("conffile `%.250s' does not appear in package"), conffilename);
355
ohshite(_("conffile `%.250s' is not stattable"), conffilename);
356
} else if (!S_ISREG(controlstab.st_mode)) {
357
warning(_("conffile '%s' is not a plain file"), conffilename);
361
if (file_info_find_name(conffiles_head, conffilename))
362
warning(_("conffile name '%s' is duplicated"), conffilename);
364
struct file_info *conffile;
366
conffile = file_info_new(conffilename);
367
add_to_filist(&conffiles_head, &conffiles_tail, conffile);
371
free_filist(conffiles_head);
373
if (ferror(cf)) ohshite(_("error reading conffiles file"));
375
} else if (errno != ENOENT) {
376
ohshite(_("error opening conffiles file"));
379
warning(P_("ignoring %d warning about the control file(s)\n",
380
"ignoring %d warnings about the control file(s)\n", warns),
436
pkg = check_new_pkg(dir);
438
debar = pkg_get_pathname(debar, pkg);
439
printf(_("dpkg-deb: building package `%s' in `%s'.\n"), pkg->name, debar);
384
441
m_output(stdout, _("<standard output>"));
386
443
/* Now that we have verified everything its time to actually
387
* build something. Lets start by making the ar-wrapper.
389
if (!(ar=fopen(debar,"wb"))) ohshite(_("unable to create `%.255s'"),debar);
390
if (setvbuf(ar, NULL, _IONBF, 0))
391
ohshite(_("unable to unbuffer `%.255s'"), debar);
392
/* Fork a tar to package the control-section of the package */
444
* build something. Let's start by making the ar-wrapper. */
445
arfd = creat(debar, 0644);
447
ohshite(_("unable to create `%.255s'"), debar);
448
/* Fork a tar to package the control-section of the package. */
393
449
unsetenv("TAR_OPTIONS");
395
451
c1 = subproc_fork();
397
453
m_dup2(p1[1],1); close(p1[0]); close(p1[1]);
398
if (chdir(directory)) ohshite(_("failed to chdir to `%.255s'"),directory);
399
if (chdir(BUILDCONTROLDIR)) ohshite(_("failed to chdir to .../DEBIAN"));
455
ohshite(_("failed to chdir to `%.255s'"), dir);
456
if (chdir(BUILDCONTROLDIR))
457
ohshite(_("failed to chdir to `%.255s'"), ".../DEBIAN");
400
458
execlp(TAR, "tar", "-cf", "-", "--format=gnu", ".", NULL);
401
ohshite(_("failed to exec tar -cf"));
459
ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
404
/* Create a temporary file to store the control data in. Immediately unlink
405
* our temporary file so others can't mess with it.
462
/* Create a temporary file to store the control data in. Immediately
463
* unlink our temporary file so others can't mess with it. */
407
464
tfbuf = path_make_temp_template("dpkg-deb");
408
if ((gzfd= mkstemp(tfbuf)) == -1) ohshite(_("failed to make tmpfile (control)"));
409
/* make sure it's gone, the fd will remain until we close it */
410
if (unlink(tfbuf)) ohshit(_("failed to unlink tmpfile (control), %s"),
465
gzfd = mkstemp(tfbuf);
467
ohshite(_("failed to make temporary file (%s)"), _("control member"));
468
/* Make sure it's gone, the fd will remain until we close it. */
470
ohshit(_("failed to unlink temporary file (%s), %s"), _("control member"),
414
/* And run gzip to compress our control archive */
474
/* And run gzip to compress our control archive. */
415
475
c2 = subproc_fork();
417
477
m_dup2(p1[0],0); m_dup2(gzfd,1); close(p1[0]); close(gzfd);
418
compress_filter(&compressor_gzip, 0, 1, 9, _("control"));
478
compress_filter(&compressor_gzip, 0, 1, 9, _("control member"));
421
481
subproc_wait_check(c2, "gzip -9c", 0);
422
482
subproc_wait_check(c1, "tar -cf", 0);
424
484
if (lseek(gzfd, 0, SEEK_SET))
425
ohshite(_("failed to rewind tmpfile (control)"));
485
ohshite(_("failed to rewind temporary file (%s)"), _("control member"));
427
/* We have our first file for the ar-archive. Write a header for it to the
428
* package and insert it.
487
/* We have our first file for the ar-archive. Write a header for it
488
* to the package and insert it. */
430
489
if (oldformatflag) {
490
struct stat controlstab;
431
493
if (fstat(gzfd, &controlstab))
432
ohshite(_("failed to fstat tmpfile (control)"));
433
if (fprintf(ar, "%-8s\n%ld\n", OLDARCHIVEVERSION, (long)controlstab.st_size) == EOF)
435
fd_fd_copy(gzfd, fileno(ar), -1, _("control"));
494
ohshite(_("failed to stat temporary file (%s)"), _("control member"));
495
sprintf(versionbuf, "%-8s\n%jd\n", OLDARCHIVEVERSION,
496
(intmax_t)controlstab.st_size);
497
if (fd_write(arfd, versionbuf, strlen(versionbuf)) < 0)
498
ohshite(_("error writing `%s'"), debar);
499
fd_fd_copy(gzfd, arfd, -1, _("control member"));
437
501
const char deb_magic[] = ARCHIVEVERSION "\n";
439
dpkg_ar_put_magic(debar, fileno(ar));
440
dpkg_ar_member_put_mem(debar, fileno(ar), DEBMAGIC,
441
deb_magic, strlen(deb_magic));
442
dpkg_ar_member_put_file(debar, fileno(ar), ADMINMEMBER, gzfd);
503
dpkg_ar_put_magic(debar, arfd);
504
dpkg_ar_member_put_mem(debar, arfd, DEBMAGIC, deb_magic, strlen(deb_magic));
505
dpkg_ar_member_put_file(debar, arfd, ADMINMEMBER, gzfd, -1);
445
508
/* Control is done, now we need to archive the data. Start by creating
446
509
* a new temporary file. Immediately unlink the temporary file so others
448
511
if (!oldformatflag) {
450
513
tfbuf = path_make_temp_template("dpkg-deb");
451
if ((gzfd= mkstemp(tfbuf)) == -1) ohshite(_("failed to make tmpfile (data)"));
452
/* make sure it's gone, the fd will remain until we close it */
453
if (unlink(tfbuf)) ohshit(_("failed to unlink tmpfile (data), %s"),
514
gzfd = mkstemp(tfbuf);
516
ohshite(_("failed to make temporary file (%s)"), _("data member"));
517
/* Make sure it's gone, the fd will remain until we close it. */
519
ohshit(_("failed to unlink temporary file (%s), %s"), _("data member"),
457
/* Fork off a tar. We will feed it a list of filenames on stdin later.
523
/* Fork off a tar. We will feed it a list of filenames on stdin later. */
461
526
c1 = subproc_fork();
463
528
m_dup2(p1[0],0); close(p1[0]); close(p1[1]);
464
529
m_dup2(p2[1],1); close(p2[0]); close(p2[1]);
465
if (chdir(directory)) ohshite(_("failed to chdir to `%.255s'"),directory);
531
ohshite(_("failed to chdir to `%.255s'"), dir);
466
532
execlp(TAR, "tar", "-cf", "-", "--format=gnu", "--null", "-T", "-", "--no-recursion", NULL);
467
ohshite(_("failed to exec tar -cf"));
533
ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
471
/* Of course we should not forget to compress the archive as well.. */
537
/* Of course we should not forget to compress the archive as well. */
472
538
c2 = subproc_fork();
475
541
m_dup2(p2[0],0); close(p2[0]);
476
m_dup2(oldformatflag ? fileno(ar) : gzfd,1);
477
compress_filter(compressor, 0, 1, compress_level, _("data"));
542
m_dup2(oldformatflag ? arfd : gzfd, 1);
543
compress_filter(compressor, 0, 1, compress_level, _("data member"));
480
547
/* All the pipes are set, now lets run find, and start feeding
548
* filenames to tar. */
485
550
c3 = subproc_fork();
487
552
m_dup2(p3[1],1); close(p3[0]); close(p3[1]);
488
if (chdir(directory)) ohshite(_("failed to chdir to `%.255s'"),directory);
554
ohshite(_("failed to chdir to `%.255s'"), dir);
489
555
execlp(FIND, "find", ".", "-path", "./" BUILDCONTROLDIR, "-prune", "-o",
490
556
"-print0", NULL);
491
ohshite(_("failed to exec find"));
557
ohshite(_("unable to execute %s (%s)"), "find", FIND);
494
560
/* We need to reorder the files so we can make sure that symlinks
495
* will not appear before their target.
497
while ((fi=getfi(directory, p3[0]))!=NULL)
561
* will not appear before their target. */
562
while ((fi = file_info_get(dir, p3[0])) != NULL)
498
563
if (S_ISLNK(fi->st.st_mode))
499
add_to_filist(&symlist, &symlist_end, fi);
564
file_info_list_append(&symlist, &symlist_end, fi);
501
if (write(p1[1], fi->fn, strlen(fi->fn)+1) ==- 1)
502
ohshite(_("failed to write filename to tar pipe (data)"));
566
if (fd_write(p1[1], fi->fn, strlen(fi->fn) + 1) < 0)
567
ohshite(_("failed to write filename to tar pipe (%s)"),
503
569
file_info_free(fi);
506
572
subproc_wait_check(c3, "find", 0);
508
574
for (fi= symlist;fi;fi= fi->next)
509
if (write(p1[1], fi->fn, strlen(fi->fn)+1) == -1)
510
ohshite(_("failed to write filename to tar pipe (data)"));
511
/* All done, clean up wait for tar and gzip to finish their job */
575
if (fd_write(p1[1], fi->fn, strlen(fi->fn) + 1) < 0)
576
ohshite(_("failed to write filename to tar pipe (%s)"), _("data member"));
577
/* All done, clean up wait for tar and gzip to finish their job. */
513
free_filist(symlist);
579
file_info_list_free(symlist);
514
580
subproc_wait_check(c2, _("<compress> from tar -cf"), 0);
515
581
subproc_wait_check(c1, "tar -cf", 0);
516
/* Okay, we have data.tar.gz as well now, add it to the ar wrapper */
582
/* Okay, we have data.tar as well now, add it to the ar wrapper. */
517
583
if (!oldformatflag) {
518
584
char datamember[16 + 1];
520
586
sprintf(datamember, "%s%s", DATAMEMBER, compressor->extension);
522
if (lseek(gzfd,0,SEEK_SET)) ohshite(_("failed to rewind tmpfile (data)"));
588
if (lseek(gzfd, 0, SEEK_SET))
589
ohshite(_("failed to rewind temporary file (%s)"), _("data member"));
524
dpkg_ar_member_put_file(debar, fileno(ar), datamember, gzfd);
591
dpkg_ar_member_put_file(debar, arfd, datamember, gzfd, -1);
527
ohshite(_("unable to flush file '%s'"), debar);
528
if (fsync(fileno(ar)))
529
594
ohshite(_("unable to sync file '%s'"), debar);
530
if (fclose(ar)) werr(debar);
596
ohshite(_("unable to close file '%s'"), debar);