~ubuntu-branches/debian/wheezy/dpkg/wheezy

« back to all changes in this revision

Viewing changes to dpkg-deb/build.c

  • Committer: Bazaar Package Importer
  • Author(s): Guillem Jover, Guillem Jover, Raphaël Hertzog, Jonathan Nieder, Steve Langasek, Mark Hymers, Updated programs translations, Updated man page translations, Updated scripts translations, Updated dselect translations
  • Date: 2011-04-01 23:56:54 UTC
  • Revision ID: james.westby@ubuntu.com-20110401235654-8y800dtb75skfrh7
Tags: 1.16.0
[ Guillem Jover ]
* Use DPKG_MAINTSCRIPT_PACKAGE environment variable as package name on
  dpkg-divert when no --package or --local options have been specified.
* Do not allow versions starting with non-digit when doing strict parsing,
  warn otherwise.
* Update dpkg(1) to note that --status-fd output does not contain newlines
  in error messages anymore (this was fixed in 1.15.0).
* Add a new --status-logger option to dpkg, similar to --status-fd but
  instead invoke the command ourselves and feed the status information
  to its standard input. Suggested by Raphaël Hertzog.
* Add missing space in update-alternative --set-selections output.
* Add missing options to update-alternative --help output.
* Count “conffile name is duplicated” for dpkg-deb warning count summary.
* Improve and clarify strings for translation. Closes: #604914
* Prefix all fatal error messages with “error: ”.
* Do not check presence of update-rc.d in the PATH in dpkg, as it's not
  a program needed for dpkg correct operation.
* Fix dpkg -GEO options on multiple versions of the same packages.
  Closes: #31141
* Propagate --admindir to programs run from maintainer scritpts.
  Closes: #97076
* Do not fail when trying to remove the root directory. This will only
  happen either on distributions where dpkg is a foreign package manager,
  or on artificial dpkg databases.
* Always warn when parsing any package control data which does not have
  an Architecture field except for status and status log files when
  packages are not-installed or half-installed.
* By default reject installing packages w/o an Architecture field. They
  now need --force-architecture, dpkg will still warn about them though.
* Fix build failure when passing --disable-nls to configure.
* Do not segfault on “dpkg -i --no-act”.
* Add missing semicolon to the vsnprintf() compat declaration.
  Thanks to Robert Millan. Closes: #612203
* On install for Ubuntu adjust the i386 GNU cpu name in cputable.
  Thanks to Colin Watson <cjwatson@ubuntu.com>. Closes: #611741
* Sync the info database directory on unpack instead of the temporary
  control information directory, and print the correct pathname on error
  instead of the last file acted on that directory.
* Document in dpkg-query --help output and man page that --list and --show
  arguments are optional.
* Do not read and write the available file unnecessarily.
  Thanks to Michel Lespinasse <walken@zoy.org>. Closes: #397121
* Fix typo in «dpkg-name --overwrite» argument parsing so that it actually
  works at all. Thanks to Ivan Gagis <igagis@gmail.com>. LP: #728708
* Add armhf support to ostable and triplettable. Closes: #594179
* Set the modification time for unpacked symlinks on supported systems.
* Fix undefined value useage in dpkg-genchanges when adding files w/o a
  matching architecture, because they are not present in debian/control,
  this is most commonly the case due to dpkg-distaddfile.
* Terminate immediately on dpkg-divert rename errors instead of propagating
  up the error codes, this improves error reporting and avoids triggering
  leak detectors. Closes: #620380
* When moving a diverted file across filesystems in dpkg-divert, remove
  the source file.

[ Raphaël Hertzog ]
* Fail properly when debian/source/format is empty. Closes: #600854
* Add new deb-src-control(5) manual page documenting the debian/control
  file contained in source packages.
  - it documents the X[SBC]- prefix. Closes: #476335
  - it documents the VCS-* fields too. Closes: #483119
  Thanks to Oxan van Leeuwen <oxan@oxanvanleeuwen.nl> who wrote it
  as part of the Google Code In program.
