コード例 #1
0
ファイル: filesdb.c プロジェクト: nisc-code/dpkg
/*
 * If mask is nonzero, will not write any file whose filenamenode
 * has any flag bits set in mask.
 */
void
write_filelist_except(struct pkginfo *pkg, struct pkgbin *pkgbin,
                      struct fileinlist *list, enum fnnflags mask)
{
  struct atomic_file *file;
  const char *listfile;

  listfile = pkg_infodb_get_file(pkg, pkgbin, LISTFILE);

  file = atomic_file_new(listfile, 0);
  atomic_file_open(file);

  while (list) {
    if (!(mask && (list->namenode->flags & mask))) {
      fputs(list->namenode->name, file->fp);
      putc('\n', file->fp);
    }
    list= list->next;
  }

  atomic_file_sync(file);
  atomic_file_close(file);
  atomic_file_commit(file);
  atomic_file_free(file);

  dir_sync_path(pkg_infodb_get_dir());

  note_must_reread_files_inpackage(pkg);
}
コード例 #2
0
ファイル: trigproc.c プロジェクト: CharizTeam/dpkg
/*
 * Called by modstatdb_note.
 */
void
trig_activate_packageprocessing(struct pkginfo *pkg)
{
	debug(dbg_triggersdetail, "trigproc_activate_packageprocessing pkg=%s",
	      pkg_name(pkg, pnaw_always));

	trig_parse_ci(pkg_infodb_get_file(pkg, &pkg->installed, TRIGGERSCIFILE),
	              NULL, trig_cicb_statuschange_activate,
	              pkg, &pkg->installed);
}
コード例 #3
0
ファイル: filesdb.c プロジェクト: nisc-code/dpkg
static void
pkg_files_optimize_load(struct pkg_array *array)
{
  struct statfs fs;
  int i;

  /* Get the filesystem block size. */
  if (statfs(pkg_infodb_get_dir(), &fs) < 0)
    return;

  /* Sort packages by the physical location of their list files, so that
   * scanning them later will minimize disk drive head movements. */
  for (i = 0; i < array->n_pkgs; i++) {
    struct pkginfo *pkg = array->pkgs[i];
    struct {
      struct fiemap fiemap;
      struct fiemap_extent extent;
    } fm;
    const char *listfile;
    int fd;

    ensure_package_clientdata(pkg);

    if (pkg->status == stat_notinstalled ||
        pkg->clientdata->listfile_phys_offs != 0)
      continue;

    pkg->clientdata->listfile_phys_offs = -1;

    listfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE);

    fd = open(listfile, O_RDONLY);
    if (fd < 0)
      continue;

    memset(&fm, 0, sizeof(fm));
    fm.fiemap.fm_start = 0;
    fm.fiemap.fm_length = fs.f_bsize;
    fm.fiemap.fm_flags = 0;
    fm.fiemap.fm_extent_count = 1;

    if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)&fm) == 0)
      pkg->clientdata->listfile_phys_offs = fm.fiemap.fm_extents[0].fe_physical;

    close(fd);
  }

  pkg_array_sort(array, pkg_sorter_by_listfile_phys_offs);
}
コード例 #4
0
ファイル: trigproc.c プロジェクト: CharizTeam/dpkg
/*
 * cstatus might be msdbrw_readonly if we're in --no-act mode, in which
 * case we don't write out all of the interest files etc. but we do
 * invent all of the activations for our own benefit.
 */
static void
trig_transitional_activate(enum modstatdb_rw cstatus)
{
	struct pkgiterator *iter;
	struct pkginfo *pkg;

	iter = pkg_db_iter_new();
	while ((pkg = pkg_db_iter_next_pkg(iter))) {
		if (pkg->status <= PKG_STAT_HALFINSTALLED)
			continue;
		debug(dbg_triggersdetail, "trig_transitional_activate %s %s",
		      pkg_name(pkg, pnaw_always),
		      pkg_status_name(pkg));
		pkg->trigpend_head = NULL;
		trig_parse_ci(pkg_infodb_get_file(pkg, &pkg->installed,
		                                  TRIGGERSCIFILE),
		              cstatus >= msdbrw_write ?
		              transitional_interest_callback :
		              transitional_interest_callback_ro, NULL,
		              pkg, &pkg->installed);
		/* Ensure we're not creating incoherent data that can't
		 * be written down. This should never happen in theory but
		 * can happen if you restore an old status file that is
		 * not in sync with the infodb files. */
		if (pkg->status < PKG_STAT_TRIGGERSAWAITED)
			continue;

		if (pkg->trigaw.head)
			pkg_set_status(pkg, PKG_STAT_TRIGGERSAWAITED);
		else if (pkg->trigpend_head)
			pkg_set_status(pkg, PKG_STAT_TRIGGERSPENDING);
		else
			pkg_set_status(pkg, PKG_STAT_INSTALLED);
	}
	pkg_db_iter_free(iter);

	if (cstatus >= msdbrw_write) {
		modstatdb_checkpoint();
		trig_file_interests_save();
	}
}
コード例 #5
0
ファイル: filesdb.c プロジェクト: nisc-code/dpkg
static void
pkg_files_optimize_load(struct pkg_array *array)
{
  int i;

  /* Ask the kernel to start preloading the list files, so as to get a
   * boost when later we actually load them. */
  for (i = 0; i < array->n_pkgs; i++) {
    struct pkginfo *pkg = array->pkgs[i];
    const char *listfile;
    int fd;

    listfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE);

    fd = open(listfile, O_RDONLY | O_NONBLOCK);
    if (fd != -1) {
      posix_fadvise(fd, 0, 0, POSIX_FADV_WILLNEED);
      close(fd);
    }
  }
}
コード例 #6
0
ファイル: filesdb.c プロジェクト: nisc-code/dpkg
/**
 * Load the list of files in this package into memory, or update the
 * list if it is there but stale.
 */
