Пример #1
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);
}
Пример #2
0
static void
op_remove(diversion *diversions, const char *file)
{
	diversion *d;
	for (d = diversions; d; d = d->next) {
		if (strcmp(d->contest, file) == 0) {
			if (divertto && strcmp(d->altname, divertto) != 0)
				ohshit(_("mismatch on divert-to\n"
					 "when removing '%s'\n"
					 "found '%s"), infoa(file), infon(d));
			if (package && strcmp(d->package, package) != 0)
				ohshit(_("mismatch on package\n"
					 "when removing '%s'\n"
					 "found '%s'"), infoa(file), infon(d));
			if (!quiet)
				printf(_("Removing '%s'\n"), infon(d));

			checkrename(d->altname, d->contest);
			dorename(d->altname, d->contest);

			diversions = diversions_remove(diversions, d);
			save(diversions);
			exit(0);
		}
	}

	if (!quiet) {
		printf(_("No diversion '%s', none removed"), infoa(file));
		putchar('\n');
	}
	exit(0);
}
Пример #3
0
static void
info_spew(const char *debar, const char *dir, const char *const *argv)
{
  struct dpkg_error err;
  const char *component;
  struct varbuf controlfile = VARBUF_INIT;
  int fd;
  int re= 0;

  while ((component = *argv++) != NULL) {
    varbuf_reset(&controlfile);
    varbuf_printf(&controlfile, "%s/%s", dir, component);

    fd = open(controlfile.buf, O_RDONLY);
    if (fd >= 0) {
      if (fd_fd_copy(fd, 1, -1, &err) < 0)
        ohshit(_("cannot extract control file '%s' from '%s': %s"),
               controlfile.buf, debar, err.str);
      close(fd);
    } else if (errno == ENOENT) {
      notice(_("'%.255s' contains no control component '%.255s'"),
             debar, component);
      re++;
    } else {
      ohshite(_("open component `%.255s' (in %.255s) failed in an unexpected way"),
              component, dir);
    }
  }
  varbuf_destroy(&controlfile);

  if (re > 0)
    ohshit(P_("%d requested control component is missing",
              "%d requested control components are missing", re), re);
}
Пример #4
0
static int
arch_add(const char *const *argv)
{
  struct dpkg_arch *arch;
  const char *archname = *argv++;

  if (archname == NULL || *argv)
    badusage(_("--%s takes exactly one argument"), cipaction->olong);

  dpkg_arch_load_list();

  arch = dpkg_arch_add(archname);
  switch (arch->type) {
  case DPKG_ARCH_NATIVE:
  case DPKG_ARCH_FOREIGN:
    break;
  case DPKG_ARCH_ILLEGAL:
    ohshit(_("architecture '%s' is illegal: %s"), archname,
           dpkg_arch_name_is_illegal(archname));
  default:
    ohshit(_("architecture '%s' is reserved and cannot be added"), archname);
  }

  dpkg_arch_save_list();

  return 0;
}
Пример #5
0
static void initbyuserid(const char *filename, const char *mode, int locktype,
                         const char userid[USERID_MAXLEN], int access,
                         FILE **file_r, int *initial_r, int *n_r) {
  FILE *file;
  int n,i;
  struct stat ustab;
  u32 hash;

  file= fopen(filename,mode);
  if (!file) ohshite("User database file `%s' inaccessible",filename);
  makelock(file,locktype,filename);
  if (fstat(fileno(file),&ustab)) ohshite("User database `%s' unstattable",filename);
  if (ustab.st_size % sizeof(struct userentry))
    ohshit("User database `%s' corrupt",filename);
  n= ustab.st_size / sizeof(struct userentry);
  if (n==0) ohshit("User database `%s' truncated",filename);
  hash= userdb_hash(userid);

  i= hash % n;
  if (fseek(file, i*sizeof(struct userentry), SEEK_SET))
    ohshite("User database `%s' unseekable",filename);

  *file_r= file;
  *initial_r= i;
  *n_r= n;
}
Пример #6
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);
}
Пример #7
0
void do_queue(const char *const *argv) {
    struct partqueue *pq, *qq;
    struct partinfo ti;
    const char *head;
    struct stat stab;
    unsigned long bytes;
    unsigned int i;

    if (*argv)
        badusage(_("--%s takes no arguments"), cipaction->olong);
    scandepot();

    head= N_("Junk files left around in the depot directory:\n");
    for (pq= queue; pq; pq= pq->nextinqueue) {
        if (pq->info.md5sum) continue;
        fputs(gettext(head),stdout);
        head= "";
        if (lstat(pq->info.filename,&stab))
            ohshit(_("unable to stat `%.250s'"),pq->info.filename);
        if (S_ISREG(stab.st_mode)) {
            bytes= stab.st_size;
            printf(_(" %s (%lu bytes)\n"),pq->info.filename,bytes);
        } else {
            printf(_(" %s (not a plain file)\n"),pq->info.filename);
        }
    }
    if (!*head) putchar('\n');

    head= N_("Packages not yet reassembled:\n");
    for (pq= queue; pq; pq= pq->nextinqueue) {
        if (!pq->info.md5sum) continue;
        mustgetpartinfo(pq->info.filename,&ti);
        fputs(gettext(head),stdout);
        head= "";
        printf(_(" Package %s: part(s) "), ti.package);
        bytes= 0;
        for (i=0; i<ti.maxpartn; i++) {
            for (qq= pq;
                    qq && !(partmatches(&qq->info,&ti) && qq->info.thispartn == i+1);
                    qq= qq->nextinqueue);
            if (qq) {
                printf("%d ",i+1);
                if (lstat(qq->info.filename,&stab))
                    ohshite(_("unable to stat `%.250s'"),qq->info.filename);
                if (!S_ISREG(stab.st_mode))
                    ohshit(_("part file `%.250s' is not a plain file"),qq->info.filename);
                bytes+= stab.st_size;

                /* Don't find this package again. */
                qq->info.md5sum = NULL;
            }
        }
        printf(_("(total %lu bytes)\n"),bytes);
    }
    m_output(stdout, _("<standard output>"));
}
Пример #8
0
static void
compress_gzip(int fd_in, int fd_out, struct compress_params *params, const char *desc)
{
	char buffer[DPKG_BUFFER_SIZE];
	char combuf[6];
	int strategy;
	int z_errnum;
	gzFile gzfile;

	if (params->strategy == COMPRESSOR_STRATEGY_FILTERED)
		strategy = 'f';
	else if (params->strategy == COMPRESSOR_STRATEGY_HUFFMAN)
		strategy = 'h';
	else if (params->strategy == COMPRESSOR_STRATEGY_RLE)
		strategy = 'R';
	else if (params->strategy == COMPRESSOR_STRATEGY_FIXED)
		strategy = 'F';
	else
		strategy = ' ';

	snprintf(combuf, sizeof(combuf), "w%d%c", params->level, strategy);
	gzfile = gzdopen(fd_out, combuf);
	if (gzfile == NULL)
		ohshit(_("%s: error binding output to gzip stream"), desc);

	for (;;) {
		int actualread, actualwrite;

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

		actualwrite = gzwrite(gzfile, buffer, actualread);
		if (actualwrite != actualread) {
			const char *errmsg = gzerror(gzfile, &z_errnum);

			if (z_errnum == Z_ERRNO)
				errmsg = strerror(errno);
			ohshit(_("%s: internal gzip write error: '%s'"), desc,
			       errmsg);
		}
	}

	z_errnum = gzclose(gzfile);
	if (z_errnum) {
		const char *errmsg;

		if (z_errnum == Z_ERRNO)
			errmsg = strerror(errno);
		else
			errmsg = zError(z_errnum);
		ohshit(_("%s: internal gzip write error: %s"), desc, errmsg);
	}
}
Пример #9
0
enum modstatdb_rw
modstatdb_open(enum modstatdb_rw readwritereq)
{
    modstatdb_init();

    cflags = readwritereq & msdbrw_available_mask;
    readwritereq &= ~msdbrw_available_mask;

    switch (readwritereq) {
    case msdbrw_needsuperuser:
    case msdbrw_needsuperuserlockonly:
        if (getuid() || geteuid())
            ohshit(_("requested operation requires superuser privilege"));
    /* Fall through. */
    case msdbrw_write:
    case msdbrw_writeifposs:
        if (access(dpkg_db_get_dir(), W_OK)) {
            if (errno != EACCES)
                ohshite(_("unable to access dpkg status area"));
            else if (readwritereq == msdbrw_write)
                ohshit(_("operation requires read/write access to dpkg status area"));
            cstatus= msdbrw_readonly;
        } else {
            modstatdb_lock();
            cstatus= (readwritereq == msdbrw_needsuperuserlockonly ?
                      msdbrw_needsuperuserlockonly :
                      msdbrw_write);
        }
        break;
    case msdbrw_readonly:
        cstatus= msdbrw_readonly;
        break;
    default:
        internerr("unknown modstatdb_rw '%d'", readwritereq);
    }

    dpkg_arch_load_list();

    if (cstatus != msdbrw_needsuperuserlockonly) {
        cleanupdates();
        if (cflags >= msdbrw_available_readonly)
            parsedb(availablefile, pdb_parse_available, NULL);
    }

    if (cstatus >= msdbrw_write) {
        createimptmp();
        varbuf_init(&uvb, 10240);
    }

    trig_fixup_awaiters(cstatus);
    trig_incorporate(cstatus);

    return cstatus;
}
Пример #10
0
void check_breaks(struct dependency *dep, struct pkginfo *pkg,
                  const char *pfilename) {
  struct pkginfo *fixbydeconf;
  struct varbuf why = VARBUF_INIT;
  int ok;

  fixbydeconf = NULL;
  if (depisok(dep, &why, &fixbydeconf, false)) {
    varbuf_destroy(&why);
    return;
  }

  varbufaddc(&why, 0);

  if (fixbydeconf && f_autodeconf) {
    char action[512];

    ensure_package_clientdata(fixbydeconf);
    assert(fixbydeconf->clientdata->istobe == itb_normal);

    sprintf(action, _("installation of %.250s"), pkg->name);
    fprintf(stderr, _("dpkg: considering deconfiguration of %s,"
                      " which would be broken by %s ...\n"),
            fixbydeconf->name, action);

    ok= try_deconfigure_can(force_breaks, fixbydeconf, dep->list,
                            action, NULL, why.buf);
    if (ok == 1) {
      fprintf(stderr, _("dpkg: yes, will deconfigure %s (broken by %s).\n"),
              fixbydeconf->name, pkg->name);
    }
  } else {
    fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
            pfilename, pkg->name, why.buf);
    ok= 0;
  }
  varbuf_destroy(&why);
  if (ok > 0) return;

  if (force_breaks(dep->list)) {
    warning(_("ignoring breakage, may proceed anyway!"));
    return;
  }

  if (fixbydeconf && !f_autodeconf) {
    ohshit(_("installing %.250s would break %.250s, and\n"
             " deconfiguration is not permitted (--auto-deconfigure might help)"),
           pkg->name, fixbydeconf->name);
  } else {
    ohshit(_("installing %.250s would break existing software"),
           pkg->name);
  }
}
Пример #11
0
void
trig_file_interests_ensure(void)
{
	FILE *f;
	char linebuf[1024], *space;
	struct pkginfo *pkg;
	struct pkgbin *pkgbin;

	if (filetriggers_edited >= 0)
		return;

	f = fopen(triggersfilefile, "r");
	if (!f) {
		if (errno == ENOENT)
			goto ok;
		ohshite(_("unable to read file triggers file '%.250s'"),
		        triggersfilefile);
	}

	push_cleanup(cu_closestream, ~0, 1, f);
	while (fgets_checked(linebuf, sizeof(linebuf), f, triggersfilefile) >= 0) {
		struct dpkg_error err;
		char *slash;
		enum trig_options trig_opts = TRIG_AWAIT;
		space = strchr(linebuf, ' ');
		if (!space || linebuf[0] != '/')
			ohshit(_("syntax error in file triggers file '%.250s'"),
			       triggersfilefile);
		*space++ = '\0';

		slash = strchr(space, '/');
		if (slash && strcmp("/noawait", slash) == 0) {
			trig_opts = TRIG_NOAWAIT;
			*slash = '\0';
		}
		if (slash && strcmp("/await", slash) == 0) {
			trig_opts = TRIG_AWAIT;
			*slash = '\0';
		}

		pkg = pkg_spec_parse_pkg(space, &err);
		if (pkg == NULL)
			ohshit(_("file triggers record mentions illegal "
			         "package name '%.250s' (for interest in file "
			         "'%.250s'): %.250s"), space, linebuf, err.str);
		pkgbin = &pkg->installed;

		trk_file_interest_change(linebuf, pkg, pkgbin, +2, trig_opts);
	}
	pop_cleanup(ehflag_normaltidy);
ok:
	filetriggers_edited = 0;
}
Пример #12
0
static char *nextline(char **ripp, const char *fn, const char *what) {
  char *newline, *rip;

  rip= *ripp;
  if (!rip) ohshit(_("file `%.250s' is corrupt - %.250s missing"),fn,what);
  newline= strchr(rip,'\n');
  if (!newline)
    ohshit(_("file `%.250s' is corrupt - missing newline after %.250s"),fn,what);
  *ripp= newline+1;
  while (newline > rip && isspace(newline[-1])) newline--;
  *newline = '\0';
  return rip;
}
Пример #13
0
static int ulist_select(const struct dirent *de) {
  const char *p;
  int l;
  for (p= de->d_name, l=0; *p; p++, l++)
    if (!cisdigit(*p)) return 0;
  if (l > IMPORTANTMAXLEN)
    ohshit(_("updates directory contains file `%.250s' whose name is too long "
           "(length=%d, max=%d)"), de->d_name, l, IMPORTANTMAXLEN);
  if (updateslength == -1) updateslength= l;
  else if (l != updateslength)
    ohshit(_("updates directory contains files with different length names "
           "(both %d and %d)"), l, updateslength);
  return 1;
}
Пример #14
0
static intmax_t
parse_intmax(const char *value, const char *fn, const char *what)
{
  intmax_t r;
  char *endp;

  errno = 0;
  r = strtoimax(value, &endp, 10);
  if (value == endp || *endp)
    ohshit(_("file `%.250s' is corrupt - bad digit (code %d) in %s"),fn,*endp,what);
  if (r < 0 || errno == ERANGE)
    ohshit(_("file '%s' is corrupt; out of range integer in %s"), fn, what);
  return r;
}
Пример #15
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);
}
Пример #16
0
void
trig_parse_ci(const char *file, trig_parse_cicb *interest,
              trig_parse_cicb *activate, struct pkginfo *pkg,
              struct pkgbin *pkgbin)
{
	FILE *f;
	char linebuf[MAXTRIGDIRECTIVE], *cmd, *spc, *eol;
	int l;