* Enhance dpkg-shlibdeps to not fail immediatly when a library is not found.
  Instead continue and fail after all problems have been reported. Thanks
  to Chris Baines <cbaines8@gmail.com> for the patch. Closes: #596841
* Fix dpkg-source to not list Debian packaging files as modified
  upstream files in Format "1.0" when unpacking to a non-standard
  directory.
* Apply patch from Colin Watson to let dpkg-buildflags return -O3
  instead of -O2 when building ppc64 packages on Ubuntu. Closes: #612472
* Add new function get_control_path() to Dpkg::Path, it wraps dpkg-query
  --control-path.
* Update dpkg-shlibdeps to be multiarch-ready:
  - use get_control_path() to find symbols/shlibs files
  - parse correctly the output of dpkg --search
* Small fix to support files >2GB in .deb on 64-bit systems. Closes: #616502
  Thanks to Martin Dorey <mdorey@bluearc.com> for the patch.
* dpkg-source now keeps the file ordering in the autogenerated patch when
  regenerating it. Closes: #606080
  Thanks to Colin Watson for the patch.
* dpkg-source now uses a timestamp retrieved from the filesystem when
  resetting the timestamp of patched files so that a time skew when using
  NFS doesn't introduce any inconsistency. Closes: #613023
  Thanks to Jonathan Nieder <jrnieder@gmail.com> for the patch and the
  diagnosis.
* dpkg-source will now remove quilt's .pc directory when --unapply-patches
  is in use. Closes: #591858
* dpkg-source is now a bit less strict when parsing patches:
  - it accepts seeing the same file twice; Closes: #608829
  - it doesn't match on the English text "No newline at end of file" as it
    might be translated in some cases. Closes: #612465
* Improve parser in Dpkg::Control::Hash to not require an empty line
  before the PGP signature. Closes: #617923
  Thanks to Roger Leigh for the initial patch.
* Fix a regression in dpkg-divert where using --rename led to a failure when
  the rename implies crossing file systems. Thanks to Durk Strooisma for
  spotting it.
* Use the correct mtime when installing a file with statoverrides.
  Regression introduced in 1.16.0. LP: #739179
* Remove duplicate word in german translation of dpkg(1). Closes: #616096
* Strip repeated non-significant spaces before and after newlines
  in Uploaders. Closes: #598922
* Ignore whitespaces after options in headers of changelog entries.
  Closes: #605719
* Fix dpkg-source's regression with empty patches (introduced while fixing
  #613023). Closes: #619541

[ Jonathan Nieder ]
* Remove support for use of synchronous sync(2), due to its pernicious
  side-effects and to ease maintenance.
* Clarify that an up-to-date dpkg only needs to be unpacked for
  dpkg-maintscript-helper to work.

[ Steve Langasek ]
* Add new variables to dpkg-architecture, DEB_HOST_MULTIARCH and
  DEB_BUILD_MULTIARCH, that return the "ideal" GNU triplet for each
  architecture which should be used as the path component for library
  installation.

[ Mark Hymers ]
* Add support for Built-Using field. Closes: #619311

[ Updated programs translations ]
* German (Sven Joachim).
* Portuguese (Miguel Figueiredo).
* Spanish (Javier Fernandez-Sanguino).
* Swedish (Peter Krefting).

[ Updated man page translations ]
* German (Helge Kreutzmann).
* Swedish (Peter Krefting).

[ Updated scripts translations ]
* German (Helge Kreutzmann).
* Swedish (Peter Krefting).

[ Updated dselect translations ]
* Spanish (Javier Fernandez-Sanguino).

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <ctype.h>
32
32
#include <string.h>
33
33
#include <dirent.h>
 
34
#include <fcntl.h>
34
35
#include <unistd.h>
35
36
#include <stdbool.h>
 
37
#include <stdint.h>
36
38
#include <stdlib.h>
37
39
#include <stdio.h>
38
40
 
40
42
#include <dpkg/dpkg.h>
41
43
#include <dpkg/dpkg-db.h>
42
44
#include <dpkg/path.h>
 
