summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build/files.c2
-rw-r--r--build/pack.c2
-rw-r--r--lib/cpio.h14
-rw-r--r--lib/fsm.c416
-rw-r--r--lib/fsm.h2
-rw-r--r--lib/header.c57
-rw-r--r--lib/package.c34
-rw-r--r--lib/psm.c180
-rw-r--r--lib/psm.h8
-rw-r--r--lib/rpmlib.h11
-rw-r--r--lib/signature.c82
-rw-r--r--lib/signature.h14
-rw-r--r--lib/transaction.c19
-rw-r--r--macros.in122
-rw-r--r--po/rpm.pot133
15 files changed, 753 insertions, 343 deletions
diff --git a/build/files.c b/build/files.c
index 111d398b8..057b8d92d 100644
--- a/build/files.c
+++ b/build/files.c
@@ -1150,7 +1150,7 @@ static void genCpioListAndHeader(struct FileList *fl, TFI_t *cpioList,
fi->actions[i] = FA_SKIP;
continue;
}
- fi->actions[i] = FA_CREATE;
+ fi->actions[i] = FA_COPYOUT;
fi->fuids[i] = flp->fl_uid;
fi->fgids[i] = flp->fl_gid;
fi->fmapflags[i] =
diff --git a/build/pack.c b/build/pack.c
index 1dec9b2ca..3a75da36a 100644
--- a/build/pack.c
+++ b/build/pack.c
@@ -471,7 +471,7 @@ int writeRPM(Header *hdrp, const char *fileName, int type,
lead.osnum = osnum;
lead.signature_type = RPMSIG_HEADERSIG; /* New-style signature */
- { const char *name, *version, *release;
+ { const char *name, *version, *release;
headerNVR(h, &name, &version, &release);
sprintf(buf, "%s-%s-%s", name, version, release);
strncpy(lead.name, buf, sizeof(lead.name));
diff --git a/lib/cpio.h b/lib/cpio.h
index 86272e914..972fc60f7 100644
--- a/lib/cpio.h
+++ b/lib/cpio.h
@@ -57,12 +57,14 @@ enum cpioErrorReturns {
/** \ingroup payload
*/
typedef enum cpioMapFlags_e {
- CPIO_MAP_PATH = (1 << 0),
- CPIO_MAP_MODE = (1 << 1),
- CPIO_MAP_UID = (1 << 2),
- CPIO_MAP_GID = (1 << 3),
- CPIO_FOLLOW_SYMLINKS = (1 << 4), /* only for building. */
- CPIO_MULTILIB = (1 << 31) /* internal, only for building. */
+ CPIO_MAP_PATH = (1 << 0),
+ CPIO_MAP_MODE = (1 << 1),
+ CPIO_MAP_UID = (1 << 2),
+ CPIO_MAP_GID = (1 << 3),
+ CPIO_FOLLOW_SYMLINKS= (1 << 4), /* only for building. */
+ CPIO_MAP_ABSOLUTE = (1 << 5),
+ CPIO_MAP_ADDDOT = (1 << 6),
+ CPIO_MULTILIB = (1 << 31) /* internal, only for building. */
} cpioMapFlags;
#define CPIO_NEWC_MAGIC "070701"
diff --git a/lib/fsm.c b/lib/fsm.c
index 195cc1755..0fd18e416 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -77,13 +77,19 @@ static /*@only@*//*@null@*/ const char * fsmFsPath(/*@null@*/ const FSM_t fsm,
/** \ingroup payload
* Destroy file info iterator.
+ * @param this file info iterator
* @retval NULL always
*/
-static /*@null@*/ void * mapFreeIterator(/*@only@*//*@null@*/const void * this) {
+static /*@null@*/ void * mapFreeIterator(/*@only@*//*@null@*/const void * this)
+{
return _free((void *)this);
}
/** \ingroup payload
+ * Create file info iterator.
+ * @param this transaction set
+ * @param that transaction element file info
+ * @return file info iterator
*/
static void *
mapInitIterator(/*@kept@*/ const void * this, /*@kept@*/ const void * that)
@@ -95,24 +101,26 @@ mapInitIterator(/*@kept@*/ const void * this, /*@kept@*/ const void * that)
iter = xcalloc(1, sizeof(*iter));
iter->ts = ts;
iter->fi = fi;
- switch (fi->type) {
- case TR_ADDED: iter->i = 0; break;
- case TR_REMOVED: iter->i = fi->fc - 1; break;
- }
+ iter->reverse = (fi->type == TR_REMOVED && fi->action != FA_COPYOUT);
+ iter->i = (iter->reverse ? (fi->fc - 1) : 0);
iter->isave = iter->i;
return iter;
}
/** \ingroup payload
+ * Return next index into file info.
+ * @param this file info iterator
+ * @return next index, -1 on termination
*/
static int mapNextIterator(void * this) {
FSMI_t iter = this;
const TFI_t fi = iter->fi;
int i = -1;
- switch (fi->type) {
- case TR_ADDED: if (iter->i < fi->fc) i = iter->i++; break;
- case TR_REMOVED: if (iter->i >= 0) i = iter->i--; break;
+ if (iter->reverse) {
+ if (iter->i >= 0) i = iter->i--;
+ } else {
+ if (iter->i < fi->fc) i = iter->i++;
}
iter->isave = i;
return i;
@@ -120,6 +128,50 @@ static int mapNextIterator(void * this) {
/** \ingroup payload
*/
+static int cpioStrCmp(const void * a, const void * b)
+{
+ const char * afn = *(const char **)a;
+ const char * bfn = *(const char **)b;
+
+ /* Match rpm-4.0 payloads with ./ prefixes. */
+ if (afn[0] == '.' && afn[1] == '/') afn += 2;
+ if (bfn[0] == '.' && bfn[1] == '/') bfn += 2;
+
+ /* If either path is absolute, make it relative. */
+ if (afn[0] == '/') afn += 1;
+ if (bfn[0] == '/') bfn += 1;
+
+ return strcmp(afn, bfn);
+}
+
+/** \ingroup payload
+ * Locate archive path in file info.
+ * @param this file info iterator
+ * @param fsmPath archive path
+ * @return index into file info, -1 if archive path was not found
+ */
+static int mapFind(void * this, const char * fsmPath) {
+ FSMI_t iter = this;
+ const TFI_t fi = iter->fi;
+ int ix = -1;
+
+ if (fi && fi->fc > 0 && fi->apath && fsmPath && *fsmPath) {
+ const char ** p;
+
+ p = bsearch(&fsmPath, fi->apath, fi->fc, sizeof(fsmPath), cpioStrCmp);
+ if (p == NULL) {
+ fprintf(stderr, "*** not mapped %s\n", fsmPath);
+ } else {
+ iter->i = p - fi->apath;
+ ix = mapNextIterator(iter);
+ }
+ }
+ return ix;
+}
+
+/** \ingroup payload
+ * Directory name iterator.
+ */
typedef struct dnli_s {
/*@dependent@*/ TFI_t fi;
/*@only@*/ /*@null@*/ char * active;
@@ -129,6 +181,9 @@ typedef struct dnli_s {
} * DNLI_t;
/** \ingroup payload
+ * Destroy directory name iterator.
+ * @param this file info iterator
+ * @retval NULL always
*/
static /*@null@*/ void * dnlFreeIterator(/*@only@*//*@null@*/ const void * this)
{
@@ -152,7 +207,10 @@ static inline int dnlIndex(const DNLI_t dnli) {
}
/** \ingroup payload
+ * Create directory name iterator.
* @param fsm file state machine data
+ * @param reverse traverse directory names in reverse order?
+ * @return directory name iterator
*/
static /*@only@*/ void * dnlInitIterator(const FSM_t fsm, int reverse)
{
@@ -223,8 +281,12 @@ static /*@only@*/ void * dnlInitIterator(const FSM_t fsm, int reverse)
}
/** \ingroup payload
+ * Return next directory name (from file info).
+ * @param dnli directory name iterator
+ * @return next directory name
*/
-static const char * dnlNextIterator(/*@null@*/ DNLI_t dnli) {
+static /*@observer@*/ const char * dnlNextIterator(/*@null@*/ DNLI_t dnli)
+{
const char * dn = NULL;
if (dnli && dnli->active) {
@@ -245,44 +307,6 @@ static const char * dnlNextIterator(/*@null@*/ DNLI_t dnli) {
}
/** \ingroup payload
- */
-static int cpioStrCmp(const void * a, const void * b) {
- const char * afn = *(const char **)a;
- const char * bfn = *(const char **)b;
-
- /* Match rpm-4.0 payloads with ./ prefixes. */
- if (afn[0] == '.' && afn[1] == '/') afn += 2;
- if (bfn[0] == '.' && bfn[1] == '/') bfn += 2;
-
- /* If either path is absolute, make it relative. */
- if (afn[0] == '/') afn += 1;
- if (bfn[0] == '/') bfn += 1;
-
- return strcmp(afn, bfn);
-}
-
-/** \ingroup payload
- */
-static int mapFind(void * this, const char * fsmPath) {
- FSMI_t iter = this;
- const TFI_t fi = iter->fi;
- int ix = -1;
-
- if (fi) {
- const char ** p;
-
- p = bsearch(&fsmPath, fi->apath, fi->fc, sizeof(fsmPath), cpioStrCmp);
- if (p == NULL) {
- fprintf(stderr, "*** not mapped %s\n", fsmPath);
- } else {
- iter->i = p - fi->apath;
- ix = mapNextIterator(iter);
- }
- }
- return ix;
-}
-
-/** \ingroup payload
* Save hard link in chain.
* @param fsm file state machine data
* @return Is chain only partially filled?
@@ -482,8 +506,6 @@ int fsmMapPath(FSM_t fsm)
fsm->mapFlags = (fi->fmapflags ? fi->fmapflags[i] : fi->mapflags);
/* src rpms have simple base name in payload. */
- fsm->archivePath =
- (fi->apath ? fi->apath[i] + fi->striplen : fi->bnl[i]);
fsm->dirName = fi->dnl[fi->dil[i]];
fsm->baseName = fi->bnl[i];
@@ -497,8 +519,11 @@ fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action
fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), (fsm->path ? fsm->path : ""));
break;
+ case FA_COPYOUT:
+ break;
+ case FA_COPYIN:
case FA_CREATE:
- assert(fi->type == TR_ADDED);
+assert(fi->type == TR_ADDED);
break;
case FA_SKIPNSTATE:
@@ -525,13 +550,13 @@ fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action
break;
case FA_ALTNAME:
- assert(fi->type == TR_ADDED);
+assert(fi->type == TR_ADDED);
fsm->nsuffix = SUFFIX_RPMNEW;
break;
case FA_SAVE:
fprintf(stderr, "*** %s:%s %s\n", fiTypeString(fi), fileActionString(fsm->action), (fsm->path ? fsm->path : ""));
- assert(fi->type == TR_ADDED);
+assert(fi->type == TR_ADDED);
fsm->osuffix = SUFFIX_RPMSAVE;
break;
case FA_ERASE:
@@ -675,8 +700,20 @@ static int writeFile(FSM_t fsm, int writeData)
st->st_size = fsm->rdnb;
}
- if (fsm->mapFlags & CPIO_MAP_PATH)
- fsm->path = fsm->archivePath;
+ if (fsm->mapFlags & CPIO_MAP_ABSOLUTE) {
+ int nb = strlen(fsm->dirName) + strlen(fsm->baseName) + sizeof(".");
+ char * t = alloca(nb);
+ *t = '\0';
+ fsm->path = t;
+ if (fsm->mapFlags & CPIO_MAP_ADDDOT)
+ *t++ = '.';
+ t = stpcpy( stpcpy(t, fsm->dirName), fsm->baseName);
+ } else if (fsm->mapFlags & CPIO_MAP_PATH) {
+ TFI_t fi = fsmGetFi(fsm);
+ fsm->path =
+ (fi->apath ? fi->apath[fsm->ix] + fi->striplen : fi->bnl[fsm->ix]);
+ }
+
rc = fsmStage(fsm, FSM_HWRITE);
fsm->path = path;
if (rc) goto exit;
@@ -801,7 +838,9 @@ static int writeLinkedFile(FSM_t fsm)
}
/** \ingroup payload
+ * Create pending hard links to existing file.
* @param fsm file state machine data
+ * @return 0 on success
*/
static int fsmMakeLinks(FSM_t fsm)
{
@@ -851,7 +890,9 @@ static int fsmMakeLinks(FSM_t fsm)
}
/** \ingroup payload
+ * Commit hard linked file set atomically.
* @param fsm file state machine data
+ * @return 0 on success
*/
static int fsmCommitLinks(FSM_t fsm)
{
@@ -886,6 +927,141 @@ static int fsmCommitLinks(FSM_t fsm)
return rc;
}
+/**
+ * Remove (if created) directories not explicitly included in package.
+ * @param fsm file state machine data
+ * @return 0 on success
+ */
+static int fsmRmdirs(FSM_t fsm)
+{
+ const char * path = fsm->path;
+ void * dnli = dnlInitIterator(fsm, 1);
+ char * dn = fsm->rdbuf;
+ int dc = dnlCount(dnli);
+ int rc = 0;
+
+ fsm->path = NULL;
+ dn[0] = '\0';
+ while ((fsm->path = dnlNextIterator(dnli)) != NULL) {
+ int dnlen = strlen(fsm->path);
+ char * te;
+
+ dc = dnlIndex(dnli);
+ if (fsm->dnlx[dc] < 1 || fsm->dnlx[dc] >= dnlen)
+ continue;
+
+ /* Copy to avoid const on fsm->path. */
+ te = stpcpy(dn, fsm->path) - 1;
+ fsm->path = dn;
+
+ /* Remove generated directories. */
+ do {
+ if (*te == '/') {
+ *te = '\0';
+ rc = fsmStage(fsm, FSM_RMDIR);
+ *te = '/';
+ }
+ if (rc) break;
+ te--;
+ } while ((te - dn) > fsm->dnlx[dc]);
+ }
+ dnli = dnlFreeIterator(dnli);
+ fsm->path = path;
+ return rc;
+}
+
+/**
+ * Create (if necessary) directories not explicitly included in package.
+ * @param fsm file state machine data
+ * @return 0 on success
+ */
+static int fsmMkdirs(FSM_t fsm)
+{
+ struct stat * st = &fsm->sb;
+ struct stat * ost = &fsm->osb;
+ const char * path = fsm->path;
+ mode_t st_mode = st->st_mode;
+ void * dnli = dnlInitIterator(fsm, 0);
+ char * dn = fsm->rdbuf;
+ int dc = dnlCount(dnli);
+ int rc = 0;
+ int i;
+
+ fsm->path = NULL;
+
+ dn[0] = '\0';
+ fsm->dnlx = (dc ? xcalloc(dc, sizeof(*fsm->dnlx)) : NULL);
+ while ((fsm->path = dnlNextIterator(dnli)) != NULL) {
+ int dnlen = strlen(fsm->path);
+ char * te;
+
+ dc = dnlIndex(dnli);
+ if (dc < 0) continue;
+ fsm->dnlx[dc] = dnlen;
+ if (dnlen <= 1)
+ continue;
+ if (dnlen <= fsm->ldnlen && !strcmp(fsm->path, fsm->ldn))
+ continue;
+
+ /* Copy to avoid const on fsm->path. */
+ (void) stpcpy(dn, fsm->path);
+ fsm->path = dn;
+
+ /* Assume '/' directory exists, otherwise "mkdir -p" if non-existent. */
+ for (i = 1, te = dn + 1; *te; te++, i++) {
+ if (*te != '/') continue;
+
+ *te = '\0';
+
+ /* Already validated? */
+ if (i < fsm->ldnlen &&
+ (fsm->ldn[i] == '/' || fsm->ldn[i] == '\0') &&
+ !strncmp(fsm->path, fsm->ldn, i))
+ {
+ *te = '/';
+ /* Move pre-existing path marker forward. */
+ fsm->dnlx[dc] = (te - dn);
+ continue;
+ }
+
+ /* Validate next component of path. */
+ rc = fsmStage(fsm, FSM_LSTAT);
+ *te = '/';
+
+ /* Directory already exists? */
+ if (rc == 0 && S_ISDIR(ost->st_mode)) {
+ /* Move pre-existing path marker forward. */
+ fsm->dnlx[dc] = (te - dn);
+ } else if (rc == CPIOERR_LSTAT_FAILED) {
+ TFI_t fi = fsmGetFi(fsm);
+ *te = '\0';
+ st->st_mode = S_IFDIR | (fi->dperms & 07777);
+ rc = fsmStage(fsm, FSM_MKDIR);
+ if (!rc)
+ rpmMessage(RPMMESS_WARNING,
+ _("%s directory created with perms %04o.\n"),
+ fsm->path, (st->st_mode & 07777));
+ *te = '/';
+ }
+ if (rc) break;
+ }
+ if (rc) break;
+
+ /* Save last validated path. */
+ if (fsm->ldnalloc < (dnlen + 1)) {
+ fsm->ldnalloc = dnlen + 100;
+ fsm->ldn = xrealloc(fsm->ldn, fsm->ldnalloc);
+ }
+ strcpy(fsm->ldn, fsm->path);
+ fsm->ldnlen = dnlen;
+ }
+ dnli = dnlFreeIterator(dnli);
+ fsm->path = path;
+ st->st_mode = st_mode; /* XXX restore st->st_mode */
+ return rc;
+}
+
+
int fsmStage(FSM_t fsm, fileStage stage)
{
#ifdef UNUSED
@@ -901,6 +1077,10 @@ int fsmStage(FSM_t fsm, fileStage stage)
int left;
int i;
+#define _fafilter(_a) \
+ (!((_a) == FA_CREATE || (_a) == FA_ERASE || (_a) == FA_COPYIN || (_a) == FA_COPYOUT) \
+ ? fileActionString(_a) : "")
+
if (stage & FSM_DEAD) {
/* do nothing */
} else if (stage & FSM_INTERNAL) {
@@ -909,8 +1089,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
cur,
st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size,
(fsm->path ? fsm->path : ""),
- ((fsm->action != FA_UNKNOWN && fsm->action != FA_CREATE)
- ? fileActionString(fsm->action) : ""));
+ _fafilter(fsm->action));
} else {
fsm->stage = stage;
if (_fsm_debug || !(stage & FSM_VERBOSE))
@@ -918,9 +1097,9 @@ int fsmStage(FSM_t fsm, fileStage stage)
cur,
st->st_mode, st->st_nlink, st->st_uid, st->st_gid, st->st_size,
(fsm->path ? fsm->path + fsm->astriplen : ""),
- ((fsm->action != FA_UNKNOWN && fsm->action != FA_CREATE)
- ? fileActionString(fsm->action) : ""));
+ _fafilter(fsm->action));
}
+#undef _fafilter
switch (stage) {
case FSM_UNKNOWN:
@@ -1112,125 +1291,11 @@ int fsmStage(FSM_t fsm, fileStage stage)
rc = fsmMapPath(fsm);
break;
case FSM_MKDIRS:
- { const char * path = fsm->path;
- mode_t st_mode = st->st_mode;
- void * dnli = dnlInitIterator(fsm, 0);
- char * dn = fsm->rdbuf;
- int dc = dnlCount(dnli);
-
- fsm->path = NULL;
- dn[0] = '\0';
- fsm->dnlx = (dc ? xcalloc(dc, sizeof(*fsm->dnlx)) : NULL);
- while ((fsm->path = dnlNextIterator(dnli)) != NULL) {
- int dnlen = strlen(fsm->path);
- char * te;
-
- dc = dnlIndex(dnli);
- if (dc < 0) continue;
- fsm->dnlx[dc] = dnlen;
- if (dnlen <= 1)
- continue;
- if (dnlen <= fsm->ldnlen && !strcmp(fsm->path, fsm->ldn))
- continue;
-
- /* Copy to avoid const on fsm->path. */
- (void) stpcpy(dn, fsm->path);
- fsm->path = dn;
-
- /* Initial mode for created dirs is 0700 */
- st->st_mode &= ~07777; /* XXX abuse st->st_mode */
- st->st_mode |= 00700;
-
- /* Assume '/' directory, otherwise "mkdir -p" */
- for (i = 1, te = dn + 1; *te; te++, i++) {
- if (*te != '/') continue;
-
- *te = '\0';
-
- /* Already validated? */
- if (i < fsm->ldnlen &&
- (fsm->ldn[i] == '/' || fsm->ldn[i] == '\0') &&
- !strncmp(fsm->path, fsm->ldn, i))
- {
- *te = '/';
- /* Move pre-existing path marker forward. */
- fsm->dnlx[dc] = (te - dn);
- continue;
- }
-
- /* Validate next component of path. */
- rc = fsmStage(fsm, FSM_LSTAT);
- *te = '/';
-
- /* Directory already exists? */
- if (rc == 0 && S_ISDIR(ost->st_mode)) {
- /* Move pre-existing path marker forward. */
- fsm->dnlx[dc] = (te - dn);
- } else if (rc == CPIOERR_LSTAT_FAILED) {
- TFI_t fi = fsmGetFi(fsm);
- mode_t st_mode = st->st_mode;
- *te = '\0';
- st->st_mode = S_IFDIR | (fi->dperms & 07777);
- rc = fsmStage(fsm, FSM_MKDIR);
- if (!rc)
- rpmMessage(RPMMESS_WARNING,
- _("%s directory created with perms %04o.\n"),
- fsm->path, (st->st_mode & 07777));
- *te = '/';
- st->st_mode = st_mode;
- }
- if (rc) break;
- }
- if (rc) break;
-
- /* Save last validated path. */
- if (fsm->ldnalloc < (dnlen + 1)) {
- fsm->ldnalloc = dnlen + 100;
- fsm->ldn = xrealloc(fsm->ldn, fsm->ldnalloc);
- }
- strcpy(fsm->ldn, fsm->path);
- fsm->ldnlen = dnlen;
- }
- dnli = dnlFreeIterator(dnli);
- fsm->path = path;
- st->st_mode = st_mode; /* XXX restore st->st_mode */
- }
+ rc = fsmMkdirs(fsm);
break;
case FSM_RMDIRS:
- if (fsm->dnlx) {
- const char * path = fsm->path;
- void * dnli = dnlInitIterator(fsm, 1);
- char * dn = fsm->rdbuf;
- int dc = dnlCount(dnli);
-
- fsm->path = NULL;
- dn[0] = '\0';
- while ((fsm->path = dnlNextIterator(dnli)) != NULL) {
- int dnlen = strlen(fsm->path);
- char * te;
-
- dc = dnlIndex(dnli);
- if (fsm->dnlx[dc] < 1 || fsm->dnlx[dc] >= dnlen)
- continue;
-
- /* Copy to avoid const on fsm->path. */
- te = stpcpy(dn, fsm->path) - 1;
- fsm->path = dn;
-
- /* Remove generated directories. */
- do {
- if (*te == '/') {
- *te = '\0';
- rc = fsmStage(fsm, FSM_RMDIR);
- *te = '/';
- }
- if (rc) break;
- te--;
- } while ((te - dn) > fsm->dnlx[dc]);
- }
- dnli = dnlFreeIterator(dnli);
- fsm->path = path;
- }
+ if (fsm->dnlx)
+ rc = fsmRmdirs(fsm);
break;
case FSM_PROCESS:
if (fsm->postpone) {
@@ -1341,6 +1406,7 @@ int fsmStage(FSM_t fsm, fileStage stage)
case FSM_POST:
break;
case FSM_MKLINKS:
+ rc = fsmMakeLinks(fsm);
break;
case FSM_NOTIFY: /* XXX move from fsm to psm -> tsm */
if (fsm->goal == FSM_PKGINSTALL || fsm->goal == FSM_PKGBUILD) {
diff --git a/lib/fsm.h b/lib/fsm.h
index f2c75135e..85c0d2da6 100644
--- a/lib/fsm.h
+++ b/lib/fsm.h
@@ -102,6 +102,7 @@ struct hardLink {
struct fsmIterator_s {
/*@kept@*/ rpmTransactionSet ts; /*!< transaction set. */
/*@kept@*/ TFI_t fi; /*!< transaction element file info. */
+ int reverse; /*!< reversed traversal? */
int isave; /*!< last returned iterator index. */
int i; /*!< iterator index. */
};
@@ -149,7 +150,6 @@ struct fsm_s {
int rc; /*!< External file stage return code. */
int commit; /*!< Commit synchronously? */
cpioMapFlags mapFlags; /*!< Bit(s) to control mapping. */
-/*@shared@*/ const char * archivePath; /*!< Path to store in cpio archive. */
/*@shared@*/ const char * dirName; /*!< File directory name. */
/*@shared@*/ const char * baseName; /*!< File base name. */
/*@shared@*/ const char * fmd5sum; /*!< File MD5 sum (NULL disables). */
diff --git a/lib/header.c b/lib/header.c
index 3bf791dc7..c50d4bc0a 100644
--- a/lib/header.c
+++ b/lib/header.c
@@ -289,16 +289,29 @@ static void copyEntry(const struct indexEntry * entry, /*@out@*/ int_32 * type,
if (p)
switch (entry->info.type) {
case RPM_BIN_TYPE:
- count = entry->length;
- *p = (!minMem
- ? memcpy(xmalloc(count), entry->data, count)
- : entry->data);
+ /* XXX this only works for HEADER_IMMUTABLE */
if (ENTRY_IS_REGION(entry)) {
- struct entryInfo * pe = (struct entryInfo *) *p;
+ int_32 * ei = ((int_32 *)entry->data) - 2;
+ struct entryInfo * pe = (struct entryInfo *) (ei + 2);
+ char * dataStart = (char *) (pe + ntohl(ei[0]));
int_32 rdl = -entry->info.offset; /* negative offset */
int_32 ril = rdl/sizeof(*pe);
- char * dataStart = (char *) (pe + ril);
+
+ count = 2 * sizeof(*ei) + (ril * sizeof(*pe)) +
+ entry->rdlen + REGION_TAG_COUNT;
+ ei = (int_32 *) *p = xmalloc(count);
+ ei[0] = htonl(ril);
+ ei[1] = htonl(entry->rdlen + REGION_TAG_COUNT);
+ pe = (struct entryInfo *) memcpy(ei + 2, pe, (ril * sizeof(*pe)));
+ dataStart = (char *) memcpy(pe + ril, dataStart,
+ (entry->rdlen + REGION_TAG_COUNT));
+
(void) regionSwab(NULL, ril, 0, pe, dataStart, 0);
+ } else {
+ count = entry->length;
+ *p = (!minMem
+ ? memcpy(xmalloc(count), entry->data, count)
+ : entry->data);
}
break;
case RPM_STRING_TYPE:
@@ -585,6 +598,38 @@ Header headerCopyLoad(void *uh)
return h;
}
+#if 0
+int headerDrips(const Header h)
+{
+ struct indexEntry * entry;
+ int i;
+
+ for (i = 0, entry = h->index; i < h->indexUsed; i++, entry++) {
+ if (ENTRY_IS_REGION(entry)) {
+ int rid = entry->info.offset;
+
+ for (; i < h->indexUsed && entry->info.offset <= rid+1; i++, entry++) {
+ if (entry->info.offset <= rid)
+ continue;
+
+fprintf(stderr, "***\t%3d dribble %s\n", i, tagName(entry->info.tag));
+ }
+ i--;
+ entry--;
+ continue;
+ }
+
+ /* Ignore deleted drips. */
+ if (entry->data == NULL || entry->length <= 0)
+ continue;
+
+fprintf(stderr, "***\t%3d drip %s\n", i, tagName(entry->info.tag));
+
+ }
+ return 0;
+}
+#endif
+
static /*@only@*/ void * doHeaderUnload(Header h, /*@out@*/ int * lengthPtr)
/*@modifies h, *lengthPtr @*/
{
diff --git a/lib/package.c b/lib/package.c
index f91d4ba35..e4bc62fd2 100644
--- a/lib/package.c
+++ b/lib/package.c
@@ -29,8 +29,6 @@ void headerMergeLegacySigs(Header h, const Header sig)
headerNextIterator(hi, &tag, &type, &ptr, &count);
ptr = headerFreeData(ptr, type))
{
- if (tag < RPMSIGTAG_SIZE)
- continue;
switch (tag) {
case RPMSIGTAG_SIZE: tag = RPMTAG_SIGSIZE; break;
case RPMSIGTAG_LEMD5_1: tag = RPMTAG_SIGLEMD5_1;break;
@@ -40,6 +38,8 @@ void headerMergeLegacySigs(Header h, const Header sig)
case RPMSIGTAG_GPG: tag = RPMTAG_SIGGPG; break;
case RPMSIGTAG_PGP5: tag = RPMTAG_SIGPGP5; break;
default: break;
+ continue;
+ /*@notreached@*/ break;
}
if (!headerIsEntry(h, tag))
headerAddEntry(h, tag, type, ptr, count);
@@ -47,6 +47,36 @@ void headerMergeLegacySigs(Header h, const Header sig)
headerFreeIterator(hi);
}
+Header headerRegenSigHeader(const Header h)
+{
+ Header sig = rpmNewSignature();
+ HeaderIterator hi;
+ int_32 tag, stag, type, count;
+ const void * ptr;
+
+ for (hi = headerInitIterator(h);
+ headerNextIterator(hi, &tag, &type, &ptr, &count);
+ ptr = headerFreeData(ptr, type))
+ {
+ switch (tag) {
+ case RPMTAG_SIGSIZE: stag = RPMSIGTAG_SIZE; break;
+ case RPMTAG_SIGLEMD5_1: stag = RPMSIGTAG_LEMD5_1;break;
+ case RPMTAG_SIGPGP: stag = RPMSIGTAG_PGP; break;
+ case RPMTAG_SIGLEMD5_2: stag = RPMSIGTAG_LEMD5_2;break;
+ case RPMTAG_SIGMD5: stag = RPMSIGTAG_MD5; break;
+ case RPMTAG_SIGGPG: stag = RPMSIGTAG_GPG; break;
+ case RPMTAG_SIGPGP5: stag = RPMSIGTAG_PGP5; break;
+ default:
+ continue;
+ /*@notreached@*/ break;
+ }
+ if (!headerIsEntry(sig, stag))
+ headerAddEntry(sig, stag, type, ptr, count);
+ }
+ headerFreeIterator(hi);
+ return sig;
+}
+
/**
* Retrieve package components from file handle.
* @param fd file handle
diff --git a/lib/psm.c b/lib/psm.c
index b0864838e..ab8efaf7e 100644
--- a/lib/psm.c
+++ b/lib/psm.c
@@ -9,6 +9,8 @@
#include <rpmurl.h>
#include "psm.h"
+#include "rpmlead.h" /* writeLead proto */
+#include "signature.h" /* signature constants */
#include "misc.h"
#include "debug.h"
@@ -97,7 +99,7 @@ void loadFi(Header h, TFI_t fi)
break;
case TR_REMOVED:
- fi->mapflags = CPIO_MAP_PATH;
+ fi->mapflags = CPIO_MAP_ABSOLUTE | CPIO_MAP_ADDDOT | CPIO_MAP_PATH | CPIO_MAP_MODE;
hge(fi->h, RPMTAG_FILEMD5S, NULL, (void **) &fi->fmd5s, NULL);
hge(fi->h, RPMTAG_FILELINKTOS, NULL, (void **) &fi->flinks, NULL);
fi->fsizes = memcpy(xmalloc(fi->fc * sizeof(*fi->fsizes)),
@@ -195,6 +197,8 @@ void freeFi(TFI_t fi)
switch (a) {
case FA_UNKNOWN: return "unknown";
case FA_CREATE: return "create";
+ case FA_COPYOUT: return "copyout";
+ case FA_COPYIN: return "copyin";
case FA_BACKUP: return "backup";
case FA_SAVE: return "save";
case FA_SKIP: return "skip";
@@ -703,7 +707,6 @@ static int installArchive(const rpmTransactionSet ts, TFI_t fi, int allFiles)
{ FD_t cfd;
cfd = Fdopen(fdDup(Fileno(alp->fd)), rpmio_flags);
- cfd = fdLink(cfd, "persist (installArchive");
rc = fsmSetup(fi->fsm, FSM_PKGINSTALL, ts, fi, cfd, NULL, &failedFile);
saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
@@ -1189,6 +1192,7 @@ int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
stepName, fi->name, fi->version, fi->release,
fi->fc, (ts->transFlags & RPMTRANS_FLAG_TEST));
+assert(fi->type == TR_REMOVED);
/*
* When we run scripts, we pass an argument which is the number of
* versions of this package that will be installed when we are finished.
@@ -1275,3 +1279,175 @@ int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi)
return 0;
}
+
+int repackage(const rpmTransactionSet ts, TFI_t fi)
+{
+ HGE_t hge = fi->hge;
+ HFD_t hfd = fi->hfd;
+ FD_t fd = NULL;
+ const char * pkgURL = NULL;
+ const char * pkgfn = NULL;
+ Header h = NULL;
+ Header oh = NULL;
+ char * rpmio_flags;
+ int chrootDone = 0;
+ int saveerrno;
+ int rc = 0;
+
+assert(fi->type == TR_REMOVED);
+ /* Retrieve installed header. */
+ { rpmdbMatchIterator mi = NULL;
+
+ mi = rpmdbInitIterator(ts->rpmdb, RPMDBI_PACKAGES,
+ &fi->record, sizeof(fi->record));
+
+ h = rpmdbNextIterator(mi);
+ if (h == NULL) {
+ rpmdbFreeIterator(mi);
+ return 2;
+ }
+ h = headerLink(h);
+ rpmdbFreeIterator(mi);
+ }
+
+ /* Regenerate original header. */
+ { void * uh = NULL;
+ int_32 uht, uhc;
+
+ if (headerGetEntry(h, RPMTAG_HEADERIMMUTABLE, &uht, &uh, &uhc)) {
+ oh = headerCopyLoad(uh);
+ uh = hfd(uh, uht);
+ } else {
+ oh = headerLink(h);
+ }
+ }
+
+ /* Open output package for writing. */
+ { const char * bfmt = rpmGetPath("%{_repackage_name_fmt}", NULL);
+ const char * pkgbn =
+ headerSprintf(h, bfmt, rpmTagTable, rpmHeaderFormats, NULL);
+
+ bfmt = _free(bfmt);
+ pkgURL = rpmGenPath( "%{?_repackage_root:%{_repackage_root}}",
+ "%{?_repackage_dir:%{_repackage_dir}}",
+ pkgbn);
+ pkgbn = _free(pkgbn);
+ (void) urlPath(pkgURL, &pkgfn);
+ fd = Fopen(pkgfn, "w.ufdio");
+ if (fd == NULL || Ferror(fd)) {
+ rc = 1;
+ goto exit;
+ }
+ }
+
+ /* Retrieve type of payload compression. */
+ { const char * payload_compressor = NULL;
+ char * t;
+
+ if (!hge(h, RPMTAG_PAYLOADCOMPRESSOR, NULL,
+ (void **) &payload_compressor, NULL))
+ payload_compressor = "gzip";
+ rpmio_flags = t = alloca(sizeof("w9.gzdio"));
+ t = stpcpy(t, "w9");
+ if (!strcmp(payload_compressor, "gzip"))
+ t = stpcpy(t, ".gzdio");
+ if (!strcmp(payload_compressor, "bzip2"))
+ t = stpcpy(t, ".bzdio");
+ }
+
+ /* Write the lead section into the package. */
+ { int archnum = -1;
+ int osnum = -1;
+ struct rpmlead lead;
+
+#ifndef DYING
+ rpmGetArchInfo(NULL, &archnum);
+ rpmGetOsInfo(NULL, &osnum);
+#endif
+
+ memset(&lead, 0, sizeof(lead));
+ /* XXX Set package version conditioned on noDirTokens. */
+ lead.major = 4;
+ lead.minor = 0;
+ lead.type = RPMLEAD_BINARY;
+ lead.archnum = archnum;
+ lead.osnum = osnum;
+ lead.signature_type = RPMSIG_UNSIGNED;
+
+ { char buf[256];
+ sprintf(buf, "%s-%s-%s", fi->name, fi->version, fi->release);
+ strncpy(lead.name, buf, sizeof(lead.name));
+ }
+
+ rc = writeLead(fd, &lead);
+ if (rc) {
+ rpmError(RPMERR_NOSPACE, _("Unable to write package: %s\n"),
+ Fstrerror(fd));
+ rc = 1;
+ goto exit;
+ }
+ }
+
+ /* Write the signature section into the package. */
+ { Header sig = headerRegenSigHeader(h);
+ rc = rpmWriteSignature(fd, sig);
+ headerFree(sig);
+ if (rc) goto exit;
+ }
+
+ /* Write the metadata section into the package. */
+ rc = headerWrite(fd, oh, HEADER_MAGIC_YES);
+ if (rc) goto exit;
+
+ /* Change root directory if requested and not already done. */
+ if (ts->rootDir && !ts->chrootDone) {
+ chdir("/");
+ /*@-unrecog@*/ chroot(ts->rootDir); /*@=unrecog@*/
+ chrootDone = ts->chrootDone = 1;
+ }
+
+ /* Write the payload into the package. */
+ { FD_t cfd;
+ fileAction * actions = fi->actions;
+ fileAction action = fi->action;
+
+ fi->action = FA_COPYOUT;
+ fi->actions = NULL;
+
+ Fflush(fd);
+ cfd = Fdopen(fdDup(Fileno(fd)), rpmio_flags);
+
+ /* XXX failedFile? */
+ rc = fsmSetup(fi->fsm, FSM_PKGBUILD, ts, fi, cfd, NULL, NULL);
+ (void) fsmTeardown(fi->fsm);
+
+ saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
+ Fclose(cfd);
+ errno = saveerrno;
+ fi->action = action;
+ fi->actions = actions;
+ }
+
+exit:
+ /* Restore root directory if changed. */
+ if (ts->rootDir && chrootDone) {
+ /*@-unrecog@*/ chroot("."); /*@=unrecog@*/
+ chrootDone = ts->chrootDone = 0;
+ chdir(ts->currDir);
+ }
+
+ if (h) headerFree(h);
+ if (oh) headerFree(oh);
+ if (fd) {
+ saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
+ Fclose(fd);
+ errno = saveerrno;
+ }
+
+ if (!rc)
+ rpmMessage(RPMMESS_VERBOSE, _("Wrote: %s\n"), pkgURL);
+
+ pkgURL = _free(pkgURL);
+
+ return rc;
+}
diff --git a/lib/psm.h b/lib/psm.h
index 8b18a90bb..7cf601969 100644
--- a/lib/psm.h
+++ b/lib/psm.h
@@ -140,11 +140,17 @@ int installBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
* Erase binary package (from transaction set).
* @param ts transaction set
* @param fi transaction element file info
- * @param pkgKey package private data
* @return 0 on success
*/
int removeBinaryPackage(const rpmTransactionSet ts, TFI_t fi);
+/**
+ * @param ts transaction set
+ * @param fi transaction element file info
+ * @return 0 on success
+ */
+int repackage(const rpmTransactionSet ts, TFI_t fi);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/rpmlib.h b/lib/rpmlib.h
index 1ce00292c..97ef774ad 100644
--- a/lib/rpmlib.h
+++ b/lib/rpmlib.h
@@ -63,6 +63,13 @@ int headerNVR(Header h, /*@out@*/ const char **np, /*@out@*/ const char **vp,
void headerMergeLegacySigs(Header h, const Header sig)
/*@modifies h @*/;
+/** \ingroup header
+ * Regenerate signature header.
+ * @param h header
+ * @return regenerated signature header
+ */
+Header headerRegenSigHeader(const Header h) /*@*/;
+
/**
* Retrieve file names from header.
* The representation of file names in package headers changed in rpm-4.0.
@@ -873,7 +880,9 @@ int rpmVersionCompare(Header first, Header second);
*/
typedef enum fileAction_e {
FA_UNKNOWN = 0, /*!< initial action for file ... */
- FA_CREATE, /*!< ... to be replaced. */
+ FA_CREATE, /*!< ... copy in from payload. */
+ FA_COPYIN, /*!< ... copy in from payload. */
+ FA_COPYOUT, /*!< ... copy out to payload. */
FA_BACKUP, /*!< ... renamed with ".rpmorig" extension. */
FA_SAVE, /*!< ... renamed with ".rpmsave" extension. */
FA_SKIP, /*!< ... already replaced, don't remove. */
diff --git a/lib/signature.c b/lib/signature.c
index 9c4a53046..37894ceec 100644
--- a/lib/signature.c
+++ b/lib/signature.c
@@ -70,7 +70,7 @@ int rpmLookupSignatureType(int action)
/* rpmDetectPGPVersion() returns the absolute path to the "pgp" */
/* executable of the requested version, or NULL when none found. */
-const char * rpmDetectPGPVersion(pgpVersion *pgpVer)
+const char * rpmDetectPGPVersion(pgpVersion * pgpVer)
{
/* Actually this should support having more then one pgp version. */
/* At the moment only one version is possible since we only */
@@ -125,7 +125,7 @@ static inline int checkSize(FD_t fd, int siglen, int pad, int datalen)
return ((sizeof(struct rpmlead) + siglen + pad + datalen) - st.st_size);
}
-int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
+int rpmReadSignature(FD_t fd, Header * headerp, short sigType)
{
byte buf[2048];
int sigSize, pad;
@@ -143,11 +143,11 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
#endif
switch (sigType) {
- case RPMSIG_NONE:
+ case RPMSIG_NONE:
rpmMessage(RPMMESS_DEBUG, _("No signature\n"));
rc = 0;
break;
- case RPMSIG_PGP262_1024:
+ case RPMSIG_PGP262_1024:
rpmMessage(RPMMESS_DEBUG, _("Old PGP signature\n"));
/* These are always 256 bytes */
if (timedRead(fd, buf, 256) != 256)
@@ -156,12 +156,13 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
headerAddEntry(h, RPMSIGTAG_PGP, RPM_BIN_TYPE, buf, 152);
rc = 0;
break;
- case RPMSIG_MD5:
- case RPMSIG_MD5_PGP:
+ case RPMSIG_MD5:
+ case RPMSIG_MD5_PGP:
rpmError(RPMERR_BADSIGTYPE,
_("Old (internal-only) signature! How did you get that!?\n"));
break;
- case RPMSIG_HEADERSIG:
+ case RPMSIG_HEADERSIG:
+ case RPMSIG_UNSIGNED:
/* This is a new style signature */
h = headerRead(fd, HEADER_MAGIC_YES);
if (h == NULL)
@@ -173,17 +174,20 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
sigSize -= (16 + 16);
pad = (8 - (sigSize % 8)) % 8; /* 8-byte pad */
- if (! headerGetEntry(h, RPMSIGTAG_SIZE, &type, (void **)&archSize, &count))
- break;
- if (checkSize(fd, sigSize, pad, *archSize))
- break;
+ if (sigType == RPMSIG_HEADERSIG) {
+ if (! headerGetEntry(h, RPMSIGTAG_SIZE, &type,
+ (void **)&archSize, &count))
+ break;
+ if (checkSize(fd, sigSize, pad, *archSize))
+ break;
+ }
if (pad) {
if (timedRead(fd, buf, pad) != pad)
break;
}
rc = 0;
break;
- default:
+ default:
break;
}
@@ -195,24 +199,23 @@ int rpmReadSignature(FD_t fd, Header *headerp, short sigType)
return rc;
}
-int rpmWriteSignature(FD_t fd, Header header)
+int rpmWriteSignature(FD_t fd, Header h)
{
- int sigSize, pad;
static byte buf[8] = "\000\000\000\000\000\000\000\000";
- int rc = 0;
+ int sigSize, pad;
+ int rc;
- rc = headerWrite(fd, header, HEADER_MAGIC_YES);
+ rc = headerWrite(fd, h, HEADER_MAGIC_YES);
if (rc)
return rc;
- sigSize = headerSizeof(header, HEADER_MAGIC_YES);
+ sigSize = headerSizeof(h, HEADER_MAGIC_YES);
pad = (8 - (sigSize % 8)) % 8;
if (pad) {
- rpmMessage(RPMMESS_DEBUG, _("Signature size: %d\n"), sigSize);
- rpmMessage(RPMMESS_DEBUG, _("Signature pad : %d\n"), pad);
if (Fwrite(buf, sizeof(buf[0]), pad, fd) != pad)
rc = 1;
}
+ rpmMessage(RPMMESS_DEBUG, _("Signature: size(%d)+pad(%d)\n"), sigSize, pad);
return rc;
}
@@ -227,15 +230,15 @@ void rpmFreeSignature(Header h)
headerFree(h);
}
-static int makePGPSignature(const char *file, /*@out@*/void **sig, /*@out@*/int_32 *size,
- const char *passPhrase)
+static int makePGPSignature(const char * file, /*@out@*/ void ** sig,
+ /*@out@*/ int_32 * size, const char * passPhrase)
{
- char sigfile[1024];
+ char * sigfile = alloca(1024);
int pid, status;
int inpipe[2];
struct stat st;
- sprintf(sigfile, "%s.sig", file);
+ (void) stpcpy( stpcpy(sigfile, file), ".sig");
inpipe[0] = inpipe[1] = 0;
pipe(inpipe);
@@ -320,16 +323,16 @@ static int makePGPSignature(const char *file, /*@out@*/void **sig, /*@out@*/int_
* but this could be a good place to start looking if errors in GPG signature
* creation crop up.
*/
-static int makeGPGSignature(const char *file, /*@out@*/void **sig, /*@out@*/int_32 *size,
- const char *passPhrase)
+static int makeGPGSignature(const char * file, /*@out@*/ void ** sig,
+ /*@out@*/ int_32 * size, const char * passPhrase)
{
- char sigfile[1024];
+ char * sigfile = alloca(1024);
int pid, status;
int inpipe[2];
- FILE *fpipe;
+ FILE * fpipe;
struct stat st;
- sprintf(sigfile, "%s.sig", file);
+ (void) stpcpy( stpcpy(sigfile, file), ".sig");
inpipe[0] = inpipe[1] = 0;
pipe(inpipe);
@@ -392,7 +395,8 @@ static int makeGPGSignature(const char *file, /*@out@*/void **sig, /*@out@*/int_
return 0;
}
-int rpmAddSignature(Header header, const char *file, int_32 sigTag, const char *passPhrase)
+int rpmAddSignature(Header header, const char * file, int_32 sigTag,
+ const char *passPhrase)
{
struct stat st;
int_32 size;
@@ -431,7 +435,7 @@ int rpmAddSignature(Header header, const char *file, int_32 sigTag, const char *
}
static rpmVerifySignatureReturn
-verifySizeSignature(const char *datafile, int_32 size, char *result)
+verifySizeSignature(const char * datafile, int_32 size, char * result)
{
struct stat st;
@@ -450,8 +454,8 @@ verifySizeSignature(const char *datafile, int_32 size, char *result)
#define X(_x) (unsigned)((_x) & 0xff)
static rpmVerifySignatureReturn
-verifyMD5Signature(const char *datafile, const byte *sig,
- char *result, md5func fn)
+verifyMD5Signature(const char * datafile, const byte * sig,
+ char * result, md5func fn)
{
byte md5sum[16];
@@ -484,7 +488,8 @@ verifyMD5Signature(const char *datafile, const byte *sig,
}
static rpmVerifySignatureReturn
-verifyPGPSignature(const char *datafile, const void * sig, int count, char *result)
+verifyPGPSignature(const char * datafile, const void * sig, int count,
+ char * result)
{
int pid, status, outpipe[2];
FD_t sfd;
@@ -595,7 +600,8 @@ verifyPGPSignature(const char *datafile, const void * sig, int count, char *resu
}
static rpmVerifySignatureReturn
-verifyGPGSignature(const char *datafile, const void * sig, int count, char *result)
+verifyGPGSignature(const char * datafile, const void * sig, int count,
+ char * result)
{
int pid, status, outpipe[2];
FD_t sfd;
@@ -656,7 +662,7 @@ verifyGPGSignature(const char *datafile, const void * sig, int count, char *resu
return res;
}
-static int checkPassPhrase(const char *passPhrase, const int sigTag)
+static int checkPassPhrase(const char * passPhrase, const int sigTag)
{
int passPhrasePipe[2];
int pid, status;
@@ -744,7 +750,7 @@ static int checkPassPhrase(const char *passPhrase, const int sigTag)
return 0;
}
-char *rpmGetPassPhrase(const char *prompt, const int sigTag)
+char *rpmGetPassPhrase(const char * prompt, const int sigTag)
{
char *pass;
int aok;
@@ -791,8 +797,8 @@ char *rpmGetPassPhrase(const char *prompt, const int sigTag)
}
rpmVerifySignatureReturn
-rpmVerifySignature(const char *file, int_32 sigTag, const void * sig, int count,
- char *result)
+rpmVerifySignature(const char * file, int_32 sigTag, const void * sig,
+ int count, char * result)
{
switch (sigTag) {
case RPMSIGTAG_SIZE:
diff --git a/lib/signature.h b/lib/signature.h
index 1a01d102e..9543fdeab 100644
--- a/lib/signature.h
+++ b/lib/signature.h
@@ -20,17 +20,19 @@ extern "C" {
/* */
/**************************************************/
-#define RPMSIG_NONE 0 /* Do not change! */
-#define RPMSIG_BAD 2 /* Returned for unknown types */
+#define RPMSIG_NONE 0 /* Do not change! */
+#define RPMSIG_BAD 2 /* Returned for unknown types */
/* The following types are no longer generated */
-#define RPMSIG_PGP262_1024 1 /* No longer generated */
-#define RPMSIG_MD5 3
-#define RPMSIG_MD5_PGP 4
+#define RPMSIG_PGP262_1024 1 /* No longer generated */
+#define RPMSIG_MD5 3
+#define RPMSIG_MD5_PGP 4
/* These are the new-style signatures. They are Header structures. */
/* Inside them we can put any number of any type of signature we like. */
-#define RPMSIG_HEADERSIG 5 /* New Header style signature */
+#define RPMSIG_HEADERSIG 5 /* New Header style signature */
+
+#define RPMSIG_UNSIGNED 6
/** \ingroup signature
* Return new, empty (signature) header instance.
diff --git a/lib/transaction.c b/lib/transaction.c
index f13d9ed9d..1a73cfa1d 100644
--- a/lib/transaction.c
+++ b/lib/transaction.c
@@ -1120,7 +1120,8 @@ static void handleOverlappedFiles(TFI_t fi, hashTable ht,
ds->bneeded += s;
break;
- /* FIXME: If a two packages share a file (same md5sum), and
+ /*
+ * FIXME: If a two packages share a file (same md5sum), and
* that file is being replaced on disk, will ds->bneeded get
* decremented twice? Quite probably!
*/
@@ -1686,6 +1687,22 @@ int rpmRunTransactions( rpmTransactionSet ts,
}
/* ===============================================
+ * Save removed files before erasing.
+ */
+ if (ts->transFlags & (RPMTRANS_FLAG_DIRSTASH | RPMTRANS_FLAG_REPACKAGE)) {
+ for (oc = 0, fi = flList; oc < ts->orderCount; oc++, fi++) {
+ switch (ts->order[oc].type) {
+ case TR_ADDED:
+ break;
+ case TR_REMOVED:
+ if (ts->transFlags & RPMTRANS_FLAG_REPACKAGE)
+ repackage(ts, fi);
+ break;
+ }
+ }
+ }
+
+ /* ===============================================
* Install and remove packages.
*/
diff --git a/macros.in b/macros.in
index dd6bfa3d8..491b5e0d9 100644
--- a/macros.in
+++ b/macros.in
@@ -1,4 +1,4 @@
-# $Id: macros.in,v 1.70 2000/12/04 00:55:17 jbj Exp $
+# $Id: macros.in,v 1.71 2001/02/11 22:02:29 jbj Exp $
#
# This is a global RPM configuration file. All changes made here will
# be lost when the rpm package is upgraded. Any per-system configuration
@@ -18,7 +18,7 @@
#==============================================================================
# ---- A macro that expands to nothing.
#
-%nil %{!?nil}
+%nil %{!?nil}
#==============================================================================
# ---- filesystem macros.
@@ -31,7 +31,7 @@
# ---- Generally useful path macros.
#
%__awk @AWK@
-%__bzip2 %{_bzip2bin}
+%__bzip2 @BZIP2BIN@
%__cat @__CAT@
%__chgrp @__CHGRP@
%__chmod @__CHMOD@
@@ -39,7 +39,7 @@
%__cp @__CP@
%__cpio @__CPIO@
%__grep @__GREP@
-%__gzip %{_gzipbin}
+%__gzip @GZIPBIN@
%__id @__ID@
%__install @__INSTALL@
%__ln_s @LN_S@
@@ -49,14 +49,14 @@
%__mv @__MV@
%__patch @__PATCH@
%__perl @__PERL@
-%__pgp %{_pgpbin}
+%__pgp @PGPBIN@
%__python @__PYTHON@
%__rm @__RM@
%__rsh @__RSH@
%__sed @__SED@
%__ssh @__SSH@
%__tar @__TAR@
-%__unzip %{_unzipbin}
+%__unzip @UNZIPBIN@
#==============================================================================
# ---- Build system path macros.
@@ -85,12 +85,24 @@
# These are the default values that can be overridden by other
# (e.g. per-platform, per-system, per-packager, per-package) macros.
#
+#
+# The directory where sources/patches will be unpacked and built.
%_builddir %{_topdir}/BUILD
+
+# The interpreter used for build scriptlets.
%_buildshell /bin/sh
-%_bzip2bin @BZIP2BIN@
+
+# The path to the bzip2 executable (legacy).
+%_bzip2bin %{__bzip2}
+
+# The location of the rpm database file(s).
%_dbpath %{_var}/lib/rpm
+
+# The location of the rpm database file(s) after "rpm --rebuilddb".
%_dbpath_rebuild %{_dbpath}
+
%_defaultdocdir %{_usr}/doc
+
#
%__find_provides @FINDPROVIDES@
%__find_requires @FINDREQUIRES@
@@ -106,20 +118,46 @@
%_fixgroup [ `%{__id_u}` = '0' ] && %{__chgrp_Rhf} @ROOT_GROUP@
%_fixperms %{__chmod} -Rf @FIXPERMS@
#
-%_gzipbin @GZIPBIN@
+
+# The path to the gzip executable (legacy).
+%_gzipbin %{__gzip}
+
+# The number of changelog entries kept when installing (legacy, unused in
+# rpm-4.0.1 and later).
%_instchangelog 5
-%_pgpbin @PGPBIN@
+
+# The path to the pgp executable (legacy).
+%_pgpbin %{__pgp}
+
+# The directory where newly built binary packages will be written.
%_rpmdir %{_topdir}/RPMS
-#
-# XXX Note escaped %% for use in headerSprintf
-%_rpmfilename %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
+
+# A template used to generate the output binary package file name
+# (legacy).
+%_rpmfilename %{_build_name_fmt}
+
+# The default signature type.
%_signature none
+
+# The directory where sources/patches from a source package will be
+# installed. This is also where sources/patches are found when building.
%_sourcedir %{_topdir}/SOURCES
+
+# The directory where the spec file from a source package will be
+# installed.
%_specdir %{_topdir}/SPECS
+
+# The directory where newly built source packages will be written.
%_srcrpmdir %{_topdir}/SRPMS
+
+# Directory where temporaray files can be created.
%_tmppath %{_var}/tmp
+
+# Path to top of build area.
%_topdir %{_usrsrc}/redhat
-%_unzipbin @UNZIPBIN@
+
+# The path to the unzip executable (legacy).
+%_unzipbin %{__unzip}
#==============================================================================
# ---- Optional rpmrc macros.
@@ -183,6 +221,7 @@
#
# Deprecated.
+#
#%_langpatt
# A colon separated list of paths where files should *not* be installed.
@@ -269,6 +308,25 @@
%_dbi_config_Depends %{_dbi_config}:temporary
#==============================================================================
+# ---- transaction macros.
+# Macro(s) used to parameterize
+#
+# The output binary package file name template used when building
+# binary packages.
+# XXX Note escaped %% for use in headerSprintf
+%_build_name_fmt %%{ARCH}/%%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
+
+# The output binary package file name template used when repackaging
+# erased packages.
+# XXX Note escaped %% for use in headerSprintf
+%_repackage_name_fmt %%{NAME}-%%{VERSION}-%%{RELEASE}.%%{ARCH}.rpm
+
+# The directory in which erased packages will be saved when using
+# the --repackage option.
+%_repackage_dir /var/tmp
+%_repackage_root %{nil}
+
+#==============================================================================
# ---- per-platform macros.
# Macros that are specific to an individual platform. The values here
# will be used if the per-platform macro file does not exist..
@@ -291,22 +349,22 @@
# ---- Scriptlet template templates.
# Global defaults used for building scriptlet templates.
#
-# XXX legacy configuration, this will be eliminated after rpm-3.0.4.
-%_preScriptEnvironment \
-RPM_SOURCE_DIR=\"%{_sourcedir}\"\
-RPM_BUILD_DIR=\"%{_builddir}\"\
-RPM_OPT_FLAGS=\"%{optflags}\"\
-RPM_ARCH=\"%{_arch}\"\
-RPM_OS=\"%{_os}\"\
-export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
-RPM_DOC_DIR=\"%{_docdir}\"\
-export RPM_DOC_DIR\
-RPM_PACKAGE_NAME=\"%{name}\"\
-RPM_PACKAGE_VERSION=\"%{version}\"\
-RPM_PACKAGE_RELEASE=\"%{release}\"\
-export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\
-%{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\
-export RPM_BUILD_ROOT}
+# XXX legacy configuration, use ___build_pre et al instead.
+#%_preScriptEnvironment \
+#RPM_SOURCE_DIR=\"%{_sourcedir}\"\
+#RPM_BUILD_DIR=\"%{_builddir}\"\
+#RPM_OPT_FLAGS=\"%{optflags}\"\
+#RPM_ARCH=\"%{_arch}\"\
+#RPM_OS=\"%{_os}\"\
+#export RPM_SOURCE_DIR RPM_BUILD_DIR RPM_OPT_FLAGS RPM_ARCH RPM_OS\
+#RPM_DOC_DIR=\"%{_docdir}\"\
+#export RPM_DOC_DIR\
+#RPM_PACKAGE_NAME=\"%{name}\"\
+#RPM_PACKAGE_VERSION=\"%{version}\"\
+#RPM_PACKAGE_RELEASE=\"%{release}\"\
+#export RPM_PACKAGE_NAME RPM_PACKAGE_VERSION RPM_PACKAGE_RELEASE\
+#%{?buildroot:RPM_BUILD_ROOT=\"%{buildroot}\"\
+#export RPM_BUILD_ROOT}
%___build_shell %{?_buildshell:%{_buildshell}}%{!?_buildshell:/bin/sh}
%___build_args -e
@@ -502,9 +560,7 @@ cd %{u2p:%{_builddir}}\
# run configure with correct prefix, platform, and CFLAGS.
# optionally restore current directory (not implemented).
# The configure macro should be invoked as %configure (rather than %{configure})
-# because the rest of the arguments will be expanded using %*. Another
-# gotcha is that arguments, if present, should be on the same line as the
-# %configure.
+# because the rest of the arguments will be expanded using %*.
#
# This is the version of %configure used through rpm-3.0.4.
#%configure \
@@ -637,7 +693,7 @@ done \
# arch macro for all Intel i?86 compatibile processors
# (Note: This macro (and it's analogues) will probably be obsoleted when
# rpm can use regular expressions against target platforms in macro
-# conditionals. This change will be introduced after rpm-3.0.4).
+# conditionals.
#
%ix86 i386 i486 i586 i686 i786 i886 i986
diff --git a/po/rpm.pot b/po/rpm.pot
index ec772b742..46008d5c3 100644
--- a/po/rpm.pot
+++ b/po/rpm.pot
@@ -6,7 +6,7 @@
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2001-02-10 11:46-0500\n"
+"POT-Creation-Date: 2001-02-11 16:49-0500\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -1808,7 +1808,7 @@ msgstr ""
msgid "Could not open %s: %s\n"
msgstr ""
-#: build/pack.c:481
+#: build/pack.c:481 lib/psm.c:1384
#, c-format
msgid "Unable to write package: %s\n"
msgstr ""
@@ -1838,7 +1838,7 @@ msgstr ""
msgid "Unable to write payload to %s: %s\n"
msgstr ""
-#: build/pack.c:563
+#: build/pack.c:563 lib/psm.c:1448
#, c-format
msgid "Wrote: %s\n"
msgstr ""
@@ -2459,7 +2459,7 @@ msgid ""
msgstr ""
#: lib/formats.c:86 lib/formats.c:112 lib/formats.c:141 lib/formats.c:182
-#: lib/header.c:2551 lib/header.c:2568 lib/header.c:2588
+#: lib/header.c:2596 lib/header.c:2613 lib/header.c:2633
msgid "(not a number)"
msgstr ""
@@ -2492,41 +2492,41 @@ msgstr ""
msgid "file %s is on an unknown device\n"
msgstr ""
-#: lib/fsm.c:214
+#: lib/fsm.c:272
msgid "========= Directories not explictly included in package:\n"
msgstr ""
-#: lib/fsm.c:216
+#: lib/fsm.c:274
#, c-format
msgid "%9d %s\n"
msgstr ""
-#: lib/fsm.c:1177
+#: lib/fsm.c:1042
#, c-format
msgid "%s directory created with perms %04o.\n"
msgstr ""
-#: lib/fsm.c:1279 lib/fsm.c:1395
+#: lib/fsm.c:1344 lib/fsm.c:1461
#, c-format
msgid "%s saved as %s\n"
msgstr ""
-#: lib/fsm.c:1420
+#: lib/fsm.c:1486
#, c-format
msgid "%s rmdir of %s failed: Directory not empty\n"
msgstr ""
-#: lib/fsm.c:1425
+#: lib/fsm.c:1491
#, c-format
msgid "%s rmdir of %s failed: %s\n"
msgstr ""
-#: lib/fsm.c:1434
+#: lib/fsm.c:1500
#, c-format
msgid "%s unlink of %s failed: %s\n"
msgstr ""
-#: lib/fsm.c:1451
+#: lib/fsm.c:1517
#, c-format
msgid "%s created as %s\n"
msgstr ""
@@ -2536,88 +2536,88 @@ msgstr ""
msgid "dataLength() RPM_STRING_TYPE count must be 1.\n"
msgstr ""
-#: lib/header.c:207 lib/header.c:1036 lib/psm.c:500
+#: lib/header.c:207 lib/header.c:1081 lib/psm.c:504
#, c-format
msgid "Data type %d not supported\n"
msgstr ""
-#: lib/header.c:1459
+#: lib/header.c:1504
#, c-format
msgid "Bad count for headerAddEntry(): %d\n"
msgstr ""
#. @-observertrans@
-#: lib/header.c:1904
+#: lib/header.c:1949
#, c-format
msgid "missing { after %"
msgstr ""
#. @-observertrans@
-#: lib/header.c:1934
+#: lib/header.c:1979
msgid "missing } after %{"
msgstr ""
#. @-observertrans@
-#: lib/header.c:1948
+#: lib/header.c:1993
msgid "empty tag format"
msgstr ""
#. @-observertrans@
-#: lib/header.c:1960
+#: lib/header.c:2005
msgid "empty tag name"
msgstr ""
#. @-observertrans@
-#: lib/header.c:1977
+#: lib/header.c:2022
msgid "unknown tag"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2004
+#: lib/header.c:2049
msgid "] expected at end of array"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2022
+#: lib/header.c:2067
msgid "unexpected ]"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2026
+#: lib/header.c:2071
msgid "unexpected }"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2086
+#: lib/header.c:2131
msgid "? expected in expression"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2095
+#: lib/header.c:2140
msgid "{ expected after ? in expression"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2108 lib/header.c:2149
+#: lib/header.c:2153 lib/header.c:2194
msgid "} expected in expression"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2118
+#: lib/header.c:2163
msgid ": expected following ? subexpression"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2134
+#: lib/header.c:2179
msgid "{ expected after : in expression"
msgstr ""
#. @-observertrans@
-#: lib/header.c:2159
+#: lib/header.c:2204
msgid "| expected at end of expression"
msgstr ""
-#: lib/header.c:2330
+#: lib/header.c:2375
msgid "(unknown type)"
msgstr ""
@@ -2626,11 +2626,11 @@ msgstr ""
msgid "error creating temporary file %s\n"
msgstr ""
-#: lib/package.c:88
+#: lib/package.c:118
msgid "packaging version 1 is not supported by this version of RPM\n"
msgstr ""
-#: lib/package.c:143
+#: lib/package.c:173
msgid ""
"only packaging with major numbers <= 4 is supported by this version of RPM\n"
msgstr ""
@@ -2904,12 +2904,12 @@ msgstr ""
msgid "unknown error %d encountered while manipulating package %s"
msgstr ""
-#: lib/psm.c:344
+#: lib/psm.c:348
#, c-format
msgid "user %s does not exist - using root\n"
msgstr ""
-#: lib/psm.c:352
+#: lib/psm.c:356
#, c-format
msgid "group %s does not exist - using root\n"
msgstr ""
@@ -2919,48 +2919,48 @@ msgstr ""
#. * was used up - if so, we should return a different error.
#.
#. XXX FIXME: Fclose with libio destroys errno
-#: lib/psm.c:725
+#: lib/psm.c:728
#, c-format
msgid "unpacking of archive failed%s%s: %s\n"
msgstr ""
-#: lib/psm.c:726
+#: lib/psm.c:729
msgid " on file "
msgstr ""
-#: lib/psm.c:767
+#: lib/psm.c:770
#, c-format
msgid "cannot create %s %s\n"
msgstr ""
-#: lib/psm.c:773
+#: lib/psm.c:776
#, c-format
msgid "cannot write to %s\n"
msgstr ""
-#: lib/psm.c:794
+#: lib/psm.c:797
msgid "installing a source package\n"
msgstr ""
-#: lib/psm.c:846
+#: lib/psm.c:849
msgid "source package contains no .spec file\n"
msgstr ""
-#: lib/psm.c:926
+#: lib/psm.c:929
msgid "source package expected, binary found\n"
msgstr ""
-#: lib/psm.c:997 lib/psm.c:1188
+#: lib/psm.c:1000 lib/psm.c:1191
#, c-format
msgid "%s: %s-%s-%s has %d files, test = %d\n"
msgstr ""
-#: lib/psm.c:1061 lib/psm.c:1143 lib/psm.c:1231 lib/psm.c:1253
+#: lib/psm.c:1064 lib/psm.c:1146 lib/psm.c:1235 lib/psm.c:1257
#, c-format
msgid "%s: running %s script(s) (if any)\n"
msgstr ""
-#: lib/psm.c:1068
+#: lib/psm.c:1071
msgid "skipping %s-%s-%s install, %%pre scriptlet failed rc %d\n"
msgstr ""
@@ -3568,100 +3568,95 @@ msgstr ""
msgid "Old (internal-only) signature! How did you get that!?\n"
msgstr ""
-#: lib/signature.c:211
-#, c-format
-msgid "Signature size: %d\n"
-msgstr ""
-
-#: lib/signature.c:212
+#: lib/signature.c:218
#, c-format
-msgid "Signature pad : %d\n"
+msgid "Signature: size(%d)+pad(%d)\n"
msgstr ""
-#: lib/signature.c:274
+#: lib/signature.c:277
#, c-format
msgid "Couldn't exec pgp (%s)\n"
msgstr ""
-#: lib/signature.c:285
+#: lib/signature.c:288
msgid "pgp failed\n"
msgstr ""
#. PGP failed to write signature
#. Just in case
-#: lib/signature.c:292
+#: lib/signature.c:295
msgid "pgp failed to write signature\n"
msgstr ""
-#: lib/signature.c:297
+#: lib/signature.c:300
#, c-format
msgid "PGP sig size: %d\n"
msgstr ""
-#: lib/signature.c:308 lib/signature.c:385
+#: lib/signature.c:311 lib/signature.c:388
msgid "unable to read the signature\n"
msgstr ""
-#: lib/signature.c:313
+#: lib/signature.c:316
#, c-format
msgid "Got %d bytes of PGP sig\n"
msgstr ""
-#: lib/signature.c:351 lib/signature.c:694
+#: lib/signature.c:354 lib/signature.c:700
msgid "Couldn't exec gpg\n"
msgstr ""
-#: lib/signature.c:362
+#: lib/signature.c:365
msgid "gpg failed\n"
msgstr ""
#. GPG failed to write signature
#. Just in case
-#: lib/signature.c:369
+#: lib/signature.c:372
msgid "gpg failed to write signature\n"
msgstr ""
-#: lib/signature.c:374
+#: lib/signature.c:377
#, c-format
msgid "GPG sig size: %d\n"
msgstr ""
-#: lib/signature.c:390
+#: lib/signature.c:393
#, c-format
msgid "Got %d bytes of GPG sig\n"
msgstr ""
-#: lib/signature.c:417
+#: lib/signature.c:421
msgid "Generating signature using PGP.\n"
msgstr ""
-#: lib/signature.c:423
+#: lib/signature.c:427
msgid "Generating signature using GPG.\n"
msgstr ""
-#: lib/signature.c:502 lib/signature.c:563
+#: lib/signature.c:507 lib/signature.c:568
msgid "Could not run pgp. Use --nopgp to skip PGP checks.\n"
msgstr ""
-#: lib/signature.c:635
+#: lib/signature.c:641
msgid "Could not run gpg. Use --nogpg to skip GPG checks.\n"
msgstr ""
-#: lib/signature.c:723
+#: lib/signature.c:729
msgid "Couldn't exec pgp\n"
msgstr ""
#. @notreached@
#. This case should have been screened out long ago.
-#: lib/signature.c:727 lib/signature.c:780
+#: lib/signature.c:733 lib/signature.c:786
msgid "Invalid %%_signature spec in macro file\n"
msgstr ""
-#: lib/signature.c:760
+#: lib/signature.c:766
msgid "You must set \"%%_gpg_name\" in your macro file\n"
msgstr ""
-#: lib/signature.c:772
+#: lib/signature.c:778
msgid "You must set \"%%_pgp_name\" in your macro file\n"
msgstr ""