	f = fopen(file, "r");
	if (!f) {
		if (errno == ENOENT)
			return; /* No file is just like an empty one. */
		ohshite(_("unable to open triggers ci file '%.250s'"), file);
	}
	push_cleanup(cu_closestream, ~0, 1, f);

	while ((l = fgets_checked(linebuf, sizeof(linebuf), f, file)) >= 0) {
		for (cmd = linebuf; c_iswhite(*cmd); cmd++) ;
		if (*cmd == '#')
			continue;
		for (eol = linebuf + l; eol > cmd && c_iswhite(eol[-1]); eol--) ;
		if (eol == cmd)
			continue;
		*eol = '\0';

		for (spc = cmd; *spc && !c_iswhite(*spc); spc++) ;
		if (!*spc)
			ohshit(_("triggers ci file contains unknown directive syntax"));
		*spc++ = '\0';
		while (c_iswhite(*spc))
			spc++;
		if (strcmp(cmd, "interest") == 0 ||
		    strcmp(cmd, "interest-await") == 0) {
			parse_ci_call(file, cmd, interest, spc, pkg, pkgbin, TRIG_AWAIT);
		} else if (strcmp(cmd, "interest-noawait") == 0) {
			parse_ci_call(file, cmd, interest, spc, pkg, pkgbin, TRIG_NOAWAIT);
		} else if (strcmp(cmd, "activate") == 0 ||
		           strcmp(cmd, "activate-await") == 0) {
			parse_ci_call(file, cmd, activate, spc, pkg, pkgbin, TRIG_AWAIT);
		} else if (strcmp(cmd, "activate-noawait") == 0) {
			parse_ci_call(file, cmd, activate, spc, pkg, pkgbin, TRIG_NOAWAIT);
		} else {
			ohshit(_("triggers ci file contains unknown directive '%.250s'"),
			       cmd);
		}
	}
	pop_cleanup(ehflag_normaltidy); /* fclose() */
}
Пример #17
0
static bool
check_rename(struct file *src, struct file *dst)
{
	file_stat(src);

	/* If the source file is not present and we are not going to do
	 * the rename anyway there's no point in checking any further. */
	if (src->stat_state == FILE_STAT_NOFILE)
		return false;

	file_stat(dst);

	/*
	 * Unfortunately we have to check for write access in both places,
	 * just having +w is not enough, since people do mount things RO,
	 * and we need to fail before we start mucking around with things.
	 * So we open a file with the same name as the diversions but with
	 * an extension that (hopefully) won't overwrite anything. If it
	 * succeeds, we assume a writable filesystem.
	 */

	check_writable_dir(src);
	check_writable_dir(dst);

	if (src->stat_state == FILE_STAT_VALID &&
	    dst->stat_state == FILE_STAT_VALID &&
	    !(src->stat.st_dev == dst->stat.st_dev &&
	      src->stat.st_ino == dst->stat.st_ino))
		ohshit(_("rename involves overwriting '%s' with\n"
		         "  different file '%s', not allowed"),
		        dst->name, src->name);

	return true;
}
Пример #18
0
int maintainer_script_alternative(struct pkginfo *pkg,
                                  const char *scriptname, const char *desc,
                                  const char *cidir, char *cidirrest,
                                  const char *ifok, const char *iffallback) {
  struct command cmd;
  const char *oldscriptpath;
  struct stat stab;
  char buf[100];

  oldscriptpath = pkgadminfile(pkg, &pkg->installed, scriptname);
  sprintf(buf, _("old %s script"), desc);

  command_init(&cmd, oldscriptpath, buf);
  command_add_args(&cmd, scriptname, ifok,
                   versiondescribe(&pkg->available.version, vdew_nonambig),
                   NULL);

  if (stat(oldscriptpath,&stab)) {
    if (errno == ENOENT) {
      debug(dbg_scripts,"maintainer_script_alternative nonexistent %s `%s'",
            scriptname,oldscriptpath);
      command_destroy(&cmd);
      return 0;
    }
    warning(_("unable to stat %s '%.250s': %s"),
            cmd.name, oldscriptpath, strerror(errno));
  } else {
    if (!do_script(pkg, &pkg->installed, &cmd, &stab, PROCWARN)) {
      command_destroy(&cmd);
      post_script_tasks();
      return 1;
    }
  }
  fprintf(stderr, _("dpkg - trying script from the new package instead ...\n"));

  strcpy(cidirrest,scriptname);
  sprintf(buf, _("new %s script"), desc);

  command_destroy(&cmd);
  command_init(&cmd, cidir, buf);
  command_add_args(&cmd, scriptname, iffallback,
                   versiondescribe(&pkg->installed.version, vdew_nonambig),
                   NULL);

  if (stat(cidir,&stab)) {
    command_destroy(&cmd);
    if (errno == ENOENT)
      ohshit(_("there is no script in the new version of the package - giving up"));
    else
      ohshite(_("unable to stat %s `%.250s'"),buf,cidir);
  }

  do_script(pkg, &pkg->available, &cmd, &stab, 0);
  fprintf(stderr, _("dpkg: ... it looks like that went OK.\n"));

  command_destroy(&cmd);
  post_script_tasks();

  return 1;
}
Пример #19
0
static const char *
parse_awaiter_package(void)
{
	struct dpkg_error err = DPKG_ERROR_INIT;
	struct pkginfo *pkg;

	if (!f_await)
		bypackage = "-";

	if (bypackage == NULL) {
		const char *pkgname, *archname;

		pkgname = getenv("DPKG_MAINTSCRIPT_PACKAGE");
		archname = getenv("DPKG_MAINTSCRIPT_ARCH");
		if (pkgname == NULL || archname == NULL)
			ohshit(_("must be called from a maintainer script"
			         " (or with a --by-package option)"));

		pkg = pkg_spec_find_pkg(pkgname, archname, &err);
	} else if (strcmp(bypackage, "-") == 0) {
		pkg = NULL;
	} else {
		pkg = pkg_spec_parse_pkg(bypackage, &err);
	}

	/* Normalize the bypackage name if there was no error. */
	if (pkg)
		bypackage = pkg_name(pkg, pnaw_nonambig);

	return err.str;
}
Пример #20
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;
}
Пример #21
0
static void DPKG_ATTR_NORET read_fail(int rc, const char *filename, const char *what)
{
    if (rc >= 0)
        ohshit("unexpected end of file in %s in %.255s",what,filename);
    else
        ohshite("error reading %s from file %.255s", what, filename);
}
Пример #22
0
/**
 * Read a filename from the file descriptor and create a file_info struct.
 *
 * @return A file_info struct or NULL if there is nothing to read.
 */