45
#include <dpkg/varbuf.h>
 
46
#include <dpkg/fdio.h>
43
47
#include <dpkg/buffer.h>
44
48
#include <dpkg/subproc.h>
45
49
#include <dpkg/compress.h>
48
52
 
49
53
#include "dpkg-deb.h"
50
54
 
51
 
/* Simple structure to store information about a file.
 
55
/**
 
56
 * Simple structure to store information about a file.
52
57
 */
53
58
struct file_info {
54
59
  struct file_info *next;
56
61
  char* fn;
57
62
};
58
63
 
59
 
static const char *arbitrary_fields[] = {
60
 
  "Package-Type",
61
 
  "Subarchitecture",
62
 
  "Kernel-Version",
63
 
  "Installer-Menu-Item",
64
 
  "Homepage",
65
 
  "Tag",
66
 
  NULL
67
 
};
68
 
 
69
 
static const char private_prefix[] = "Private-";
70
 
 
71
 
static bool
72
 
known_arbitrary_field(const struct arbitraryfield *field)
73
 
{
74
 
  const char **known;
75
 
 
76
 
  /* Always accept fields starting with a private field prefix. */
77
 
  if (strncasecmp(field->name, private_prefix, strlen(private_prefix)) == 0)
78
 
    return true;
79
 
 
80
 
  for (known= arbitrary_fields; *known; known++)
81
 
    if (strcasecmp(field->name, *known) == 0)
82
 
      return true;
83
 
 
84
 
  return false;
85
 
}
86
 
 
87
64
static struct file_info *
88
65
file_info_new(const char *filename)
89
66
{
115
92
  return NULL;
116
93
}
117
94
 
118
 
/*
119
 
 * Read the next filename from a filedescriptor and create a file_info struct
120
 
 * for it. If there is nothing to read return NULL.
 
95
/**
 
96
 * Read a filename from the file descriptor and create a file_info struct.
 
97
 *
 
98
 * @return A file_info struct or NULL if there is nothing to read.
121
99
 */
122
100
static struct file_info *
123
 
getfi(const char *root, int fd)
 
101
file_info_get(const char *root, int fd)
124
102
{
125
 
  static char* fn = NULL;
126
 
  static size_t fnlen = 0;
127
 
  size_t i= 0;
 
103
  static struct varbuf fn = VARBUF_INIT;
128
104
  struct file_info *fi;
129
 
  size_t rl = strlen(root);
130
 
 
131
 
  if (fn == NULL) {
132
 
    fnlen = rl + MAXFILENAME;
133
 
    fn = m_malloc(fnlen);
134
 
  } else if (fnlen < (rl + MAXFILENAME)) {
135
 
    fnlen = rl + MAXFILENAME;
136
 
    fn = m_realloc(fn, fnlen);
137
 
  }
138
 
  i=sprintf(fn,"%s/",root);
139
 
  
 
105
  size_t root_len;
 
106
 
 
107
  varbuf_reset(&fn);
 
108
  root_len = varbuf_printf(&fn, "%s/", root);
 
109
 
140
110
  while (1) {
141
111
    int res;
142
 
    if (i>=fnlen) {
143
 
      fnlen += MAXFILENAME;
144
 
      fn = m_realloc(fn, fnlen);
145
 
    }
146
 
    if ((res=read(fd, (fn+i), sizeof(*fn)))<0) {
147
 
      if ((errno==EINTR) || (errno==EAGAIN))
148
 
        continue;
149
 
      else
150
 
        return NULL;
151
 
    }
 
112
 
 
113
    varbuf_grow(&fn, 1);
 
114
    res = fd_read(fd, (fn.buf + fn.used), 1);
 
115
    if (res < 0)
 
116
      return NULL;
152
117
    if (res == 0) /* EOF -> parent died. */
153
118
      return NULL;
154
 
    if (fn[i] == '\0')
 
119
    if (fn.buf[fn.used] == '\0')
155
120
      break;
156
121
 
157
 
    i++;
158
 
 
159
 
    if (i >= MAXFILENAME)
160
 
      ohshit(_("file name '%.50s...' is too long"), fn + rl + 1);
 
122
    varbuf_trunc(&fn, fn.used + 1);
 
123
    if (fn.used >= MAXFILENAME)
 
124
      ohshit(_("file name '%.50s...' is too long"), fn.buf + root_len);
161
125
  }
162
126
 
163
 
  fi = file_info_new(fn + rl + 1);
164
 
  if (lstat(fn, &(fi->st)) != 0)
165
 
    ohshite(_("unable to stat file name '%.250s'"), fn);
 
127
  fi = file_info_new(fn.buf + root_len);
 
128
  if (lstat(fn.buf, &(fi->st)) != 0)
 
129
    ohshite(_("unable to stat file name '%.250s'"), fn.buf);
166
130
 
167
131
  return fi;
168
132
}
169
133
 
