コード例 #1
0
static void
pkg_disappear(struct pkginfo *pkg, struct pkginfo *infavour)
{
  printf(_("(Noting disappearance of %s, which has been completely replaced.)\n"),
         pkg_name(pkg, pnaw_nonambig));
  log_action("disappear", pkg, &pkg->installed);
  debug(dbg_general, "pkg_disappear disappearing %s",
        pkg_name(pkg, pnaw_nonambig));

  trig_activate_packageprocessing(pkg);
  maintainer_script_installed(pkg, POSTRMFILE,
                              "post-removal script (for disappearance)",
                              "disappear",
                              infavour->set->name,
                              versiondescribe(&infavour->available.version,
                                              vdew_nonambig),
                              NULL);

  /* OK, now we delete all the stuff in the ‘info’ directory .. */
  debug(dbg_general, "pkg_disappear cleaning info directory");
  pkg_infodb_foreach(pkg, &pkg->installed, pkg_infodb_remove_file);
  dir_sync_path(pkgadmindir());

  pkg_set_status(pkg, stat_notinstalled);
  pkg_set_want(pkg, want_unknown);
  pkg_reset_eflags(pkg);

  blankversion(&pkg->configversion);
  pkgbin_blank(&pkg->installed);

  pkg->clientdata->fileslistvalid = false;

  modstatdb_note(pkg);
}
コード例 #2
0
static void cleanupdates(void) {
    struct dirent **cdlist;
    int cdn, i;

    parsedb(statusfile, pdb_parse_status, NULL);

    *updatefnrest = '\0';
    updateslength= -1;
    cdn= scandir(updatefnbuf, &cdlist, &ulist_select, alphasort);
    if (cdn == -1) ohshite(_("cannot scan updates directory `%.255s'"),updatefnbuf);

    if (cdn) {
        for (i=0; i<cdn; i++) {
            strcpy(updatefnrest, cdlist[i]->d_name);
            parsedb(updatefnbuf, pdb_parse_update, NULL);
            if (cstatus < msdbrw_write) free(cdlist[i]);
        }

        if (cstatus >= msdbrw_write) {
            writedb(statusfile, wdb_must_sync);

            for (i=0; i<cdn; i++) {
                strcpy(updatefnrest, cdlist[i]->d_name);
                if (unlink(updatefnbuf))
                    ohshite(_("failed to remove incorporated update file %.255s"),updatefnbuf);
                free(cdlist[i]);
            }

            dir_sync_path(updatesdir);
        }
    }
    free(cdlist);

    nextupdate= 0;
}
コード例 #3
0
ファイル: statcmd.c プロジェクト: nisc-code/dpkg
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);
}
コード例 #4
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);
}
コード例 #5
0
ファイル: dir.c プロジェクト: samdunne/dpkg-diversions
/**
 * Sync to disk the parent directory of a pathname.
 *
 * @param path The child pathname of the directory to sync.
 */