static struct file_info *
file_info_get(const char *root, int fd)
{
  static struct varbuf fn = VARBUF_INIT;
  struct file_info *fi;
  size_t root_len;

  varbuf_reset(&fn);
  root_len = varbuf_printf(&fn, "%s/", root);

  while (1) {
    int res;

    varbuf_grow(&fn, 1);
    res = fd_read(fd, (fn.buf + fn.used), 1);
    if (res < 0)
      return NULL;
    if (res == 0) /* EOF -> parent died. */
      return NULL;
    if (fn.buf[fn.used] == '\0')
      break;

    varbuf_trunc(&fn, fn.used + 1);
    if (fn.used >= MAXFILENAME)
      ohshit(_("file name '%.50s...' is too long"), fn.buf + root_len);
  }

  fi = file_info_new(fn.buf + root_len);
  if (lstat(fn.buf, &(fi->st)) != 0)
    ohshite(_("unable to stat file name '%.250s'"), fn.buf);

  return fi;
}
Пример #23
0
static void
setcompresstype(const struct cmdinfo *cip, const char *value)
{
  compress_params.type = compressor_find_by_name(value);
  if (compress_params.type == compressor_type_unknown)
    ohshit(_("unknown compression type `%s'!"), value);
}
Пример #24
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;
}
Пример #25
0
bool
find_command(const char *prog)
{
  struct varbuf filename = VARBUF_INIT;
  struct stat stab;
  const char *path_list;
  const char *path, *path_end;
  size_t path_len;

  path_list = getenv("PATH");
  if (!path_list)
    ohshit(_("PATH is not set"));

  for (path = path_list; path; path = path_end ? path_end + 1 : NULL) {
    path_end = strchr(path, ':');
    path_len = path_end ? (size_t)(path_end - path) : strlen(path);

    varbuf_reset(&filename);
    varbuf_add_buf(&filename, path, path_len);
    if (path_len)
      varbuf_add_char(&filename, '/');
    varbuf_add_str(&filename, prog);
    varbuf_end_str(&filename);

    if (stat(filename.buf, &stab) == 0 && (stab.st_mode & 0111)) {
      varbuf_destroy(&filename);
      return true;
    }
  }

  varbuf_destroy(&filename);
  return false;
}
Пример #26
0
static void info_spew(const char *debar, const char *directory,
                      const char *const *argv) {
  const char *component;
  struct varbuf controlfile = VARBUF_INIT;
  int fd;
  int re= 0;

  while ((component = *argv++) != NULL) {
    varbufreset(&controlfile);
    varbufaddstr(&controlfile, directory);
    varbufaddc(&controlfile, '/');
    varbufaddstr(&controlfile, component);
    varbufaddc(&controlfile, '\0');

    fd = open(controlfile.buf, O_RDONLY);
    if (fd >= 0) {
      fd_fd_copy(fd, 1, -1, _("control file '%s'"), controlfile.buf);
      close(fd);
    } else if (errno == ENOENT) {
      fprintf(stderr,
              _("dpkg-deb: `%.255s' contains no control component `%.255s'\n"),
              debar, component);
      re++;
    } else {
      ohshite(_("open component `%.255s' (in %.255s) failed in an unexpected way"),
	      component, directory);
    }
  }
  varbuf_destroy(&controlfile);

  if (re > 0)
    ohshit(P_("%d requested control component is missing",
              "%d requested control components are missing", re), re);
}
Пример #27
0
static void
trk_explicit_activate_awaiter(struct pkginfo *aw)
{
	char buf[1024];
	const char *emsg;
	struct pkginfo *pend;

	if (!trk_explicit_f)
		return;

	if (fseek(trk_explicit_f, 0, SEEK_SET))
		ohshite(_("failed to rewind trigger interest file `%.250s'"),
		        trk_explicit_fn.buf);

	while (trk_explicit_fgets(buf, sizeof(buf)) >= 0) {
		char *slash;
		bool noawait = false;
		slash = strchr(buf, '/');
		if (slash && strcmp("/noawait", slash) == 0) {
			noawait = true;
			*slash = '\0';
		}
		emsg = pkg_name_is_illegal(buf, NULL);
		if (emsg)
			ohshit(_("trigger interest file `%.250s' syntax error; "
			         "illegal package name `%.250s': %.250s"),
			       trk_explicit_fn.buf, buf, emsg);
		pend = pkg_db_find(buf);
		trig_record_activation(pend, noawait ? NULL : aw,
		                       trk_explicit_trig);
	}
}
Пример #28
0
static void readfail(FILE *a, const char *filename, const char *what) {
  if (ferror(a)) {
    ohshite(_("error reading %s from file %.255s"), what, filename);
  } else {
    ohshit(_("unexpected end of file in %s in %.255s"),what,filename);
  }
}
Пример #29
0
/**
 * Lock a file.
 *
 * @param lockfd The pointer to the lock file descriptor. It must be allocated
 *        statically as its addresses is passed to a cleanup handler.
 * @param flags The lock flags specifying what type of locking to perform.
 * @param filename The name of the file to lock.
 * @param desc The description of the file to lock.
 */