170
 
/*
 
134
/**
171
135
 * Add a new file_info struct to a single linked list of file_info structs.
172
 
 * We perform a slight optimization to work around a `feature' in tar: tar
 
136
 *
 
137
 * We perform a slight optimization to work around a ‘feature’ in tar: tar
173
138
 * always recurses into subdirectories if you list a subdirectory. So if an
174
139
 * entry is added and the previous entry in the list is its subdirectory we
175
 
 * remove the subdirectory. 
 
140
 * remove the subdirectory.
176
141
 *
177
142
 * After a file_info struct is added to a list it may no longer be freed, we
178
143
 * assume full responsibility for its memory.
179
144
 */
180
145
static void
181
 
add_to_filist(struct file_info **start, struct file_info **end,
182
 
              struct file_info *fi)
 
146
file_info_list_append(struct file_info **head, struct file_info **tail,
 
147
                      struct file_info *fi)
183
148
{
184
 
  if (*start==NULL)
185
 
    *start=*end=fi;
186
 
  else 
187
 
    *end=(*end)->next=fi;
 
149
  if (*head == NULL)
 
150
    *head = *tail = fi;
 
151
  else
 
152
    *tail = (*tail)->next =fi;
188
153
}
189
154
 
190
 
/*
 
155
/**
191
156
 * Free the memory for all entries in a list of file_info structs.
192
157
 */
193
158
static void
194
 
free_filist(struct file_info *fi)
 
159
file_info_list_free(struct file_info *fi)
195
160
{
196
161
  while (fi) {
197
162
    struct file_info *fl;
201
166
  }
202
167
}
203
168
 
204
 
/* Overly complex function that builds a .deb file
205
 
 */
206
 
void do_build(const char *const *argv) {
207
 
  static const char *const maintainerscripts[]= {
208
 
    PREINSTFILE, POSTINSTFILE, PRERMFILE, POSTRMFILE, NULL
209
 
  };
210
 
  
211
 
  char *m;
212
 
  const char *debar, *directory, *const *mscriptp, *versionstring, *arch;
 
169
static const char *const maintainerscripts[] = {
 
170
  PREINSTFILE,
 
171
  POSTINSTFILE,
 
172
  PRERMFILE,
 
173
  POSTRMFILE,
 
174
  NULL,
 
175
};
 
176
 
 
177
/**
 
178
 * Check control directory and file permissions.
 
179
 */
 
180
static void
 
181
check_file_perms(const char *dir)
 
182
{
 
183
  struct varbuf path = VARBUF_INIT;
 
184
  const char *const *mscriptp;
 
185
  struct stat mscriptstab;
 
186
 
 
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));
 
196
 
 
197
  for (mscriptp = maintainerscripts; *mscriptp; mscriptp++) {
 
198
    varbuf_reset(&path);
 
199
    varbuf_printf(&path, "%s/%s/%s", dir, BUILDCONTROLDIR, *mscriptp);
 
200
    if (!lstat(path.buf, &mscriptstab)) {
 
201
      if (S_ISLNK(mscriptstab.st_mode))
 
202
        continue;
 
203
      if (!S_ISREG(mscriptstab.st_mode))
 
204
        ohshit(_("maintainer script `%.50s' is not a plain file or symlink"),
 
205
               *mscriptp);
 
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);
 
212
    }
 
