summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorScott James Remnant <scott@netsplit.com>2005-03-18 16:21:32 +0000
committerScott James Remnant <scott@netsplit.com>2005-03-18 16:21:32 +0000
commit00e5640a99be03aba40c9e08a663b90d8f8aa797 (patch)
treef2b69382011851aa321df38f8669220675c34617 /src
parent841a630143cd3a35dbf8bce0a111ebd39dd12f44 (diff)
downloaddpkg-00e5640a99be03aba40c9e08a663b90d8f8aa797.tar.gz
dpkg (1.13.2) experimental; urgency=low
* md5sum has been removed, the coreutils or textutils version will be diverted to /usr/bin/md5sum. Closes: #6633, #136110. The following bugs are filed against the dpkg md5sum, so no longer apply. Closes: #95755, #193877, #223381, #264195, #270241, #286632, * Take Replaces into account when installing packages; don't issue a "trying to overwrite" error if the file that already exists is in a package that Replaces the one being installed. Closes: #164595, #184635, #277890. * Allow actions and status changes to be logged to a file. Disabled by default, uncomment line in /etc/dpkg/dpkg.cfg to enable. Closes: #957, #53376, #77109, #143882, #284499. * Don't truncate output of 'dpkg -l' when stdout is not a tty. Closes: #92263, #253860, #258608, #261822, #282790. * Fix further compilation problems with gcc 4.0. Closes: #299699 * Handle tar files without trailing slash in directory names. Closes: #287152. * Output arguments to maintainer scripts with -D2. Closes: #237684, #296030. * Architecture Support: - Added ppc64. Closes: #263743. - Split archtable into cputable and ostable, archtable is retained for compatibility with other packages that might use it only. - dpkg-architecture no longer canonises -t argument. Closes: #173205. - dpkg-architecture output includes new DEB_*_ARCH_OS and DEB_*_ARCH_CPU variables that contain the Debian system and CPU names respectively. - dpkg-architecture outputs (mostly) correct GNU system names now, in particular this means that it will output "linux-gnu" instead of "linux". You should use the new _ARCH_OS variables instead. * Documentation: - Add examples to dpkg-divert(8). Closes: #291816. - Correct typo in dpkg-architecture(1). Closes: #299090. -- Scott James Remnant <scott@netsplit.com> Fri, 18 Mar 2005 16:21:32 +0000
Diffstat (limited to 'src')
-rw-r--r--src/archives.c35
-rw-r--r--src/help.c27
-rw-r--r--src/main.c21
-rw-r--r--src/main.h1
-rw-r--r--src/processarc.c7
-rw-r--r--src/query.c50
-rw-r--r--src/remove.c2
7 files changed, 122 insertions, 21 deletions
diff --git a/src/archives.c b/src/archives.c
index 76d61edc3..d57f69322 100644
--- a/src/archives.c
+++ b/src/archives.c
@@ -314,11 +314,11 @@ int tarobject(struct TarInfo *ti) {
const char *usename;
struct tarcontext *tc= (struct tarcontext*)ti->UserData;
- int statr, fd, i, existingdirectory;
+ int statr, fd, i, existingdirectory, keepexisting;
size_t r;
struct stat stab, stabd;
char databuf[TARBLKSZ];
- struct fileinlist *nifd;
+ struct fileinlist *nifd, **oldnifd;
struct pkginfo *divpkg, *otherpkg;
struct filepackages *packageslump;
mode_t am;
@@ -329,6 +329,7 @@ int tarobject(struct TarInfo *ti) {
* The trailing / put on the end of names in tarfiles has already
* been stripped by TarExtractor (lib/tarfn.c).
*/
+ oldnifd= tc->newfilesp;
nifd= obstack_alloc(&tar_obs, sizeof(struct fileinlist));
nifd->namenode= findnamenode(ti->Name, 0);
nifd->next= 0; *tc->newfilesp= nifd; tc->newfilesp= &nifd->next;
@@ -423,6 +424,7 @@ int tarobject(struct TarInfo *ti) {
ohshit(_("archive contained object `%.255s' of unknown type 0x%x"),ti->Name,ti->Type);
}
+ keepexisting= 0;
if (!existingdirectory) {
for (packageslump= nifd->namenode->packages;
packageslump;
@@ -442,7 +444,12 @@ int tarobject(struct TarInfo *ti) {
if (otherpkg == divpkg || tc->pkg == divpkg) continue;
}
/* Nope ? Hmm, file conflict, perhaps. Check Replaces. */
- if (otherpkg->clientdata->replacingfilesandsaid) continue;
+ switch (otherpkg->clientdata->replacingfilesandsaid) {
+ case 2:
+ keepexisting= 1;
+ case 1:
+ continue;
+ }
/* Is the package with the conflicting file in the `config files
* only' state ? If so it must be a config file and we can
* silenty take it over.
@@ -453,6 +460,11 @@ int tarobject(struct TarInfo *ti) {
if (does_replace(tc->pkg,&tc->pkg->available,otherpkg)) {
printf(_("Replacing files in old package %s ...\n"),otherpkg->name);
otherpkg->clientdata->replacingfilesandsaid= 1;
+ } else if (does_replace(otherpkg,&otherpkg->installed,tc->pkg)) {
+ printf(_("Replaced by files in installed package %s ...\n"),
+ otherpkg->name);
+ otherpkg->clientdata->replacingfilesandsaid= 2;
+ keepexisting = 1;
} else {
if (!statr && S_ISDIR(stab.st_mode)) {
forcibleerr(fc_overwritedir, _("trying to overwrite directory `%.250s' "
@@ -480,6 +492,23 @@ int tarobject(struct TarInfo *ti) {
ensure_pathname_nonexisting(fnametmpvb.buf);
if (existingdirectory) return 0;
+ if (keepexisting) {
+ obstack_free(&tar_obs, nifd);
+ tc->newfilesp= oldnifd;
+ *oldnifd = 0;
+
+ /* We need to advance the tar file to the next object, so read the
+ * file data and set it to oblivion.
+ */
+ if ((ti->Type == NormalFile0) || (ti->Type == NormalFile1)) {
+ char fnamebuf[256];
+ fd_null_copy(tc->backendpipe, ti->Size, _("gobble replaced file `%.255s'"),quote_filename(fnamebuf,256,ti->Name));
+ r= ti->Size % TARBLKSZ;
+ if (r > 0) r= safe_read(tc->backendpipe,databuf,TARBLKSZ - r);
+ }
+
+ return 0;
+ }
/* Now we start to do things that we need to be able to undo
* if something goes wrong.
diff --git a/src/help.c b/src/help.c
index 8a4746208..6190ae613 100644
--- a/src/help.c
+++ b/src/help.c
@@ -29,6 +29,7 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
+#include <time.h>
#include <dpkg.h>
#include <dpkg-db.h>
@@ -179,7 +180,7 @@ static const char* preexecscript(const char *path, char *const *argv) {
}
if (f_debug & dbg_scripts) {
fprintf(stderr,"D0%05o: fork/exec %s (",dbg_scripts,path);
- while (*argv) fprintf(stderr," %s",*argv++);
+ while (*++argv) fprintf(stderr," %s",*argv);
fputs(" )\n",stderr);
}
instdirl= strlen(instdir);
@@ -478,3 +479,27 @@ void ensure_pathname_nonexisting(const char *pathname) {
debug(dbg_eachfile,"ensure_pathname_nonexisting running rm -rf");
waitsubproc(c1,"rm cleanup",0);
}
+
+void log_action(const char *action, struct pkginfo *pkg) {
+ if (log_pipes) {
+ static struct varbuf *log= NULL;
+ struct pipef *pipef= log_pipes;
+ char time_str[20];
+ time_t now;
+ int r;
+ if (log == NULL) {
+ log = nfmalloc(sizeof(struct varbuf));
+ varbufinit(log);
+ } else
+ varbufreset(log);
+ time(&now);
+ strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", gmtime(&now));
+ r= varbufprintf(log, "%s %s %s %s %s\n", time_str, action,
+ pkg->name, versiondescribe(&pkg->installed.version, vdew_nonambig),
+ versiondescribe(&pkg->available.version, vdew_nonambig));
+ while (pipef) {
+ write(pipef->fd, log->buf, r);
+ pipef= pipef->next;
+ }
+ }
+}
diff --git a/src/main.c b/src/main.c
index 955fc4b89..a999d3bdb 100644
--- a/src/main.c
+++ b/src/main.c
@@ -32,6 +32,7 @@
#include <dirent.h>
#include <limits.h>
#include <ctype.h>
+#include <fcntl.h>
#include <dpkg.h>
#include <dpkg-db.h>
@@ -98,6 +99,7 @@ Options:\n\
Just say what we would do - don't do it\n\
-D|--debug=<octal> Enable debugging - see -Dhelp or --debug=help\n\
--status-fd <n> Send status change updates to file descriptor <n>\n\
+ --log=<filename> Log status changes and actions to <filename>\n\
--ignore-depends=<package>,... Ignore dependencies involving <package>\n\
--force-... Override problems - see --force-help\n\
--no-force-...|--refuse-... Stop when problems encountered\n\
@@ -281,6 +283,24 @@ static void setpipe(const struct cmdinfo *cip, const char *value) {
(*lastpipe)->next= NULL;
}
+static void setfile(const struct cmdinfo *cip, const char *value) {
+ static struct pipef **lastpipe;
+ int v;
+
+ v= open(value, (O_CREAT|O_APPEND|O_WRONLY), 0644);
+ if (v < 0) ohshite(_("couldn't open log `%s'"), value);
+
+ lastpipe= cip->parg;
+ if (*lastpipe) {
+ (*lastpipe)->next= nfmalloc(sizeof(struct pipef));
+ *lastpipe= (*lastpipe)->next;
+ } else {
+ *lastpipe= nfmalloc(sizeof(struct pipef));
+ }
+ (*lastpipe)->fd= v;
+ (*lastpipe)->next= NULL;
+}
+
static void setforce(const struct cmdinfo *cip, const char *value) {
const char *comma;
size_t l;
@@ -388,6 +408,7 @@ static const struct cmdinfo cmdinfos[]= {
*/
{ "status-fd", 0, 1, 0, 0, setpipe, 0, &status_pipes },
+ { "log", 0, 1, 0, 0, setfile, 0, &log_pipes },
{ "pending", 'a', 0, &f_pending, 0, 0, 1 },
{ "recursive", 'R', 0, &f_recursive, 0, 0, 1 },
{ "no-act", 0, 0, &f_noact, 0, 0, 1 },
diff --git a/src/main.h b/src/main.h
index 7c6e33e06..44a4fd631 100644
--- a/src/main.h
+++ b/src/main.h
@@ -211,6 +211,7 @@ enum debugflags {
void debug(int which, const char *fmt, ...) PRINTFFORMAT(2,3);
void check_libver(void);
+void log_action(const char *action, struct pkginfo *pkg);
/* from depcon.c */
diff --git a/src/processarc.c b/src/processarc.c
index 9de7e9dee..71454526c 100644
--- a/src/processarc.c
+++ b/src/processarc.c
@@ -279,13 +279,16 @@ void process_archive(const char *filename) {
ensure_allinstfiles_available();
filesdbinit();
- if (pkg->status != stat_notinstalled && pkg->status != stat_configfiles)
+ if (pkg->status != stat_notinstalled && pkg->status != stat_configfiles) {
+ log_action("upgrade", pkg);
printf(_("Preparing to replace %s %s (using %s) ...\n"),
pkg->name,
versiondescribe(&pkg->installed.version,vdew_nonambig),
pfilename);
- else
+ } else {
printf(_("Unpacking %s (from %s) ...\n"),pkg->name,pfilename);
+ log_action("install", pkg);
+ }
if (f_noact) {
pop_cleanup(ehflag_normaltidy);
diff --git a/src/query.c b/src/query.c
index 8b43daf12..b36dafce6 100644
--- a/src/query.c
+++ b/src/query.c
@@ -107,32 +107,52 @@ static int getwidth(void) {
const char* columns;
if ((columns=getenv("COLUMNS")) && ((res=atoi(columns))>0))
- ws.ws_col=res;
+ return res;
else if (!isatty(1))
- ws.ws_col=80;
+ return -1;
else {
if ((fd=open("/dev/tty",O_RDONLY))!=-1) {
if (ioctl(fd, TIOCGWINSZ, &ws)==-1)
- ws.ws_col=80;
+ ws.ws_col=80;
close(fd);
}
+ return ws.ws_col;
}
- return ws.ws_col;
}
-static void list1package(struct pkginfo *pkg, int *head) {
- int l,w;
+static void list1package(struct pkginfo *pkg, int *head,
+ struct pkginfo **pkgl, int np) {
+ int i,l,w;
static int nw,vw,dw;
const char *pdesc;
static char format[80] = "";
if (format[0]==0) {
- w=getwidth()-80; /* get spare width */
- if (w<0) w=0; /* lets not try to deal with terminals that are too small */
- w>>=2; /* halve that so we can add that to the both the name and description */
- nw=(14+w); /* name width */
- vw=(14+w); /* version width */
- dw=(44+(2*w)); /* description width */
+ w=getwidth();
+ if (w == -1) {
+ nw=14, vw=14, dw=44;
+ for (i=0; i<np; i++) {
+ const char *pdesc;
+ int plen, vlen, dlen;
+
+ pdesc= pkg->installed.valid ? pkg->installed.description : 0;
+ if (!pdesc) pdesc= _("(no description available)");
+
+ plen= strlen(pkgl[i]->name);
+ vlen= strlen(versiondescribe(&pkgl[i]->installed.version,vdew_never));
+ dlen= strcspn(pdesc, "\n");
+ if (plen > nw) nw = plen;
+ if (vlen > vw) vw = vlen;
+ if (dlen > dw) dw = dlen;
+ }
+ } else {
+ w-=80;
+ if (w<0) w=0; /* lets not try to deal with terminals that are too small */
+ w>>=2; /* halve that so we can add that to the both the name and description */
+ nw=(14+w); /* name width */
+ vw=(14+w); /* version width */
+ dw=(44+(2*w)); /* description width */
+ }
sprintf(format,"%%c%%c%%c %%-%d.%ds %%-%d.%ds %%.*s\n", nw, nw, vw, vw);
}
@@ -181,12 +201,12 @@ void listpackages(const char *const *argv) {
qsort(pkgl,np,sizeof(struct pkginfo*),pkglistqsortcmp);
head=0;
-
+
if (!*argv) {
for (i=0; i<np; i++) {
pkg= pkgl[i];
if (pkg->status == stat_notinstalled) continue;
- list1package(pkg,&head);
+ list1package(pkg,&head,pkgl,np);
}
} else {
while ((thisarg= *argv++)) {
@@ -194,7 +214,7 @@ void listpackages(const char *const *argv) {
for (i=0; i<np; i++) {
pkg= pkgl[i];
if (fnmatch(thisarg,pkg->name,0)) continue;
- list1package(pkg,&head); found++;
+ list1package(pkg,&head,pkgl,np); found++;
}
if (!found) {
fprintf(stderr,_("No packages found matching %s.\n"),thisarg);
diff --git a/src/remove.c b/src/remove.c
index 6dbf1a18c..8964de7c3 100644
--- a/src/remove.c
+++ b/src/remove.c
@@ -162,6 +162,7 @@ void deferred_remove(struct pkginfo *pkg) {
oldconffsetflags(pkg->installed.conffiles);
printf(_("Removing %s ...\n"),pkg->name);
+ log_action("remove", pkg);
if (pkg->status == stat_halfconfigured || pkg->status == stat_installed) {
if (pkg->status == stat_installed || pkg->status == stat_halfconfigured) {
@@ -391,6 +392,7 @@ static void removal_bulk_remove_configfiles(struct pkginfo *pkg) {
const char *const *ext;
printf(_("Purging configuration files for %s ...\n"),pkg->name);
+ log_action("purge", pkg);
ensure_packagefiles_available(pkg); /* We may have modified this above. */
/* We're about to remove the configuration, so remove the note