void
dir_sync_path_parent(const char *path)
{
    char *dirname, *slash;

    dirname = m_strdup(path);

    slash = strrchr(dirname, '/');
    if (slash != NULL) {
        *slash = '\0';
        dir_sync_path(dirname);
    }

    free(dirname);
}
コード例 #6
0
ファイル: triglib.c プロジェクト: guillemj/dpkg
void
trig_file_interests_save(void)
{
	if (filetriggers_edited <= 0)
		return;

	if (!filetriggers.head)
		trig_file_interests_remove();
	else
		trig_file_interests_update();

	dir_sync_path(triggersdir);

	filetriggers_edited = 0;
}
コード例 #7
0
ファイル: filesdb.c プロジェクト: pexip/os-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)
{
  static struct varbuf newvb;
  const char *listfile;
  FILE *file;

  listfile = pkgadminfile(pkg, pkgbin, LISTFILE);

  varbuf_reset(&newvb);
  varbuf_add_str(&newvb, listfile);
  varbuf_add_str(&newvb, NEWDBEXT);
  varbuf_end_str(&newvb);

  file= fopen(newvb.buf,"w+");
  if (!file)
    ohshite(_("unable to create updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));
  push_cleanup(cu_closestream, ehflag_bombout, NULL, 0, 1, (void *)file);
  while (list) {
    if (!(mask && (list->namenode->flags & mask))) {
      fputs(list->namenode->name,file);
      putc('\n',file);
    }
    list= list->next;
  }
  if (ferror(file))
    ohshite(_("failed to write to updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));
  if (fflush(file))
    ohshite(_("failed to flush updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));
  if (fsync(fileno(file)))
    ohshite(_("failed to sync updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));
  pop_cleanup(ehflag_normaltidy); /* file = fopen() */
  if (fclose(file))
    ohshite(_("failed to close updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));
  if (rename(newvb.buf, listfile))
    ohshite(_("failed to install updated files list file for package %s"),
            pkg_describe(pkg, pdo_foreign));

  dir_sync_path(pkgadmindir());

  note_must_reread_files_inpackage(pkg);
}
コード例 #8
0
ファイル: triglib.c プロジェクト: samdunne/dpkg-diversions
static void
trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg, int signum,
                             enum trig_options opts)
{
	static struct varbuf newfn;
	char buf[1024];
	FILE *nf;
	bool empty = true;

	trk_explicit_start(trig);
	varbuf_reset(&newfn);
	varbuf_printf(&newfn, "%s/%s.new", triggersdir, trig);

	nf = fopen(newfn.buf, "w");
	if (!nf)
		ohshite(_("unable to create new trigger interest file `%.250s'"),
		        newfn.buf);
	push_cleanup(cu_closestream, ~ehflag_normaltidy, NULL, 0, 1, nf);

	while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
		int len = strlen(pkg->name);
		if (strncmp(buf, pkg->name, len) == 0 &&
		    (buf[len] == '\0' || buf[len] == '/'))
			continue;
		fprintf(nf, "%s\n", buf);
		empty = false;
	}
	if (signum > 0) {
		fprintf(nf, "%s%s\n", pkg->name,
		        (opts == trig_noawait) ? "/noawait" : "");
		empty = false;
	}

	if (!empty)
		trk_explicit_interest_flush(newfn.buf, nf);

	pop_cleanup(ehflag_normaltidy);
	if (fclose(nf))
		ohshite(_("unable to close new trigger interest file `%.250s'"),
		        newfn.buf);

	if (empty)
		trk_explicit_interest_remove(newfn.buf);
	else
		trk_explicit_interest_commit(newfn.buf);

	dir_sync_path(triggersdir);
}
コード例 #9
0
void modstatdb_checkpoint(void) {
    int i;

    assert(cstatus >= msdbrw_write);
    writedb(statusfile, wdb_must_sync);

    for (i=0; i<nextupdate; i++) {
        sprintf(updatefnrest, IMPORTANTFMT, i);
        /* Have we made a real mess? */
        assert(strlen(updatefnrest) <= IMPORTANTMAXLEN);
        if (unlink(updatefnbuf))
            ohshite(_("failed to remove my own update file %.255s"),updatefnbuf);
    }

    dir_sync_path(updatesdir);

    nextupdate= 0;
}
コード例 #10
0
ファイル: triglib.c プロジェクト: guillemj/dpkg
static void
trk_explicit_interest_change(const char *trig,  struct pkginfo *pkg,
                             struct pkgbin *pkgbin, int signum,
                             enum trig_options opts)
{
	char buf[1024];
	struct atomic_file *file;
	bool empty = true;

	trk_explicit_start(trig);
	file = atomic_file_new(trk_explicit_fn.buf, 0);
	atomic_file_open(file);

	while (trk_explicit_f && trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
		const char *pkgname = pkgbin_name(pkg, pkgbin, pnaw_nonambig);
		size_t len = strlen(pkgname);

		if (strncmp(buf, pkgname, len) == 0 && len < sizeof(buf) &&
		    (buf[len] == '\0' || buf[len] == '/'))
			continue;
		fprintf(file->fp, "%s\n", buf);
		empty = false;
	}
	if (signum > 0) {
		fprintf(file->fp, "%s%s\n",
		        pkgbin_name(pkg, pkgbin, pnaw_nonambig),
		        (opts == TRIG_NOAWAIT) ? "/noawait" : "");
		empty = false;
	}

	if (!empty)
		atomic_file_sync(file);

	atomic_file_close(file);

	if (empty)
		atomic_file_remove(file);
	else
		atomic_file_commit(file);

	atomic_file_free(file);

	dir_sync_path(triggersdir);
}
コード例 #11
0
static void
modstatdb_note_core(struct pkginfo *pkg)
{
    assert(cstatus >= msdbrw_write);

    varbuf_reset(&uvb);
    varbufrecord(&uvb, pkg, &pkg->installed);

    if (fwrite(uvb.buf, 1, uvb.used, importanttmp) != uvb.used)
        ohshite(_("unable to write updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));
    if (fflush(importanttmp))
        ohshite(_("unable to flush updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));
    if (ftruncate(fileno(importanttmp), uvb.used))
        ohshite(_("unable to truncate for updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));
    if (fsync(fileno(importanttmp)))
        ohshite(_("unable to fsync updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));
    if (fclose(importanttmp))
        ohshite(_("unable to close updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));
    sprintf(updatefnrest, IMPORTANTFMT, nextupdate);
    if (rename(importanttmpfile, updatefnbuf))
        ohshite(_("unable to install updated status of `%.250s'"),
                pkg_name(pkg, pnaw_nonambig));

    dir_sync_path(updatesdir);

    /* Have we made a real mess? */
    assert(strlen(updatefnrest) <= IMPORTANTMAXLEN);

    nextupdate++;

    if (nextupdate > MAXUPDATES) {
        modstatdb_checkpoint();
        nextupdate = 0;
    }

    createimptmp();
}
コード例 #12
0
static void
pkg_infodb_update(struct pkginfo *pkg, char *cidir, char *cidirrest)
{
  struct match_node *match_node;
  DIR *dsd;
  struct dirent *de;

  /* Deallocate the match list in case we aborted previously. */
  while ((match_node = match_head)) {
    match_head = match_node->next;
    match_node_free(match_node);
  }

  pkg_infodb_foreach(pkg, &pkg->available, pkg_infodb_update_file);

  while ((match_node = match_head)) {
    strcpy(cidirrest, match_node->filetype);

    if (!rename(cidir, match_node->filename)) {
      debug(dbg_scripts, "process_archive info installed %s as %s",
            cidir, match_node->filename);
    } else if (errno == ENOENT) {
      /* Right, no new version. */
      if (unlink(match_node->filename))
        ohshite(_("unable to remove obsolete info file `%.250s'"),
                match_node->filename);
      debug(dbg_scripts, "process_archive info unlinked %s",
            match_node->filename);
    } else {
      ohshite(_("unable to install (supposed) new info file `%.250s'"), cidir);
    }
    match_head = match_node->next;
    match_node_free(match_node);
  }

  /* The control directory itself. */
  cidirrest[0] = '\0';
  dsd = opendir(cidir);
  if (!dsd)
    ohshite(_("unable to open temp control directory"));
  push_cleanup(cu_closedir, ~0, NULL, 0, 1, (void *)dsd);
  while ((de = readdir(dsd))) {
    const char *newinfofilename;

    if (strchr(de->d_name, '.')) {
      debug(dbg_scripts,"process_archive tmp.ci script/file `%s' contains dot",
            de->d_name);
      continue;
    }
    if (strlen(de->d_name) > MAXCONTROLFILENAME)
      ohshit(_("package contains overly-long control info file name (starting `%.50s')"),
             de->d_name);

    strcpy(cidirrest, de->d_name);

    /* First we check it's not a directory. */
    if (rmdir(cidir) == 0)
      ohshit(_("package control info contained directory `%.250s'"), cidir);
    else if (errno != ENOTDIR)
      ohshite(_("package control info rmdir of `%.250s' didn't say not a dir"),
              de->d_name);

    /* Ignore the control file. */
    if (strcmp(de->d_name, CONTROLFILE) == 0) {
      debug(dbg_scripts, "process_archive tmp.ci script/file `%s' is control",
            cidir);
      continue;
    }
    if (strcmp(de->d_name, LISTFILE) == 0) {
      warning(_("package %s contained list as info file"),
              pkgbin_name(pkg, &pkg->available, pnaw_nonambig));
      continue;
    }

    /* Right, install it */
    newinfofilename = pkgadminfile(pkg, &pkg->available, de->d_name);
    if (rename(cidir, newinfofilename))
      ohshite(_("unable to install new info file `%.250s' as `%.250s'"),
              cidir, newinfofilename);

    debug(dbg_scripts,
          "process_archive tmp.ci script/file `%s' installed as `%s'",
          cidir, newinfofilename);
  }
  pop_cleanup(ehflag_normaltidy); /* closedir */

  dir_sync_path(pkgadmindir());
}
コード例 #13
0
ファイル: queue.c プロジェクト: nexgenta/dpkg
void do_auto(const char *const *argv) {
    const char *partfile;
    struct partinfo *pi, *refi, *npi, **partlist, *otherthispart;
    struct partqueue *pq;
    unsigned int i;
    int j, ap;
    long nr;
    FILE *part;
    void *buffer;
    char *p, *q;

    if (!opt_outputfile)
        badusage(_("--auto requires the use of the --output option"));
    if (!(partfile= *argv++) || *argv)
        badusage(_("--auto requires exactly one part file argument"));

    refi= nfmalloc(sizeof(struct partqueue));
    part= fopen(partfile,"r");
    if (!part) ohshite(_("unable to read part file `%.250s'"),partfile);
    if (!read_info(part,partfile,refi)) {
        if (!opt_npquiet)
            printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile);
        m_output(stdout, _("<standard output>"));
        exit(1);
    }
    fclose(part);
    scandepot();
    partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
    for (i = 0; i < refi->maxpartn; i++)
        partlist[i] = NULL;
    for (pq= queue; pq; pq= pq->nextinqueue) {
        pi= &pq->info;
        if (!partmatches(pi,refi)) continue;
        npi= nfmalloc(sizeof(struct partinfo));
        mustgetpartinfo(pi->filename,npi);
        addtopartlist(partlist,npi,refi);
    }
    /* If we already have a copy of this version we ignore it and prefer the
     * new one, but we still want to delete the one in the depot, so we
     * save its partinfo (with the filename) for later. This also prevents
     * us from accidentally deleting the source file. */
    otherthispart= partlist[refi->thispartn-1];
    partlist[refi->thispartn-1]= refi;
    for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);

    if (j>=0) {

        part= fopen(partfile,"r");
        if (!part) ohshite(_("unable to reopen part file `%.250s'"),partfile);
        buffer= nfmalloc(refi->filesize);
        nr= fread(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) rerreof(part,partfile);
        if (getc(part) != EOF) ohshit(_("part file `%.250s' has trailing garbage"),partfile);
        if (ferror(part)) rerr(partfile);
        fclose(part);
        p = nfmalloc(strlen(opt_depotdir) + 50);
        q = nfmalloc(strlen(opt_depotdir) + 200);
        sprintf(p, "%st.%lx", opt_depotdir, (long)getpid());
        sprintf(q, "%s%s.%lx.%x.%x", opt_depotdir, refi->md5sum,
                refi->maxpartlen,refi->thispartn,refi->maxpartn);
        part= fopen(p,"w");
        if (!part) ohshite(_("unable to open new depot file `%.250s'"),p);
        nr= fwrite(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) werr(p);
        if (fflush(part))
            ohshite(_("unable to flush file '%s'"), p);
        if (fsync(fileno(part)))
            ohshite(_("unable to sync file '%s'"), p);
        if (fclose(part)) werr(p);
        if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q);

        printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package);
        /* There are still some parts missing. */
        for (i=0, ap=0; i<refi->maxpartn; i++)
            if (!partlist[i])
                printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1);
        printf(").\n");

        dir_sync_path(opt_depotdir);
    } else {

        /* We have all the parts. */
        reassemble(partlist, opt_outputfile);

        /* OK, delete all the parts (except the new one, which we never copied). */
        partlist[refi->thispartn-1]= otherthispart;
        for (i=0; i<refi->maxpartn; i++)
            if (partlist[i])
                if (unlink(partlist[i]->filename))
                    ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename);

    }

    m_output(stderr, _("<standard error>"));
}
コード例 #14
0
ファイル: queue.c プロジェクト: samdunne/dpkg-diversions
int
do_auto(const char *const *argv)
{
  const char *partfile;
  struct partinfo *refi, **partlist, *otherthispart;
  struct partqueue *pq;
  unsigned int i;
  int j;
  FILE *part;

  if (!opt_outputfile)
    badusage(_("--auto requires the use of the --output option"));
  if (!(partfile= *argv++) || *argv)
    badusage(_("--auto requires exactly one part file argument"));

  refi= nfmalloc(sizeof(struct partqueue));
  part= fopen(partfile,"r");
  if (!part) ohshite(_("unable to read part file `%.250s'"),partfile);
  if (!read_info(part,partfile,refi)) {
    if (!opt_npquiet)
      printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile);
    m_output(stdout, _("<standard output>"));
    return 1;
  }
  fclose(part);
  scandepot();
  partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
  for (i = 0; i < refi->maxpartn; i++)
    partlist[i] = NULL;
  for (pq= queue; pq; pq= pq->nextinqueue) {
    struct partinfo *npi, *pi = &pq->info;

    if (!partmatches(pi,refi)) continue;
    npi= nfmalloc(sizeof(struct partinfo));
    mustgetpartinfo(pi->filename,npi);
    addtopartlist(partlist,npi,refi);
  }
  /* If we already have a copy of this version we ignore it and prefer the
   * new one, but we still want to delete the one in the depot, so we
   * save its partinfo (with the filename) for later. This also prevents
   * us from accidentally deleting the source file. */
  otherthispart= partlist[refi->thispartn-1];
  partlist[refi->thispartn-1]= refi;
  for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);

  if (j>=0) {
    int fd_src, fd_dst;
    int ap;
    char *p, *q;

    m_asprintf(&p, "%st.%lx", opt_depotdir, (long)getpid());
    m_asprintf(&q, "%s%s.%jx.%x.%x", opt_depotdir, refi->md5sum,
               (intmax_t)refi->maxpartlen, refi->thispartn, refi->maxpartn);

    fd_src = open(partfile, O_RDONLY);
    if (fd_src < 0)
      ohshite(_("unable to reopen part file `%.250s'"), partfile);
    fd_dst = creat(p, 0644);
    if (fd_dst < 0)
      ohshite(_("unable to open new depot file `%.250s'"), p);

    fd_fd_copy(fd_src, fd_dst, refi->filesize, _("extracting split part"));

    if (fsync(fd_dst))
      ohshite(_("unable to sync file '%s'"), p);
    if (close(fd_dst))
      ohshite(_("unable to close file '%s'"), p);
    close(fd_src);

    if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q);
    free(q);
    free(p);

    printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package);
    /* There are still some parts missing. */
    for (i=0, ap=0; i<refi->maxpartn; i++)
      if (!partlist[i])
        printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1);
    printf(").\n");

    dir_sync_path(opt_depotdir);
  } else {

    /* We have all the parts. */
    reassemble(partlist, opt_outputfile);

    /* OK, delete all the parts (except the new one, which we never copied). */
    partlist[refi->thispartn-1]= otherthispart;
    for (i=0; i<refi->maxpartn; i++)
      if (partlist[i])
        if (unlink(partlist[i]->filename))
          ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename);

  }

  m_output(stderr, _("<standard error>"));

  return 0;
}