213
  }
 
214
 
 
215
  varbuf_destroy(&path);
 
216
}
 
217
 
 
218
/**
 
219
 * Check if conffiles contains sane information.
 
220
 */
 
221
static void
 
222
check_conffiles(const char *dir)
 
223
{
 
224
  FILE *cf;
 
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;
 
229
 
 
230
  varbuf_printf(&controlfile, "%s/%s/%s", dir, BUILDCONTROLDIR, CONFFILESFILE);
 
231
 
 
232
  cf = fopen(controlfile.buf, "r");
 
233
  if (cf == NULL) {
 
234
    if (errno == ENOENT)
 
235
      return;
 
236
 
 
237
    ohshite(_("error opening conffiles file"));
 
238
  }
 
239
 
 
240
  while (fgets(conffilename, MAXCONFFILENAME + 1, cf)) {
 
241
    struct stat controlstab;
 
242
    int n;
 
243
 
 
244
    n = strlen(conffilename);
 
245
    if (!n)
 
246
      ohshite(_("empty string from fgets reading conffiles"));
 
247
 
 
248
    if (conffilename[n - 1] != '\n') {
 
249
      int c;
 
250
 
 
251
      warning(_("conffile name '%.50s...' is too long, or missing final newline"),
 
252
              conffilename);
 
253
      while ((c = getc(cf)) != EOF && c != '\n');
 
254
 
 
255
      continue;
 
256
    }
 
257
 
 
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"),
 
265
                  conffilename);
 
266
        ohshit(_("conffile `%.250s' does not appear in package"), conffilename);
 
267
      } else
 
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);
 
271
    }
 
272
 
 
273
    if (file_info_find_name(conffiles_head, conffilename)) {
 
274
      warning(_("conffile name '%s' is duplicated"), conffilename);
 
275
    } else {
 
276
      struct file_info *conffile;
 
277
 
 
278
      conffile = file_info_new(conffilename);
 
279
      file_info_list_append(&conffiles_head, &conffiles_tail, conffile);
 
280
    }
 
281
  }
 
282
 
 
283
  file_info_list_free(conffiles_head);
 
284
  varbuf_destroy(&controlfile);
 
285
 
 
286
  if (ferror(cf))
 
287
    ohshite(_("error reading conffiles file"));
 
288
  fclose(cf);
 
289
}
 
290
 
 
291
static const char *arbitrary_fields[] = {
 
292
  "Built-Using",
 
293
  "Package-Type",
 
294
  "Subarchitecture",
 
295
  "Kernel-Version",
 
296
  "Installer-Menu-Item",
 
297
  "Homepage",
 
298
  "Tag",
 
299
  NULL
 
300
};
 
301
 
 
302
static const char private_prefix[] = "Private-";
 
303
 
 
304
static bool
 
305
known_arbitrary_field(const struct arbitraryfield *field)
 
306
{
 
307
  const char **known;
 
308
 
 
309
  /* Always accept fields starting with a private field prefix. */
 
310
  if (strncasecmp(field->name, private_prefix, strlen(private_prefix)) == 0)
 
311
    return true;
 
312
 
 
313
  for (known = arbitrary_fields; *known; known++)
 
314
    if (strcasecmp(field->name, *known) == 0)
 
315
      return true;
 
316
 
 
317
  return false;
 
318
}
 
319
 
 
320
/**
 
321
 * Perform some sanity checks on the to-be-built package.
 
322
 *
 
323
 * @return The pkginfo struct from the parsed control file.
 
324
 */
 
325
static struct pkginfo *
 
326
check_new_pkg(const char *dir)
 
327
{
 
328
  struct pkginfo *pkg;
 
329
  struct arbitraryfield *field;
 
330
  char *controlfile;
 
331
  int warns;
 
332
 
 
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);
 
