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

« back to all changes in this revision

Viewing changes to lib/dpkg/dbmodify.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:
35
35
#include <fcntl.h>
36
36
#include <dirent.h>
37
37
#include <unistd.h>
 
38
#include <stdbool.h>
38
39
#include <stdlib.h>
39
40
#include <stdio.h>
40
41
 
45
46
#include <dpkg/dir.h>
46
47
#include <dpkg/triglib.h>
47
48
 
 
49
static bool db_initialized;
 
50
 
48
51
static enum modstatdb_rw cstatus=-1, cflags=0;
 
52
static char *lockfile;
49
53
static char *statusfile, *availablefile;
50
54
static char *importanttmpfile=NULL;
51
55
static FILE *importanttmp;
75
79
  struct dirent **cdlist;
76
80
  int cdn, i;
77
81
 
78
 
  parsedb(statusfile, pdb_lax_parser | pdb_weakclassification,
79
 
          NULL, NULL, NULL);
 
82
  parsedb(statusfile, pdb_lax_parser | pdb_weakclassification, NULL);
80
83
 
81
84
  *updatefnrest = '\0';
82
85
  updateslength= -1;
84
87
  if (cdn == -1) ohshite(_("cannot scan updates directory `%.255s'"),updatefnbuf);
85
88
 
86
89
  if (cdn) {
87
 
    
88
90
    for (i=0; i<cdn; i++) {
89
91
      strcpy(updatefnrest, cdlist[i]->d_name);
90
92
      parsedb(updatefnbuf, pdb_lax_parser | pdb_weakclassification,
91
 
              NULL, NULL, NULL);
 
93
              NULL);
92
94
      if (cstatus < msdbrw_write) free(cdlist[i]);
93
95
    }
94
96
 
95
97
    if (cstatus >= msdbrw_write) {
96
98
      writedb(statusfile,0,1);
97
 
    
 
99
 
98
100
      for (i=0; i<cdn; i++) {
99
101
        strcpy(updatefnrest, cdlist[i]->d_name);
100
102
        if (unlink(updatefnbuf))
104
106
 
105
107
      dir_sync_path(updatesdir);
106
108
    }
107
 
    
108
109
  }
109
110
  free(cdlist);
110
111
 
113
114
 
114
115
static void createimptmp(void) {
115
116
  int i;
116
 
  
 
117
 
117
118
  onerr_abort++;
118
 
  
 
119
 
119
120
  importanttmp= fopen(importanttmpfile,"w");
120
121
  if (!importanttmp)
121
122
    ohshite(_("unable to create `%.255s'"), importanttmpfile);
136
137
  const char *suffix;
137
138
  char **store;
138
139
} fnis[] = {
 
140
  {   LOCKFILE,                   &lockfile           },
139
141
  {   STATUSFILE,                 &statusfile         },
140
142
  {   AVAILFILE,                  &availablefile      },
141
143
  {   UPDATESDIR,                 &updatesdir         },
144
146
  {   NULL, NULL                                      }
145
147
};
146
148
 
 
149
void
 
150
modstatdb_init(void)
 
151
{
 
152
  const struct fni *fnip;
 
153
 
 
154
  if (db_initialized)
 
155
    return;
 
156
 
 
157
  for (fnip = fnis; fnip->suffix; fnip++) {
 
158
    free(*fnip->store);
 
159
    *fnip->store = dpkg_db_get_path(fnip->suffix);
 
160
  }
 
161
 
 
162
  updatefnbuf = m_malloc(strlen(updatesdir) + IMPORTANTMAXLEN + 5);
 
163
  strcpy(updatefnbuf, updatesdir);
 
164
  updatefnrest = updatefnbuf + strlen(updatefnbuf);
 
165
 
 
166
  db_initialized = true;
 
167
}
 
168
 
 
169
void
 
170
modstatdb_done(void)
 
