Пример #1
0
static void
statdb_write(void)
{
	char *dbname;
	struct atomic_file *dbfile;
	struct fileiterator *iter;
	struct filenamenode *file;

	dbname = dpkg_db_get_path(STATOVERRIDEFILE);
	dbfile = atomic_file_new(dbname, aff_backup);
	atomic_file_open(dbfile);

	iter = files_db_iter_new();
	while ((file = files_db_iter_next(iter)))
		statdb_node_print(dbfile->fp, file);
	files_db_iter_free(iter);

	atomic_file_sync(dbfile);
	atomic_file_close(dbfile);
	atomic_file_commit(dbfile);
	atomic_file_free(dbfile);

	dir_sync_path(dpkg_db_get_dir());

	free(dbname);
}
Пример #2
0
static void
divertdb_write(void)
{
	char *dbname;
	struct atomic_file *file;
	struct fsys_hash_iter *iter;
	struct fsys_namenode *namenode;

	dbname = dpkg_db_get_path(DIVERSIONSFILE);

	file = atomic_file_new(dbname, ATOMIC_FILE_BACKUP);
	atomic_file_open(file);

	iter = fsys_hash_iter_new();
	while ((namenode = fsys_hash_iter_next(iter))) {
		struct fsys_diversion *d = namenode->divert;

		if (d == NULL || d->useinstead == NULL)
			continue;

		fprintf(file->fp, "%s\n%s\n%s\n",
		        d->useinstead->divert->camefrom->name,
		        d->useinstead->name,
		        diversion_pkg_name(d));
	}
	fsys_hash_iter_free(iter);

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

	free(dbname);
}
Пример #3
0
static enum pkg_infodb_format
pkg_infodb_read_format(void)
{
	struct atomic_file *file;
	struct stat st;
	char *filename;

	filename = dpkg_db_get_path(INFODIR "/format");
	file = atomic_file_new(filename, 0);

	db_format = pkg_infodb_parse_format(file->name);

	/* Check if a previous upgrade got interrupted. Because we are only
	 * supposed to upgrade the db layout one format at a time, if the
	 * new file exists that means the new format is just one ahead,
	 * we don't try to read it because it contains unreliable data. */
	if (stat(file->name_new, &st) == 0) {
		db_format++;
		db_upgrading = true;
	}

	atomic_file_free(file);
	free(filename);

	if (db_format < 0 || db_format >= PKG_INFODB_FORMAT_LAST)
		ohshit(_("info database format (%d) is bogus or too new; "
		         "try getting a newer dpkg"), db_format);

	return db_format;
}
Пример #4
0
void
trig_incorporate(enum modstatdb_rw cstatus)
{
	enum trigdef_update_status ur;
	enum trigdef_updateflags tduf;

	free(triggersdir);
	triggersdir = dpkg_db_get_path(TRIGGERSDIR);

	free(triggersfilefile);
	triggersfilefile = trig_get_filename(triggersdir, "File");

	free(triggersnewfilefile);
	triggersnewfilefile = trig_get_filename(triggersdir, "File.new");

	trigdef_set_methods(&tdm_incorp);
	trig_file_interests_ensure();

	tduf = tduf_nolockok;
	if (cstatus >= msdbrw_write) {
		tduf |= tduf_write;
		if (trigh.transitional_activate)
			tduf |= tduf_writeifenoent;
	}

	ur = trigdef_update_start(tduf);
	if (ur == tdus_error_no_dir && cstatus >= msdbrw_write) {
		if (mkdir(triggersdir, 0755)) {
			if (errno != EEXIST)
				ohshite(_("unable to create triggers state"
				          " directory `%.250s'"), triggersdir);
		} else if (chown(triggersdir, 0, 0)) {
			ohshite(_("unable to set ownership of triggers state"
			          " directory `%.250s'"), triggersdir);
		}
		ur = trigdef_update_start(tduf);
	}
	switch (ur) {
	case tdus_error_empty_deferred:
		return;
	case tdus_error_no_dir:
	case tdus_error_no_deferred:
		if (!trigh.transitional_activate)
			return;
	/* Fall through. */
	case tdus_no_deferred:
		trigh.transitional_activate(cstatus);
		break;
	case tdus_ok:
		/* Read and incorporate triggers. */
		trigdef_parse();
		break;
	default:
		internerr("unknown trigdef_update_start return value '%d'", ur);
	}

	/* Right, that's it. New (empty) Unincorp can be installed. */
	trigdef_process_done();
}
Пример #5
0
const char *
pkg_infodb_get_dir(void)
{
	if (db_infodir == NULL)
		db_infodir = dpkg_db_get_path(INFODIR);

	return db_infodir;
}
Пример #6
0
void
trig_incorporate(enum modstatdb_rw cstatus)
{
	enum trigdef_update_status ur;
	enum trigdef_update_flags tduf;

	free(triggersdir);
	triggersdir = dpkg_db_get_path(TRIGGERSDIR);

	free(triggersfilefile);
	triggersfilefile = trig_get_filename(triggersdir, TRIGGERSFILEFILE);

	trigdef_set_methods(&tdm_incorp);
	trig_file_interests_ensure();

	tduf = TDUF_NO_LOCK_OK;
	if (cstatus >= msdbrw_write) {
		tduf |= TDUF_WRITE;
		if (trigh.transitional_activate)
			tduf |= TDUF_WRITE_IF_ENOENT;
	}

	ur = trigdef_update_start(tduf);
	if (ur == TDUS_ERROR_NO_DIR && cstatus >= msdbrw_write) {
		if (mkdir(triggersdir, 0755)) {
			if (errno != EEXIST)
				ohshite(_("unable to create triggers state"
				          " directory '%.250s'"), triggersdir);
		} else if (chown(triggersdir, 0, 0)) {
			ohshite(_("unable to set ownership of triggers state"
			          " directory '%.250s'"), triggersdir);
		}
		ur = trigdef_update_start(tduf);
	}
	switch (ur) {
	case TDUS_ERROR_EMPTY_DEFERRED:
		return;
	case TDUS_ERROR_NO_DIR:
	case TDUS_ERROR_NO_DEFERRED:
		if (!trigh.transitional_activate)
			return;
	/* Fall through. */
	case TDUS_NO_DEFERRED:
		trigh.transitional_activate(cstatus);
		break;
	case TDUS_OK:
		/* Read and incorporate triggers. */
		trigdef_parse();
		break;
	default:
		internerr("unknown trigdef_update_start return value '%d'", ur);
	}

	/* Right, that's it. New (empty) Unincorp can be installed. */
	trigdef_process_done();
}
Пример #7
0
const char *
pkg_infodb_get_dir(void)
{
	static char *infodir;

	if (infodir == NULL)
		infodir = dpkg_db_get_path(INFODIR);

	return infodir;
}
Пример #8
0
void
modstatdb_init(void)
{
    const struct fni *fnip;

    if (db_initialized)
        return;

    for (fnip = fnis; fnip->suffix; fnip++) {
        free(*fnip->store);
        *fnip->store = dpkg_db_get_path(fnip->suffix);
    }

    updatefnbuf = m_malloc(strlen(updatesdir) + IMPORTANTMAXLEN + 5);
    strcpy(updatefnbuf, updatesdir);
    updatefnrest = updatefnbuf + strlen(updatefnbuf);

    db_initialized = true;
}
Пример #9
0
static bool
deb_reassemble(const char **filename, const char **pfilename)
{
  static char *reasmbuf = NULL;
  struct stat stab;
  int status;
  pid_t pid;

  if (!reasmbuf)
    reasmbuf = dpkg_db_get_path(REASSEMBLETMP);
  if (unlink(reasmbuf) && errno != ENOENT)
    ohshite(_("error ensuring `%.250s' doesn't exist"), reasmbuf);

  push_cleanup(cu_pathname, ~0, NULL, 0, 1, (void *)reasmbuf);

  pid = subproc_fork();
  if (!pid) {
    execlp(SPLITTER, SPLITTER, "-Qao", reasmbuf, *filename, NULL);
    ohshite(_("unable to execute %s (%s)"),
            _("split package reassembly"), SPLITTER);
  }
  status = subproc_wait(pid, SPLITTER);
  switch (WIFEXITED(status) ? WEXITSTATUS(status) : -1) {
  case 0:
    /* It was a part - is it complete? */
    if (!stat(reasmbuf, &stab)) {
      /* Yes. */
      *filename = reasmbuf;
      *pfilename = _("reassembled package file");
      break;
    } else if (errno == ENOENT) {
      /* No. That's it, we skip it. */
      return false;
    }
  case 1:
    /* No, it wasn't a part. */
    break;
  default:
    subproc_check(status, SPLITTER, 0);
  }

  return true;
}
Пример #10
0
static void
pkgadmindir_init(void)
{
  infodir = dpkg_db_get_path(INFODIR);
}
Пример #11
0
void
ensure_diversions(void)
{
	struct stat stab1, stab2;
	char linebuf[MAXDIVERTFILENAME];
	FILE *file;
	struct diversion *ov, *oicontest, *oialtname;

	if (diversionsname != NULL)
		free(diversionsname);
	diversionsname = dpkg_db_get_path(DIVERSIONSFILE);

	onerr_abort++;

	file = fopen(diversionsname, "r");
	if (!file) {
		if (errno != ENOENT)
			ohshite(_("failed to open diversions file"));
		if (!diversionsfile) {
			onerr_abort--;
			return;
		}
	} else if (diversionsfile) {
		if (fstat(fileno(diversionsfile), &stab1))
			ohshite(_("failed to fstat previous diversions file"));
		if (fstat(fileno(file), &stab2))
			ohshite(_("failed to fstat diversions file"));
		if (stab1.st_dev == stab2.st_dev &&
		    stab1.st_ino == stab2.st_ino) {
			fclose(file);
			onerr_abort--;
			return;
		}
	}
	if (diversionsfile)
		fclose(diversionsfile);
	diversionsfile = file;
	setcloexec(fileno(diversionsfile), diversionsname);

	for (ov = diversions; ov; ov = ov->next) {
		ov->useinstead->divert->camefrom->divert = NULL;
		ov->useinstead->divert = NULL;
	}
	diversions = NULL;
	if (!file) {
		onerr_abort--;
		return;
	}

	while (fgets_checked(linebuf, sizeof(linebuf), file, diversionsname) >= 0) {
		oicontest = nfmalloc(sizeof(struct diversion));
		oialtname = nfmalloc(sizeof(struct diversion));

		oialtname->camefrom = findnamenode(linebuf, 0);
		oialtname->useinstead = NULL;

		fgets_must(linebuf, sizeof(linebuf), file, diversionsname);
		oicontest->useinstead = findnamenode(linebuf, 0);
		oicontest->camefrom = NULL;

		fgets_must(linebuf, sizeof(linebuf), file, diversionsname);
		oicontest->pkgset = strcmp(linebuf, ":") ?
		                    pkg_db_find_set(linebuf) : NULL;
		oialtname->pkgset = oicontest->pkgset;

		if (oialtname->camefrom->divert ||
		    oicontest->useinstead->divert)
			ohshit(_("conflicting diversions involving `%.250s' or `%.250s'"),
			       oialtname->camefrom->name, oicontest->useinstead->name);

		oialtname->camefrom->divert = oicontest;
		oicontest->useinstead->divert = oialtname;

		oicontest->next = diversions;
		diversions = oicontest;
	}

	onerr_abort--;
}
Пример #12
0
int
updateavailable(const char *const *argv)
{
  const char *sourcefile= argv[0];
  char *availfile;
  int count= 0;

  modstatdb_init();

  switch (cipaction->arg_int) {
  case act_avclear:
    if (sourcefile) badusage(_("--%s takes no arguments"),cipaction->olong);
    break;
  case act_avreplace: case act_avmerge:
    if (!sourcefile || argv[1])
      badusage(_("--%s needs exactly one Packages-file argument"),
               cipaction->olong);
    break;
  default:
    internerr("unknown action '%d'", cipaction->arg_int);
  }

  if (!f_noact) {
    if (access(dpkg_db_get_dir(), W_OK)) {
      if (errno != EACCES)
        ohshite(_("unable to access dpkg status area for bulk available update"));
      else
        ohshit(_("bulk available update requires write access to dpkg status area"));
    }
    modstatdb_lock();
  }

  switch (cipaction->arg_int) {
  case act_avreplace:
    printf(_("Replacing available packages info, using %s.\n"),sourcefile);
    break;
  case act_avmerge:
    printf(_("Updating available packages info, using %s.\n"),sourcefile);
    break;
  case act_avclear:
    break;
  default:
    internerr("unknown action '%d'", cipaction->arg_int);
  }

  availfile = dpkg_db_get_path(AVAILFILE);

  if (cipaction->arg_int == act_avmerge)
    parsedb(availfile, pdb_parse_available, NULL);

  if (cipaction->arg_int != act_avclear)
    count += parsedb(sourcefile, pdb_parse_available | pdb_ignoreolder, NULL);

  if (!f_noact) {
    writedb(availfile, wdb_dump_available);
    modstatdb_unlock();
  }

  free(availfile);

  if (cipaction->arg_int != act_avclear)
    printf(P_("Information about %d package was updated.\n",
              "Information about %d packages was updated.\n", count), count);

  modstatdb_done();

  return 0;
}