336
 
 
337
  if (strspn(pkg->name, "abcdefghijklmnopqrstuvwxyz0123456789+-.") !=
 
338
      strlen(pkg->name))
 
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))
 
345
      continue;
 
346
 
 
347
    warning(_("'%s' contains user-defined field '%s'"), controlfile,
 
348
            field->name);
 
349
  }
 
350
 
 
351
  free(controlfile);
 
352
 
 
353
  check_file_perms(dir);
 
354
  check_conffiles(dir);
 
355
 
 
356
  warns = warning_get_count();
 
357
  if (warns)
 
358
    warning(P_("ignoring %d warning about the control file(s)\n",
 
359
               "ignoring %d warnings about the control file(s)\n", warns),
 
360
            warns);
 
361
 
 
362
  return pkg;
 
363
}
 
364
 
 
365
/**
 
366
 * Generate the pathname for the to-be-built package.
 
367
 *
 
368
 * @return The pathname for the package being built.
 
369
 */
 
370
static char *
 
371
pkg_get_pathname(const char *dir, struct pkginfo *pkg)
 
372
{
 
373
  char *path;
 
374
  const char *versionstring, *arch_sep;
 
375
 
 
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);
 
380
 
 
381
  return path;
 
382
}
 
383
 
 
384
/**
 
385
 * Overly complex function that builds a .deb file.
 
386
 */
 
387
int
 
388
do_build(const char *const *argv)
 
389
{
 
390
  const char *debar, *dir;
213
391
  bool subdir;
214
 
  char *controlfile, *tfbuf;
215
 
  struct pkginfo *checkedinfo;
216
 
  struct arbitraryfield *field;
217
 
  FILE *ar, *cf;
218
 
  int p1[2], p2[2], p3[2], warns, n, c, gzfd;
 
392
  char *tfbuf;
 
393
  int arfd;
 
394
  int p1[2], p2[2], p3[2], gzfd;
219
395
  pid_t c1,c2,c3;
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;
225
 
  
226
 
/* Decode our arguments */
227
 
  directory = *argv++;
228
 
  if (!directory)
 
399
 
 
400
  /* Decode our arguments. */
 
401
  dir = *argv++;
 
402
  if (!dir)
229
403
    badusage(_("--%s needs a <directory> argument"), cipaction->olong);
230
404
  subdir = false;
231
405
  debar = *argv++;
232
406
  if (debar != NULL) {
 
407
    struct stat debarstab;
 
408
 
233
409
    if (*argv) badusage(_("--build takes at most two arguments"));
234
 
    if (debar) {
235
 
      if (stat(debar,&debarstab)) {
236
 
        if (errno != ENOENT)
237
 
          ohshite(_("unable to check for existence of archive `%.250s'"),debar);
238
 
      } else if (S_ISDIR(debarstab.st_mode)) {
239
 
        subdir = true;
240
 
      }
 
410
 
 
411
    if (stat(debar, &debarstab)) {
 
412
      if (errno != ENOENT)
 
413
        ohshite(_("unable to check for existence of archive `%.250s'"), debar);
 
414
    } else if (S_ISDIR(debarstab.st_mode)) {
 
415
      subdir = true;
241
416
    }
242
417
  } else {
243
 
    m= m_malloc(strlen(directory) + sizeof(DEBEXT));
244
 
    strcpy(m, directory);
245
 
    path_rtrim_slash_slashdot(m);
 
418
    char *m;
 
419
 
 
420
    m= m_malloc(strlen(dir) + sizeof(DEBEXT));
 
421
    strcpy(m, dir);
 
422
    path_trim_slash_slashdot(m);
246
423
    strcat(m, DEBEXT);
247
424
    debar= m;
248
425
  }
249
 
    
250
 
  /* Perform some sanity checks on the to-be-build package.
251
 
   */
 
426
 
 
427
  /* Perform some sanity checks on the to-be-build package. */
252
428
  if (nocheckflag) {
253
429
    if (subdir)
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);
257
433
  } else {
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);
266
 
    warns = 0;
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);
276
 
      warns++;