171
{
 
172
  const struct fni *fnip;
 
173
 
 
174
  if (!db_initialized)
 
175
    return;
 
176
 
 
177
  for (fnip = fnis; fnip->suffix; fnip++) {
 
178
    free(*fnip->store);
 
179
    *fnip->store = NULL;
 
180
  }
 
181
  free(updatefnbuf);
 
182
 
 
183
  db_initialized = false;
 
184
}
 
185
 
147
186
static int dblockfd = -1;
148
187
 
149
188
bool
150
 
modstatdb_is_locked(const char *admindir)
 
189
modstatdb_is_locked(void)
151
190
{
152
 
  struct varbuf lockfile = VARBUF_INIT;
153
191
  int lockfd;
154
192
  bool locked;
155
193
 
156
 
  varbufprintf(&lockfile, "%s/%s", admindir, LOCKFILE);
157
 
 
158
194
  if (dblockfd == -1) {
159
 
    lockfd = open(lockfile.buf, O_RDONLY);
 
195
    lockfd = open(lockfile, O_RDONLY);
160
196
    if (lockfd == -1)
161
 
      ohshite(_("unable to open lock file %s for testing"), lockfile.buf);
 
197
      ohshite(_("unable to open lock file %s for testing"), lockfile);
162
198
  } else {
163
199
    lockfd = dblockfd;
164
200
  }
165
201
 
166
 
  locked = file_is_locked(lockfd, lockfile.buf);
 
202
  locked = file_is_locked(lockfd, lockfile);
167
203
 
168
204
  /* We only close the file if there was no lock open, otherwise we would
169
205
   * release the existing lock on close. */
170
206
  if (dblockfd == -1)
171
207
    close(lockfd);
172
208
 
173
 
  varbuf_destroy(&lockfile);
174
 
 
175
209
  return locked;
176
210
}
177
211
 
178
 
void
179
 
modstatdb_lock(const char *admindir)
 
212
bool
 
213
modstatdb_can_lock(void)
180
214
{
181
 
  int n;
182
 
  char *dblockfile = NULL;
183
 
 
184
 
  n = strlen(admindir);
185
 
  dblockfile = m_malloc(n + sizeof(LOCKFILE) + 2);
186
 
  strcpy(dblockfile, admindir);
187
 
  strcpy(dblockfile + n, "/" LOCKFILE);
188
 
 
 
215
  if (dblockfd >= 0)
 
216
    return true;
 
217
 
 
218
  dblockfd = open(lockfile, O_RDWR | O_CREAT | O_TRUNC, 0660);
189
219
  if (dblockfd == -1) {
190
 
    dblockfd = open(dblockfile, O_RDWR | O_CREAT | O_TRUNC, 0660);
191
 
    if (dblockfd == -1) {
192
 
      if (errno == EPERM)
193
 
        ohshit(_("you do not have permission to lock the dpkg status database"));
 
220
    if (errno == EACCES || errno == EPERM)
 
221
      return false;
 
222
    else
194
223
      ohshite(_("unable to open/create status database lockfile"));
195
 
    }
196
224
  }
197
225
 
198
 
  file_lock(&dblockfd, dblockfile,
199
 
            _("unable to lock dpkg status database"),
200
 
            _("status database area is locked by another process"));
201
 
 
202
 
  free(dblockfile);
 
226
  return true;
 
227
}
 
228
 
 
229
void
 
230
modstatdb_lock(void)
 
231
{
 
232
  if (!modstatdb_can_lock())
 
233
    ohshit(_("you do not have permission to lock the dpkg status database"));
 
234
 
 
235
  file_lock(&dblockfd, FILE_LOCK_NOWAIT, lockfile, _("dpkg status database"));
203
236
}
204
237
 
205
238
void
206
239
modstatdb_unlock(void)
207
240
{
208
 
  file_unlock();
 
241
  /* Unlock. */
 
242
  pop_cleanup(ehflag_normaltidy);
 
243
 
 
244
  dblockfd = -1;
209
245
}
210
246
 
211
247
enum modstatdb_rw
212
 
