Пример #1
0
static void
tar_writeback_barrier(struct fileinlist *files, struct pkginfo *pkg)
{
  struct fileinlist *cfile;

  for (cfile = files; cfile; cfile = cfile->next) {
    struct filenamenode *usenode;
    const char *usename;
    int fd;

    if (!(cfile->namenode->flags & fnnf_deferred_fsync))
      continue;

    usenode = namenodetouse(cfile->namenode, pkg);
    usename = usenode->name + 1; /* Skip the leading '/'. */

    setupfnamevbs(usename);

    fd = open(fnamenewvb.buf, O_WRONLY);
    if (fd < 0)
      ohshite(_("unable to open '%.255s'"), fnamenewvb.buf);
    sync_file_range(fd, 0, 0, SYNC_FILE_RANGE_WAIT_BEFORE);
    if (close(fd))
      ohshite(_("error closing/writing `%.255s'"), fnamenewvb.buf);
  }
}
Пример #2
0
/**
 * Returns the path to the script inside the chroot.
 */
static const char *
preexecscript(struct command *cmd)
{
  const char *admindir = dpkg_db_get_dir();
  size_t instdirl = strlen(instdir);

  if (*instdir) {
    if (strncmp(admindir, instdir, instdirl) != 0)
      ohshit(_("admindir must be inside instdir for dpkg to work properly"));
    if (setenv("DPKG_ADMINDIR", admindir + instdirl, 1) < 0)
      ohshite(_("unable to setenv for subprocesses"));

    if (chroot(instdir)) ohshite(_("failed to chroot to `%.250s'"),instdir);
    if (chdir("/"))
      ohshite(_("failed to chdir to `%.255s'"), "/");
  }
  if (debug_has_flag(dbg_scripts)) {
    struct varbuf args = VARBUF_INIT;
    const char **argv = cmd->argv;

    while (*++argv) {
      varbuf_add_char(&args, ' ');
      varbuf_add_str(&args, *argv);
    }
    varbuf_end_str(&args);
    debug(dbg_scripts, "fork/exec %s (%s )", cmd->filename, args.buf);
    varbuf_destroy(&args);
  }
  if (!instdirl)
    return cmd->filename;
  assert(strlen(cmd->filename) >= instdirl);
  return cmd->filename + instdirl;
}
Пример #3
0
/**
 * Remove a pathname and anything below it.
 *
 * This function removes pathname and all its contents recursively.
 */