277
 
    }
278
 
    for (field= checkedinfo->available.arbs; field; field= field->next) {
279
 
      if (known_arbitrary_field(field))
280
 
        continue;
281
 
 
282
 
      warning(_("'%s' contains user-defined field '%s'"),
283
 
              controlfile, field->name);
284
 
      warns++;
285
 
    }
286
 
 
287
 
    if (subdir) {
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);
294
 
      debar= m;
295
 
    }
296
 
    printf(_("dpkg-deb: building package `%s' in `%s'.\n"), checkedinfo->name, debar);
297
 
 
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));
308
 
 
309
 
    for (mscriptp= maintainerscripts; *mscriptp; mscriptp++) {
310
 
      strcpy(controlfile, directory);
311
 
      strcat(controlfile, "/" BUILDCONTROLDIR "/");
312
 
      strcat(controlfile, *mscriptp);
313
 
 
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);
324
 
      }
325
 
    }
326
 
 
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;
333
 
 
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"),
339
 
                  conffilename);
340
 
          warns++;
341
 
          while ((c= getc(cf)) != EOF && c != '\n');
342
 
          continue;
343
 
        }
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"),
352
 
                      conffilename);
353
 
            ohshit(_("conffile `%.250s' does not appear in package"), conffilename);
354
 
          } else
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);
358
 
          warns++;
359
 
        }
360
 
 
361
 
        if (file_info_find_name(conffiles_head, conffilename))
362
 
          warning(_("conffile name '%s' is duplicated"), conffilename);
363
 
        else {
364
 
          struct file_info *conffile;
365
 
 
366
 
          conffile = file_info_new(conffilename);
367
 
          add_to_filist(&conffiles_head, &conffiles_tail, conffile);
368
 
        }
369
 
      }
370
 
 
371
 
      free_filist(conffiles_head);
372
 
 
373
 
      if (ferror(cf)) ohshite(_("error reading conffiles file"));
374
 
      fclose(cf);
375
 
    } else if (errno != ENOENT) {
376
 
      ohshite(_("error opening conffiles file"));
377
 
    }
378
 
    if (warns)
379
 
      warning(P_("ignoring %d warning about the control file(s)\n",
380
 
                 "ignoring %d warnings about the control file(s)\n", warns),
381
 
              warns);
382
 
 
 
434
    struct pkginfo *pkg;
 
435
 
 
436
    pkg = check_new_pkg(dir);
 
437
    if (subdir)
 
438
      debar = pkg_get_pathname(debar, pkg);
 
439
    printf(_("dpkg-deb: building package `%s' in `%s'.\n"), pkg->name, debar);
383
440
  }
384
441
  m_output(stdout, _("<standard output>"));
385
 
  
 
442
 
386
443
  /* Now that we have verified everything its time to actually
387
 
   * build something. Lets start by making the ar-wrapper.
388
 
   */
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);
 
446
  if (arfd < 0)
 
447
    ohshite(_("unable to create `%.255s'"), debar);
 
448
  /* Fork a tar to package the control-section of the package. */
393
449
  unsetenv("TAR_OPTIONS");
394
450
  m_pipe(p1);
395
451
  c1 = subproc_fork();
396
452
  if (!c1) {
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"));
 
454
    if (chdir(dir))
 
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);
402
460
  }
403
461
  close(p1[1]);
404
 
  /* Create a temporary file to store the control data in. Immediately unlink
405
 
   * our temporary file so others can't mess with it.
406
 
   */
 
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"),
411
 
      tfbuf);
 
465
  gzfd = mkstemp(tfbuf);
 
466
  if (gzfd == -1)
 
467
    ohshite(_("failed to make temporary file (%s)"), _("control member"));
 
468
  /* Make sure it's gone, the fd will remain until we close it. */
 
469
  if (unlink(tfbuf))
 
470
    ohshit(_("failed to unlink temporary file (%s), %s"), _("control member"),
 
471
           tfbuf);
