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

« back to all changes in this revision

Viewing changes to src/archives.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:
4
4
 *
5
5
 * Copyright © 1994,1995 Ian Jackson <ian@chiark.greenend.org.uk>
6
6
 * Copyright © 2000 Wichert Akkerman <wakkerma@debian.org>
 
7
 * Copyright © 2007-2011 Guillem Jover <guillem@debian.org>
7
8
 *
8
9
 * This is free software; you can redistribute it and/or modify
9
10
 * it under the terms of the GNU General Public License as published by
23
24
#include <compat.h>
24
25
 
25
26
#include <sys/types.h>
 
27
#include <sys/time.h>
26
28
#include <sys/stat.h>
27
29
 
28
30
#include <assert.h>
30
32
#include <ctype.h>
31
33
#include <string.h>
32
34
#include <time.h>
33
 
#include <utime.h>
34
35
#include <fcntl.h>
35
36
#include <unistd.h>
 
37
#include <stdint.h>
36
38
#include <stdlib.h>
37
39
#include <stdio.h>
38
40
#include <obstack.h>
43
45
#include <dpkg/dpkg.h>
44
46
#include <dpkg/dpkg-db.h>
45
47
#include <dpkg/path.h>
 
48
#include <dpkg/fdio.h>
46
49
#include <dpkg/buffer.h>
47
50
#include <dpkg/subproc.h>
48
51
#include <dpkg/command.h>
 
52
#include <dpkg/file.h>
49
53
#include <dpkg/tarfn.h>
50
54
#include <dpkg/myopt.h>
51
55
#include <dpkg/triglib.h>
59
63
#include "archives.h"
60
64
#include "filters.h"
61
65
 
62
 
#define MAXCONFLICTORS 20
63
 
 
64
 
struct pkginfo *conflictor[MAXCONFLICTORS];
65
 
int cflict_index = 0;
66
 
 
67
 
/* special routine to handle partial reads from the tarfile */
68
 
static int safe_read(int fd, void *buf, int len)
69
 
{
70
 
  int r, have= 0;
71
 
  char *p = (char *)buf;
72
 
  while (have < len) {
73
 
    if ((r= read(fd,p,len-have))==-1) {
74
 
      if (errno==EINTR || errno==EAGAIN) continue;
75
 
      return r;
76
 
    }
77
 
    if (r==0)
78
 
      break;
79
 
    have+= r;
80
 
    p+= r;
81
 
  }
82
 
  return have;
83
 
}
84
 
 
85
66
static inline void
86
67
fd_writeback_init(int fd)
87
68
{
 
69
  /* Ignore the return code as it should be considered equivalent to an
 
70
   * asynchronous hint for the kernel, we are doing an fsync() later on
 
71
   * anyway. */
88
72
#if defined(SYNC_FILE_RANGE_WRITE)
89
73
  sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WRITE);
90
74
#elif defined(HAVE_POSIX_FADVISE)
95
79
static struct obstack tar_obs;
96
80
static bool tarobs_init = false;
97
81
 
98
 
/* ensure the obstack is properly initialized */
 
82
/**
 
83
 * Ensure the obstack is properly initialized.
 
84
 */
99
85
static void ensureobstackinit(void) {
100
86
 
101
87
  if (!tarobs_init) {
104
90
  }
105
91
}
106
92
 
107
 
/* destroy the obstack */
 
93
/**
 
94
 * Destroy the obstack.
 
95
 */
108
96
static void destroyobstack(void) {
109
97
  if (tarobs_init) {
110
98
    obstack_free(&tar_obs, NULL);
112
100
  }
113
101
}
114
102
 
 
103
/**
 
104
 * Check if a file or directory will save a package from disappearance.
 
105
 *
 
106
 * A package can only be saved by a file or directory which is part
 
107
 * only of itself - it must be neither part of the new package being
 
108
 * installed nor part of any 3rd package (this is important so that
 
109
 * shared directories don't stop packages from disappearing).
 
110
 */
