244
newtarobject_utime(const char *path, struct tar_entry *ti)
234
tarobject_set_mtime(struct tar_entry *te, const char *path)
247
utb.actime= currenttime;
248
utb.modtime = ti->mtime;
249
if (utime(path,&utb))
250
ohshite(_("error setting timestamps of `%.255s'"), ti->name);
236
struct timeval tv[2];
238
tv[0].tv_sec = currenttime;
240
tv[1].tv_sec = te->mtime;
243
if (te->type == tar_filetype_symlink) {
245
if (lutimes(path, tv))
246
ohshite(_("error setting timestamps of `%.255s'"), path);
249
if (utimes(path, tv))
250
ohshite(_("error setting timestamps of `%.255s'"), path);
254
newtarobject_allmodes(const char *path, struct tar_entry *ti,
255
struct filestatoverride *statoverride)
255
tarobject_set_perms(struct tar_entry *te, const char *path, struct file_stat *st)
258
statoverride ? statoverride->uid : ti->uid,
259
statoverride ? statoverride->gid : ti->gid))
260
ohshite(_("error setting ownership of `%.255s'"), ti->name);
261
if (chmod(path,(statoverride ? statoverride->mode : ti->mode) & ~S_IFMT))
262
ohshite(_("error setting permissions of `%.255s'"), ti->name);
263
newtarobject_utime(path,ti);
257
if (te->type == tar_filetype_file)
258
return; /* Already handled using the file descriptor. */
260
if (te->type == tar_filetype_symlink) {
261
if (lchown(path, st->uid, st->gid))
262
ohshite(_("error setting ownership of symlink `%.255s'"), path);
264
if (chown(path, st->uid, st->gid))
265
ohshite(_("error setting ownership of `%.255s'"), path);
266
if (chmod(path, st->mode & ~S_IFMT))
267
ohshite(_("error setting permissions of `%.255s'"), path);
305
310
void setupfnamevbs(const char *filename) {
306
311
varbuf_trunc(&fnamevb, fnameidlu);
307
varbufaddstr(&fnamevb,filename);
308
varbufaddc(&fnamevb,0);
312
varbuf_add_str(&fnamevb, filename);
313
varbuf_end_str(&fnamevb);
310
315
varbuf_trunc(&fnametmpvb, fnameidlu);
311
varbufaddstr(&fnametmpvb,filename);
312
varbufaddstr(&fnametmpvb,DPKGTEMPEXT);
313
varbufaddc(&fnametmpvb,0);
316
varbuf_add_str(&fnametmpvb, filename);
317
varbuf_add_str(&fnametmpvb, DPKGTEMPEXT);
318
varbuf_end_str(&fnametmpvb);
315
320
varbuf_trunc(&fnamenewvb, fnameidlu);
316
varbufaddstr(&fnamenewvb,filename);
317
varbufaddstr(&fnamenewvb,DPKGNEWEXT);
318
varbufaddc(&fnamenewvb,0);
321
varbuf_add_str(&fnamenewvb, filename);
322
varbuf_add_str(&fnamenewvb, DPKGNEWEXT);
323
varbuf_end_str(&fnamenewvb);
320
325
debug(dbg_eachfiledetail, "setupvnamevbs main=`%s' tmp=`%s' new=`%s'",
321
326
fnamevb.buf, fnametmpvb.buf, fnamenewvb.buf);
324
int unlinkorrmdir(const char *filename) {
325
/* Returns 0 on success or -1 on failure, just like unlink & rmdir */
330
* Securely remove a pathname.
332
* This is a secure version of remove(3) using secure_unlink() instead of
335
* @retval 0 On success.
336
* @retval -1 On failure, just like unlink(2) & rmdir(2).
339
secure_remove(const char *filename)
328
343
if (!rmdir(filename)) {
329
debug(dbg_eachfiledetail,"unlinkorrmdir `%s' rmdir OK",filename);
344
debug(dbg_eachfiledetail, "secure_remove '%s' rmdir OK", filename);
333
348
if (errno != ENOTDIR) {
335
debug(dbg_eachfiledetail,"unlinkorrmdir `%s' rmdir %s",filename,strerror(e));
350
debug(dbg_eachfiledetail, "secure_remove '%s' rmdir %s", filename,
336
352
errno= e; return -1;
339
355
r = secure_unlink(filename);
341
debug(dbg_eachfiledetail,"unlinkorrmdir `%s' unlink %s",
357
debug(dbg_eachfiledetail, "secure_remove '%s' unlink %s",
342
358
filename, r ? strerror(e) : "OK");
343
359
errno= e; return r;
696
712
r = ti->size % TARBLKSZ;
698
if (safe_read(tc->backendpipe, databuf, TARBLKSZ - r) == -1)
714
if (fd_read(tc->backendpipe, databuf, TARBLKSZ - r) < 0)
699
715
ohshite(_("error reading from dpkg-deb pipe"));
701
717
fd_writeback_init(fd);
703
if (nifd->namenode->statoverride)
719
if (nifd->namenode->statoverride)
704
720
debug(dbg_eachfile, "tarobject ... stat override, uid=%d, gid=%d, mode=%04o",
705
721
nifd->namenode->statoverride->uid,
706
722
nifd->namenode->statoverride->gid,
707
723
nifd->namenode->statoverride->mode);
709
nifd->namenode->statoverride ?
710
nifd->namenode->statoverride->uid : ti->uid,
711
nifd->namenode->statoverride ?
712
nifd->namenode->statoverride->gid : ti->gid))
724
if (fchown(fd, st->uid, st->gid))
713
725
ohshite(_("error setting ownership of `%.255s'"), ti->name);
714
am = (nifd->namenode->statoverride ?
715
nifd->namenode->statoverride->mode : ti->mode) & ~S_IFMT;
726
if (fchmod(fd, st->mode & ~S_IFMT))
717
727
ohshite(_("error setting permissions of `%.255s'"), ti->name);
719
729
/* Postpone the fsync, to try to avoid massive I/O degradation. */
720
730
if (!fc_unsafe_io)
721
731
nifd->namenode->flags |= fnnf_deferred_fsync;
723
pop_cleanup(ehflag_normaltidy); /* fd= open(fnamenewvb.buf) */
733
pop_cleanup(ehflag_normaltidy); /* fd = open(fnamenewvb.buf) */
725
735
ohshite(_("error closing/writing `%.255s'"), ti->name);
726
newtarobject_utime(fnamenewvb.buf,ti);
728
737
case tar_filetype_fifo:
729
738
if (mkfifo(fnamenewvb.buf,0))
730
739
ohshite(_("error creating pipe `%.255s'"), ti->name);
731
740
debug(dbg_eachfiledetail, "tarobject fifo");
732
newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
734
742
case tar_filetype_chardev:
735
743
if (mknod(fnamenewvb.buf, S_IFCHR, ti->dev))
736
744
ohshite(_("error creating device `%.255s'"), ti->name);
737
745
debug(dbg_eachfiledetail, "tarobject chardev");
738
newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
740
747
case tar_filetype_blockdev:
741
748
if (mknod(fnamenewvb.buf, S_IFBLK, ti->dev))
742
749
ohshite(_("error creating device `%.255s'"), ti->name);
743
750
debug(dbg_eachfiledetail, "tarobject blockdev");
744
newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
746
752
case tar_filetype_hardlink:
747
varbufreset(&hardlinkfn);
748
varbufaddstr(&hardlinkfn,instdir); varbufaddc(&hardlinkfn,'/');
749
varbufaddstr(&hardlinkfn, ti->linkname);
753
varbuf_reset(&hardlinkfn);
754
varbuf_add_str(&hardlinkfn, instdir);
755
varbuf_add_char(&hardlinkfn, '/');
756
varbuf_add_str(&hardlinkfn, ti->linkname);
750
757
linknode = findnamenode(ti->linkname, 0);
751
758
if (linknode->flags & fnnf_deferred_rename)
752
varbufaddstr(&hardlinkfn, DPKGNEWEXT);
753
varbufaddc(&hardlinkfn, '\0');
759
varbuf_add_str(&hardlinkfn, DPKGNEWEXT);
760
varbuf_end_str(&hardlinkfn);
754
761
if (link(hardlinkfn.buf,fnamenewvb.buf))
755
762
ohshite(_("error creating hard link `%.255s'"), ti->name);
756
763
debug(dbg_eachfiledetail, "tarobject hardlink");
757
newtarobject_allmodes(fnamenewvb.buf,ti, nifd->namenode->statoverride);
759
765
case tar_filetype_symlink:
760
/* We've already cheched for an existing directory. */
766
/* We've already checked for an existing directory. */
761
767
if (symlink(ti->linkname, fnamenewvb.buf))
762
768
ohshite(_("error creating symbolic link `%.255s'"), ti->name);
763
769
debug(dbg_eachfiledetail, "tarobject symlink creating");
764
if (lchown(fnamenewvb.buf,
765
nifd->namenode->statoverride ?
766
nifd->namenode->statoverride->uid : ti->uid,
767
nifd->namenode->statoverride ?
768
nifd->namenode->statoverride->gid : ti->gid))
769
ohshite(_("error setting ownership of symlink `%.255s'"), ti->name);
771
771
case tar_filetype_dir:
772
772
/* We've already checked for an existing directory. */
773
773
if (mkdir(fnamenewvb.buf,0))
774
774
ohshite(_("error creating directory `%.255s'"), ti->name);
775
775
debug(dbg_eachfiledetail, "tarobject directory creating");
776
newtarobject_allmodes(fnamenewvb.buf,ti,nifd->namenode->statoverride);
779
778
internerr("unknown tar type '%d', but already checked", ti->type);
782
set_selinux_path_context(fnamevb.buf, fnamenewvb.buf, ti->mode);
781
tarobject_set_perms(ti, fnamenewvb.buf, st);
782
tarobject_set_mtime(ti, fnamenewvb.buf);
783
set_selinux_path_context(fnamevb.buf, fnamenewvb.buf, st->mode);
784
/* CLEANUP: Now we have extracted the new object in .dpkg-new (or,
785
* if the file already exists as a directory and we were trying to extract
786
* a directory or symlink, we returned earlier, so we don't need
787
* to worry about that here).
786
* CLEANUP: Now we have extracted the new object in .dpkg-new (or,
787
* if the file already exists as a directory and we were trying to
788
* extract a directory or symlink, we returned earlier, so we don't
789
* need to worry about that here).
789
791
* The old file is still in the original filename,
792
/* First, check to see if it's a conffile. If so we don't install
793
* it now - we leave it in .dpkg-new for --configure to take care of
794
/* First, check to see if it's a conffile. If so we don't install
795
* it now - we leave it in .dpkg-new for --configure to take care of. */
795
796
if (nifd->namenode->flags & fnnf_new_conff) {
796
797
debug(dbg_conffdetail,"tarobject conffile extracted");
797
798
nifd->namenode->flags |= fnnf_elide_other_lists;
965
* Try if we can deconfigure the package and queue it if so.
967
* Also checks whether the pdep is forced, first, according to force_p.
968
* force_p may be NULL in which case nothing is considered forced.
970
* Action is a string describing the action which causes the
973
* "removal of <package>" (due to Conflicts+Depends; removal != NULL)
974
* "installation of <package>" (due to Breaks; removal == NULL)
976
* @retval 0 Not possible (why is printed).
977
* @retval 1 Deconfiguration queued ok (no message printed).
978
* @retval 2 Forced (no deconfiguration needed, why is printed).
964
981
try_deconfigure_can(bool (*force_p)(struct deppossi *), struct pkginfo *pkg,
965
982
struct deppossi *pdep, const char *action,
966
983
struct pkginfo *removal, const char *why)
968
/* Also checks whether the pdep is forced, first, according to force_p.
969
* force_p may be 0 in which case nothing is considered forced.
971
* Action is a string describing the action which causes the
973
* removal of <package> (due to Conflicts+Depends removal!=0)
974
* installation of <package> (due to Breaks removal==0)
976
* Return values: 2: forced (no deconfiguration needed, why is printed)
977
* 1: deconfiguration queued ok (no message printed)
978
* 0: not possible (why is printed)
980
985
struct pkg_deconf_list *newdeconf;
982
987
if (force_p && force_p(pdep)) {
983
988
warning(_("ignoring dependency problem with %s:\n%s"), action, why);
1158
if (cflict_index >= MAXCONFLICTORS)
1159
ohshit(_("package %s has too many Conflicts/Replaces pairs"),
1162
1163
/* This conflict is OK - we'll remove the conflictor. */
1163
conflictor[cflict_index++]= fixbyrm;
1164
push_conflictor(pkg, fixbyrm);
1164
1165
varbuf_destroy(&conflictwhy); varbuf_destroy(&removalwhy);
1165
1166
fprintf(stderr, _("dpkg: yes, will remove %s in favour of %s.\n"),
1166
1167
fixbyrm->name, pkg->name);
1169
fixbyrm->clientdata->istobe= itb_normal; /* put it back */
1171
fixbyrm->clientdata->istobe = itb_normal;
1172
varbufaddc(&conflictwhy,0);
1174
varbuf_end_str(&conflictwhy);
1173
1175
fprintf(stderr, _("dpkg: regarding %s containing %s:\n%s"),
1174
1176
pfilename, pkg->name, conflictwhy.buf);
1175
1177
if (!force_conflicts(dep->list))
1176
1178
ohshit(_("conflicting packages - not installing %.250s"),pkg->name);
1177
1179
warning(_("ignoring conflict, may proceed anyway!"));
1178
1180
varbuf_destroy(&conflictwhy);
1185
1187
char *cidirrest= (char*)argv[1];
1186
1188
cidirrest[-1] = '\0';
1187
1189
ensure_pathname_nonexisting(cidir);
1190
1192
void cu_fileslist(int argc, void **argv) {
1191
1193
destroyobstack();
1194
void archivefiles(const char *const *argv) {
1197
archivefiles(const char *const *argv)
1195
1199
const char *volatile thisarg;
1196
1200
const char *const *volatile argp;
1198
int pi[2], fc, nfiles, c, i, r;
1200
static struct varbuf findoutput;
1201
const char **arglist;
1204
1203
trigproc_install_hooks();
1206
modstatdb_init(admindir,
1207
f_noact ? msdbrw_readonly
1208
: cipaction->arg == act_avail ? msdbrw_write
1209
: fc_nonroot ? msdbrw_write
1210
: msdbrw_needsuperuser);
1205
modstatdb_open(f_noact ? msdbrw_readonly :
1206
(cipaction->arg_int == act_avail ? msdbrw_readonly :
1207
fc_nonroot ? msdbrw_write :
1208
msdbrw_needsuperuser) |
1209
msdbrw_available_write);
1213
1212
log_message("startup archives %s", cipaction->olong);
1215
1214
if (f_recursive) {
1215
int pi[2], nfiles, c, i, r;
1218
static struct varbuf findoutput;
1219
const char **arglist;
1218
1223
badusage(_("--%s --recursive needs at least one path argument"),cipaction->olong);
1221
fc = subproc_fork();
1226
pid = subproc_fork();
1223
1228
struct command cmd;
1224
1229
const char *const *ap;
1250
1254
pf= fdopen(pi[0],"r"); if (!pf) ohshite(_("failed to fdopen find's pipe"));
1251
varbufreset(&findoutput);
1255
varbuf_reset(&findoutput);
1252
1256
while ((c= fgetc(pf)) != EOF) {
1253
varbufaddc(&findoutput,c);
1257
varbuf_add_char(&findoutput, c);
1254
1258
if (!c) nfiles++;
1256
1260
if (ferror(pf)) ohshite(_("error reading find's pipe"));
1257
1261
if (fclose(pf)) ohshite(_("error closing find's pipe"));
1258
r = subproc_wait_check(fc, "find", PROCNOERR);
1262
r = subproc_wait_check(pid, "find", PROCNOERR);
1260
1264
ohshit(_("find for --recursive returned unhandled error %i"),r);
1263
1267
ohshit(_("searched, but found no packages (files matching *.deb)"));
1265
varbufaddc(&findoutput,0);
1266
varbufaddc(&findoutput,0);
1268
1269
arglist= m_malloc(sizeof(char*)*(nfiles+1));
1269
p= findoutput.buf; i=0;
1271
for (i = 0; i < nfiles; i++) {
1271
1272
arglist[i++]= p;
1272
1273
while (*p++ != '\0') ;
1274
1275
arglist[i] = NULL;
1279
1278
if (!*argv) badusage(_("--%s needs at least one package archive file argument"),
1280
1279
cipaction->olong);
1285
1283
currenttime = time(NULL);
1287
1285
/* Initialize fname variables contents. */
1289
varbufreset(&fnamevb);
1290
varbufreset(&fnametmpvb);
1291
varbufreset(&fnamenewvb);
1287
varbuf_reset(&fnamevb);
1288
varbuf_reset(&fnametmpvb);
1289
varbuf_reset(&fnamenewvb);
1293
varbufaddstr(&fnamevb,instdir); varbufaddc(&fnamevb,'/');
1294
varbufaddstr(&fnametmpvb,instdir); varbufaddc(&fnametmpvb,'/');
1295
varbufaddstr(&fnamenewvb,instdir); varbufaddc(&fnamenewvb,'/');
1291
varbuf_add_str(&fnamevb, instdir);
1292
varbuf_add_char(&fnamevb, '/');
1293
varbuf_add_str(&fnametmpvb, instdir);
1294
varbuf_add_char(&fnametmpvb, '/');
1295
varbuf_add_str(&fnamenewvb, instdir);
1296
varbuf_add_char(&fnamenewvb, '/');
1296
1297
fnameidlu= fnamevb.used;
1298
1299
ensure_diversions();
1299
1300
ensure_statoverrides();
1301
1302
while ((thisarg = *argp++) != NULL) {
1302
1303
if (setjmp(ejbuf)) {
1303
error_unwind(ehflag_bombout);
1304
pop_error_context(ehflag_bombout);
1304
1305
if (abort_processing)
1308
push_error_handler(&ejbuf,print_error_perpackage,thisarg);
1309
push_error_context_jump(&ejbuf, print_error_perpackage, thisarg);
1309
1311
process_archive(thisarg);
1311
1313
m_output(stdout, _("<standard output>"));
1312
1314
m_output(stderr, _("<standard error>"));
1314
set_error_display(NULL, NULL);
1315
error_unwind(ehflag_normaltidy);
1317
pop_error_context(ehflag_normaltidy);
1318
switch (cipaction->arg) {
1320
switch (cipaction->arg_int) {
1319
1321
case act_install:
1320
1322
case act_configure:
1321
1323
case act_triggers:
1326
1328
case act_avail:
1329
internerr("unknown action '%d'", cipaction->arg);
1331
internerr("unknown action '%d'", cipaction->arg_int);
1332
1334
trigproc_run_deferred();
1333
1335
modstatdb_shutdown();
1337
wanttoinstall(struct pkginfo *pkg, const struct versionrevision *ver,
1341
* Decide whether we want to install a new version of the package.
1343
* @param pkg The package with the version we might want to install
1345
* @retval true If the package should be skipped.
1346
* @retval false If the package should be installed.
1349
wanttoinstall(struct pkginfo *pkg)
1340
/* Decide whether we want to install a new version of the package.
1341
* ver is the version we might want to install. If saywhy is 1 then
1342
* if we skip the package we say what we are doing (and, if we are
1343
* selecting a previously deselected package, say so and actually do
1344
* the select). want_install returns 0 if the package should be
1345
* skipped and 1 if it should be installed.
1347
* ver may be 0, in which case saywhy must be 0 and want_install may
1348
* also return -1 to mean it doesn't know because it would depend on
1349
* the version number.
1353
1353
if (pkg->want != want_install && pkg->want != want_hold) {
1354
1354
if (f_alsoselect) {
1356
printf(_("Selecting previously deselected package %s.\n"),pkg->name);
1357
pkg->want= want_install;
1355
printf(_("Selecting previously deselected package %s.\n"), pkg->name);
1356
pkg->want = want_install;
1361
if (saywhy) printf(_("Skipping deselected package %s.\n"),pkg->name);
1359
printf(_("Skipping deselected package %s.\n"), pkg->name);
1366
if (!(pkg->status == stat_installed ||
1367
pkg->status == stat_triggersawaited ||
1368
pkg->status == stat_triggerspending))
1370
if (!ver) return -1;
1364
if (pkg->eflag & eflag_reinstreq)
1366
if (pkg->status < stat_unpacked)
1372
r= versioncompare(ver,&pkg->installed.version);
1369
r = versioncompare(&pkg->available.version, &pkg->installed.version);
1375
1372
} else if (r == 0) {
1376
1373
/* Same version fully installed. */
1377
1374
if (f_skipsame) {
1378
if (saywhy) fprintf(stderr, _("Version %.250s of %.250s already installed, "
1380
versiondescribe(&pkg->installed.version, vdew_nonambig),
1375
fprintf(stderr, _("Version %.250s of %.250s already installed, "
1377
versiondescribe(&pkg->installed.version, vdew_nonambig),
1387
1384
if (fc_downgrade) {
1389
warning(_("downgrading %.250s from %.250s to %.250s."), pkg->name,
1390
versiondescribe(&pkg->installed.version, vdew_nonambig),
1391
versiondescribe(&pkg->available.version, vdew_nonambig));
1385
warning(_("downgrading %.250s from %.250s to %.250s."), pkg->name,
1386
versiondescribe(&pkg->installed.version, vdew_nonambig),
1387
versiondescribe(&pkg->available.version, vdew_nonambig));
1394
if (saywhy) fprintf(stderr, _("Will not downgrade %.250s from version %.250s "
1395
"to %.250s, skipping.\n"), pkg->name,
1396
versiondescribe(&pkg->installed.version, vdew_nonambig),
1397
versiondescribe(&pkg->available.version, vdew_nonambig));
1390
fprintf(stderr, _("Will not downgrade %.250s from version %.250s "
1391
"to %.250s, skipping.\n"), pkg->name,
1392
versiondescribe(&pkg->installed.version, vdew_nonambig),
1393
versiondescribe(&pkg->available.version, vdew_nonambig));