412
472
  free(tfbuf);
413
473
 
414
 
  /* And run gzip to compress our control archive */
 
474
  /* And run gzip to compress our control archive. */
415
475
  c2 = subproc_fork();
416
476
  if (!c2) {
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"));
419
479
  }
420
480
  close(p1[0]);
421
481
  subproc_wait_check(c2, "gzip -9c", 0);
422
482
  subproc_wait_check(c1, "tar -cf", 0);
423
483
 
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"));
426
486
 
427
 
  /* We have our first file for the ar-archive. Write a header for it to the
428
 
   * package and insert it.
429
 
   */
 
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;
 
491
    char versionbuf[40];
 
492
 
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)
434
 
      werr(debar);
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"));
436
500
  } else {
437
501
    const char deb_magic[] = ARCHIVEVERSION "\n";
438
502
 
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);
443
 
  }                
 
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);
 
506
  }
444
507
 
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) {
449
512
    close(gzfd);
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"),
454
 
        tfbuf);
 
514
    gzfd = mkstemp(tfbuf);
 
515
    if (gzfd == -1)
 
516
      ohshite(_("failed to make temporary file (%s)"), _("data member"));
 
517
    /* Make sure it's gone, the fd will remain until we close it. */
 
518
    if (unlink(tfbuf))
 
519
      ohshit(_("failed to unlink temporary file (%s), %s"), _("data member"),
 
520
             tfbuf);
455
521
    free(tfbuf);
456
522
  }
457
 
  /* Fork off a tar. We will feed it a list of filenames on stdin later.
458
 
   */
 
523
  /* Fork off a tar. We will feed it a list of filenames on stdin later. */
459
524
  m_pipe(p1);
460
525
  m_pipe(p2);
461
526
  c1 = subproc_fork();
462
527
  if (!c1) {
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);
 
530
    if (chdir(dir))
 
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);
468
534
  }
469
535
  close(p1[0]);
470
536
  close(p2[1]);
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();
473
539
  if (!c2) {
474
540
    close(p1[1]);
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"));
478
544
  }
479
545
  close(p2[0]);
 
546
 
480
547
  /* All the pipes are set, now lets run find, and start feeding
481
 
   * filenames to tar.
482
 
   */
483
 
 
 
548
   * filenames to tar. */
484
549
  m_pipe(p3);
485
550
  c3 = subproc_fork();
486
551
  if (!c3) {
487
552
    m_dup2(p3[1],1); close(p3[0]); close(p3[1]);
488
 
    if (chdir(directory)) ohshite(_("failed to chdir to `%.255s'"),directory);
 
553
    if (chdir(dir))
 
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);
492
558
  }
493
559
  close(p3[1]);
494
560
  /* We need to reorder the files so we can make sure that symlinks
495
 
   * will not appear before their target.
496
 
   */
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);
500
565
    else {
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)"),
 
568
                _("data member"));
503
569
      file_info_free(fi);
504
570
    }
505
571
  close(p3[0]);
506
572
  subproc_wait_check(c3, "find", 0);
507
573
 
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. */
512
578
  close(p1[1]);
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];
519
585
 
520
586
    sprintf(datamember, "%s%s", DATAMEMBER, compressor->extension);
521
587
 
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"));
523
590
 
524
 
    dpkg_ar_member_put_file(debar, fileno(ar), datamember, gzfd);
 
591
    dpkg_ar_member_put_file(debar, arfd, datamember, gzfd, -1);
525
592
  }
526
 
  if (fflush(ar))
527
 
    ohshite(_("unable to flush file '%s'"), debar);
528
 
  if (fsync(fileno(ar)))
 
593
  if (fsync(arfd))
529
594
    ohshite(_("unable to sync file '%s'"), debar);
530
 
  if (fclose(ar)) werr(debar);
531
 
                             
532
 
  exit(0);
 
595
  if (close(arfd))
 
596
    ohshite(_("unable to close file '%s'"), debar);
 
597
 
 
598
  return 0;
533
599
}
534