115
111
bool
116
112
filesavespackage(struct fileinlist *file,
117
113
                 struct pkginfo *pkgtobesaved,
119
115
{
120
116
  struct filepackages_iterator *iter;
121
117
  struct pkginfo *divpkg, *thirdpkg;
122
 
  
 
118
 
123
119
  debug(dbg_eachfiledetail,"filesavespackage file `%s' package %s",
124
120
        file->namenode->name,pkgtobesaved->name);
125
 
  /* A package can only be saved by a file or directory which is part
126
 
   * only of itself - it must be neither part of the new package being
127
 
   * installed nor part of any 3rd package (this is important so that
128
 
   * shared directories don't stop packages from disappearing).
129
 
   */
 
121
 
130
122
  /* If the file is a contended one and it's overridden by either
131
123
   * the package we're considering disappearing or the package
132
124
   * we're installing then they're not actually the same file, so
133
 
   * we can't disappear the package - it is saved by this file.
134
 
   */
 
125
   * we can't disappear the package - it is saved by this file. */
135
126
  if (file->namenode->divert && file->namenode->divert->useinstead) {
136
127
    divpkg= file->namenode->divert->pkg;
137
128
    if (divpkg == pkgtobesaved || divpkg == pkgbeinginstalled) {
139
130
      return true;
140
131
    }
141
132
  }
142
 
  /* Is the file in the package being installed ?  If so then it can't save.
143
 
   */
 
133
  /* Is the file in the package being installed? If so then it can't save. */
144
134
  if (file->namenode->flags & fnnf_new_inarchive) {
145
135
    debug(dbg_eachfiledetail,"filesavespackage ... in new archive -- no save");
146
136
    return false;
147
137
  }
148
138
  /* Look for a 3rd package which can take over the file (in case
149
 
   * it's a directory which is shared by many packages.
150
 
   */
 
139
   * it's a directory which is shared by many packages. */
151
140
  iter = filepackages_iter_new(file->namenode);
152
141
  while ((thirdpkg = filepackages_iter_next(iter))) {
153
142
    debug(dbg_eachfiledetail, "filesavespackage ... also in %s",
179
168
 
180
169
void cu_pathname(int argc, void **argv) {
181
170
  ensure_pathname_nonexisting((char*)(argv[0]));
182
 
 
171
}
183
172
 
184
173
int tarfileread(void *ud, char *buf, int len) {
185
174
  struct tarcontext *tc= (struct tarcontext*)ud;
186
175
  int r;
187
 
  if ((r= safe_read(tc->backendpipe,buf,len)) == -1)
 
176
 
 
177
  r = fd_read(tc->backendpipe, buf, len);
 
178
  if (r < 0)
188
179
    ohshite(_("error reading from dpkg-deb pipe"));
189
180
  return r;
190
181
}
196
187
  char databuf[TARBLKSZ];
197
188
 
198
189
  /* We need to advance the tar file to the next object, so read the
199
 
   * file data and set it to oblivion.
200
 
   */
 
190
   * file data and set it to oblivion. */
201
191
  if (ti->type == tar_filetype_file) {
202
192
    char fnamebuf[256];
203
193
 
206
196
                 path_quote_filename(fnamebuf, ti->name, 256));
207
197
    r = ti->size % TARBLKSZ;
208
198
    if (r > 0)
209
 
      if (safe_read(tc->backendpipe, databuf, TARBLKSZ - r) == -1)
 
199
      if (fd_read(tc->backendpipe, databuf, TARBLKSZ - r) < 0)
210
200
        ohshite(_("error reading from dpkg-deb pipe"));
211
201
  }
212
202
}
220
210
static time_t currenttime;
221
211
 
222
212
static int
223
 
does_replace(struct pkginfo *newpigp, struct pkginfoperfile *newpifp,
224
 
             struct pkginfo *oldpigp, struct pkginfoperfile *oldpifp)
 
213
does_replace(struct pkginfo *newpigp, struct pkgbin *newpifp,
 
214
             struct pkginfo *oldpigp, struct pkgbin *oldpifp)
225
215
{
226
216
  struct dependency *dep;
227
 
  
 
217
 
228
218
  debug(dbg_depcon,"does_replace new=%s old=%s (%s)",newpigp->name,
229
219
        oldpigp->name, versiondescribe(&oldpifp->version, vdew_always));
230
220
  for (dep= newpifp->depends; dep; dep= dep->next) {
241
231
}
242
232
 
243
233
static void
244
 
newtarobject_utime(const char *path, struct tar_entry *ti)
 
234
tarobject_set_mtime(struct tar_entry *te, const char *path)
245
235
{
246
 
  struct utimbuf utb;
247
 
  utb.actime= currenttime;
248
 
  utb.modtime = ti->mtime;
249
 
  if (utime(path,&utb))
250
 
    ohshite(_("error setting timestamps of `%.255s'"), ti->name);
 
236
  struct timeval tv[2];
 
237
 
 
238
  tv[0].tv_sec = currenttime;
 
239
  tv[0].tv_usec = 0;
 
240
  tv[1].tv_sec = te->mtime;
 
241
  tv[1].tv_usec = 0;
 
242
 
 
243
  if (te->type == tar_filetype_symlink) {
 
244
#ifdef HAVE_LUTIMES
 
245
    if (lutimes(path, tv))
 
246
      ohshite(_("error setting timestamps of `%.255s'"), path);
 
247
#endif
 
248
  } else {
 
249
    if (utimes(path, tv))
 
250
      ohshite(_("error setting timestamps of `%.255s'"), path);
 
251
  }
251
252
}
252
253
 
253
254
static void
254
 
newtarobject_allmodes(const char *path, struct tar_entry *ti,
255
 
                      struct filestatoverride *statoverride)
 
255
tarobject_set_perms(struct tar_entry *te, const char *path, struct file_stat *st)
256
256
{
257
 
  if (chown(path,
258
 
            statoverride ? statoverride->uid : ti->uid,
259
 
            statoverride ? statoverride->gid : ti->gid))
260
 
    ohshite(_("error setting ownership of `%.255s'"), ti->name);
261
 
  if (chmod(path,(statoverride ? statoverride->mode : ti->mode) & ~S_IFMT))
262
 
    ohshite(_("error setting permissions of `%.255s'"), ti->name);
263
 
  newtarobject_utime(path,ti);
 
257
  if (te->type == tar_filetype_file)
 
258
    return; /* Already handled using the file descriptor. */
 
259
 
 
260
  if (te->type == tar_filetype_symlink) {
 
261
    if (lchown(path, st->uid, st->gid))
 
262
      ohshite(_("error setting ownership of symlink `%.255s'"), path);
 
263
  } else {
 
264
    if (chown(path, st->uid, st->gid))
 
265
      ohshite(_("error setting ownership of `%.255s'"), path);
 
266
    if (chmod(path, st->mode & ~S_IFMT))
 
267
      ohshite(_("error setting permissions of `%.255s'"), path);
 
268
  }
264
269
}
265
270
 
266
271
static void
304
309
 
305
310
void setupfnamevbs(const char *filename) {
306
311
  varbuf_trunc(&fnamevb, fnameidlu);
307
 
  varbufaddstr(&fnamevb,filename);
308
 
  varbufaddc(&fnamevb,0);
 
312
  varbuf_add_str(&fnamevb, filename);
 
313
  varbuf_end_str(&fnamevb);
309
314
 
310
315
  varbuf_trunc(&fnametmpvb, fnameidlu);
311
 
  varbufaddstr(&fnametmpvb,filename);
312
 
  varbufaddstr(&fnametmpvb,DPKGTEMPEXT);
313
 
  varbufaddc(&fnametmpvb,0);
 
316
  varbuf_add_str(&fnametmpvb, filename);
 
317
  varbuf_add_str(&fnametmpvb, DPKGTEMPEXT);
 
318
  varbuf_end_str(&fnametmpvb);
314
319
 
315
320
  varbuf_trunc(&fnamenewvb, fnameidlu);
316
 
  varbufaddstr(&fnamenewvb,filename);
317
 
  varbufaddstr(&fnamenewvb,DPKGNEWEXT);
318
 
  varbufaddc(&fnamenewvb,0);
 
321
  varbuf_add_str(&fnamenewvb, filename);
 
322
  varbuf_add_str(&fnamenewvb, DPKGNEWEXT);
 
323
  varbuf_end_str(&fnamenewvb);
319
324
 
320
325
  debug(dbg_eachfiledetail, "setupvnamevbs main=`%s' tmp=`%s' new=`%s'",
321
326
        fnamevb.buf, fnametmpvb.buf, fnamenewvb.buf);
322
327
}
323
328
 
324
 
int unlinkorrmdir(const char *filename) {
325
 
  /* Returns 0 on success or -1 on failure, just like unlink & rmdir */
 
329
/**
 
330
 * Securely remove a pathname.
 
331
 *
 
332
 * This is a secure version of remove(3) using secure_unlink() instead of
 
333
 * unlink(2).
 
334
 *
 
335
 * @retval  0 On success.
 
336
 * @retval -1 On failure, just like unlink(2) & rmdir(2).
 
337
 */
 
338
int
 
339
secure_remove(const char *filename)
 
340
{
326
341
  int r, e;
327
 
  
 
342
 
328
343
  if (!rmdir(filename)) {
329
 
    debug(dbg_eachfiledetail,"unlinkorrmdir `%s' rmdir OK",filename);
 
344
    debug(dbg_eachfiledetail, "secure_remove '%s' rmdir OK", filename);
330
345
    return 0;
331
346
  }
332
 
  
 
347
 
333
348
  if (errno != ENOTDIR) {
334
349
    e= errno;
335
 
    debug(dbg_eachfiledetail,"unlinkorrmdir `%s' rmdir %s",filename,strerror(e));
 
350
    debug(dbg_eachfiledetail, "secure_remove '%s' rmdir %s", filename,
 
351
          strerror(e));
336
352
    errno= e; return -1;
337
353
  }
338
 
  
 
354
 
339
355
  r = secure_unlink(filename);
340
356
  e = errno;
341
 
  debug(dbg_eachfiledetail,"unlinkorrmdir `%s' unlink %s",
 
357
  debug(dbg_eachfiledetail, "secure_remove '%s' unlink %s",
342
358
        filename, r ? strerror(e) : "OK");
343
359
  errno= e; return r;
344
360
}
346
362
struct fileinlist *addfiletolist(struct tarcontext *tc,
347
363
                                 struct filenamenode *namenode) {
348
364
  struct fileinlist *nifd;
349
 
  
 
365
 
350
366
  nifd= obstack_alloc(&tar_obs, sizeof(struct fileinlist));
351
367
  nifd->namenode= namenode;
352
368
  nifd->next = NULL;
383
399
  if (!S_ISDIR(oldstab.st_mode))
384
400
    return false;
385
401
 
386
 
  /* But is it to the same dir ? */
387
 
  varbufreset(symlinkfn);
 
402
  /* But is it to the same dir? */
 
403
  varbuf_reset(symlinkfn);
388
404
  if (ti->linkname[0] == '/') {
389
 
    varbufaddstr(symlinkfn, instdir);
 
405
    varbuf_add_str(symlinkfn, instdir);
390
406
  } else {
391
407
    lastslash= strrchr(fname, '/');
392
408
    assert(lastslash);
393
 
    varbufaddbuf(symlinkfn, fname, (lastslash - fname) + 1);
 
409
    varbuf_add_buf(symlinkfn, fname, (lastslash - fname) + 1);
394
410
  }
395
 
  varbufaddstr(symlinkfn, ti->linkname);
396
 
  varbufaddc(symlinkfn, 0);
 
411
  varbuf_add_str(symlinkfn, ti->linkname);
 
412
  varbuf_end_str(symlinkfn);
397
413
 
398
414
  statr= stat(symlinkfn->buf, &newstab);
399
415
  if (statr) {
421
437
 
422
438
  struct conffile *conff;
423
439
  struct tarcontext *tc = ctx;
424
 
  bool existingdirectory, keepexisting;
 
440
  bool existingdir, keepexisting;
425
441
  int statr;
426
442
  ssize_t r;
427
443
  struct stat stab, stabtmp;
428
444
  char databuf[TARBLKSZ];
 
445
  struct file_stat *st;
429
446
  struct fileinlist *nifd, **oldnifd;
430
447
  struct pkginfo *divpkg, *otherpkg;
431
 
  mode_t am;
432
448
 
433
449
  ensureobstackinit();
434
450
 
435
451
  /* Append to list of files.
436
 
   * The trailing / put on the end of names in tarfiles has already
437
 
   * been stripped by tar_extractor (lib/tarfn.c).
438
 
   */
 
452
   * The trailing ‘/’ put on the end of names in tarfiles has already
 
453
   * been stripped by tar_extractor(). */
439
454
  oldnifd= tc->newfilesp;
440
455
  nifd= addfiletolist(tc, findnamenode(ti->name, 0));
441
456
  nifd->namenode->flags |= fnnf_new_inarchive;
443
458
  debug(dbg_eachfile,
444
459
        "tarobject ti->name='%s' mode=%lo owner=%u.%u type=%d(%c)"
445
460
        " ti->linkname='%s' namenode='%s' flags=%o instead='%s'",
446
 
        ti->name, (long)ti->mode, (unsigned)ti->uid, (unsigned)ti->gid,
 
461
        ti->name, (long)ti->stat.mode,
 
462
        (unsigned)ti->stat.uid, (unsigned)ti->stat.gid,
447
463
        ti->type,
448
464
        ti->type >= '0' && ti->type <= '6' ? "-hlcbdp"[ti->type - '0'] : '?',
449
465
        ti->linkname,
468
484
    }
469
485
  }
470
486
 
 
487
  if (nifd->namenode->statoverride)
 
488
    st = nifd->namenode->statoverride;
 
489
  else
 
490
    st = &ti->stat;
 
491
 
471
492
  usenode = namenodetouse(nifd->namenode, tc->pkg);
472
493
  usename = usenode->name + 1; /* Skip the leading '/'. */
473
494
 
475
496
 
476
497
  if (nifd->namenode->flags & fnnf_new_conff) {
477
498
    /* If it's a conffile we have to extract it next to the installed
478
 
     * version (ie, we do the usual link-following).
479
 
     */
 
499
     * version (i.e. we do the usual link-following). */
480
500
    if (conffderef(tc->pkg, &conffderefn, usename))
481
501
      usename= conffderefn.buf;
482
502
    debug(dbg_conff,"tarobject fnnf_new_conff deref=`%s'",usename);
483
503
  }
484
 
  
 
504
 
485
505
  setupfnamevbs(usename);
486
506
 
487
507
  statr= lstat(fnamevb.buf,&stab);
493
513
    /* OK, so it doesn't exist.
494
514
     * However, it's possible that we were in the middle of some other
495
515
     * backup/restore operation and were rudely interrupted.
496
 
     * So, we see if we have .dpkg-tmp, and if so we restore it.
497
 
     */
 
516
     * So, we see if we have .dpkg-tmp, and if so we restore it. */
498
517
    if (rename(fnametmpvb.buf,fnamevb.buf)) {
499
518
      if (errno != ENOENT && errno != ENOTDIR)
500
519
        ohshite(_("unable to clean up mess surrounding `%.255s' before "
511
530
  }
512
531
 
513
532
  /* Check to see if it's a directory or link to one and we don't need to
514
 
   * do anything.  This has to be done now so that we don't die due to
515
 
   * a file overwriting conflict.
516
 
   */
517
 
  existingdirectory = false;
 
533
   * do anything. This has to be done now so that we don't die due to
 
534
   * a file overwriting conflict. */
 
535
  existingdir = false;
518
536
  switch (ti->type) {
519
537
  case tar_filetype_symlink:
520
538
    /* If it's already an existing directory, do nothing. */
521
539
    if (!statr && S_ISDIR(stab.st_mode)) {
522
540
      debug(dbg_eachfiledetail, "tarobject symlink exists as directory");
523
 
      existingdirectory = true;
 
541
      existingdir = true;
524
542
    } else if (!statr && S_ISLNK(stab.st_mode)) {
525
543
      if (linktosameexistingdir(ti, fnamevb.buf, &symlinkfn))
526
 
        existingdirectory = true;
 
544
        existingdir = true;
527
545
    }
528
546
    break;
529
547
  case tar_filetype_dir:
530
548
    /* If it's already an existing directory, do nothing. */
531
549
    if (!stat(fnamevb.buf,&stabtmp) && S_ISDIR(stabtmp.st_mode)) {
532
550
      debug(dbg_eachfiledetail, "tarobject directory exists");
533
 
      existingdirectory = true;
 
551
      existingdir = true;
534
552
    }
535
553
    break;
536
554
  case tar_filetype_file:
545
563
  }
546
564
 
547
565
  keepexisting = false;
548
 
  if (!existingdirectory) {
 
566
  if (!existingdir) {
549
567
    struct filepackages_iterator *iter;
550
568
 
551
569
    iter = filepackages_iter_new(nifd->namenode);
565
583
          continue;
566
584
      }
567
585
 
568
 
      /* Nope ?  Hmm, file conflict, perhaps.  Check Replaces. */
 
586
      /* Nope? Hmm, file conflict, perhaps. Check Replaces. */
569
587
      switch (otherpkg->clientdata->replacingfilesandsaid) {
570
588
      case 2:
571
589
        keepexisting = true;
601
619
        }
602
620
        if (conff) {
603
621
          debug(dbg_eachfiledetail, "tarobject other's obsolete conffile");
604
 
          /* processarc.c will have copied its hash already. */
 
622
          /* process_archive() will have copied its hash already. */
605
623
          continue;
606
624
        }
607
625
      }
626
644
                      versiondescribe(&otherpkg->installed.version,
627
645
                                      vdew_nonambig));
628
646
        } else {
629
 
          /* WTA: At this point we are replacing something without a Replaces.
630
 
           * if the new object is a directory and the previous object does not
631
 
           * exist assume it's also a directory and don't complain. */
 
647
          /* At this point we are replacing something without a Replaces.
 
648
           * If the new object is a directory and the previous object does
 
649
           * not exist assume it's also a directory and don't complain. */
632
650
          if (!(statr && ti->type == tar_filetype_dir))
633
651
            forcibleerr(fc_overwrite,
634
652
                        _("trying to overwrite '%.250s', "
656
674
    return 0;
657
675
  }
658
676
 
659
 
  if (existingdirectory)
 
677
  if (existingdir)
660
678
    return 0;
661
679
 
662
 
  /* Now, at this stage we want to make sure neither of .dpkg-new and .dpkg-tmp
663
 
   * are hanging around.
664
 
   */
 
680
  /* Now, at this stage we want to make sure neither of .dpkg-new and
 
681
   * .dpkg-tmp are hanging around. */
665
682
  ensure_pathname_nonexisting(fnamenewvb.buf);
666
683
  ensure_pathname_nonexisting(fnametmpvb.buf);
667
684
 
668
685
  /* Now we start to do things that we need to be able to undo
669
 
   * if something goes wrong.  Watch out for the CLEANUP comments to
670
 
   * keep an eye on what's installed on the disk at each point.
671
 
   */
 
686
   * if something goes wrong. Watch out for the CLEANUP comments to
 
687
   * keep an eye on what's installed on the disk at each point. */
672
688
  push_cleanup(cu_installnew, ~ehflag_normaltidy, NULL, 0, 1, (void *)nifd);
673
689
 
674
 
  /* CLEANUP: Now we either have the old file on the disk, or not, in
 
690
  /*
 
691
   * CLEANUP: Now we either have the old file on the disk, or not, in
675
692
   * its original filename.
676
693
   */
677
694
 
679
696
  switch (ti->type) {
680
697
  case tar_filetype_file:
681
698
    /* We create the file with mode 0 to make sure nobody can do anything with
682
 
     * it until we apply the proper mode, which might be a statoverride.
683
 
     */
 
699
     * it until we apply the proper mode, which might be a statoverride. */
684
700
    fd= open(fnamenewvb.buf, (O_CREAT|O_EXCL|O_WRONLY), 0);
685
701
    if (fd < 0)
686
702
      ohshite(_("unable to create `%.255s' (while processing `%.255s')"),
687
703
              fnamenewvb.buf, ti->name);
688
704
    push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd);
689
 
    debug(dbg_eachfiledetail, "tarobject file open size=%lu",
690
 
          (unsigned long)ti->size);
 
705
    debug(dbg_eachfiledetail, "tarobject file open size=%jd",
 
706
          (intmax_t)ti->size);
691
707
    { char fnamebuf[256];
692
708
    fd_fd_copy(tc->backendpipe, fd, ti->size,
693
709
               _("backend dpkg-deb during `%.255s'"),
695
711
    }
696
712
    r = ti->size % TARBLKSZ;
697
713
    if (r > 0)
698
 
      if (safe_read(tc->backendpipe, databuf, TARBLKSZ - r) == -1)
 
714
      if (fd_read(tc->backendpipe, databuf, TARBLKSZ - r) < 0)
699
715
        ohshite(_("error reading from dpkg-deb pipe"));
700
716
 
701
717
    fd_writeback_init(fd);
702
718
 
703
 
    if (nifd->namenode->statoverride) 
 
719
    if (nifd->namenode->statoverride)
704
720
      debug(dbg_eachfile, "tarobject ... stat override, uid=%d, gid=%d, mode=%04o",
705
721
                          nifd->namenode->statoverride->uid,
706
722
                          nifd->namenode->statoverride->gid,
707
723
                          nifd->namenode->statoverride->mode);
708
 
    if (fchown(fd,
709
 
               nifd->namenode->statoverride ?
710
 
               nifd->namenode->statoverride->uid : ti->uid,
711
 
               nifd->namenode->statoverride ?
712
 
               nifd->namenode->statoverride->gid : ti->gid))
 
724
    if (fchown(fd, st->uid, st->gid))
713
725
      ohshite(_("error setting ownership of `%.255s'"), ti->name);
714
 
    am = (nifd->namenode->statoverride ?
715
 
          nifd->namenode->statoverride->mode : ti->mode) & ~S_IFMT;
716
 
    if (fchmod(fd,am))
 
726
    if (fchmod(fd, st->mode & ~S_IFMT))
717
727
      ohshite(_("error setting permissions of `%.255s'"), ti->name);
718
728
 
719
729
    /* Postpone the fsync, to try to avoid massive I/O degradation. */
720
730
    if (!fc_unsafe_io)
721
731
      nifd->namenode->flags |= fnnf_deferred_fsync;
722
732
 
723
 
    pop_cleanup(ehflag_normaltidy); /* fd= open(fnamenewvb.buf) */
 
733
    pop_cleanup(ehflag_normaltidy); /* fd = open(fnamenewvb.buf) */
724
734
    if (close(fd))
725
735
      ohshite(_("error closing/writing `%.255s'"), ti->name);
726
 
    newtarobject_utime(fnamenewvb.buf,ti);
727
736
    break;
728
737
  case tar_filetype_fifo:
729
738
    if (mkfifo(fnamenewvb.buf,0))
730
739
      ohshite(_("error creating pipe `%.255s'"), ti->name);
731
740
    debug(dbg_eachfiledetail, "tarobject fifo");
732
 
    newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
733
741
    break;
734
742
  case tar_filetype_chardev:
735
743
    if (mknod(fnamenewvb.buf, S_IFCHR, ti->dev))
736
744
      ohshite(_("error creating device `%.255s'"), ti->name);
737
745
    debug(dbg_eachfiledetail, "tarobject chardev");
738
 
    newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
739
 
    break; 
 
746
    break;
740
747
  case tar_filetype_blockdev:
741
748
    if (mknod(fnamenewvb.buf, S_IFBLK, ti->dev))
742
749
      ohshite(_("error creating device `%.255s'"), ti->name);
743
750
    debug(dbg_eachfiledetail, "tarobject blockdev");
744
 
    newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
745
 
    break; 
 
751
    break;
746
752
  case tar_filetype_hardlink:
747
 
    varbufreset(&hardlinkfn);
748
 
    varbufaddstr(&hardlinkfn,instdir); varbufaddc(&hardlinkfn,'/');
749
 
    varbufaddstr(&hardlinkfn, ti->linkname);
 
753
    varbuf_reset(&hardlinkfn);
 
754
    varbuf_add_str(&hardlinkfn, instdir);
 
755
    varbuf_add_char(&hardlinkfn, '/');
 
756
    varbuf_add_str(&hardlinkfn, ti->linkname);
750
757
    linknode = findnamenode(ti->linkname, 0);
751
758
    if (linknode->flags & fnnf_deferred_rename)
752
 
      varbufaddstr(&hardlinkfn, DPKGNEWEXT);
753
 
    varbufaddc(&hardlinkfn, '\0');
 
759
      varbuf_add_str(&hardlinkfn, DPKGNEWEXT);
 
760
    varbuf_end_str(&hardlinkfn);
754
761
    if (link(hardlinkfn.buf,fnamenewvb.buf))
755
762
      ohshite(_("error creating hard link `%.255s'"), ti->name);
756
763
    debug(dbg_eachfiledetail, "tarobject hardlink");
757
 
    newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
758
764
    break;
759
765
  case tar_filetype_symlink:
760
 
    /* We've already cheched for an existing directory. */
 
766
    /* We've already checked for an existing directory. */
761
767
    if (symlink(ti->linkname, fnamenewvb.buf))
762
768
      ohshite(_("error creating symbolic link `%.255s'"), ti->name);
763
769
    debug(dbg_eachfiledetail, "tarobject symlink creating");
764
 
    if (lchown(fnamenewvb.buf,
765
 
               nifd->namenode->statoverride ?
766
 
               nifd->namenode->statoverride->uid : ti->uid,
767
 
               nifd->namenode->statoverride ?
768
 
               nifd->namenode->statoverride->gid : ti->gid))
769
 
      ohshite(_("error setting ownership of symlink `%.255s'"), ti->name);
770
770
    break;
771
771
  case tar_filetype_dir:
772
772
    /* We've already checked for an existing directory. */
773
773
    if (mkdir(fnamenewvb.buf,0))
774
774
      ohshite(_("error creating directory `%.255s'"), ti->name);
775
775
    debug(dbg_eachfiledetail, "tarobject directory creating");
776
 
    newtarobject_allmodes(fnamenewvb.buf,ti,nifd->namenode->statoverride);
777
776
    break;
778
777
  default:
779
778
    internerr("unknown tar type '%d', but already checked", ti->type);
780
779
  }
781
780
 
782
 
  set_selinux_path_context(fnamevb.buf, fnamenewvb.buf, ti->mode);
 
781
  tarobject_set_perms(ti, fnamenewvb.buf, st);
 
782
  tarobject_set_mtime(ti, fnamenewvb.buf);
 
783
  set_selinux_path_context(fnamevb.buf, fnamenewvb.buf, st->mode);
783
784
 
784
 
  /* CLEANUP: Now we have extracted the new object in .dpkg-new (or,
785
 
   * if the file already exists as a directory and we were trying to extract
786
 
   * a directory or symlink, we returned earlier, so we don't need
787
 
   * to worry about that here).
 
785
  /*
 
786
   * CLEANUP: Now we have extracted the new object in .dpkg-new (or,
 
787
   * if the file already exists as a directory and we were trying to
 
788
   * extract a directory or symlink, we returned earlier, so we don't
 
789
   * need to worry about that here).
788
790
   *
789
791
   * The old file is still in the original filename,
790
792
   */
791
793
 
792
 
  /* First, check to see if it's a conffile.  If so we don't install
793
 
   * it now - we leave it in .dpkg-new for --configure to take care of
794
 
   */
 
794
  /* First, check to see if it's a conffile. If so we don't install
 
795
   * it now - we leave it in .dpkg-new for --configure to take care of. */
795
796
  if (nifd->namenode->flags & fnnf_new_conff) {
796
797
    debug(dbg_conffdetail,"tarobject conffile extracted");
797
798
    nifd->namenode->flags |= fnnf_elide_other_lists;
799
800
  }
800
801
 
801
802
  /* Now we move the old file out of the way, the backup file will
802
 
   * be deleted later.
803
 
   */
804
 
  if (statr) { /* Don't try to back it up if it didn't exist. */
 
803
   * be deleted later. */
 
804
  if (statr) {
 
805
    /* Don't try to back it up if it didn't exist. */
805
806
    debug(dbg_eachfiledetail,"tarobject new - no backup");
806
807
  } else {
807
808
    if (ti->type == tar_filetype_dir || S_ISDIR(stab.st_mode)) {
812
813
        ohshite(_("unable to move aside `%.255s' to install new version"),
813
814
                ti->name);
814
815
    } else if (S_ISLNK(stab.st_mode)) {
815
 
      /* We can't make a symlink with two hardlinks, so we'll have to copy it.
816
 
       * (Pretend that making a copy of a symlink is the same as linking to it.)
817
 
       */
818
 
      varbufreset(&symlinkfn);
 
816
      /* We can't make a symlink with two hardlinks, so we'll have to
 
817
       * copy it. (Pretend that making a copy of a symlink is the same
 
818
       * as linking to it.) */
 
819
      varbuf_reset(&symlinkfn);
819
820
      varbuf_grow(&symlinkfn, stab.st_size + 1);
820
821
      r = readlink(fnamevb.buf, symlinkfn.buf, symlinkfn.size);
821
822
      if (r < 0)
822
823
        ohshite(_("unable to read link `%.255s'"), ti->name);
823
824
      assert(r == stab.st_size);
824
825
      varbuf_trunc(&symlinkfn, r);
825
 
      varbufaddc(&symlinkfn, '\0');
 
826
      varbuf_end_str(&symlinkfn);
826
827
      if (symlink(symlinkfn.buf,fnametmpvb.buf))
827
828
        ohshite(_("unable to make backup symlink for `%.255s'"), ti->name);
828
829
      if (lchown(fnametmpvb.buf,stab.st_uid,stab.st_gid))
836
837
    }
837
838
  }
838
839
 
839
 
  /* CLEANUP: now the old file is in dpkg-tmp, and the new file is still
840
 
   * in dpkg-new.
 
840
  /*
 
841
   * CLEANUP: Now the old file is in .dpkg-tmp, and the new file is still
 
842
   * in .dpkg-new.
841
843
   */
842
844
 
843
845
  if (ti->type == tar_filetype_file || ti->type == tar_filetype_symlink) {
848
850
    if (rename(fnamenewvb.buf, fnamevb.buf))
849
851
      ohshite(_("unable to install new version of `%.255s'"), ti->name);
850
852
 
851
 
    /* CLEANUP: now the new file is in the destination file, and the
852
 
     * old file is in dpkg-tmp to be cleaned up later.  We now need
 
853
    /*
 
854
     * CLEANUP: Now the new file is in the destination file, and the
 
855
     * old file is in .dpkg-tmp to be cleaned up later. We now need
853
856
     * to take a different attitude to cleanup, because we need to
854
 
     * remove the new file. */
 
857
     * remove the new file.
 
858
     */
855
859
 
856
860
    nifd->namenode->flags |= fnnf_placed_on_disk;
857
861
    nifd->namenode->flags |= fnnf_elide_other_lists;
884
888
    fd = open(fnamenewvb.buf, O_WRONLY);
885
889
    if (fd < 0)
886
890
      ohshite(_("unable to open '%.255s'"), fnamenewvb.buf);
 
891
    /* Ignore the return code as it should be considered equivalent to an
 
892
     * asynchronous hint for the kernel, we are doing an fsync() later on
 
893
     * anyway. */
887
894
    sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE);
888
895
    if (close(fd))
889
896
      ohshite(_("error closing/writing `%.255s'"), fnamenewvb.buf);
903
910
  struct filenamenode *usenode;
904
911
  const char *usename;
905
912
 
906
 
#if defined(USE_SYNC_SYNC)
907
 
  debug(dbg_general, "deferred extract mass sync");
908
 
  if (!fc_unsafe_io)
909
 
    sync();
910
 
#else
911
913
  tar_writeback_barrier(files, pkg);
912
 
#endif
913
914
 
914
915
  for (cfile = files; cfile; cfile = cfile->next) {
915
916
    debug(dbg_eachfile, "deferred extract of '%.255s'", cfile->namenode->name);
922
923
 
923
924
    setupfnamevbs(usename);
924
925
 
925
 
#if !defined(USE_SYNC_SYNC)
926
926
    if (cfile->namenode->flags & fnnf_deferred_fsync) {
927
927
      int fd;
928
928
 
938
938
 
939
939
      cfile->namenode->flags &= ~fnnf_deferred_fsync;
940
940
    }
941
 
#endif
942
941
 
943
942
    debug(dbg_eachfiledetail, "deferred extract needs rename");
944
943
 
948
947
 
949
948
    cfile->namenode->flags &= ~fnnf_deferred_rename;
950
949
 
951
 
    /* CLEANUP: now the new file is in the destination file, and the
952
 
     * old file is in dpkg-tmp to be cleaned up later.  We now need
 
950
    /*
 
951
     * CLEANUP: Now the new file is in the destination file, and the
 
952
     * old file is in .dpkg-tmp to be cleaned up later. We now need
953
953
     * to take a different attitude to cleanup, because we need to
954
 
     * remove the new file. */
 
954
     * remove the new file.
 
955
     */
955
956
 
956
957
    cfile->namenode->flags |= fnnf_placed_on_disk;
957
958
    cfile->namenode->flags |= fnnf_elide_other_lists;
960
961
  }
961
962
}
962
963
 
 
964
/**
 
965
 * Try if we can deconfigure the package and queue it if so.
 
966
 *
 
967
 * Also checks whether the pdep is forced, first, according to force_p.
 
968
 * force_p may be NULL in which case nothing is considered forced.
 
969
 *
 
970
 * Action is a string describing the action which causes the
 
971
 * deconfiguration:
 
972
 *
 
973
 *   "removal of <package>"       (due to Conflicts+Depends; removal != NULL)
 
974
 *   "installation of <package>"  (due to Breaks;            removal == NULL)
 
975
 *
 
976
 * @retval 0 Not possible (why is printed).
 
977
 * @retval 1 Deconfiguration queued ok (no message printed).
 
978
 * @retval 2 Forced (no deconfiguration needed, why is printed).
 
979
 */
963
980
static int
964
981
try_deconfigure_can(bool (*force_p)(struct deppossi *), struct pkginfo *pkg,
965
982
                    struct deppossi *pdep, const char *action,
966
983
                    struct pkginfo *removal, const char *why)
967
984
{
968
 
  /* Also checks whether the pdep is forced, first, according to force_p.
969
 
   * force_p may be 0 in which case nothing is considered forced.
970
 
   *
971
 
   * Action is a string describing the action which causes the
972
 
   * deconfiguration:
973
 
   *     removal of <package>         (due to Conflicts+Depends   removal!=0)
974
 
   *     installation of <package>    (due to Breaks              removal==0)
975
 
   *
976
 
   * Return values:  2: forced (no deconfiguration needed, why is printed)
977
 
   *                 1: deconfiguration queued ok (no message printed)
978
 
   *                 0: not possible (why is printed)
979
 
   */
980
985
  struct pkg_deconf_list *newdeconf;
981
 
  
 
986
 
982
987
  if (force_p && force_p(pdep)) {
983
988
    warning(_("ignoring dependency problem with %s:\n%s"), action, why);
984
989
    return 2;
1029
1034
    return;
1030
1035
  }
1031
1036
 
1032
 
  varbufaddc(&why, 0);
 
1037
  varbuf_end_str(&why);
1033
1038
 
1034
1039
  if (fixbydeconf && f_autodeconf) {
1035
1040
    char action[512];
1113
1118
            continue;
1114
1119
          if (depisok(pdep->up, &removalwhy, NULL, false))
1115
1120
            continue;
1116
 
          varbufaddc(&removalwhy,0);
 
1121
          varbuf_end_str(&removalwhy);
1117
1122
          if (!try_remove_can(pdep,fixbyrm,removalwhy.buf))
1118
1123
            break;
1119
1124
        }
1130
1135
                continue;
1131
1136
              if (depisok(pdep->up, &removalwhy, NULL, false))
1132
1137
                continue;
1133
 
              varbufaddc(&removalwhy,0);
 
1138
              varbuf_end_str(&removalwhy);
1134
1139
              fprintf(stderr, _("dpkg"
1135
1140
                      ": may have trouble removing %s, as it provides %s ...\n"),
1136
1141
                      fixbyrm->name, providecheck->list->ed->name);
1155
1160
        }
1156
1161
      }
1157
1162
      if (!pdep) {
1158
 
        if (cflict_index >= MAXCONFLICTORS)
1159
 
          ohshit(_("package %s has too many Conflicts/Replaces pairs"),
1160
 
                 pkg->name);
1161
 
 
1162
1163
        /* This conflict is OK - we'll remove the conflictor. */
1163
 
        conflictor[cflict_index++]= fixbyrm;
 
1164
        push_conflictor(pkg, fixbyrm);
1164
1165
        varbuf_destroy(&conflictwhy); varbuf_destroy(&removalwhy);
1165
1166
        fprintf(stderr, _("dpkg: yes, will remove %s in favour of %s.\n"),
1166
1167
                fixbyrm->name, pkg->name);
1167
1168
        return;
1168
1169
      }
1169
 
      fixbyrm->clientdata->istobe= itb_normal; /* put it back */
 
1170
      /* Put it back. */
 
1171
      fixbyrm->clientdata->istobe = itb_normal;
1170
1172
    }
1171
1173
  }
1172
 
  varbufaddc(&conflictwhy,0);
 
1174
  varbuf_end_str(&conflictwhy);
1173
1175
  fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
1174
1176
          pfilename, pkg->name, conflictwhy.buf);
1175
1177
  if (!force_conflicts(dep->list))
1176
1178
    ohshit(_("conflicting packages - not installing %.250s"),pkg->name);
1177
1179
  warning(_("ignoring conflict, may proceed anyway!"));
1178
1180
  varbuf_destroy(&conflictwhy);
1179
 
  
 
1181
 
1180
1182
  return;
1181
1183
}
1182
1184
 
1185
1187
  char *cidirrest= (char*)argv[1];
1186
1188
  cidirrest[-1] = '\0';
1187
1189
  ensure_pathname_nonexisting(cidir);
1188
 
}  
 
1190
}
1189
1191
 
1190
1192
void cu_fileslist(int argc, void **argv) {
1191
1193
  destroyobstack();
1192
 
}  
 
1194
}
1193
1195
 