modstatdb_init(const char *admindir, enum modstatdb_rw readwritereq)
 
248
modstatdb_open(enum modstatdb_rw readwritereq)
213
249
{
214
 
  const struct fni *fnip;
215
 
  
216
 
  for (fnip=fnis; fnip->suffix; fnip++) {
217
 
    free(*fnip->store);
218
 
    *fnip->store = m_malloc(strlen(admindir) + strlen(fnip->suffix) + 2);
219
 
    sprintf(*fnip->store, "%s/%s", admindir, fnip->suffix);
220
 
  }
 
250
  modstatdb_init();
221
251
 
222
 
  cflags= readwritereq & msdbrw_flagsmask;
223
 
  readwritereq &= ~msdbrw_flagsmask;
 
252
  cflags = readwritereq & msdbrw_available_mask;
 
253
  readwritereq &= ~msdbrw_available_mask;
224
254
 
225
255
  switch (readwritereq) {
226
256
  case msdbrw_needsuperuser:
227
257
  case msdbrw_needsuperuserlockonly:
228
258
    if (getuid() || geteuid())
229
259
      ohshit(_("requested operation requires superuser privilege"));
230
 
    /* fall through */
 
260
    /* Fall through. */
231
261
  case msdbrw_write: case msdbrw_writeifposs:
232
 
    if (access(admindir, W_OK)) {
 
262
    if (access(dpkg_db_get_dir(), W_OK)) {
233
263
      if (errno != EACCES)
234
264
        ohshite(_("unable to access dpkg status area"));
235
265
      else if (readwritereq == msdbrw_write)
236
266
        ohshit(_("operation requires read/write access to dpkg status area"));
237
267
      cstatus= msdbrw_readonly;
238
268
    } else {
239
 
      modstatdb_lock(admindir);
 
269
      modstatdb_lock();
240
270
      cstatus= (readwritereq == msdbrw_needsuperuserlockonly ?
241
271
                msdbrw_needsuperuserlockonly :
242
272
                msdbrw_write);
248
278
    internerr("unknown modstatdb_rw '%d'", readwritereq);
249
279
  }
250
280
 
251
 
  updatefnbuf = m_malloc(strlen(updatesdir) + IMPORTANTMAXLEN + 5);
252
 
  strcpy(updatefnbuf, updatesdir);
253
 
  updatefnrest= updatefnbuf+strlen(updatefnbuf);
254
 
 
255
281
  if (cstatus != msdbrw_needsuperuserlockonly) {
256
282
    cleanupdates();
257
 
    if(!(cflags & msdbrw_noavail))
 
283
    if (cflags >= msdbrw_available_readonly)
258
284
    parsedb(availablefile,
259
285
            pdb_recordavailable | pdb_rejectstatus | pdb_lax_parser,
260
 
            NULL,NULL,NULL);
 
286
            NULL);
261
287
  }
262
288
 
263
289
  if (cstatus >= msdbrw_write) {
264
290
    createimptmp();
265
 
    varbufinit(&uvb, 10240);
 
291
    varbuf_init(&uvb, 10240);
266
292
  }
267
293
 
268
294
  trig_fixup_awaiters(cstatus);
269
 
  trig_incorporate(cstatus, admindir);
 
295
  trig_incorporate(cstatus);
270
296
 
271
297
  return cstatus;
272
298
}
276
302
 
277
303
  assert(cstatus >= msdbrw_write);
278
304
  writedb(statusfile,0,1);
279
 
  
 
305
 
280
306
  for (i=0; i<nextupdate; i++) {
281
307
    sprintf(updatefnrest, IMPORTANTFMT, i);
282
 
    assert(strlen(updatefnrest)<=IMPORTANTMAXLEN); /* or we've made a real mess */
 
308
    /* Have we made a real mess? */
 
309
    assert(strlen(updatefnrest) <= IMPORTANTMAXLEN);
283
310
    if (unlink(updatefnbuf))
284
311
      ohshite(_("failed to remove my own update file %.255s"),updatefnbuf);
285
312
  }
290
317
}
291
318
 