void
ensure_packagefiles_available(struct pkginfo *pkg)
{
  static int fd;
  const char *filelistfile;
  struct fileinlist **lendp;
  struct stat stat_buf;
  char *loaded_list, *loaded_list_end, *thisline, *nextline, *ptr;

  if (pkg->clientdata && pkg->clientdata->fileslistvalid)
    return;
  ensure_package_clientdata(pkg);

  /* Throw away any stale data, if there was any. */
  pkg_files_blank(pkg);

  /* Packages which aren't installed don't have a files list. */
  if (pkg->status == stat_notinstalled) {
    pkg->clientdata->fileslistvalid = true;
    return;
  }

  filelistfile = pkg_infodb_get_file(pkg, &pkg->installed, LISTFILE);

  onerr_abort++;

  fd= open(filelistfile,O_RDONLY);

  if (fd==-1) {
    if (errno != ENOENT)
      ohshite(_("unable to open files list file for package `%.250s'"),
              pkg_name(pkg, pnaw_nonambig));
    onerr_abort--;
    if (pkg->status != stat_configfiles &&
        dpkg_version_is_informative(&pkg->configversion)) {
      warning(_("files list file for package '%.250s' missing; assuming "
                "package has no files currently installed"),
              pkg_name(pkg, pnaw_nonambig));
    }
    pkg->clientdata->files = NULL;
    pkg->clientdata->fileslistvalid = true;
    return;
  }

  push_cleanup(cu_closefd, ehflag_bombout, NULL, 0, 1, &fd);

  if (fstat(fd, &stat_buf))
    ohshite(_("unable to stat files list file for package '%.250s'"),
            pkg_name(pkg, pnaw_nonambig));

  if (!S_ISREG(stat_buf.st_mode))
    ohshit(_("files list for package '%.250s' is not a regular file"),
           pkg_name(pkg, pnaw_nonambig));

  if (stat_buf.st_size) {
    loaded_list = nfmalloc(stat_buf.st_size);
    loaded_list_end = loaded_list + stat_buf.st_size;

    if (fd_read(fd, loaded_list, stat_buf.st_size) < 0)
      ohshite(_("reading files list for package '%.250s'"),
              pkg_name(pkg, pnaw_nonambig));

    lendp= &pkg->clientdata->files;
    thisline = loaded_list;
    while (thisline < loaded_list_end) {
      struct filenamenode *namenode;

      ptr = memchr(thisline, '\n', loaded_list_end - thisline);
      if (ptr == NULL)
        ohshit(_("files list file for package '%.250s' is missing final newline"),
               pkg_name(pkg, pnaw_nonambig));
      /* Where to start next time around. */
      nextline = ptr + 1;
      /* Strip trailing ‘/’. */
      if (ptr > thisline && ptr[-1] == '/') ptr--;
      /* Add the file to the list. */
      if (ptr == thisline)
        ohshit(_("files list file for package `%.250s' contains empty filename"),
               pkg_name(pkg, pnaw_nonambig));
      *ptr = '\0';

      namenode = findnamenode(thisline, fnn_nocopy);
      lendp = pkg_files_add_file(pkg, namenode, lendp);
      thisline = nextline;
    }
  }
  pop_cleanup(ehflag_normaltidy); /* fd = open() */
  if (close(fd))
    ohshite(_("error closing files list file for package `%.250s'"),
            pkg_name(pkg, pnaw_nonambig));

  onerr_abort--;

  pkg->clientdata->fileslistvalid = true;
}