1194
 
void archivefiles(const char *const *argv) {
 
1196
int
 
1197
archivefiles(const char *const *argv)
 
1198
{
1195
1199
  const char *volatile thisarg;
1196
1200
  const char *const *volatile argp;
1197
1201
  jmp_buf ejbuf;
1198
 
  int pi[2], fc, nfiles, c, i, r;
1199
 
  FILE *pf;
1200
 
  static struct varbuf findoutput;
1201
 
  const char **arglist;
1202
 
  char *p;
1203
1202
 
1204
1203
  trigproc_install_hooks();
1205
1204
 
1206
 
  modstatdb_init(admindir,
1207
 
                 f_noact ?                     msdbrw_readonly
1208
 
               : cipaction->arg == act_avail ? msdbrw_write
1209
 
               : fc_nonroot ?                  msdbrw_write
1210
 
               :                               msdbrw_needsuperuser);
 
1205
  modstatdb_open(f_noact ?                          msdbrw_readonly :
 
1206
                 (cipaction->arg_int == act_avail ? msdbrw_readonly :
 
1207
                  fc_nonroot ?                      msdbrw_write :
 
1208
                                                    msdbrw_needsuperuser) |
 
1209
                 msdbrw_available_write);
1211
1210
 
1212
1211
  checkpath();
1213
1212
  log_message("startup archives %s", cipaction->olong);
1214
 
  
 
1213
 
1215
1214
  if (f_recursive) {
1216
 
    
 
1215
    int pi[2], nfiles, c, i, r;
 
1216
    pid_t pid;
 
1217
    FILE *pf;
 
1218
    static struct varbuf findoutput;
 
1219
    const char **arglist;
 
1220
    char *p;
 
1221
 
1217
1222
    if (!*argv)
1218
1223
      badusage(_("--%s --recursive needs at least one path argument"),cipaction->olong);
1219
 
    
 
1224
 
1220
1225
    m_pipe(pi);
1221
 
    fc = subproc_fork();
1222
 
    if (!fc) {
 
1226
    pid = subproc_fork();
 
1227
    if (pid == 0) {
1223
1228
      struct command cmd;
1224
1229
      const char *const *ap;
1225
1230
 
1231
1236
      for (ap = argv; *ap; ap++) {
1232
1237
        if (strchr(FIND_EXPRSTARTCHARS,(*ap)[0])) {
1233
1238
          char *a;
1234
 
          a= m_malloc(strlen(*ap)+10);
1235
 
          strcpy(a,"./");
1236
 
          strcat(a,*ap);
 
1239
 
 
1240
          m_asprintf(&a, "./%s", *ap);
1237
1241
          command_add_arg(&cmd, a);
1238
1242
        } else {
1239
1243
          command_add_arg(&cmd, (const char *)*ap);
1248
1252
 
1249
1253
    nfiles= 0;
1250
1254
    pf= fdopen(pi[0],"r");  if (!pf) ohshite(_("failed to fdopen find's pipe"));
1251
 
    varbufreset(&findoutput);
 
1255
    varbuf_reset(&findoutput);
1252
1256
    while ((c= fgetc(pf)) != EOF) {
1253
 
      varbufaddc(&findoutput,c);
 
1257
      varbuf_add_char(&findoutput, c);
1254
1258
      if (!c) nfiles++;
1255
1259
    }
1256
1260
    if (ferror(pf)) ohshite(_("error reading find's pipe"));
1257
1261
    if (fclose(pf)) ohshite(_("error closing find's pipe"));
1258
 
    r = subproc_wait_check(fc, "find", PROCNOERR);
 
1262
    r = subproc_wait_check(pid, "find", PROCNOERR);
1259
1263
    if (r != 0)
1260
1264
      ohshit(_("find for --recursive returned unhandled error %i"),r);
1261
1265
 
1262
1266
    if (!nfiles)
1263
1267
      ohshit(_("searched, but found no packages (files matching *.deb)"));
1264
1268
 
1265
 
    varbufaddc(&findoutput,0);
1266
 
    varbufaddc(&findoutput,0);
1267
 
    
1268
1269
    arglist= m_malloc(sizeof(char*)*(nfiles+1));
1269
 
    p= findoutput.buf; i=0;
1270
 
    while (*p) {
 
1270
    p = findoutput.buf;
 
1271
    for (i = 0; i < nfiles; i++) {
1271
1272
      arglist[i++]= p;
1272
1273
      while (*p++ != '\0') ;
1273
1274
    }
1274
1275
    arglist[i] = NULL;
1275
1276
    argp= arglist;
1276
 
 
1277
1277
  } else {
1278
 
 
1279
1278
    if (!*argv) badusage(_("--%s needs at least one package archive file argument"),
1280
1279
                         cipaction->olong);
1281
1280
    argp= argv;
1282
 
    
1283
1281
  }
1284
1282
 
1285
1283
  currenttime = time(NULL);
1286
1284
 
1287
1285
  /* Initialize fname variables contents. */
1288
1286
 
1289
 
  varbufreset(&fnamevb);
1290
 
  varbufreset(&fnametmpvb);
1291
 
  varbufreset(&fnamenewvb);
 
1287
  varbuf_reset(&fnamevb);
 
1288
  varbuf_reset(&fnametmpvb);
 
1289
  varbuf_reset(&fnamenewvb);
1292
1290
 
1293
 
  varbufaddstr(&fnamevb,instdir); varbufaddc(&fnamevb,'/');
1294
 
  varbufaddstr(&fnametmpvb,instdir); varbufaddc(&fnametmpvb,'/');
1295
 
  varbufaddstr(&fnamenewvb,instdir); varbufaddc(&fnamenewvb,'/');
 
1291
  varbuf_add_str(&fnamevb, instdir);
 
1292
  varbuf_add_char(&fnamevb, '/');
 
1293
  varbuf_add_str(&fnametmpvb, instdir);
 
1294
  varbuf_add_char(&fnametmpvb, '/');
 
1295
  varbuf_add_str(&fnamenewvb, instdir);
 
1296
  varbuf_add_char(&fnamenewvb, '/');
1296
1297
  fnameidlu= fnamevb.used;
1297
1298
 
1298
1299
  ensure_diversions();
1299
1300
  ensure_statoverrides();
1300
 
  
 
1301
 
1301
1302
  while ((thisarg = *argp++) != NULL) {
1302
1303
    if (setjmp(ejbuf)) {
1303
 
      error_unwind(ehflag_bombout);
 
1304
      pop_error_context(ehflag_bombout);
1304
1305
      if (abort_processing)
1305
1306
        break;
1306
1307
      continue;
1307
1308
    }
1308
 
    push_error_handler(&ejbuf,print_error_perpackage,thisarg);
 
1309
    push_error_context_jump(&ejbuf, print_error_perpackage, thisarg);
 
1310
 
1309
1311
    process_archive(thisarg);
1310
1312
    onerr_abort++;
1311
1313
    m_output(stdout, _("<standard output>"));
1312
1314
    m_output(stderr, _("<standard error>"));
1313
1315
    onerr_abort--;
1314
 
    set_error_display(NULL, NULL);
1315
 
    error_unwind(ehflag_normaltidy);
 
1316
 
 
1317
    pop_error_context(ehflag_normaltidy);
1316
1318
  }
1317
1319
 
1318
 
  switch (cipaction->arg) {
 
1320
  switch (cipaction->arg_int) {
1319
1321
  case act_install:
1320
1322
  case act_configure:
1321
1323
  case act_triggers:
1326
1328
  case act_avail:
1327
1329
    break;
1328
1330
  default:
1329
 
    internerr("unknown action '%d'", cipaction->arg);
 
1331
    internerr("unknown action '%d'", cipaction->arg_int);
1330
1332
  }
1331
1333
 
1332
1334
  trigproc_run_deferred();
1333
1335
  modstatdb_shutdown();
 
1336
 
 
1337
  return 0;
1334
1338
}
1335
1339
 
1336
 
int
1337
 
wanttoinstall(struct pkginfo *pkg, const struct versionrevision *ver,
1338
 
              bool saywhy)
 
1340
/**
 
1341
 * Decide whether we want to install a new version of the package.
 
1342
 *
 
1343
 * @param pkg The package with the version we might want to install
 
1344
 *
 
1345
 * @retval true  If the package should be skipped.
 
1346
 * @retval false If the package should be installed.
 
1347
 */
 
1348
bool
 
1349
wanttoinstall(struct pkginfo *pkg)
1339
1350
{
1340
 
  /* Decide whether we want to install a new version of the package.
1341
 
   * ver is the version we might want to install.  If saywhy is 1 then
1342
 
   * if we skip the package we say what we are doing (and, if we are
1343
 
   * selecting a previously deselected package, say so and actually do
1344
 
   * the select).  want_install returns 0 if the package should be
1345
 
   * skipped and 1 if it should be installed.
1346
 
   *
1347
 
   * ver may be 0, in which case saywhy must be 0 and want_install may
1348
 
   * also return -1 to mean it doesn't know because it would depend on
1349
 
   * the version number.
1350
 
   */
1351
1351
  int r;
1352
1352
 
1353
1353
  if (pkg->want != want_install && pkg->want != want_hold) {
1354
1354
    if (f_alsoselect) {
1355
 
      if (saywhy) {
1356
 
   printf(_("Selecting previously deselected package %s.\n"),pkg->name);
1357
 
   pkg->want= want_install;
1358
 
      }
1359
 
      return 1;
 
1355
      printf(_("Selecting previously deselected package %s.\n"), pkg->name);
 
1356
      pkg->want = want_install;
 
1357
      return true;
1360
1358
    } else {
1361
 
      if (saywhy) printf(_("Skipping deselected package %s.\n"),pkg->name);
1362
 
      return 0;
 
1359
      printf(_("Skipping deselected package %s.\n"), pkg->name);
 
1360
      return false;
1363
1361
    }
1364
1362
  }
1365
1363
 
1366
 
  if (!(pkg->status == stat_installed ||
1367
 
        pkg->status == stat_triggersawaited ||
1368
 
        pkg->status == stat_triggerspending))
1369
 
    return 1;
1370
 
  if (!ver) return -1;
 
1364
  if (pkg->eflag & eflag_reinstreq)
 
1365
    return true;
 
1366
  if (pkg->status < stat_unpacked)
 
1367
    return true;
1371
1368
 
1372
 
  r= versioncompare(ver,&pkg->installed.version);
 
1369
  r = versioncompare(&pkg->available.version, &pkg->installed.version);
1373
1370
  if (r > 0) {
1374
 
    return 1;
 
1371
    return true;
1375
1372
  } else if (r == 0) {
1376
1373
    /* Same version fully installed. */
1377
1374
    if (f_skipsame) {
1378
 
      if (saywhy) fprintf(stderr, _("Version %.250s of %.250s already installed, "
1379
 
             "skipping.\n"),
1380
 
             versiondescribe(&pkg->installed.version, vdew_nonambig),
1381
 
             pkg->name);
1382
 
      return 0;
 
1375
      fprintf(stderr, _("Version %.250s of %.250s already installed, "
 
1376
                        "skipping.\n"),
 
1377
              versiondescribe(&pkg->installed.version, vdew_nonambig),
 
1378
              pkg->name);
 
1379
      return false;
1383
1380
    } else {
1384
 
      return 1;
 
1381
      return true;
1385
1382
    }
1386
1383
  } else {
1387
1384
    if (fc_downgrade) {
1388
 
      if (saywhy)
1389
 
        warning(_("downgrading %.250s from %.250s to %.250s."), pkg->name,
1390
 
             versiondescribe(&pkg->installed.version, vdew_nonambig),
1391
 
             versiondescribe(&pkg->available.version, vdew_nonambig));
1392
 
      return 1;
 
1385
      warning(_("downgrading %.250s from %.250s to %.250s."), pkg->name,
 
1386
              versiondescribe(&pkg->installed.version, vdew_nonambig),
 
1387
              versiondescribe(&pkg->available.version, vdew_nonambig));
 
1388
      return true;
1393
1389
    } else {
1394
 
      if (saywhy) fprintf(stderr, _("Will not downgrade %.250s from version %.250s "
1395
 
             "to %.250s, skipping.\n"), pkg->name,
1396
 
             versiondescribe(&pkg->installed.version, vdew_nonambig),
1397
 
             versiondescribe(&pkg->available.version, vdew_nonambig));
1398
 
      return 0;
 
1390
      fprintf(stderr, _("Will not downgrade %.250s from version %.250s "
 
1391
                        "to %.250s, skipping.\n"), pkg->name,
 
1392
              versiondescribe(&pkg->installed.version, vdew_nonambig),
 
1393
              versiondescribe(&pkg->available.version, vdew_nonambig));
 
1394
      return false;
1399
1395
    }
1400
1396
  }
1401
1397
}