292
319
void modstatdb_shutdown(void) {
293
 
  const struct fni *fnip;
 
320
  if (cflags >= msdbrw_available_write)
 
321
    writedb(availablefile, 1, 0);
 
322
 
294
323
  switch (cstatus) {
295
324
  case msdbrw_write:
296
325
    modstatdb_checkpoint();
297
 
    writedb(availablefile,1,0);
298
 
    /* tidy up a bit, but don't worry too much about failure */
 
326
    /* Tidy up a bit, but don't worry too much about failure. */
299
327
    fclose(importanttmp);
300
328
    unlink(importanttmpfile);
301
329
    varbuf_destroy(&uvb);
302
 
    /* fall through */
 
330
    /* Fall through. */
303
331
  case msdbrw_needsuperuserlockonly:
304
332
    modstatdb_unlock();
305
333
  default:
306
334
    break;
307
335
  }
308
336
 
309
 
  for (fnip=fnis; fnip->suffix; fnip++) {
310
 
    free(*fnip->store);
311
 
    *fnip->store= NULL;
312
 
  }
313
 
  free(updatefnbuf);
 
337
  modstatdb_done();
314
338
}
315
339
 
316
340
static void
318
342
{
319
343
  assert(cstatus >= msdbrw_write);
320
344
 
321
 
  varbufreset(&uvb);
 
345
  varbuf_reset(&uvb);
322
346
  varbufrecord(&uvb, pkg, &pkg->installed);
323
347
 
324
348
  if (fwrite(uvb.buf, 1, uvb.used, importanttmp) != uvb.used)
350
374
  createimptmp();
351
375
}
352
376
 
353
 
/* Note: If anyone wants to set some triggers-pending, they must also
 
377
/*
 
378
 * Note: If anyone wants to set some triggers-pending, they must also
354
379
 * set status appropriately, or we will undo it. That is, it is legal
355
380
 * to call this when pkg->status and pkg->trigpend_head disagree and
356
381
 * in that case pkg->status takes precedence and pkg->trigpend_head
362
387
  onerr_abort++;
363
388
 
364
389
  /* Clear pending triggers here so that only code that sets the status
365
 
   * to interesting (for triggers) values has to care about triggers.
366
 
   */
 
390
   * to interesting (for triggers) values has to care about triggers. */
367
391
  if (pkg->status != stat_triggerspending &&
368
392
      pkg->status != stat_triggersawaited)
369
393
    pkg->trigpend_head = NULL;
383
407
 
384
408
  if (!pkg->trigpend_head && pkg->othertrigaw_head) {
385
409
    /* Automatically remove us from other packages' Triggers-Awaited.
386
 
     * We do this last because we want to maximise our chances of
 
410
     * We do this last because we want to maximize our chances of
387
411
     * successfully recording the status of the package we were
388
412
     * pointed at by our caller, although there is some risk of
389
413
     * leaving us in a slightly odd situation which is cleared up
390
 
     * by the trigger handling logic in deppossi_ok_found.
391
 
     */
 
414
     * by the trigger handling logic in deppossi_ok_found. */
392
415
    trig_clear_awaiters(pkg);
393
416
  }
394
417
 
402
425
    modstatdb_note(pkg);
403
426
}
404
427
 
405
 
const char *
406
 
pkgadmindir(void)
407
 
{
408
 
  return infodir;
409
 
}
410
 
 
411
 
const char *pkgadminfile(struct pkginfo *pkg, const char *whichfile) {
412
 
  static struct varbuf vb;
413
 
  varbufreset(&vb);
414
 
  varbufaddstr(&vb, infodir);
415
 
  varbufaddstr(&vb,pkg->name);
416
 
  varbufaddc(&vb,'.');
417
 
  varbufaddstr(&vb,whichfile);
418
 
  varbufaddc(&vb,0);
419
 
  return vb.buf;
420
 
}
421