void
file_lock(int *lockfd, enum file_lock_flags flags, const char *filename,
          const char *desc)
{
	struct flock fl;
	int lock_cmd;

	setcloexec(*lockfd, filename);

	file_lock_setup(&fl, F_WRLCK);

	if (flags == FILE_LOCK_WAIT)
		lock_cmd = F_SETLKW;
	else
		lock_cmd = F_SETLK;

	if (fcntl(*lockfd, lock_cmd, &fl) == -1) {
		if (errno == EACCES || errno == EAGAIN)
			ohshit(_("%s is locked by another process"), desc);
		else
			ohshite(_("unable to lock %s"), desc);
	}

	push_cleanup(file_unlock_cleanup, ~0, NULL, 0, 2, lockfd, desc);
}
Пример #30
0
static void
deb_verify(const char *filename)
{
  struct stat stab;
  pid_t pid;

  if (stat(DEBSIGVERIFY, &stab) < 0)
    return;

  printf(_("Authenticating %s ...\n"), filename);
  fflush(stdout);
  pid = subproc_fork();
  if (!pid) {
    execl(DEBSIGVERIFY, DEBSIGVERIFY, "-q", filename, NULL);
    ohshite(_("unable to execute %s (%s)"),
            _("package signature verification"), DEBSIGVERIFY);
  } else {
    int status;

    status = subproc_wait(pid, "debsig-verify");
    if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) {
      if (!fc_badverify)
        ohshit(_("Verification on package %s failed!"), filename);
      else
        fprintf(stderr, _("Verification on package %s failed,\n"
                          "but installing anyway as you requested.\n"),
                filename);
    } else {
      printf(_("passed\n"));
    }
  }
}