void
path_remove_tree(const char *pathname)
{
	pid_t pid;
	const char *u;

	u = path_skip_slash_dotslash(pathname);
	assert(*u);

	debug(dbg_eachfile, "%s '%s'", __func__, pathname);
	if (!rmdir(pathname))
		return; /* Deleted it OK, it was a directory. */
	if (errno == ENOENT || errno == ELOOP)
		return;
	if (errno == ENOTDIR) {
		/* Either it's a file, or one of the path components is. If
		 * one of the path components is this will fail again ... */
		if (secure_unlink(pathname) == 0)
			return; /* OK, it was. */
		if (errno == ENOTDIR)
			return;
	}
	if (errno != ENOTEMPTY && errno != EEXIST) /* Huh? */
		ohshite(_("unable to securely remove '%.255s'"), pathname);

	pid = subproc_fork();
	if (pid == 0) {
		execlp(RM, "rm", "-rf", "--", pathname, NULL);
		ohshite(_("unable to execute %s (%s)"),
		        _("rm command for cleanup"), RM);
	}
	debug(dbg_eachfile, "%s running rm -rf '%s'", __func__, pathname);
	subproc_reap(pid, _("rm command for cleanup"), 0);
}
Пример #4
0
static void
decompress_bzip2(int fd_in, int fd_out, const char *desc)
{
	char buffer[DPKG_BUFFER_SIZE];
	BZFILE *bzfile = BZ2_bzdopen(fd_in, "r");

	if (bzfile == NULL)
		ohshit(_("%s: error binding input to bzip2 stream"), desc);

	for (;;) {
		int actualread, actualwrite;

		actualread = BZ2_bzread(bzfile, buffer, sizeof(buffer));
		if (actualread < 0) {
			int bz_errnum = 0;
			const char *errmsg = BZ2_bzerror(bzfile, &bz_errnum);

			if (bz_errnum == BZ_IO_ERROR)
				errmsg = strerror(errno);
			ohshit(_("%s: internal bzip2 read error: '%s'"), desc,
			       errmsg);
		}
		if (actualread == 0) /* EOF. */
			break;

		actualwrite = fd_write(fd_out, buffer, actualread);
		if (actualwrite != actualread)
			ohshite(_("%s: internal bzip2 write error"), desc);
	}

	if (close(fd_out))
		ohshite(_("%s: internal bzip2 write error"), desc);
}
Пример #5
0
void
cu_installsharedconf(int argc, void **argv) {
  struct fileinlist *nifd = (struct fileinlist*)argv[0];
  struct filenamenode *namenode;
  struct stat stab;

  cleanup_pkg_failed++; cleanup_conflictor_failed++;

  namenode = nifd->namenode;
  debug(dbg_eachfile, "cu_installsharedconf `%s' flags=%o", namenode->name,
        namenode->flags);

  setupfnamevbs(namenode->name);

  if ((namenode->flags & fnnf_new_conff) && !lstat(fnametmpvb.buf, &stab)) {
    /* OK, <foo>.dpkg-tmp exists. Restore it to <foo>.dpkg-new as it was a
     * previously unpacked (but not configured) configuration file. */
    if (secure_remove(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR)
      ohshite(_("unable to remove newly-installed version of `%.250s' to allow"
              " reinstallation of backup copy"), fnamenewvb.buf);
    /* Either we can do an atomic restore, or we've made room: */
    if (rename(fnametmpvb.buf, fnamenewvb.buf))
      ohshite(_("unable to restore backup version of `%.250s'"),
              fnamenewvb.buf);
  } else {
    debug(dbg_eachfiledetail,"cu_installsharedconf not restoring");
  }

  cleanup_pkg_failed--; cleanup_conflictor_failed--;
}
Пример #6
0
void push_cleanup(void (*call1)(int argc, void **argv), int mask1,
                  void (*call2)(int argc, void **argv), int mask2,
                  unsigned int nargs, ...) {
  struct cleanup_entry *cep;
  void **argv;
  int e = 0;
  va_list args;

  onerr_abort++;

  cep = malloc(sizeof(struct cleanup_entry) + sizeof(char *) * (nargs + 1));
  if (!cep) {
    if (nargs > array_count(emergency.args))
      ohshite(_("out of memory for new cleanup entry with many arguments"));
    e= errno; cep= &emergency.ce;
  }
  cep->calls[0].call= call1; cep->calls[0].mask= mask1;
  cep->calls[1].call= call2; cep->calls[1].mask= mask2;
  cep->cpmask=~0; cep->cpvalue=0; cep->argc= nargs;
  va_start(args, nargs);
  argv = cep->argv;
  while (nargs-- > 0)
    *argv++ = va_arg(args, void *);
  *argv++ = NULL;
  va_end(args);
  cep->next= econtext->cleanups;
  econtext->cleanups= cep;
  if (cep == &emergency.ce) {
    errno = e;
    ohshite(_("out of memory for new cleanup entry"));
  }

  onerr_abort--;
}
Пример #7
0
static void
decompress_gzip(int fd_in, int fd_out, const char *desc)
{
	char buffer[DPKG_BUFFER_SIZE];
	gzFile gzfile = gzdopen(fd_in, "r");

	if (gzfile == NULL)
		ohshit(_("%s: error binding input to gzip stream"), desc);

	for (;;) {
		int actualread, actualwrite;

		actualread = gzread(gzfile, buffer, sizeof(buffer));
		if (actualread < 0) {
			int z_errnum = 0;
			const char *errmsg = gzerror(gzfile, &z_errnum);

			if (z_errnum == Z_ERRNO)
				errmsg = strerror(errno);
			ohshit(_("%s: internal gzip read error: '%s'"), desc,
			       errmsg);
		}
		if (actualread == 0) /* EOF. */
			break;

		actualwrite = fd_write(fd_out, buffer, actualread);
		if (actualwrite != actualread)
			ohshite(_("%s: internal gzip write error"), desc);
	}

	if (close(fd_out))
		ohshite(_("%s: internal gzip write error"), desc);
}
Пример #8
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();
}
Пример #9
0
void
atomic_file_remove(struct atomic_file *file)
{
	if (unlink(file->name_new))
		ohshite(_("cannot remove '%.250s'"), file->name_new);
	if (unlink(file->name) && errno != ENOENT)
		ohshite(_("cannot remove '%.250s'"), file->name);
}
Пример #10
0
void setcloexec(int fd, const char* fn) {
    int f;

    if ((f=fcntl(fd, F_GETFD))==-1)
        ohshite(_("unable to read filedescriptor flags for %.250s"),fn);
    if (fcntl(fd, F_SETFD, (f|FD_CLOEXEC))==-1)
        ohshite(_("unable to set close-on-exec flag for %.250s"),fn);
}
Пример #11
0
static void
statdb_node_apply(const char *filename, struct file_stat *filestat)
{
	if (chown(filename, filestat->uid, filestat->gid) < 0)
		ohshite(_("error setting ownership of `%.255s'"), filename);
	if (chmod(filename, filestat->mode))
		ohshite(_("error setting permissions of `%.255s'"), filename);
}
Пример #12
0
static void
trk_explicit_interest_remove(const char *newfilename)
{
	if (unlink(newfilename))
		ohshite(_("cannot remove `%.250s'"), newfilename);
	if (unlink(trk_explicit_fn.buf) && errno != ENOENT)
		ohshite(_("cannot remove `%.250s'"), trk_explicit_fn.buf);
}
Пример #13
0
void cu_installnew(int argc, void **argv) {
  /* Something went wrong and we're undoing.
   * We have the following possible situations for non-conffiles:
   *   <foo>.dpkg-tmp exists - in this case we want to remove
   *    <foo> if it exists and replace it with <foo>.dpkg-tmp.
   *    This undoes the backup operation.
   *   <foo>.dpkg-tmp does not exist - <foo> may be on the disk,
   *    as a new file which didn't fail, remove it if it is.
   * In both cases, we also make sure we delete <foo>.dpkg-new in
   * case that's still hanging around.
   * For conffiles, we simply delete <foo>.dpkg-new.  For these,
   * <foo>.dpkg-tmp shouldn't exist, as we don't make a backup
   * at this stage.  Just to be on the safe side, though, we don't
   * look for it.
   */
  struct fileinlist *nifd= (struct fileinlist*)argv[0];
  struct filenamenode *namenode;
  struct stat stab;

  cleanup_pkg_failed++; cleanup_conflictor_failed++;
  
  namenode= nifd->namenode;
  debug(dbg_eachfile,"cu_installnew `%s' flags=%o",namenode->name,namenode->flags);
        
  setupfnamevbs(namenode->name);
  
  if (!(namenode->flags & fnnf_new_conff) && !lstat(fnametmpvb.buf,&stab)) {
    /* OK, <foo>.dpkg-tmp exists.  Remove <foo> and
     * restore <foo>.dpkg-tmp ...
     */
    if (namenode->flags & fnnf_no_atomic_overwrite) {
      /* If we can't do an atomic overwrite we have to delete first any
       * link to the new version we may have created.
       */
      debug(dbg_eachfiledetail,"cu_installnew restoring nonatomic");
      if (unlinkorrmdir(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
        ohshite(_("unable to remove newly-installed version of `%.250s' to allow"
                " reinstallation of backup copy"),namenode->name);
    } else {
      debug(dbg_eachfiledetail,"cu_installnew restoring atomic");
    }
    /* Either we can do an atomic restore, or we've made room: */
    if (rename(fnametmpvb.buf,fnamevb.buf))
      ohshite(_("unable to restore backup version of `%.250s'"),namenode->name);
  } else if (namenode->flags & fnnf_placed_on_disk) {
    debug(dbg_eachfiledetail,"cu_installnew removing new file");
    if (unlinkorrmdir(fnamevb.buf) && errno != ENOENT && errno != ENOTDIR)
      ohshite(_("unable to remove newly-installed version of `%.250s'"),
	      namenode->name);
  } else {
    debug(dbg_eachfiledetail,"cu_installnew not restoring");
  }
  /* Whatever, we delete <foo>.dpkg-new now, if it still exists. */
  if (unlinkorrmdir(fnamenewvb.buf) && errno != ENOENT && errno != ENOTDIR)
    ohshite(_("unable to remove newly-extracted version of `%.250s'"),namenode->name);

  cleanup_pkg_failed--; cleanup_conflictor_failed--;
}
Пример #14
0
void m_dup2(int oldfd, int newfd) {
  const char *const stdstrings[]= { "in", "out", "err" };

  if (dup2(oldfd,newfd) == newfd) return;

  onerr_abort++;
  if (newfd < 3) ohshite(_("failed to dup for std%s"),stdstrings[newfd]);
  ohshite(_("failed to dup for fd %d"),newfd);
}
Пример #15
0
void myfileopt(const char* fn, const struct cmdinfo* cmdinfos) {
  FILE* file;
  char linebuf[MAXDIVERTFILENAME];

  file= fopen(fn, "r");
  if (!file) {
    if (errno==ENOENT)
      return;
    warningf(_("failed to open configuration file `%.255s' for reading"),fn);
    return;
  }

  while (fgets(linebuf, sizeof(linebuf), file)) {
    char* opt;
    const struct cmdinfo *cip;
    int l;

    if ((linebuf[0]=='#') || (linebuf[0]=='\n') || (linebuf[0]==0)) continue;
    l=strlen(linebuf);
    if (linebuf[l-1]=='\n') linebuf[l-1]=0;
    for (opt=linebuf;isalnum(*opt)||*opt=='-';opt++) ;
    if (*opt==0)
      opt=NULL;
    else {
      *opt++=0;
      if (*opt=='=') opt++;
      while (isspace(*opt)) opt++;
    }

    for (cip=cmdinfos; cip->olong || cip->oshort; cip++) {
      int l;
      if (!cip->olong) continue;
      if (!strcmp(cip->olong,linebuf)) break;
      l=strlen(cip->olong);
      if ((cip->takesvalue==2) && (linebuf[l]=='-') &&
	  !opt && !strncmp(linebuf,cip->olong,l)) {
	opt=linebuf+l+1;
	break;
      }
    }

    if (!cip->olong) ohshite(_("configuration error: unknown option %s"), linebuf);

    if (cip->takesvalue) {
      if (!opt) ohshite(_("configuration error: %s needs a value"), linebuf);
      if (cip->call) cip->call(cip,opt);
      else
        *cip->sassignto = m_strdup(opt);
    } else {
      if (opt) ohshite(_("configuration error: %s does not take a value"), linebuf);
      if (cip->call) cip->call(cip,NULL);
      else *cip->iassignto= cip->arg;
    }
  }
  if (ferror(file)) ohshite(_("read error in configuration file `%.255s'"), fn);
  if (fclose(file)) ohshite(_("error closing configuration file `%.255s'"), fn);
}
Пример #16
0
void mustgetpartinfo(const char *filename, struct partinfo *ri) {
  FILE *part;

  part= fopen(filename,"r");
  if (!part) ohshite(_("cannot open archive part file `%.250s'"),filename);
  if (!read_info(part,filename,ri))
    ohshite(_("file `%.250s' is not an archive part"),filename);
  fclose(part);
}
Пример #17
0
static void
newtarobject_allmodes(const char *path, struct file_stat *st)
{
  if (chown(path, st->uid, st->gid))
    ohshite(_("error setting ownership of `%.255s'"), path);
  if (chmod(path, st->mode & ~S_IFMT))
    ohshite(_("error setting permissions of `%.255s'"), path);
  newtarobject_utime(path, st);
}
Пример #18
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();
}
Пример #19
0
void mustgetpartinfo(const char *filename, struct partinfo *ri) {
  struct dpkg_ar *part;

  part = dpkg_ar_open(filename);
  if (!part)
    ohshite(_("cannot open archive part file '%.250s'"), filename);
  if (!read_info(part, ri))
    ohshite(_("file '%.250s' is not an archive part"), filename);
  dpkg_ar_close(part);
}
Пример #20
0
void
atomic_file_sync(struct atomic_file *file)
{
	if (ferror(file->fp))
		ohshite(_("unable to write new file '%.250s'"), file->name_new);
	if (fflush(file->fp))
		ohshite(_("unable to flush new file '%.250s'"), file->name_new);
	if (fsync(fileno(file->fp)))
		ohshite(_("unable to sync new file '%.250s'"), file->name_new);
}
Пример #21
0
static void info_field(const char *debar, const char *directory,
                       const char *const *fields, bool showfieldname)
{
  FILE *cc;
  char fieldname[MAXFIELDNAME+1];
  char *pf;
  const char *const *fp;
  int c, lno, fnl;
  bool doing;

  if (!(cc= fopen("control","r"))) ohshite(_("could not open the `control' component"));
  doing = true;
  lno = 1;
  for (;;) {
    c = getc(cc);
    if (c == EOF) {
      doing = false;
      break;
    }
    if (c == '\n') {
      lno++;
      doing = true;
      continue;
    }
    if (!isspace(c)) {
      for (pf=fieldname, fnl=0;
           fnl <= MAXFIELDNAME && c!=EOF && !isspace(c) && c!=':';
           c= getc(cc)) { *pf++= c; fnl++; }
      *pf = '\0';
      doing= fnl >= MAXFIELDNAME || c=='\n' || c==EOF;
      for (fp=fields; !doing && *fp; fp++)
        if (!strcasecmp(*fp, fieldname))
          doing = true;
      if (showfieldname) {
        if (doing)
          fputs(fieldname,stdout);
      } else {
        if (c==':') c= getc(cc);
        while (c != '\n' && isspace(c)) c= getc(cc);
      }
    }
    for(;;) {
      if (c == EOF) break;
      if (doing) putc(c,stdout);
      if (c == '\n') { lno++; break; }
      c= getc(cc);
    }
    if (c == EOF) break;
  }
  if (ferror(cc)) ohshite(_("failed during read of `control' component"));
  if (fclose(cc))
    ohshite(_("error closing the '%s' component"), "control");
  if (doing) putc('\n',stdout);
  m_output(stdout, _("<standard output>"));
}
Пример #22
0
/**
 * Pack the contents of a directory into a tarball.
 */
static void
tarball_pack(const char *dir, filenames_feed_func *tar_filenames_feeder,
             time_t timestamp,
             struct compress_params *tar_compress_params, int fd_out)
{
  int pipe_filenames[2], pipe_tarball[2];
  pid_t pid_tar, pid_comp;

  /* Fork off a tar. We will feed it a list of filenames on stdin later. */
  m_pipe(pipe_filenames);
  m_pipe(pipe_tarball);
  pid_tar = subproc_fork();
  if (pid_tar == 0) {
    char mtime[50];

    m_dup2(pipe_filenames[0], 0);
    close(pipe_filenames[0]);
    close(pipe_filenames[1]);
    m_dup2(pipe_tarball[1], 1);
    close(pipe_tarball[0]);
    close(pipe_tarball[1]);

    if (chdir(dir))
      ohshite(_("failed to chdir to '%.255s'"), dir);

    snprintf(mtime, sizeof(mtime), "@%ld", timestamp);

    execlp(TAR, "tar", "-cf", "-", "--format=gnu",
                       "--mtime", mtime, "--clamp-mtime",
                       "--null", "--no-unquote",
                       "--no-recursion", "-T", "-", NULL);
    ohshite(_("unable to execute %s (%s)"), "tar -cf", TAR);
  }
  close(pipe_filenames[0]);
  close(pipe_tarball[1]);

  /* Of course we should not forget to compress the archive as well. */
  pid_comp = subproc_fork();
  if (pid_comp == 0) {
    close(pipe_filenames[1]);
    compress_filter(tar_compress_params, pipe_tarball[0], fd_out,
                    _("compressing tar member"));
    exit(0);
  }
  close(pipe_tarball[0]);

  /* All the pipes are set, now lets start feeding filenames to tar. */
  tar_filenames_feeder(dir, pipe_filenames[1]);

  /* All done, clean up wait for tar and <compress> to finish their job. */
  close(pipe_filenames[1]);
  subproc_reap(pid_comp, _("<compress> from tar -cf"), 0);
  subproc_reap(pid_tar, "tar -cf", 0);
}
Пример #23
0
static void
statdb_node_apply(const char *filename, struct file_stat *filestat)
{
	if (chown(filename, filestat->uid, filestat->gid) < 0)
		ohshite(_("error setting ownership of '%.255s'"), filename);
	if (chmod(filename, filestat->mode))
		ohshite(_("error setting permissions of '%.255s'"), filename);

	dpkg_selabel_load();
	dpkg_selabel_set_context(filename, filename, filestat->mode);
	dpkg_selabel_close();
}
Пример #24
0
/**
 * Sync a directory to disk from a DIR structure.
 *
 * @param dir The directory to sync.
 * @param path The name of the directory to sync (for error messages).
 */
static void
dir_sync(DIR *dir, const char *path)
{
    int fd;

    fd = dirfd(dir);
    if (fd < 0)
        ohshite(_("unable to get file descriptor for directory '%s'"),
                path);

    if (fsync(fd))
        ohshite(_("unable to sync directory '%s'"), path);
}
Пример #25
0
static void
trk_explicit_interest_flush(const char *newfilename, FILE *nf)
{
	if (ferror(nf))
		ohshite(_("unable to write new trigger interest file `%.250s'"),
		        newfilename);
	if (fflush(nf))
		ohshite(_("unable to flush new trigger interest file '%.250s'"),
		        newfilename);
	if (fsync(fileno(nf)))
		ohshite(_("unable to sync new trigger interest file '%.250s'"),
		        newfilename);
}
Пример #26
0
int userdb_change(const char *filename, const struct userentry *uep, int create) {
  /* possible values for `create' are:
   *   0: never create a new record (return 1 if not already there).
   *   1: create a new record if required.
   *   2: fail (and return 1) if already exists (ie, force creation)
   *  -1: delete an existing record (return 1 if it doesn't exist).
   * return values are:
   *   0: OK
   *   1: Value for `create' prevented us from going ahead
   *   2: Wanted to create a new record, but there is no room.
   */
     
  static struct userentry ue;
  int n, initial, i, place;
  FILE *file;

  initbyuserid(filename,"r+b",F_WRLCK,uep->userid,uep->access,&file,&initial,&n);
  i= initial; place= -1;
  for(;;) {
    getentry(file,&ue,filename);
    if (!ue.userid[0]) {
      if (place==-1) place= i;
    } else if (!strncmp(uep->userid,ue.userid,USERID_MAXLEN)) /* &&
								(uep->access < 0 || uep->access == ue.access)) */ {
      if (create==2) { ufclose(file,filename); return 1; }
      place=i; break;
    }
    i= nextentry(file,i,n,filename);
    if (i == initial) {
      /* OK, we didn't find it.  We may have found a space, though */
      if (create<=0) { ufclose(file,filename); return 1; }
      if (place==-1) { ufclose(file,filename); return 2; }
      break;
    }
  }
  if (fseek(file,sizeof(struct userentry)*place,SEEK_SET))
    ohshite("User database `%s' unseekable for update",filename);
  if (create<0) {
    ue.userid[0]= 0;
    ue.secretbytes= 0;
    ue.disabled= 0;
    memset(ue.secret,0,SECRET_MAXBYTES);
    uep= &ue;
  } else {
    assert(uep->access >= 0);
  }
  errno=0; if (fwrite(uep,sizeof(*uep),1,file)!=1)
    ohshite("User database `%s' unwriteable",filename);
  if (ufclose(file,filename)) ohshite("User database `%s' uncloseable",filename);
  return 0;
}
Пример #27
0
Файл: ar.c Проект: pexip/os-dpkg
void
dpkg_ar_member_put_mem(const char *ar_name, int ar_fd,
                       const char *name, const void *data, size_t size)
{
    dpkg_ar_member_put_header(ar_name, ar_fd, name, size);

    /* Copy data contents. */
    if (fd_write(ar_fd, data, size) < 0)
        ohshite(_("unable to write file '%s'"), ar_name);

    if (size & 1)
        if (fd_write(ar_fd, "\n", 1) < 0)
            ohshite(_("unable to write file '%s'"), ar_name);
}
Пример #28
0
static void
atomic_file_backup(struct atomic_file *file)
{
	char *name_old;

	name_old = str_fmt("%s%s", file->name, ATOMIC_FILE_OLD_EXT);

	if (unlink(name_old) && errno != ENOENT)
		ohshite(_("error removing old backup file '%s'"), name_old);
	if (link(file->name, name_old) && errno != ENOENT)
		ohshite(_("error creating new backup file '%s'"), name_old);

	free(name_old);
}
Пример #29
0
static void
compress_bzip2(int fd_in, int fd_out, struct compress_params *params, const char *desc)
{
	char buffer[DPKG_BUFFER_SIZE];
	char combuf[6];
	int bz_errnum;
	BZFILE *bzfile;

	snprintf(combuf, sizeof(combuf), "w%d", params->level);
	bzfile = BZ2_bzdopen(fd_out, combuf);
	if (bzfile == NULL)
		ohshit(_("%s: error binding output to bzip2 stream"), desc);

	for (;;) {
		int actualread, actualwrite;

		actualread = fd_read(fd_in, buffer, sizeof(buffer));
		if (actualread < 0)
			ohshite(_("%s: internal bzip2 read error"), desc);
		if (actualread == 0) /* EOF. */
			break;

		actualwrite = BZ2_bzwrite(bzfile, buffer, actualread);
		if (actualwrite != actualread) {
			const char *errmsg = BZ2_bzerror(bzfile, &bz_errnum);

			if (bz_errnum == BZ_IO_ERROR)
				errmsg = strerror(errno);
			ohshit(_("%s: internal bzip2 write error: '%s'"), desc,
			       errmsg);
		}
	}

	BZ2_bzWriteClose(&bz_errnum, bzfile, 0, NULL, NULL);
	if (bz_errnum != BZ_OK) {
		const char *errmsg = _("unexpected bzip2 error");

		if (bz_errnum == BZ_IO_ERROR)
			errmsg = strerror(errno);
		ohshit(_("%s: internal bzip2 write error: '%s'"), desc,
		       errmsg);
	}

	/* Because BZ2_bzWriteClose has done a fflush on the file handle,
	 * doing a close on the file descriptor associated with it should
	 * be safe™. */
	if (close(fd_out))
		ohshite(_("%s: internal bzip2 write error"), desc);
}
Пример #30
0
static void
file_treewalk_feed(const char *dir, int fd_out)
{
  int pipefd[2];
  pid_t pid;
  struct file_info *fi;
  struct file_info *symlist = NULL;
  struct file_info *symlist_end = NULL;

  m_pipe(pipefd);

  pid = subproc_fork();
  if (pid == 0) {
    m_dup2(pipefd[1], 1);
    close(pipefd[0]);
    close(pipefd[1]);

    if (chdir(dir))
      ohshite(_("failed to chdir to `%.255s'"), dir);

    execlp(FIND, "find", ".", "-path", "./" BUILDCONTROLDIR, "-prune", "-o",
           "-print0", NULL);
    ohshite(_("unable to execute %s (%s)"), "find", FIND);
  }
  close(pipefd[1]);

  /* We need to reorder the files so we can make sure that symlinks
   * will not appear before their target. */
  while ((fi = file_info_get(dir, pipefd[0])) != NULL) {
    if (S_ISLNK(fi->st.st_mode)) {
      file_info_list_append(&symlist, &symlist_end, fi);
    } else {
      if (fd_write(fd_out, fi->fn, strlen(fi->fn) + 1) < 0)
        ohshite(_("failed to write filename to tar pipe (%s)"),
                _("data member"));
      file_info_free(fi);
    }
  }

  close(pipefd[0]);
  subproc_wait_check(pid, "find", 0);

  for (fi = symlist; fi; fi = fi->next)
    if (fd_write(fd_out, fi->fn, strlen(fi->fn) + 1) < 0)
      ohshite(_("failed to write filename to tar pipe (%s)"), _("data member"));

  file_info_list_free(symlist);
}