2000-08-28 03:18:25 +08:00
|
|
|
/** \ingroup rpmbuild
|
|
|
|
* \file build/files.c
|
2000-01-25 04:02:32 +08:00
|
|
|
* The post-build, pre-packaging file tree walk to assemble the package
|
|
|
|
* manifest.
|
|
|
|
*/
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
#include "system.h"
|
1998-03-05 00:51:06 +08:00
|
|
|
|
1999-02-21 11:57:09 +08:00
|
|
|
#define MYALLPERMS 07777
|
1999-01-14 06:53:33 +08:00
|
|
|
|
1998-03-20 12:34:09 +08:00
|
|
|
#include <regex.h>
|
1998-07-26 05:00:26 +08:00
|
|
|
#include <signal.h> /* getOutputFrom() */
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2000-06-20 23:54:48 +08:00
|
|
|
#include <rpmio_internal.h>
|
1999-10-30 07:03:12 +08:00
|
|
|
#include <rpmbuild.h>
|
|
|
|
|
1998-08-09 06:27:08 +08:00
|
|
|
#include "buildio.h"
|
1998-07-31 06:09:42 +08:00
|
|
|
|
1996-06-08 02:32:10 +08:00
|
|
|
#include "myftw.h"
|
2001-11-19 01:49:21 +08:00
|
|
|
#include "legacy.h" /* XXX domd5, expandFileList, compressFileList */
|
2001-09-26 00:21:44 +08:00
|
|
|
#include "misc.h"
|
2000-12-13 04:03:45 +08:00
|
|
|
#include "debug.h"
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-03-15 07:09:09 +08:00
|
|
|
/*@access Header @*/
|
|
|
|
/*@access TFI_t @*/
|
|
|
|
/*@access FD_t @*/
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@access StringBuf @*/ /* compared with NULL */
|
2001-03-15 07:09:09 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
#define SKIPWHITE(_x) {while(*(_x) && (xisspace(*_x) || *(_x) == ',')) (_x)++;}
|
|
|
|
#define SKIPNONWHITE(_x){while(*(_x) &&!(xisspace(*_x) || *(_x) == ',')) (_x)++;}
|
1999-07-04 06:58:08 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
#define MAXDOCDIR 1024
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
/**
|
|
|
|
*/
|
|
|
|
typedef enum specdFlags_e {
|
|
|
|
SPECD_DEFFILEMODE = (1 << 0),
|
|
|
|
SPECD_DEFDIRMODE = (1 << 1),
|
|
|
|
SPECD_DEFUID = (1 << 2),
|
|
|
|
SPECD_DEFGID = (1 << 3),
|
|
|
|
SPECD_DEFVERIFY = (1 << 4),
|
|
|
|
|
|
|
|
SPECD_FILEMODE = (1 << 8),
|
|
|
|
SPECD_DIRMODE = (1 << 9),
|
|
|
|
SPECD_UID = (1 << 10),
|
|
|
|
SPECD_GID = (1 << 11),
|
|
|
|
SPECD_VERIFY = (1 << 12)
|
|
|
|
} specdFlags;
|
2001-03-17 00:33:25 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
typedef struct FileListRec_s {
|
1998-11-25 08:42:36 +08:00
|
|
|
struct stat fl_st;
|
|
|
|
#define fl_dev fl_st.st_dev
|
|
|
|
#define fl_ino fl_st.st_ino
|
|
|
|
#define fl_mode fl_st.st_mode
|
2001-07-16 22:48:07 +08:00
|
|
|
#define fl_nlink fl_st.st_nlink
|
1998-11-25 08:42:36 +08:00
|
|
|
#define fl_uid fl_st.st_uid
|
|
|
|
#define fl_gid fl_st.st_gid
|
|
|
|
#define fl_rdev fl_st.st_rdev
|
|
|
|
#define fl_size fl_st.st_size
|
|
|
|
#define fl_mtime fl_st.st_mtime
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
/*@only@*/ const char * diskURL; /* get file from here */
|
|
|
|
/*@only@*/ const char * fileURL; /* filename in cpio archive */
|
|
|
|
/*@observer@*/ const char * uname;
|
|
|
|
/*@observer@*/ const char * gname;
|
2002-01-19 06:51:30 +08:00
|
|
|
unsigned flags;
|
2001-04-29 09:05:43 +08:00
|
|
|
specdFlags specdFlags; /* which attributes have been explicitly specified. */
|
2002-01-19 06:51:30 +08:00
|
|
|
unsigned verifyFlags;
|
2001-04-29 09:05:43 +08:00
|
|
|
/*@only@*/ const char *langs; /* XXX locales separated with | */
|
|
|
|
} * FileListRec;
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
typedef struct AttrRec_s {
|
|
|
|
const char * ar_fmodestr;
|
|
|
|
const char * ar_dmodestr;
|
|
|
|
const char * ar_user;
|
|
|
|
const char * ar_group;
|
1998-11-26 03:31:10 +08:00
|
|
|
mode_t ar_fmode;
|
|
|
|
mode_t ar_dmode;
|
2001-04-29 09:05:43 +08:00
|
|
|
} * AttrRec;
|
1998-11-26 03:31:10 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@unchecked@*/
|
2000-07-06 04:39:15 +08:00
|
|
|
static int multiLib = 0; /* MULTILIB */
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* Package file tree walk data.
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
typedef struct FileList_s {
|
|
|
|
/*@only@*/ const char * buildRootURL;
|
|
|
|
/*@only@*/ const char * prefix;
|
1997-03-31 22:14:20 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
int fileCount;
|
|
|
|
int totalFileSize;
|
|
|
|
int processingFailed;
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
int passedSpecialDoc;
|
|
|
|
int isSpecialDoc;
|
2001-07-16 22:48:07 +08:00
|
|
|
|
|
|
|
int noGlob;
|
|
|
|
unsigned devtype;
|
|
|
|
unsigned devmajor;
|
|
|
|
int devminor;
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
int isDir;
|
|
|
|
int inFtw;
|
|
|
|
int currentFlags;
|
2001-04-29 09:05:43 +08:00
|
|
|
specdFlags currentSpecdFlags;
|
1998-01-13 05:31:29 +08:00
|
|
|
int currentVerifyFlags;
|
2001-04-29 09:05:43 +08:00
|
|
|
struct AttrRec_s cur_ar;
|
|
|
|
struct AttrRec_s def_ar;
|
|
|
|
specdFlags defSpecdFlags;
|
1998-01-13 05:31:29 +08:00
|
|
|
int defVerifyFlags;
|
1999-05-18 00:27:38 +08:00
|
|
|
int nLangs;
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@only@*/ /*@null@*/ const char ** currentLangs;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
|
|
|
/* Hard coded limit of MAXDOCDIR docdirs. */
|
|
|
|
/* If you break it you are doing something wrong. */
|
2001-04-29 09:05:43 +08:00
|
|
|
const char * docDirs[MAXDOCDIR];
|
1998-01-13 05:31:29 +08:00
|
|
|
int docDirCount;
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
/*@only@*/ FileListRec fileList;
|
1998-01-13 05:31:29 +08:00
|
|
|
int fileListRecsAlloced;
|
|
|
|
int fileListRecsUsed;
|
2001-04-29 09:05:43 +08:00
|
|
|
} * FileList;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static void nullAttrRec(/*@out@*/ AttrRec ar) /*@modifies ar @*/
|
1999-10-05 01:29:58 +08:00
|
|
|
{
|
|
|
|
ar->ar_fmodestr = NULL;
|
|
|
|
ar->ar_dmodestr = NULL;
|
|
|
|
ar->ar_user = NULL;
|
|
|
|
ar->ar_group = NULL;
|
|
|
|
ar->ar_fmode = 0;
|
|
|
|
ar->ar_dmode = 0;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static void freeAttrRec(AttrRec ar) /*@modifies ar @*/
|
1999-10-05 01:29:58 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
ar->ar_fmodestr = _free(ar->ar_fmodestr);
|
|
|
|
ar->ar_dmodestr = _free(ar->ar_dmodestr);
|
|
|
|
ar->ar_user = _free(ar->ar_user);
|
|
|
|
ar->ar_group = _free(ar->ar_group);
|
1998-11-26 03:31:10 +08:00
|
|
|
/* XXX doesn't free ar (yet) */
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullstate@*/
|
|
|
|
return;
|
|
|
|
/*@=nullstate@*/
|
1998-11-26 03:31:10 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
static void dupAttrRec(const AttrRec oar, /*@in@*/ /*@out@*/ AttrRec nar)
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@modifies nar @*/
|
1999-10-05 01:29:58 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
if (oar == nar)
|
1999-01-28 03:40:01 +08:00
|
|
|
return;
|
|
|
|
freeAttrRec(nar);
|
1999-10-05 01:29:58 +08:00
|
|
|
nar->ar_fmodestr = (oar->ar_fmodestr ? xstrdup(oar->ar_fmodestr) : NULL);
|
|
|
|
nar->ar_dmodestr = (oar->ar_dmodestr ? xstrdup(oar->ar_dmodestr) : NULL);
|
|
|
|
nar->ar_user = (oar->ar_user ? xstrdup(oar->ar_user) : NULL);
|
|
|
|
nar->ar_group = (oar->ar_group ? xstrdup(oar->ar_group) : NULL);
|
|
|
|
nar->ar_fmode = oar->ar_fmode;
|
|
|
|
nar->ar_dmode = oar->ar_dmode;
|
1998-11-26 03:31:10 +08:00
|
|
|
}
|
|
|
|
|
1999-01-28 03:40:01 +08:00
|
|
|
#if 0
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-07 03:17:14 +08:00
|
|
|
static void dumpAttrRec(const char * msg, AttrRec ar)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals fileSystem@*/
|
2001-05-07 03:17:14 +08:00
|
|
|
/*@modifies fileSystem @*/
|
2001-05-04 05:00:18 +08:00
|
|
|
{
|
1999-01-28 03:40:01 +08:00
|
|
|
if (msg)
|
|
|
|
fprintf(stderr, "%s:\t", msg);
|
|
|
|
fprintf(stderr, "(%s, %s, %s, %s)\n",
|
|
|
|
ar->ar_fmodestr,
|
|
|
|
ar->ar_user,
|
|
|
|
ar->ar_group,
|
|
|
|
ar->ar_dmodestr);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* strtokWithQuotes() modified from glibc strtok() */
|
|
|
|
/* Copyright (C) 1991, 1996 Free Software Foundation, Inc.
|
|
|
|
This file is part of the GNU C Library.
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
The GNU C Library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public License as
|
|
|
|
published by the Free Software Foundation; either version 2 of the
|
|
|
|
License, or (at your option) any later version.
|
1998-04-30 23:20:58 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
The GNU C Library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
You should have received a copy of the GNU Library General Public
|
|
|
|
License along with the GNU C Library; see the file COPYING.LIB. If
|
|
|
|
not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
Boston, MA 02111-1307, USA. */
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1998-07-26 05:00:26 +08:00
|
|
|
static char *strtokWithQuotes(char *s, char *delim)
|
2001-12-09 01:21:36 +08:00
|
|
|
/*@modifies *s @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
|
|
|
static char *olds = NULL;
|
|
|
|
char *token;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (s == NULL) {
|
|
|
|
s = olds;
|
|
|
|
}
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Skip leading delimiters */
|
|
|
|
s += strspn(s, delim);
|
|
|
|
if (*s == '\0') {
|
|
|
|
return NULL;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Find the end of the token. */
|
|
|
|
token = s;
|
|
|
|
if (*token == '"') {
|
|
|
|
token++;
|
|
|
|
/* Find next " char */
|
|
|
|
s = strchr(token, '"');
|
|
|
|
} else {
|
|
|
|
s = strpbrk(token, delim);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Terminate it */
|
|
|
|
if (s == NULL) {
|
|
|
|
/* This token finishes the string */
|
|
|
|
olds = strchr(token, '\0');
|
|
|
|
} else {
|
|
|
|
/* Terminate the token and make olds point past it */
|
|
|
|
*s = '\0';
|
|
|
|
olds = s+1;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2001-12-09 01:21:36 +08:00
|
|
|
/*@-retalias -temptrans @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
return token;
|
2001-12-09 01:21:36 +08:00
|
|
|
/*@=retalias =temptrans @*/
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-10-16 01:53:34 +08:00
|
|
|
static void timeCheck(int tc, Header h)
|
|
|
|
/*@globals internalState @*/
|
|
|
|
/*@modifies internalState @*/
|
1998-01-13 05:31:29 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
|
|
HFD_t hfd = headerFreeData;
|
2001-06-12 12:10:21 +08:00
|
|
|
int * mtime;
|
2001-04-29 09:05:43 +08:00
|
|
|
const char ** files;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType fnt;
|
2001-04-29 09:05:43 +08:00
|
|
|
int count, x;
|
|
|
|
time_t currentTime = time(NULL);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
x = hge(h, RPMTAG_OLDFILENAMES, &fnt, (void **) &files, &count);
|
|
|
|
x = hge(h, RPMTAG_FILEMTIMES, NULL, (void **) &mtime, NULL);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-11-25 03:30:38 +08:00
|
|
|
for (x = 0; x < count; x++) {
|
2001-04-29 09:05:43 +08:00
|
|
|
if ((currentTime - mtime[x]) > tc)
|
1999-10-30 00:06:01 +08:00
|
|
|
rpmMessage(RPMMESS_WARNING, _("TIMECHECK failure: %s\n"), files[x]);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
files = hfd(files, fnt);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1998-11-26 03:09:55 +08:00
|
|
|
typedef struct VFA {
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@observer@*/ /*@null@*/ const char * attribute;
|
|
|
|
int flag;
|
1998-11-26 03:09:55 +08:00
|
|
|
} VFA_t;
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@-exportlocal -exportheadervar@*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@unchecked@*/
|
1998-11-26 03:09:55 +08:00
|
|
|
VFA_t verifyAttrs[] = {
|
2001-06-06 03:26:22 +08:00
|
|
|
{ "md5", RPMVERIFY_MD5 },
|
|
|
|
{ "size", RPMVERIFY_FILESIZE },
|
|
|
|
{ "link", RPMVERIFY_LINKTO },
|
|
|
|
{ "user", RPMVERIFY_USER },
|
|
|
|
{ "group", RPMVERIFY_GROUP },
|
|
|
|
{ "mtime", RPMVERIFY_MTIME },
|
|
|
|
{ "mode", RPMVERIFY_MODE },
|
|
|
|
{ "rdev", RPMVERIFY_RDEV },
|
|
|
|
{ NULL, 0 }
|
1998-11-26 03:09:55 +08:00
|
|
|
};
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@=exportlocal =exportheadervar@*/
|
1998-11-26 03:09:55 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int parseForVerify(char * buf, FileList fl)
|
|
|
|
/*@modifies buf, fl->processingFailed,
|
|
|
|
fl->currentVerifyFlags, fl->defVerifyFlags,
|
|
|
|
fl->currentSpecdFlags, fl->defSpecdFlags @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1999-07-04 06:58:08 +08:00
|
|
|
char *p, *pe, *q;
|
|
|
|
const char *name;
|
1998-07-26 05:00:26 +08:00
|
|
|
int *resultVerify;
|
2001-06-04 21:55:58 +08:00
|
|
|
int negated;
|
1999-07-04 06:58:08 +08:00
|
|
|
int verifyFlags;
|
2001-04-29 09:05:43 +08:00
|
|
|
specdFlags * specdFlags;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if ((p = strstr(buf, (name = "%verify"))) != NULL) {
|
1998-07-26 05:00:26 +08:00
|
|
|
resultVerify = &(fl->currentVerifyFlags);
|
2001-03-17 00:33:25 +08:00
|
|
|
specdFlags = &fl->currentSpecdFlags;
|
1999-07-04 06:58:08 +08:00
|
|
|
} else if ((p = strstr(buf, (name = "%defverify"))) != NULL) {
|
|
|
|
resultVerify = &(fl->defVerifyFlags);
|
2001-03-17 00:33:25 +08:00
|
|
|
specdFlags = &fl->defSpecdFlags;
|
1999-07-04 06:58:08 +08:00
|
|
|
} else
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (pe = p; (pe-p) < strlen(name); pe++)
|
|
|
|
*pe = ' ';
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
SKIPSPACE(pe);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (*pe != '(') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
1997-04-15 04:04:18 +08:00
|
|
|
}
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Bracket %*verify args */
|
|
|
|
*pe++ = ' ';
|
|
|
|
for (p = pe; *pe && *pe != ')'; pe++)
|
2001-06-06 03:26:22 +08:00
|
|
|
{};
|
1997-04-15 04:04:18 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (*pe == '\0') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Localize. Erase parsed string */
|
|
|
|
q = alloca((pe-p) + 1);
|
|
|
|
strncpy(q, p, pe-p);
|
|
|
|
q[pe-p] = '\0';
|
|
|
|
while (p <= pe)
|
|
|
|
*p++ = ' ';
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-06-04 21:55:58 +08:00
|
|
|
negated = 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
verifyFlags = RPMVERIFY_NONE;
|
1998-11-25 03:30:38 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
for (p = q; *p != '\0'; p = pe) {
|
1999-07-04 06:58:08 +08:00
|
|
|
SKIPWHITE(p);
|
|
|
|
if (*p == '\0')
|
|
|
|
break;
|
|
|
|
pe = p;
|
|
|
|
SKIPNONWHITE(pe);
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*pe != '\0')
|
1999-07-04 06:58:08 +08:00
|
|
|
*pe++ = '\0';
|
|
|
|
|
1998-11-26 03:09:55 +08:00
|
|
|
{ VFA_t *vfa;
|
|
|
|
for (vfa = verifyAttrs; vfa->attribute != NULL; vfa++) {
|
|
|
|
if (strcmp(p, vfa->attribute))
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
1998-11-26 03:09:55 +08:00
|
|
|
verifyFlags |= vfa->flag;
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@innerbreak@*/ break;
|
1998-11-26 03:09:55 +08:00
|
|
|
}
|
|
|
|
if (vfa->attribute)
|
|
|
|
continue;
|
|
|
|
}
|
1999-07-04 06:58:08 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (!strcmp(p, "not")) {
|
2001-06-04 21:55:58 +08:00
|
|
|
negated ^= 1;
|
1998-06-03 03:53:21 +08:00
|
|
|
} else {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Invalid %s token: %s\n"), name, p);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-06-04 21:55:58 +08:00
|
|
|
*resultVerify = negated ? ~(verifyFlags) : verifyFlags;
|
2001-03-17 00:33:25 +08:00
|
|
|
*specdFlags |= SPECD_VERIFY;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1998-11-26 04:23:32 +08:00
|
|
|
#define isAttrDefault(_ars) ((_ars)[0] == '-' && (_ars)[1] == '\0')
|
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
/**
|
|
|
|
* Parse %dev from file manifest.
|
|
|
|
* @param fl package file tree walk data
|
|
|
|
*/
|
|
|
|
static int parseForDev(char * buf, FileList fl)
|
|
|
|
/*@modifies buf, fl->processingFailed,
|
|
|
|
fl->noGlob, fl->devtype, fl->devmajor, fl->devminor @*/
|
|
|
|
{
|
|
|
|
const char * name;
|
|
|
|
const char * errstr = NULL;
|
|
|
|
char *p, *pe, *q;
|
|
|
|
int rc = RPMERR_BADSPEC; /* assume error */
|
|
|
|
|
|
|
|
if ((p = strstr(buf, (name = "%dev"))) == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (pe = p; (pe-p) < strlen(name); pe++)
|
|
|
|
*pe = ' ';
|
|
|
|
SKIPSPACE(pe);
|
|
|
|
|
|
|
|
if (*pe != '(') {
|
|
|
|
errstr = "'('";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Bracket %dev args */
|
|
|
|
*pe++ = ' ';
|
|
|
|
for (p = pe; *pe && *pe != ')'; pe++)
|
|
|
|
{};
|
|
|
|
if (*pe != ')') {
|
|
|
|
errstr = "')'";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Localize. Erase parsed string */
|
|
|
|
q = alloca((pe-p) + 1);
|
|
|
|
strncpy(q, p, pe-p);
|
|
|
|
q[pe-p] = '\0';
|
|
|
|
while (p <= pe)
|
|
|
|
*p++ = ' ';
|
|
|
|
|
|
|
|
p = q; SKIPWHITE(p);
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
|
|
|
if (*p == 'b')
|
|
|
|
fl->devtype = 'b';
|
|
|
|
else if (*p == 'c')
|
|
|
|
fl->devtype = 'c';
|
|
|
|
else {
|
|
|
|
errstr = "devtype";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
|
|
|
for (pe = p; *pe && xisdigit(*pe); pe++)
|
|
|
|
{} ;
|
|
|
|
if (*pe == '\0') {
|
|
|
|
fl->devmajor = atoi(p);
|
2001-09-21 23:07:11 +08:00
|
|
|
/*@-unsignedcompare @*/ /* LCL: ge is ok */
|
2001-07-16 22:48:07 +08:00
|
|
|
if (!(fl->devmajor >= 0 && fl->devmajor < 256)) {
|
|
|
|
errstr = "devmajor";
|
|
|
|
goto exit;
|
|
|
|
}
|
2001-09-21 23:07:11 +08:00
|
|
|
/*@=unsignedcompare @*/
|
2001-07-16 22:48:07 +08:00
|
|
|
pe++;
|
|
|
|
} else {
|
|
|
|
errstr = "devmajor";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
|
|
|
for (pe = p; *pe && xisdigit(*pe); pe++)
|
|
|
|
{} ;
|
|
|
|
if (*pe == '\0') {
|
|
|
|
fl->devminor = atoi(p);
|
|
|
|
if (!(fl->devminor >= 0 && fl->devminor < 256)) {
|
|
|
|
errstr = "devminor";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
pe++;
|
|
|
|
} else {
|
|
|
|
errstr = "devminor";
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
|
|
|
fl->noGlob = 1;
|
|
|
|
|
|
|
|
rc = 0;
|
|
|
|
|
|
|
|
exit:
|
|
|
|
if (rc) {
|
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing %s in %s %s\n"), errstr, name, p);
|
|
|
|
fl->processingFailed = 1;
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-06-26 04:01:42 +08:00
|
|
|
* Parse %attr and %defattr from file manifest.
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int parseForAttr(char * buf, FileList fl)
|
|
|
|
/*@modifies buf, fl->processingFailed,
|
|
|
|
fl->cur_ar, fl->def_ar,
|
|
|
|
fl->currentSpecdFlags, fl->defSpecdFlags @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1999-07-04 06:58:08 +08:00
|
|
|
const char *name;
|
2001-07-16 22:48:07 +08:00
|
|
|
char *p, *pe, *q;
|
1999-07-04 06:58:08 +08:00
|
|
|
int x;
|
2001-04-29 09:05:43 +08:00
|
|
|
struct AttrRec_s arbuf;
|
|
|
|
AttrRec ar = &arbuf, ret_ar;
|
|
|
|
specdFlags * specdFlags;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if ((p = strstr(buf, (name = "%attr"))) != NULL) {
|
1998-11-26 04:23:32 +08:00
|
|
|
ret_ar = &(fl->cur_ar);
|
2001-03-17 00:33:25 +08:00
|
|
|
specdFlags = &fl->currentSpecdFlags;
|
1999-07-04 06:58:08 +08:00
|
|
|
} else if ((p = strstr(buf, (name = "%defattr"))) != NULL) {
|
|
|
|
ret_ar = &(fl->def_ar);
|
2001-03-17 00:33:25 +08:00
|
|
|
specdFlags = &fl->defSpecdFlags;
|
1999-07-04 06:58:08 +08:00
|
|
|
} else
|
|
|
|
return 0;
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
for (pe = p; (pe-p) < strlen(name); pe++)
|
|
|
|
*pe = ' ';
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
SKIPSPACE(pe);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (*pe != '(') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Bracket %*attr args */
|
|
|
|
*pe++ = ' ';
|
|
|
|
for (p = pe; *pe && *pe != ')'; pe++)
|
2001-06-06 03:26:22 +08:00
|
|
|
{};
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (ret_ar == &(fl->def_ar)) { /* %defattr */
|
|
|
|
q = pe;
|
|
|
|
q++;
|
|
|
|
SKIPSPACE(q);
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*q != '\0') {
|
1998-07-26 05:00:26 +08:00
|
|
|
rpmError(RPMERR_BADSPEC,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Non-white space follows %s(): %s\n"), name, q);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
1997-03-31 22:14:20 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1997-03-31 22:14:20 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Localize. Erase parsed string */
|
|
|
|
q = alloca((pe-p) + 1);
|
|
|
|
strncpy(q, p, pe-p);
|
|
|
|
q[pe-p] = '\0';
|
|
|
|
while (p <= pe)
|
|
|
|
*p++ = ' ';
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
nullAttrRec(ar);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
p = q; SKIPWHITE(p);
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*p != '\0') {
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
1999-07-04 06:58:08 +08:00
|
|
|
ar->ar_fmodestr = p;
|
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*p != '\0') {
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
1999-07-04 06:58:08 +08:00
|
|
|
ar->ar_user = p;
|
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*p != '\0') {
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
1999-07-04 06:58:08 +08:00
|
|
|
ar->ar_group = p;
|
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*p != '\0' && ret_ar == &(fl->def_ar)) { /* %defattr */
|
|
|
|
pe = p; SKIPNONWHITE(pe); if (*pe != '\0') *pe++ = '\0';
|
2001-03-17 00:33:25 +08:00
|
|
|
ar->ar_dmodestr = p;
|
1999-07-04 06:58:08 +08:00
|
|
|
p = pe; SKIPWHITE(p);
|
|
|
|
}
|
1999-02-08 05:19:00 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (!(ar->ar_fmodestr && ar->ar_user && ar->ar_group) || *p != '\0') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad syntax: %s(%s)\n"), name, q);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Do a quick test on the mode argument and adjust for "-" */
|
1998-11-26 04:23:32 +08:00
|
|
|
if (ar->ar_fmodestr && !isAttrDefault(ar->ar_fmodestr)) {
|
|
|
|
unsigned int ui;
|
|
|
|
x = sscanf(ar->ar_fmodestr, "%o", &ui);
|
1999-02-21 11:57:09 +08:00
|
|
|
if ((x == 0) || (ar->ar_fmode & ~MYALLPERMS)) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad mode spec: %s(%s)\n"), name, q);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1998-11-26 04:23:32 +08:00
|
|
|
ar->ar_fmode = ui;
|
|
|
|
} else
|
|
|
|
ar->ar_fmodestr = NULL;
|
|
|
|
|
|
|
|
if (ar->ar_dmodestr && !isAttrDefault(ar->ar_dmodestr)) {
|
|
|
|
unsigned int ui;
|
|
|
|
x = sscanf(ar->ar_dmodestr, "%o", &ui);
|
1999-02-21 11:57:09 +08:00
|
|
|
if ((x == 0) || (ar->ar_dmode & ~MYALLPERMS)) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad dirmode spec: %s(%s)\n"), name, q);
|
1998-11-26 04:23:32 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
1998-11-26 04:23:32 +08:00
|
|
|
ar->ar_dmode = ui;
|
|
|
|
} else
|
|
|
|
ar->ar_dmodestr = NULL;
|
|
|
|
|
|
|
|
if (!(ar->ar_user && !isAttrDefault(ar->ar_user)))
|
1998-11-26 03:31:10 +08:00
|
|
|
ar->ar_user = NULL;
|
1998-11-26 04:23:32 +08:00
|
|
|
|
|
|
|
if (!(ar->ar_group && !isAttrDefault(ar->ar_group)))
|
1998-11-26 03:31:10 +08:00
|
|
|
ar->ar_group = NULL;
|
1998-11-26 04:23:32 +08:00
|
|
|
|
|
|
|
dupAttrRec(ar, ret_ar);
|
2001-03-17 00:33:25 +08:00
|
|
|
|
|
|
|
/* XXX fix all this */
|
|
|
|
*specdFlags |= SPECD_UID | SPECD_GID | SPECD_FILEMODE | SPECD_DIRMODE;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int parseForConfig(char * buf, FileList fl)
|
|
|
|
/*@modifies buf, fl->processingFailed,
|
|
|
|
fl->currentFlags @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1999-07-04 06:58:08 +08:00
|
|
|
char *p, *pe, *q;
|
|
|
|
const char *name;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if ((p = strstr(buf, (name = "%config"))) == NULL)
|
1998-07-26 05:00:26 +08:00
|
|
|
return 0;
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
fl->currentFlags = RPMFILE_CONFIG;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
for (pe = p; (pe-p) < strlen(name); pe++)
|
|
|
|
*pe = ' ';
|
|
|
|
SKIPSPACE(pe);
|
|
|
|
if (*pe != '(')
|
1998-07-26 05:00:26 +08:00
|
|
|
return 0;
|
1998-03-04 01:07:39 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Bracket %config args */
|
|
|
|
*pe++ = ' ';
|
|
|
|
for (p = pe; *pe && *pe != ')'; pe++)
|
2001-06-06 03:26:22 +08:00
|
|
|
{};
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (*pe == '\0') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Localize. Erase parsed string */
|
|
|
|
q = alloca((pe-p) + 1);
|
|
|
|
strncpy(q, p, pe-p);
|
|
|
|
q[pe-p] = '\0';
|
|
|
|
while (p <= pe)
|
|
|
|
*p++ = ' ';
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
for (p = q; *p != '\0'; p = pe) {
|
1999-07-04 06:58:08 +08:00
|
|
|
SKIPWHITE(p);
|
|
|
|
if (*p == '\0')
|
|
|
|
break;
|
|
|
|
pe = p;
|
|
|
|
SKIPNONWHITE(pe);
|
2001-05-01 06:32:22 +08:00
|
|
|
if (*pe != '\0')
|
1999-07-04 06:58:08 +08:00
|
|
|
*pe++ = '\0';
|
1998-07-26 05:00:26 +08:00
|
|
|
if (!strcmp(p, "missingok")) {
|
|
|
|
fl->currentFlags |= RPMFILE_MISSINGOK;
|
|
|
|
} else if (!strcmp(p, "noreplace")) {
|
|
|
|
fl->currentFlags |= RPMFILE_NOREPLACE;
|
|
|
|
} else {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Invalid %s token: %s\n"), name, p);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int langCmp(const void * ap, const void * bp) /*@*/
|
|
|
|
{
|
2001-01-19 09:38:55 +08:00
|
|
|
return strcmp(*(const char **)ap, *(const char **)bp);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param fl package file tree walk data
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int parseForLang(char * buf, FileList fl)
|
|
|
|
/*@modifies buf, fl->processingFailed,
|
|
|
|
fl->currentLangs, fl->nLangs @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1999-07-04 06:58:08 +08:00
|
|
|
char *p, *pe, *q;
|
|
|
|
const char *name;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
while ((p = strstr(buf, (name = "%lang"))) != NULL) {
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
for (pe = p; (pe-p) < strlen(name); pe++)
|
|
|
|
*pe = ' ';
|
|
|
|
SKIPSPACE(pe);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
if (*pe != '(') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing '(' in %s %s\n"), name, pe);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Bracket %lang args */
|
|
|
|
*pe++ = ' ';
|
1999-05-18 02:44:14 +08:00
|
|
|
for (pe = p; *pe && *pe != ')'; pe++)
|
2001-06-06 03:26:22 +08:00
|
|
|
{};
|
1999-07-04 06:58:08 +08:00
|
|
|
|
1999-05-18 02:44:14 +08:00
|
|
|
if (*pe == '\0') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Missing ')' in %s(%s\n"), name, p);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
/* Localize. Erase parsed string */
|
|
|
|
q = alloca((pe-p) + 1);
|
|
|
|
strncpy(q, p, pe-p);
|
|
|
|
q[pe-p] = '\0';
|
|
|
|
while (p <= pe)
|
|
|
|
*p++ = ' ';
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-05-18 02:44:14 +08:00
|
|
|
/* Parse multiple arguments from %lang */
|
2001-05-01 06:32:22 +08:00
|
|
|
for (p = q; *p != '\0'; p = pe) {
|
1999-05-18 02:44:14 +08:00
|
|
|
char *newp;
|
|
|
|
size_t np;
|
|
|
|
int i;
|
|
|
|
|
1999-07-04 06:58:08 +08:00
|
|
|
SKIPWHITE(p);
|
|
|
|
pe = p;
|
|
|
|
SKIPNONWHITE(pe);
|
1999-05-18 00:27:38 +08:00
|
|
|
|
1999-05-18 02:44:14 +08:00
|
|
|
np = pe - p;
|
|
|
|
|
|
|
|
/* Sanity check on locale lengths */
|
1999-09-08 06:49:45 +08:00
|
|
|
if (np < 1 || (np == 1 && *p != 'C') || np >= 32) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC,
|
|
|
|
_("Unusual locale length: \"%.*s\" in %%lang(%s)\n"),
|
1999-09-08 06:49:45 +08:00
|
|
|
(int)np, p, q);
|
1999-05-18 02:44:14 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check for duplicate locales */
|
2001-05-04 05:00:18 +08:00
|
|
|
if (fl->currentLangs != NULL)
|
1999-05-18 02:44:14 +08:00
|
|
|
for (i = 0; i < fl->nLangs; i++) {
|
|
|
|
if (strncmp(fl->currentLangs[i], p, np))
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Duplicate locale %.*s in %%lang(%s)\n"),
|
1999-09-08 06:49:45 +08:00
|
|
|
(int)np, p, q);
|
1999-05-18 02:44:14 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Add new locale */
|
2001-05-04 05:00:18 +08:00
|
|
|
fl->currentLangs = xrealloc(fl->currentLangs,
|
|
|
|
(fl->nLangs + 1) * sizeof(*fl->currentLangs));
|
1999-09-21 11:22:53 +08:00
|
|
|
newp = xmalloc( np+1 );
|
1999-05-18 03:32:15 +08:00
|
|
|
strncpy(newp, p, np);
|
|
|
|
newp[np] = '\0';
|
1999-05-18 02:44:14 +08:00
|
|
|
fl->currentLangs[fl->nLangs++] = newp;
|
1999-05-18 03:32:15 +08:00
|
|
|
if (*pe == ',') pe++; /* skip , if present */
|
1999-05-18 02:44:14 +08:00
|
|
|
}
|
|
|
|
}
|
2001-01-19 09:38:55 +08:00
|
|
|
|
|
|
|
/* Insure that locales are sorted. */
|
|
|
|
if (fl->currentLangs)
|
|
|
|
qsort(fl->currentLangs, fl->nLangs, sizeof(*fl->currentLangs), langCmp);
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
static int parseForRegexLang(const char * fileName, /*@out@*/ char ** lang)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext @*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies *lang, rpmGlobalMacroContext @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
|
|
|
static int initialized = 0;
|
|
|
|
static int hasRegex = 0;
|
|
|
|
static regex_t compiledPatt;
|
|
|
|
static char buf[BUFSIZ];
|
|
|
|
int x;
|
|
|
|
regmatch_t matches[2];
|
1998-11-25 08:42:36 +08:00
|
|
|
const char *s;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (! initialized) {
|
1999-03-21 05:09:47 +08:00
|
|
|
const char *patt = rpmExpand("%{_langpatt}", NULL);
|
1999-10-30 00:06:01 +08:00
|
|
|
int rc = 0;
|
1999-03-21 05:09:47 +08:00
|
|
|
if (!(patt && *patt != '%'))
|
1999-10-30 00:06:01 +08:00
|
|
|
rc = 1;
|
|
|
|
else if (regcomp(&compiledPatt, patt, REG_EXTENDED))
|
|
|
|
rc = -1;
|
2001-04-29 09:05:43 +08:00
|
|
|
patt = _free(patt);
|
1999-10-30 00:06:01 +08:00
|
|
|
if (rc)
|
|
|
|
return rc;
|
1998-07-26 05:00:26 +08:00
|
|
|
hasRegex = 1;
|
1999-03-21 05:09:47 +08:00
|
|
|
initialized = 1;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
memset(matches, 0, sizeof(matches));
|
1998-11-25 08:42:36 +08:00
|
|
|
if (! hasRegex || regexec(&compiledPatt, fileName, 2, matches, REG_NOTEOL))
|
1998-07-26 05:00:26 +08:00
|
|
|
return 1;
|
|
|
|
|
1998-11-25 08:42:36 +08:00
|
|
|
/* Got match */
|
|
|
|
s = fileName + matches[1].rm_eo - 1;
|
|
|
|
x = matches[1].rm_eo - matches[1].rm_so;
|
|
|
|
buf[x] = '\0';
|
|
|
|
while (x) {
|
|
|
|
buf[--x] = *s--;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-11-25 08:42:36 +08:00
|
|
|
if (lang)
|
|
|
|
*lang = buf;
|
|
|
|
return 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-10-15 11:22:10 +08:00
|
|
|
static int parseForRegexMultiLib(const char *fileName)
|
|
|
|
/*@globals rpmGlobalMacroContext @*/
|
|
|
|
/*@modifies rpmGlobalMacroContext @*/
|
2000-07-06 04:39:15 +08:00
|
|
|
{
|
|
|
|
static int initialized = 0;
|
|
|
|
static int hasRegex = 0;
|
|
|
|
static regex_t compiledPatt;
|
|
|
|
|
|
|
|
if (! initialized) {
|
|
|
|
const char *patt;
|
|
|
|
int rc = 0;
|
|
|
|
|
|
|
|
initialized = 1;
|
|
|
|
patt = rpmExpand("%{_multilibpatt}", NULL);
|
|
|
|
if (!(patt && *patt != '%'))
|
|
|
|
rc = 1;
|
|
|
|
else if (regcomp(&compiledPatt, patt, REG_EXTENDED | REG_NOSUB))
|
|
|
|
rc = -1;
|
2001-04-29 09:05:43 +08:00
|
|
|
patt = _free(patt);
|
2000-07-06 04:39:15 +08:00
|
|
|
if (rc)
|
|
|
|
return rc;
|
|
|
|
hasRegex = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! hasRegex || regexec(&compiledPatt, fileName, 0, NULL, 0))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@-exportlocal -exportheadervar@*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@unchecked@*/
|
1998-09-05 00:17:46 +08:00
|
|
|
VFA_t virtualFileAttributes[] = {
|
|
|
|
{ "%dir", 0 }, /* XXX why not RPMFILE_DIR? */
|
|
|
|
{ "%doc", RPMFILE_DOC },
|
|
|
|
{ "%ghost", RPMFILE_GHOST },
|
2001-03-17 00:33:25 +08:00
|
|
|
{ "%exclude", RPMFILE_EXCLUDE },
|
1998-09-05 00:17:46 +08:00
|
|
|
{ "%readme", RPMFILE_README },
|
|
|
|
{ "%license", RPMFILE_LICENSE },
|
2000-07-06 04:39:15 +08:00
|
|
|
{ "%multilib", 0 },
|
1998-09-05 00:17:46 +08:00
|
|
|
|
|
|
|
#if WHY_NOT
|
|
|
|
{ "%spec", RPMFILE_SPEC },
|
|
|
|
{ "%config", RPMFILE_CONFIG },
|
|
|
|
{ "%donotuse", RPMFILE_DONOTUSE }, /* XXX WTFO? */
|
|
|
|
{ "%missingok", RPMFILE_CONFIG|RPMFILE_MISSINGOK },
|
|
|
|
{ "%noreplace", RPMFILE_CONFIG|RPMFILE_NOREPLACE },
|
|
|
|
#endif
|
|
|
|
|
1998-10-08 19:55:37 +08:00
|
|
|
{ NULL, 0 }
|
1998-09-05 00:17:46 +08:00
|
|
|
};
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@=exportlocal =exportheadervar@*/
|
1998-09-05 00:17:46 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int parseForSimple(/*@unused@*/Spec spec, Package pkg, char * buf,
|
|
|
|
FileList fl, /*@out@*/ const char ** fileName)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext @*/
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@modifies buf, fl->processingFailed, *fileName,
|
|
|
|
fl->currentFlags,
|
|
|
|
fl->docDirs, fl->docDirCount, fl->isDir,
|
|
|
|
fl->passedSpecialDoc, fl->isSpecialDoc,
|
2001-10-18 00:43:36 +08:00
|
|
|
pkg->specialDoc, rpmGlobalMacroContext @*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
1998-09-05 00:17:46 +08:00
|
|
|
char *s, *t;
|
1998-07-26 05:00:26 +08:00
|
|
|
int res, specialDoc = 0;
|
|
|
|
char specialDocBuf[BUFSIZ];
|
|
|
|
|
|
|
|
specialDocBuf[0] = '\0';
|
|
|
|
*fileName = NULL;
|
|
|
|
res = 0;
|
1998-09-05 00:17:46 +08:00
|
|
|
|
|
|
|
t = buf;
|
|
|
|
while ((s = strtokWithQuotes(t, " \t\n")) != NULL) {
|
|
|
|
t = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
if (!strcmp(s, "%docdir")) {
|
|
|
|
s = strtokWithQuotes(NULL, " \t\n");
|
|
|
|
if (fl->docDirCount == MAXDOCDIR) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_INTERNAL, _("Hit limit for %%docdir\n"));
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
res = 1;
|
|
|
|
}
|
1999-09-21 11:22:53 +08:00
|
|
|
fl->docDirs[fl->docDirCount++] = xstrdup(s);
|
1998-07-26 05:00:26 +08:00
|
|
|
if (strtokWithQuotes(NULL, " \t\n")) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_INTERNAL, _("Only one arg for %%docdir\n"));
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
break;
|
1998-09-05 00:17:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Set flags for virtual file attributes */
|
|
|
|
{ VFA_t *vfa;
|
|
|
|
for (vfa = virtualFileAttributes; vfa->attribute != NULL; vfa++) {
|
|
|
|
if (strcmp(s, vfa->attribute))
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2000-07-06 04:39:15 +08:00
|
|
|
if (!vfa->flag) {
|
|
|
|
if (!strcmp(s, "%dir"))
|
|
|
|
fl->isDir = 1; /* XXX why not RPMFILE_DIR? */
|
|
|
|
else if (!strcmp(s, "%multilib"))
|
|
|
|
fl->currentFlags |= multiLib;
|
|
|
|
} else
|
1998-09-05 00:17:46 +08:00
|
|
|
fl->currentFlags |= vfa->flag;
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@innerbreak@*/ break;
|
1998-09-05 00:17:46 +08:00
|
|
|
}
|
1998-09-15 22:26:02 +08:00
|
|
|
/* if we got an attribute, continue with next token */
|
|
|
|
if (vfa->attribute != NULL)
|
1998-09-05 00:17:46 +08:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*fileName) {
|
|
|
|
/* We already got a file -- error */
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Two files on one line: %s\n"),
|
|
|
|
*fileName);
|
1998-09-05 00:17:46 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
res = 1;
|
|
|
|
}
|
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
1998-09-05 00:17:46 +08:00
|
|
|
if (*s != '/') {
|
|
|
|
if (fl->currentFlags & RPMFILE_DOC) {
|
|
|
|
specialDoc = 1;
|
|
|
|
strcat(specialDocBuf, " ");
|
|
|
|
strcat(specialDocBuf, s);
|
|
|
|
} else {
|
|
|
|
/* not in %doc, does not begin with / -- error */
|
1998-07-26 05:00:26 +08:00
|
|
|
rpmError(RPMERR_BADSPEC,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("File must begin with \"/\": %s\n"), s);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
res = 1;
|
|
|
|
}
|
1998-09-05 00:17:46 +08:00
|
|
|
} else {
|
|
|
|
*fileName = s;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
if (specialDoc) {
|
|
|
|
if (*fileName || (fl->currentFlags & ~(RPMFILE_DOC))) {
|
|
|
|
rpmError(RPMERR_BADSPEC,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Can't mix special %%doc with other forms: %s\n"),
|
2001-05-04 05:00:18 +08:00
|
|
|
(*fileName ? *fileName : ""));
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
res = 1;
|
|
|
|
} else {
|
1999-01-06 07:13:56 +08:00
|
|
|
/* XXX WATCHOUT: buf is an arg */
|
1999-09-07 04:59:39 +08:00
|
|
|
{ const char *ddir, *n, *v;
|
1999-01-14 04:24:00 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerNVR(pkg->header, &n, &v, NULL);
|
1999-01-14 04:24:00 +08:00
|
|
|
|
1999-09-07 04:59:39 +08:00
|
|
|
ddir = rpmGetPath("%{_docdir}/", n, "-", v, NULL);
|
1999-01-14 04:24:00 +08:00
|
|
|
strcpy(buf, ddir);
|
2001-04-29 09:05:43 +08:00
|
|
|
ddir = _free(ddir);
|
1999-01-14 04:24:00 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX FIXME: this is easy to do as macro expansion */
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
if (! fl->passedSpecialDoc) {
|
|
|
|
pkg->specialDoc = newStringBuf();
|
|
|
|
appendStringBuf(pkg->specialDoc, "DOCDIR=$RPM_BUILD_ROOT");
|
|
|
|
appendLineStringBuf(pkg->specialDoc, buf);
|
|
|
|
appendLineStringBuf(pkg->specialDoc, "export DOCDIR");
|
|
|
|
appendLineStringBuf(pkg->specialDoc, "rm -rf $DOCDIR");
|
|
|
|
appendLineStringBuf(pkg->specialDoc, MKDIR_P " $DOCDIR");
|
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-temptrans@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
*fileName = buf;
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=temptrans@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
fl->passedSpecialDoc = 1;
|
|
|
|
fl->isSpecialDoc = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
appendStringBuf(pkg->specialDoc, "cp -pr ");
|
|
|
|
appendStringBuf(pkg->specialDoc, specialDocBuf);
|
|
|
|
appendLineStringBuf(pkg->specialDoc, " $DOCDIR");
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
return res;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int compareFileListRecs(const void * ap, const void * bp) /*@*/
|
1996-06-08 02:32:10 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
const char *a = ((FileListRec)ap)->fileURL;
|
|
|
|
const char *b = ((FileListRec)bp)->fileURL;
|
1998-07-26 05:00:26 +08:00
|
|
|
return strcmp(a, b);
|
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int isDoc(FileList fl, const char * fileName) /*@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
|
|
|
int x = fl->docDirCount;
|
|
|
|
|
|
|
|
while (x--) {
|
2001-03-17 00:33:25 +08:00
|
|
|
if (strstr(fileName, fl->docDirs[x]) == fileName)
|
1998-07-26 05:00:26 +08:00
|
|
|
return 1;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
return 0;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-01-19 09:38:55 +08:00
|
|
|
/**
|
|
|
|
* Verify that file attributes scope over hardlinks correctly.
|
2002-01-12 07:03:22 +08:00
|
|
|
* If partial hardlink sets are possible, then add tracking dependency.
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2002-01-12 07:03:22 +08:00
|
|
|
* @return 1 if partial hardlink sets can exist, 0 otherwise.
|
2001-01-19 09:38:55 +08:00
|
|
|
*/
|
2002-01-12 07:03:22 +08:00
|
|
|
static int checkHardLinks(FileList fl)
|
|
|
|
/*@*/
|
2001-01-19 09:38:55 +08:00
|
|
|
{
|
|
|
|
char nlangs[BUFSIZ];
|
2001-04-29 09:05:43 +08:00
|
|
|
FileListRec ilp, jlp;
|
2001-01-19 09:38:55 +08:00
|
|
|
int i, j;
|
|
|
|
|
2001-09-21 23:07:11 +08:00
|
|
|
nlangs[0] = '\0';
|
2001-01-19 09:38:55 +08:00
|
|
|
for (i = 0; i < fl->fileListRecsUsed; i++) {
|
|
|
|
char *te;
|
|
|
|
|
|
|
|
ilp = fl->fileList + i;
|
|
|
|
if (!(S_ISREG(ilp->fl_mode) && ilp->fl_nlink > 1))
|
|
|
|
continue;
|
|
|
|
if (ilp->flags & RPMFILE_SPECFILE)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
te = nlangs;
|
|
|
|
*te = '\0';
|
|
|
|
for (j = i + 1; j < fl->fileListRecsUsed; j++) {
|
|
|
|
jlp = fl->fileList + j;
|
|
|
|
if (!S_ISREG(jlp->fl_mode))
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2001-01-19 09:38:55 +08:00
|
|
|
if (ilp->fl_nlink != jlp->fl_nlink)
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2001-01-19 09:38:55 +08:00
|
|
|
if (ilp->fl_ino != jlp->fl_ino)
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2001-01-19 09:38:55 +08:00
|
|
|
if (ilp->fl_dev != jlp->fl_dev)
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@innercontinue@*/ continue;
|
2002-01-12 07:03:22 +08:00
|
|
|
return 1;
|
2001-01-19 09:38:55 +08:00
|
|
|
}
|
|
|
|
}
|
2002-01-12 07:03:22 +08:00
|
|
|
return 0;
|
2001-01-19 09:38:55 +08:00
|
|
|
}
|
|
|
|
|
2000-09-27 01:19:32 +08:00
|
|
|
/**
|
|
|
|
* @todo Should directories have %doc/%config attributes? (#14531)
|
2001-01-24 07:03:28 +08:00
|
|
|
* @todo Remove RPMTAG_OLDFILENAMES, add dirname/basename instead.
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2000-09-27 01:19:32 +08:00
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
static void genCpioListAndHeader(/*@partial@*/ FileList fl,
|
2001-05-04 05:00:18 +08:00
|
|
|
TFI_t * cpioList, Header h, int isSrc)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem @*/
|
|
|
|
/*@modifies h, *cpioList, fl->processingFailed, fl->fileList,
|
2001-10-18 00:43:36 +08:00
|
|
|
rpmGlobalMacroContext, fileSystem @*/
|
1998-01-13 05:31:29 +08:00
|
|
|
{
|
2001-01-24 23:58:35 +08:00
|
|
|
int _addDotSlash = !(isSrc || rpmExpandNumeric("%{_noPayloadPrefix}"));
|
|
|
|
uint_32 multiLibMask = 0;
|
|
|
|
int apathlen = 0;
|
|
|
|
int dpathlen = 0;
|
|
|
|
int skipLen = 0;
|
2001-04-29 09:05:43 +08:00
|
|
|
FileListRec flp;
|
1999-10-01 01:45:42 +08:00
|
|
|
char buf[BUFSIZ];
|
2001-01-24 23:58:35 +08:00
|
|
|
int i;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
|
|
|
/* Sort the big list */
|
|
|
|
qsort(fl->fileList, fl->fileListRecsUsed,
|
|
|
|
sizeof(*(fl->fileList)), compareFileListRecs);
|
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
/* Generate the header. */
|
1998-01-13 05:31:29 +08:00
|
|
|
if (! isSrc) {
|
1998-11-25 03:30:38 +08:00
|
|
|
skipLen = 1;
|
|
|
|
if (fl->prefix)
|
|
|
|
skipLen += strlen(fl->prefix);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-11-25 03:30:38 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
for (i = 0, flp = fl->fileList; i < fl->fileListRecsUsed; i++, flp++) {
|
|
|
|
char *s;
|
|
|
|
|
2001-03-17 00:33:25 +08:00
|
|
|
/* Merge duplicate entries. */
|
|
|
|
while (i < (fl->fileListRecsUsed - 1) &&
|
|
|
|
!strcmp(flp->fileURL, flp[1].fileURL)) {
|
|
|
|
|
|
|
|
/* Two entries for the same file found, merge the entries. */
|
|
|
|
|
2001-07-04 03:26:58 +08:00
|
|
|
rpmMessage(RPMMESS_WARNING, _("File listed twice: %s\n"),
|
|
|
|
flp->fileURL);
|
|
|
|
|
2001-03-17 00:33:25 +08:00
|
|
|
/* file flags */
|
|
|
|
flp[1].flags |= flp->flags;
|
|
|
|
|
|
|
|
/* file mode */
|
|
|
|
if (S_ISDIR(flp->fl_mode)) {
|
|
|
|
if ((flp[1].specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)) <
|
|
|
|
(flp->specdFlags & (SPECD_DIRMODE | SPECD_DEFDIRMODE)))
|
|
|
|
flp[1].fl_mode = flp->fl_mode;
|
|
|
|
} else {
|
|
|
|
if ((flp[1].specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)) <
|
|
|
|
(flp->specdFlags & (SPECD_FILEMODE | SPECD_DEFFILEMODE)))
|
|
|
|
flp[1].fl_mode = flp->fl_mode;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* uid */
|
|
|
|
if ((flp[1].specdFlags & (SPECD_UID | SPECD_DEFUID)) <
|
|
|
|
(flp->specdFlags & (SPECD_UID | SPECD_DEFUID)))
|
|
|
|
{
|
|
|
|
flp[1].fl_uid = flp->fl_uid;
|
|
|
|
flp[1].uname = flp->uname;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* gid */
|
|
|
|
if ((flp[1].specdFlags & (SPECD_GID | SPECD_DEFGID)) <
|
|
|
|
(flp->specdFlags & (SPECD_GID | SPECD_DEFGID)))
|
|
|
|
{
|
|
|
|
flp[1].fl_gid = flp->fl_gid;
|
|
|
|
flp[1].gname = flp->gname;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* verify flags */
|
|
|
|
if ((flp[1].specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)) <
|
|
|
|
(flp->specdFlags & (SPECD_VERIFY | SPECD_DEFVERIFY)))
|
|
|
|
flp[1].verifyFlags = flp->verifyFlags;
|
|
|
|
|
|
|
|
/* XXX to-do: language */
|
|
|
|
|
|
|
|
flp++; i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Skip files that were marked with %exclude. */
|
|
|
|
if (flp->flags & RPMFILE_EXCLUDE) continue;
|
2000-07-06 04:39:15 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
/* Omit '/' and/or URL prefix, leave room for "./" prefix */
|
|
|
|
apathlen += (strlen(flp->fileURL) - skipLen + (_addDotSlash ? 3 : 1));
|
|
|
|
|
|
|
|
/* Leave room for both dirname and basename NUL's */
|
|
|
|
dpathlen += (strlen(flp->diskURL) + 2);
|
|
|
|
|
2000-07-06 04:39:15 +08:00
|
|
|
if (flp->flags & RPMFILE_MULTILIB_MASK)
|
|
|
|
multiLibMask |=
|
2001-04-29 09:05:43 +08:00
|
|
|
(1u << ((flp->flags & RPMFILE_MULTILIB_MASK))
|
2000-07-06 04:39:15 +08:00
|
|
|
>> RPMFILE_MULTILIB_SHIFT);
|
|
|
|
|
2001-03-17 00:33:25 +08:00
|
|
|
/*
|
|
|
|
* Make the header, the OLDFILENAMES will get converted to a
|
|
|
|
* compressed file list write before we write the actual package to
|
|
|
|
* disk.
|
|
|
|
*/
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_OLDFILENAMES, RPM_STRING_ARRAY_TYPE,
|
1999-11-24 08:03:54 +08:00
|
|
|
&(flp->fileURL), 1);
|
1999-06-02 22:45:46 +08:00
|
|
|
|
2001-10-16 22:58:57 +08:00
|
|
|
/*@-sizeoftype@*/
|
1999-06-02 22:45:46 +08:00
|
|
|
if (sizeof(flp->fl_size) != sizeof(uint_32)) {
|
|
|
|
uint_32 psize = (uint_32)flp->fl_size;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILESIZES, RPM_INT32_TYPE,
|
1999-06-02 22:45:46 +08:00
|
|
|
&(psize), 1);
|
|
|
|
} else {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILESIZES, RPM_INT32_TYPE,
|
1998-11-25 08:42:36 +08:00
|
|
|
&(flp->fl_size), 1);
|
1999-06-02 22:45:46 +08:00
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEUSERNAME, RPM_STRING_ARRAY_TYPE,
|
1998-11-25 03:30:38 +08:00
|
|
|
&(flp->uname), 1);
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEGROUPNAME, RPM_STRING_ARRAY_TYPE,
|
1998-11-25 03:30:38 +08:00
|
|
|
&(flp->gname), 1);
|
2001-11-07 06:46:26 +08:00
|
|
|
if (sizeof(flp->fl_mtime) != sizeof(uint_32)) {
|
|
|
|
uint_32 mtime = (uint_32)flp->fl_mtime;
|
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEMTIMES, RPM_INT32_TYPE,
|
|
|
|
&(mtime), 1);
|
|
|
|
} else {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEMTIMES, RPM_INT32_TYPE,
|
1998-11-25 08:42:36 +08:00
|
|
|
&(flp->fl_mtime), 1);
|
2001-11-07 06:46:26 +08:00
|
|
|
}
|
1999-01-28 03:40:01 +08:00
|
|
|
if (sizeof(flp->fl_mode) != sizeof(uint_16)) {
|
1998-11-25 08:42:36 +08:00
|
|
|
uint_16 pmode = (uint_16)flp->fl_mode;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEMODES, RPM_INT16_TYPE,
|
1998-03-01 04:29:11 +08:00
|
|
|
&(pmode), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
} else {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEMODES, RPM_INT16_TYPE,
|
1998-11-25 08:42:36 +08:00
|
|
|
&(flp->fl_mode), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
}
|
|
|
|
if (sizeof(flp->fl_rdev) != sizeof(uint_16)) {
|
1998-11-25 08:42:36 +08:00
|
|
|
uint_16 prdev = (uint_16)flp->fl_rdev;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILERDEVS, RPM_INT16_TYPE,
|
1998-03-01 04:29:11 +08:00
|
|
|
&(prdev), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
} else {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILERDEVS, RPM_INT16_TYPE,
|
1998-11-25 08:42:36 +08:00
|
|
|
&(flp->fl_rdev), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
}
|
|
|
|
if (sizeof(flp->fl_dev) != sizeof(uint_32)) {
|
1998-11-25 08:42:36 +08:00
|
|
|
uint_32 pdevice = (uint_32)flp->fl_dev;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEDEVICES, RPM_INT32_TYPE,
|
1998-03-01 04:29:11 +08:00
|
|
|
&(pdevice), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
} else {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEDEVICES, RPM_INT32_TYPE,
|
1998-11-25 08:42:36 +08:00
|
|
|
&(flp->fl_dev), 1);
|
1999-01-28 03:40:01 +08:00
|
|
|
}
|
2001-11-07 06:46:26 +08:00
|
|
|
if (sizeof(flp->fl_ino) != sizeof(uint_32)) {
|
|
|
|
uint_32 ino = (uint_32)flp->fl_ino;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEINODES, RPM_INT32_TYPE,
|
2001-11-07 06:46:26 +08:00
|
|
|
&(ino), 1);
|
|
|
|
} else {
|
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEINODES, RPM_INT32_TYPE,
|
|
|
|
&(flp->fl_ino), 1);
|
|
|
|
}
|
|
|
|
/*@=sizeoftype@*/
|
1999-05-18 00:40:11 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILELANGS, RPM_STRING_ARRAY_TYPE,
|
1999-05-18 02:44:14 +08:00
|
|
|
&(flp->langs), 1);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
|
|
|
/* We used to add these, but they should not be needed */
|
2001-05-01 06:32:22 +08:00
|
|
|
/* (void) headerAddOrAppendEntry(h, RPMTAG_FILEUIDS,
|
1998-11-25 08:42:36 +08:00
|
|
|
* RPM_INT32_TYPE, &(flp->fl_uid), 1);
|
2001-05-01 06:32:22 +08:00
|
|
|
* (void) headerAddOrAppendEntry(h, RPMTAG_FILEGIDS,
|
1998-11-25 08:42:36 +08:00
|
|
|
* RPM_INT32_TYPE, &(flp->fl_gid), 1);
|
1998-01-13 05:31:29 +08:00
|
|
|
*/
|
|
|
|
|
|
|
|
buf[0] = '\0';
|
1998-11-25 08:42:36 +08:00
|
|
|
if (S_ISREG(flp->fl_mode))
|
2001-11-19 01:49:21 +08:00
|
|
|
(void) domd5(flp->diskURL, buf, 1);
|
1998-01-13 05:31:29 +08:00
|
|
|
s = buf;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEMD5S, RPM_STRING_ARRAY_TYPE,
|
1998-01-13 05:31:29 +08:00
|
|
|
&s, 1);
|
|
|
|
|
|
|
|
buf[0] = '\0';
|
1999-12-03 01:07:29 +08:00
|
|
|
if (S_ISLNK(flp->fl_mode)) {
|
|
|
|
buf[Readlink(flp->diskURL, buf, BUFSIZ)] = '\0';
|
|
|
|
if (fl->buildRootURL) {
|
|
|
|
const char * buildRoot;
|
|
|
|
(void) urlPath(fl->buildRootURL, &buildRoot);
|
|
|
|
|
|
|
|
if (buf[0] == '/' && strcmp(buildRoot, "/") &&
|
|
|
|
!strncmp(buf, buildRoot, strlen(buildRoot))) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC,
|
|
|
|
_("Symlink points to BuildRoot: %s -> %s\n"),
|
1999-12-03 01:07:29 +08:00
|
|
|
flp->fileURL, buf);
|
|
|
|
fl->processingFailed = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
s = buf;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILELINKTOS, RPM_STRING_ARRAY_TYPE,
|
1998-01-13 05:31:29 +08:00
|
|
|
&s, 1);
|
|
|
|
|
1998-11-25 03:30:38 +08:00
|
|
|
if (flp->flags & RPMFILE_GHOST) {
|
|
|
|
flp->verifyFlags &= ~(RPMVERIFY_MD5 | RPMVERIFY_FILESIZE |
|
1998-01-13 05:31:29 +08:00
|
|
|
RPMVERIFY_LINKTO | RPMVERIFY_MTIME);
|
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEVERIFYFLAGS, RPM_INT32_TYPE,
|
1998-11-25 03:30:38 +08:00
|
|
|
&(flp->verifyFlags), 1);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
if (!isSrc && isDoc(fl, flp->fileURL))
|
1998-11-25 03:30:38 +08:00
|
|
|
flp->flags |= RPMFILE_DOC;
|
2000-09-27 01:19:32 +08:00
|
|
|
/* XXX Should directories have %doc/%config attributes? (#14531) */
|
1998-11-25 08:42:36 +08:00
|
|
|
if (S_ISDIR(flp->fl_mode))
|
1998-11-25 03:30:38 +08:00
|
|
|
flp->flags &= ~(RPMFILE_CONFIG|RPMFILE_DOC);
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(h, RPMTAG_FILEFLAGS, RPM_INT32_TYPE,
|
1998-11-25 03:30:38 +08:00
|
|
|
&(flp->flags), 1);
|
2001-01-24 07:03:28 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddEntry(h, RPMTAG_SIZE, RPM_INT32_TYPE,
|
1998-01-13 05:31:29 +08:00
|
|
|
&(fl->totalFileSize), 1);
|
2001-01-24 07:03:28 +08:00
|
|
|
|
2000-07-06 04:39:15 +08:00
|
|
|
/* XXX This should be added always so that packages look alike.
|
|
|
|
* XXX However, there is logic in files.c/depends.c that checks for
|
|
|
|
* XXX existence (rather than value) that will need to change as well.
|
|
|
|
*/
|
|
|
|
if (multiLibMask)
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddEntry(h, RPMTAG_MULTILIBS, RPM_INT32_TYPE,
|
2000-07-06 04:39:15 +08:00
|
|
|
&multiLibMask, 1);
|
2001-01-24 07:03:28 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
if (_addDotSlash)
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) rpmlibNeedsFeature(h, "PayloadFilesHavePrefix", "4.0-1");
|
2001-01-24 23:58:35 +08:00
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
/* Choose how filenames are represented. */
|
|
|
|
if (_noDirTokens)
|
|
|
|
expandFilelist(h);
|
|
|
|
else {
|
|
|
|
compressFilelist(h);
|
|
|
|
/* Binary packages with dirNames cannot be installed by legacy rpm. */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) rpmlibNeedsFeature(h, "CompressedFileNames", "3.0.4-1");
|
2001-01-24 07:03:28 +08:00
|
|
|
}
|
|
|
|
|
2001-11-12 00:17:57 +08:00
|
|
|
{ TFI_t fi = xcalloc(1, sizeof(*fi));
|
2001-11-12 04:45:20 +08:00
|
|
|
int scareMem = 1;
|
2001-01-24 23:58:35 +08:00
|
|
|
char * a, * d;
|
2001-01-24 07:03:28 +08:00
|
|
|
|
2001-11-12 00:17:57 +08:00
|
|
|
/* XXX FIXME drill rpmTransactionSet ts all the way down here */
|
|
|
|
/*@i@*/ fi->te = xcalloc(1, sizeof(*fi->te));
|
|
|
|
/*@i@*/ fi->te->type = TR_ADDED;
|
|
|
|
|
2001-11-12 04:45:20 +08:00
|
|
|
fi = fiNew(NULL, fi, h, RPMTAG_BASENAMES, scareMem);
|
2001-11-13 04:51:05 +08:00
|
|
|
if (fi == NULL) return; /* XXX can't happen */
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
fi->dnl = _free(fi->dnl);
|
|
|
|
fi->bnl = _free(fi->bnl);
|
2001-01-25 20:58:03 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
fi->dnl = xmalloc(fi->fc * sizeof(*fi->dnl) + dpathlen);
|
|
|
|
d = (char *)(fi->dnl + fi->fc);
|
|
|
|
*d = '\0';
|
|
|
|
|
|
|
|
fi->bnl = xmalloc(fi->fc * (sizeof(*fi->bnl) + sizeof(*fi->dil)));
|
2001-11-11 20:47:08 +08:00
|
|
|
/*@-dependenttrans@*/ /* FIX: artifact of spoofing headerGetEntry */
|
2001-01-24 23:58:35 +08:00
|
|
|
fi->dil = (int *)(fi->bnl + fi->fc);
|
2001-11-11 20:47:08 +08:00
|
|
|
/*@=dependenttrans@*/
|
2001-01-24 23:58:35 +08:00
|
|
|
|
|
|
|
fi->apath = xmalloc(fi->fc * sizeof(*fi->apath) + apathlen);
|
|
|
|
a = (char *)(fi->apath + fi->fc);
|
|
|
|
*a = '\0';
|
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
fi->actions = xcalloc(sizeof(*fi->actions), fi->fc);
|
|
|
|
fi->fmapflags = xcalloc(sizeof(*fi->fmapflags), fi->fc);
|
2001-02-04 04:07:39 +08:00
|
|
|
fi->astriplen = 0;
|
|
|
|
if (fl->buildRootURL)
|
|
|
|
fi->astriplen = strlen(fl->buildRootURL);
|
2001-01-24 23:58:35 +08:00
|
|
|
fi->striplen = 0;
|
2001-01-24 07:03:28 +08:00
|
|
|
fi->fuser = NULL;
|
|
|
|
fi->fuids = xcalloc(sizeof(*fi->fuids), fi->fc);
|
|
|
|
fi->fgroup = NULL;
|
|
|
|
fi->fgids = xcalloc(sizeof(*fi->fgids), fi->fc);
|
|
|
|
|
|
|
|
/* Make the cpio list */
|
|
|
|
for (i = 0, flp = fl->fileList; i < fi->fc; i++, flp++) {
|
2001-01-24 23:58:35 +08:00
|
|
|
char * b;
|
|
|
|
|
2001-07-04 03:26:58 +08:00
|
|
|
/* Skip (possible) duplicate file entries, use last entry info. */
|
|
|
|
while (((flp - fl->fileList) < (fl->fileListRecsUsed - 1)) &&
|
|
|
|
!strcmp(flp->fileURL, flp[1].fileURL))
|
|
|
|
flp++;
|
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
/* Create disk directory and base name. */
|
|
|
|
fi->dil[i] = i;
|
2001-11-11 20:47:08 +08:00
|
|
|
/*@-dependenttrans@*/ /* FIX: artifact of spoofing headerGetEntry */
|
2001-01-24 23:58:35 +08:00
|
|
|
fi->dnl[fi->dil[i]] = d;
|
2001-11-11 20:47:08 +08:00
|
|
|
/*@=dependenttrans@*/
|
2001-01-24 23:58:35 +08:00
|
|
|
d = stpcpy(d, flp->diskURL);
|
|
|
|
|
|
|
|
/* Make room for the dirName NUL, find start of baseName. */
|
|
|
|
for (b = d; b > fi->dnl[fi->dil[i]] && *b != '/'; b--)
|
|
|
|
b[1] = b[0];
|
|
|
|
b++; /* dirname's end in '/' */
|
|
|
|
*b++ = '\0'; /* terminate dirname, b points to basename */
|
|
|
|
fi->bnl[i] = b;
|
|
|
|
d += 2; /* skip both dirname and basename NUL's */
|
|
|
|
|
|
|
|
/* Create archive path, normally adding "./" */
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@-dependenttrans@*/ /* FIX: xstrdup? nah ... */
|
2001-01-24 23:58:35 +08:00
|
|
|
fi->apath[i] = a;
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@=dependenttrans@*/
|
2001-01-24 23:58:35 +08:00
|
|
|
if (_addDotSlash) a = stpcpy(a, "./");
|
|
|
|
a = stpcpy(a, (flp->fileURL + skipLen));
|
|
|
|
a++; /* skip apath NUL */
|
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
if (flp->flags & RPMFILE_GHOST) {
|
|
|
|
fi->actions[i] = FA_SKIP;
|
|
|
|
continue;
|
|
|
|
}
|
2001-02-12 06:02:29 +08:00
|
|
|
fi->actions[i] = FA_COPYOUT;
|
2001-07-04 03:26:58 +08:00
|
|
|
fi->fuids[i] = getUidS(flp->uname);
|
|
|
|
fi->fgids[i] = getGidS(flp->gname);
|
|
|
|
if (fi->fuids[i] == (uid_t)-1) fi->fuids[i] = 0;
|
|
|
|
if (fi->fgids[i] == (gid_t)-1) fi->fgids[i] = 0;
|
2001-07-16 22:48:07 +08:00
|
|
|
fi->fmapflags[i] = CPIO_MAP_PATH |
|
|
|
|
CPIO_MAP_TYPE | CPIO_MAP_MODE | CPIO_MAP_UID | CPIO_MAP_GID;
|
2001-01-24 07:03:28 +08:00
|
|
|
if (isSrc)
|
|
|
|
fi->fmapflags[i] |= CPIO_FOLLOW_SYMLINKS;
|
|
|
|
if (flp->flags & RPMFILE_MULTILIB_MASK)
|
|
|
|
fi->fmapflags[i] |= CPIO_MULTILIB;
|
|
|
|
|
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2001-01-24 07:03:28 +08:00
|
|
|
if (cpioList)
|
|
|
|
*cpioList = fi;
|
|
|
|
else
|
2001-04-29 09:05:43 +08:00
|
|
|
fi = _free(fi);
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2001-01-24 07:03:28 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static /*@null@*/ FileListRec freeFileList(/*@only@*/ FileListRec fileList,
|
|
|
|
int count)
|
|
|
|
/*@*/
|
1996-06-08 02:32:10 +08:00
|
|
|
{
|
1998-01-13 05:31:29 +08:00
|
|
|
while (count--) {
|
2001-04-29 09:05:43 +08:00
|
|
|
fileList[count].diskURL = _free(fileList[count].diskURL);
|
|
|
|
fileList[count].fileURL = _free(fileList[count].fileURL);
|
|
|
|
fileList[count].langs = _free(fileList[count].langs);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
fileList = _free(fileList);
|
|
|
|
return NULL;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int addFile(FileList fl, const char * diskURL, struct stat * statp)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem@*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies *statp, *fl, fl->processingFailed,
|
2001-05-04 05:00:18 +08:00
|
|
|
fl->fileList, fl->fileListRecsAlloced, fl->fileListRecsUsed,
|
2001-10-15 11:22:10 +08:00
|
|
|
fl->totalFileSize, fl->fileCount, fl->inFtw, fl->isDir,
|
|
|
|
rpmGlobalMacroContext, fileSystem @*/
|
1996-06-08 02:32:10 +08:00
|
|
|
{
|
1999-11-24 08:03:54 +08:00
|
|
|
const char *fileURL = diskURL;
|
1998-01-13 05:31:29 +08:00
|
|
|
struct stat statbuf;
|
1998-11-25 08:42:36 +08:00
|
|
|
mode_t fileMode;
|
|
|
|
uid_t fileUid;
|
|
|
|
gid_t fileGid;
|
1999-10-05 03:40:03 +08:00
|
|
|
const char *fileUname;
|
|
|
|
const char *fileGname;
|
1998-03-20 12:34:09 +08:00
|
|
|
char *lang;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
/* Path may have prepended buildRootURL, so locate the original filename. */
|
|
|
|
/*
|
|
|
|
* XXX There are 3 types of entry into addFile:
|
|
|
|
*
|
|
|
|
* From diskUrl statp
|
|
|
|
* =====================================================
|
|
|
|
* processBinaryFile path NULL
|
|
|
|
* processBinaryFile glob result path NULL
|
|
|
|
* myftw path stat
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
{ const char *fileName;
|
1999-11-27 05:58:42 +08:00
|
|
|
(void) urlPath(fileURL, &fileName);
|
1999-11-24 08:03:54 +08:00
|
|
|
if (fl->buildRootURL && strcmp(fl->buildRootURL, "/"))
|
|
|
|
fileURL += strlen(fl->buildRootURL);
|
|
|
|
}
|
1996-07-09 10:06:26 +08:00
|
|
|
|
2000-07-10 07:10:25 +08:00
|
|
|
/* XXX make sure '/' can be packaged also */
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
2000-07-10 07:10:25 +08:00
|
|
|
if (*fileURL == '\0')
|
|
|
|
fileURL = "/";
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
2000-07-10 07:10:25 +08:00
|
|
|
|
1996-07-09 10:06:26 +08:00
|
|
|
/* If we are using a prefix, validate the file */
|
1998-01-13 05:31:29 +08:00
|
|
|
if (!fl->inFtw && fl->prefix) {
|
1999-11-24 08:03:54 +08:00
|
|
|
const char *prefixTest;
|
1998-11-25 03:30:38 +08:00
|
|
|
const char *prefixPtr = fl->prefix;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
(void) urlPath(fileURL, &prefixTest);
|
1996-07-10 09:38:14 +08:00
|
|
|
while (*prefixPtr && *prefixTest && (*prefixTest == *prefixPtr)) {
|
1996-07-09 10:06:26 +08:00
|
|
|
prefixPtr++;
|
|
|
|
prefixTest++;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
if (*prefixPtr || (*prefixTest && *prefixTest != '/')) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("File doesn't match prefix (%s): %s\n"),
|
1999-11-24 08:03:54 +08:00
|
|
|
fl->prefix, fileURL);
|
1998-01-13 05:31:29 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
1996-07-09 10:06:26 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
if (statp == NULL) {
|
1998-01-13 05:31:29 +08:00
|
|
|
statp = &statbuf;
|
2001-07-16 22:48:07 +08:00
|
|
|
memset(statp, 0, sizeof(*statp));
|
|
|
|
if (fl->devtype) {
|
|
|
|
time_t now = time(NULL);
|
|
|
|
|
|
|
|
/* XXX hack up a stat structure for a %dev(...) directive. */
|
|
|
|
statp->st_nlink = 1;
|
|
|
|
statp->st_rdev =
|
|
|
|
((fl->devmajor & 0xff) << 8) | (fl->devminor & 0xff);
|
|
|
|
statp->st_dev = statp->st_rdev;
|
|
|
|
statp->st_mode = (fl->devtype == 'b' ? S_IFBLK : S_IFCHR);
|
|
|
|
statp->st_mode |= (fl->cur_ar.ar_fmode & 0777);
|
|
|
|
statp->st_atime = now;
|
|
|
|
statp->st_mtime = now;
|
|
|
|
statp->st_ctime = now;
|
|
|
|
} else if (Lstat(diskURL, statp)) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("File not found: %s\n"), diskURL);
|
1998-01-13 05:31:29 +08:00
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
1996-07-23 10:41:54 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
if ((! fl->isDir) && S_ISDIR(statp->st_mode)) {
|
1996-06-08 02:32:10 +08:00
|
|
|
/* We use our own ftw() call, because ftw() uses stat() */
|
|
|
|
/* instead of lstat(), which causes it to follow symlinks! */
|
1998-01-13 05:31:29 +08:00
|
|
|
/* It also has better callback support. */
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
fl->inFtw = 1; /* Flag to indicate file has buildRootURL prefixed */
|
1998-01-13 05:31:29 +08:00
|
|
|
fl->isDir = 1; /* Keep it from following myftw() again */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) myftw(diskURL, 16, (myftwFunc) addFile, fl);
|
1998-01-13 05:31:29 +08:00
|
|
|
fl->isDir = 0;
|
|
|
|
fl->inFtw = 0;
|
1998-11-25 03:30:38 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
fileMode = statp->st_mode;
|
|
|
|
fileUid = statp->st_uid;
|
|
|
|
fileGid = statp->st_gid;
|
|
|
|
|
1999-02-08 05:19:00 +08:00
|
|
|
if (S_ISDIR(fileMode) && fl->cur_ar.ar_dmodestr) {
|
|
|
|
fileMode &= S_IFMT;
|
|
|
|
fileMode |= fl->cur_ar.ar_dmode;
|
|
|
|
} else if (fl->cur_ar.ar_fmodestr != NULL) {
|
|
|
|
fileMode &= S_IFMT;
|
|
|
|
fileMode |= fl->cur_ar.ar_fmode;
|
1998-11-25 03:30:38 +08:00
|
|
|
}
|
1998-11-26 03:31:10 +08:00
|
|
|
if (fl->cur_ar.ar_user) {
|
|
|
|
fileUname = getUnameS(fl->cur_ar.ar_user);
|
1998-11-25 03:30:38 +08:00
|
|
|
} else {
|
|
|
|
fileUname = getUname(fileUid);
|
|
|
|
}
|
1998-11-26 03:31:10 +08:00
|
|
|
if (fl->cur_ar.ar_group) {
|
|
|
|
fileGname = getGnameS(fl->cur_ar.ar_group);
|
1998-11-25 03:30:38 +08:00
|
|
|
} else {
|
|
|
|
fileGname = getGname(fileGid);
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-01-28 03:40:01 +08:00
|
|
|
#if 0 /* XXX this looks dumb to me */
|
1998-11-25 03:30:38 +08:00
|
|
|
if (! (fileUname && fileGname)) {
|
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s\n"), diskName);
|
|
|
|
fl->processingFailed = 1;
|
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
1999-03-24 20:38:08 +08:00
|
|
|
#else
|
|
|
|
/* Default user/group to builder's user/group */
|
2000-07-10 07:10:25 +08:00
|
|
|
if (fileUname == NULL)
|
1999-03-24 20:38:08 +08:00
|
|
|
fileUname = getUname(getuid());
|
2000-07-10 07:10:25 +08:00
|
|
|
if (fileGname == NULL)
|
1999-03-24 20:38:08 +08:00
|
|
|
fileGname = getGname(getgid());
|
1999-01-28 03:40:01 +08:00
|
|
|
#endif
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
rpmMessage(RPMMESS_DEBUG, _("File %4d: %07o %s.%s\t %s\n"), fl->fileCount,
|
2001-05-01 06:32:22 +08:00
|
|
|
(unsigned)fileMode, fileUname, fileGname, fileURL);
|
1998-11-25 03:30:38 +08:00
|
|
|
|
|
|
|
/* Add to the file list */
|
|
|
|
if (fl->fileListRecsUsed == fl->fileListRecsAlloced) {
|
|
|
|
fl->fileListRecsAlloced += 128;
|
1999-09-21 11:22:53 +08:00
|
|
|
fl->fileList = xrealloc(fl->fileList,
|
1998-11-25 03:30:38 +08:00
|
|
|
fl->fileListRecsAlloced * sizeof(*(fl->fileList)));
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
{ FileListRec flp = &fl->fileList[fl->fileListRecsUsed];
|
2001-07-16 22:48:07 +08:00
|
|
|
int i;
|
1999-01-28 03:40:01 +08:00
|
|
|
|
|
|
|
flp->fl_st = *statp; /* structure assignment */
|
|
|
|
flp->fl_mode = fileMode;
|
|
|
|
flp->fl_uid = fileUid;
|
|
|
|
flp->fl_gid = fileGid;
|
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
flp->fileURL = xstrdup(fileURL);
|
|
|
|
flp->diskURL = xstrdup(diskURL);
|
1999-01-28 03:40:01 +08:00
|
|
|
flp->uname = fileUname;
|
|
|
|
flp->gname = fileGname;
|
|
|
|
|
1999-05-18 00:27:38 +08:00
|
|
|
if (fl->currentLangs && fl->nLangs > 0) {
|
2001-07-16 22:48:07 +08:00
|
|
|
char * ncl;
|
1999-05-18 02:44:14 +08:00
|
|
|
size_t nl = 0;
|
1999-05-18 00:27:38 +08:00
|
|
|
|
|
|
|
for (i = 0; i < fl->nLangs; i++)
|
1999-05-18 02:44:14 +08:00
|
|
|
nl += strlen(fl->currentLangs[i]) + 1;
|
|
|
|
|
1999-09-21 11:22:53 +08:00
|
|
|
flp->langs = ncl = xmalloc(nl);
|
1999-05-18 02:44:14 +08:00
|
|
|
for (i = 0; i < fl->nLangs; i++) {
|
|
|
|
const char *ocl;
|
|
|
|
if (i) *ncl++ = '|';
|
2001-05-01 06:32:22 +08:00
|
|
|
for (ocl = fl->currentLangs[i]; *ocl != '\0'; ocl++)
|
1999-05-18 02:44:14 +08:00
|
|
|
*ncl++ = *ocl;
|
|
|
|
*ncl = '\0';
|
|
|
|
}
|
1999-11-24 08:03:54 +08:00
|
|
|
} else if (! parseForRegexLang(fileURL, &lang)) {
|
1999-09-21 11:22:53 +08:00
|
|
|
flp->langs = xstrdup(lang);
|
1999-01-28 03:40:01 +08:00
|
|
|
} else {
|
1999-09-21 11:22:53 +08:00
|
|
|
flp->langs = xstrdup("");
|
1999-01-28 03:40:01 +08:00
|
|
|
}
|
1998-03-20 12:34:09 +08:00
|
|
|
|
1999-01-28 03:40:01 +08:00
|
|
|
flp->flags = fl->currentFlags;
|
2001-03-17 00:33:25 +08:00
|
|
|
flp->specdFlags = fl->currentSpecdFlags;
|
1999-01-28 03:40:01 +08:00
|
|
|
flp->verifyFlags = fl->currentVerifyFlags;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2000-07-06 04:39:15 +08:00
|
|
|
if (multiLib
|
|
|
|
&& !(flp->flags & RPMFILE_MULTILIB_MASK)
|
|
|
|
&& !parseForRegexMultiLib(fileURL))
|
|
|
|
flp->flags |= multiLib;
|
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
|
|
|
|
/* Hard links need be counted only once. */
|
|
|
|
if (S_ISREG(flp->fl_mode) && flp->fl_nlink > 1) {
|
|
|
|
FileListRec ilp;
|
|
|
|
for (i = 0; i < fl->fileListRecsUsed; i++) {
|
|
|
|
ilp = fl->fileList + i;
|
|
|
|
if (!S_ISREG(ilp->fl_mode))
|
|
|
|
continue;
|
|
|
|
if (flp->fl_nlink != ilp->fl_nlink)
|
|
|
|
continue;
|
|
|
|
if (flp->fl_ino != ilp->fl_ino)
|
|
|
|
continue;
|
|
|
|
if (flp->fl_dev != ilp->fl_dev)
|
|
|
|
continue;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
i = fl->fileListRecsUsed;
|
|
|
|
|
|
|
|
if (S_ISREG(flp->fl_mode) && i >= fl->fileListRecsUsed)
|
|
|
|
fl->totalFileSize += flp->fl_size;
|
1999-01-28 03:40:01 +08:00
|
|
|
}
|
1998-11-25 03:30:38 +08:00
|
|
|
|
|
|
|
fl->fileListRecsUsed++;
|
|
|
|
fl->fileCount++;
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1998-01-13 05:31:29 +08:00
|
|
|
return 0;
|
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
2001-01-19 09:38:55 +08:00
|
|
|
* @param fl package file tree walk data
|
2001-01-11 22:13:04 +08:00
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static int processBinaryFile(/*@unused@*/ Package pkg, FileList fl,
|
|
|
|
const char * fileURL)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem@*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies *fl, fl->processingFailed,
|
2001-05-04 05:00:18 +08:00
|
|
|
fl->fileList, fl->fileListRecsAlloced, fl->fileListRecsUsed,
|
2001-10-15 11:22:10 +08:00
|
|
|
fl->totalFileSize, fl->fileCount, fl->inFtw, fl->isDir,
|
2001-10-18 00:43:36 +08:00
|
|
|
rpmGlobalMacroContext, fileSystem @*/
|
1996-06-08 02:32:10 +08:00
|
|
|
{
|
1999-11-24 08:03:54 +08:00
|
|
|
int doGlob;
|
|
|
|
const char *diskURL = NULL;
|
1999-10-05 01:29:58 +08:00
|
|
|
int rc = 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
doGlob = myGlobPatternP(fileURL);
|
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
/* Check that file starts with leading "/" */
|
1999-11-24 08:03:54 +08:00
|
|
|
{ const char * fileName;
|
|
|
|
(void) urlPath(fileURL, &fileName);
|
|
|
|
if (*fileName != '/') {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("File needs leading \"/\": %s\n"),
|
|
|
|
fileName);
|
1999-11-24 08:03:54 +08:00
|
|
|
rc = 1;
|
|
|
|
goto exit;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
/* Copy file name or glob pattern removing multiple "/" chars. */
|
1999-11-24 08:03:54 +08:00
|
|
|
/*
|
|
|
|
* Note: rpmGetPath should guarantee a "canonical" path. That means
|
|
|
|
* that the following pathologies should be weeded out:
|
|
|
|
* //bin//sh
|
|
|
|
* //usr//bin/
|
1999-11-25 00:16:17 +08:00
|
|
|
* /.././../usr/../bin//./sh
|
1999-11-24 08:03:54 +08:00
|
|
|
*/
|
|
|
|
diskURL = rpmGenPath(fl->buildRootURL, NULL, fileURL);
|
1999-10-05 01:29:58 +08:00
|
|
|
|
|
|
|
if (doGlob) {
|
1999-12-13 05:14:05 +08:00
|
|
|
const char ** argv = NULL;
|
|
|
|
int argc = 0;
|
1999-12-12 09:46:13 +08:00
|
|
|
int i;
|
1999-11-24 08:03:54 +08:00
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
if (fl->noGlob) {
|
|
|
|
rpmError(RPMERR_BADSPEC, _("Glob not permitted: %s\n"),
|
|
|
|
diskURL);
|
|
|
|
rc = 1;
|
|
|
|
goto exit;
|
|
|
|
}
|
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
1999-12-13 01:46:22 +08:00
|
|
|
rc = rpmGlob(diskURL, &argc, &argv);
|
2000-01-06 03:46:45 +08:00
|
|
|
if (rc == 0 && argc >= 1 && !myGlobPatternP(argv[0])) {
|
1999-12-12 09:46:13 +08:00
|
|
|
for (i = 0; i < argc; i++) {
|
|
|
|
rc = addFile(fl, argv[i], NULL);
|
2001-04-29 09:05:43 +08:00
|
|
|
argv[i] = _free(argv[i]);
|
1999-12-12 09:46:13 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
argv = _free(argv);
|
2000-01-06 03:46:45 +08:00
|
|
|
} else {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("File not found by glob: %s\n"),
|
|
|
|
diskURL);
|
2000-01-06 03:46:45 +08:00
|
|
|
rc = 1;
|
1999-12-12 09:46:13 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
} else {
|
1999-11-24 08:03:54 +08:00
|
|
|
rc = addFile(fl, diskURL, NULL);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
exit:
|
2001-04-29 09:05:43 +08:00
|
|
|
diskURL = _free(diskURL);
|
1999-10-05 01:29:58 +08:00
|
|
|
if (rc)
|
|
|
|
fl->processingFailed = 1;
|
1998-07-26 05:00:26 +08:00
|
|
|
return rc;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1998-07-26 05:00:26 +08:00
|
|
|
static int processPackageFiles(Spec spec, Package pkg,
|
|
|
|
int installSpecialDoc, int test)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState@*/
|
2001-05-06 03:28:32 +08:00
|
|
|
/*@modifies spec->macros,
|
2001-10-15 11:22:10 +08:00
|
|
|
pkg->cpioList, pkg->fileList, pkg->specialDoc, pkg->header,
|
2001-10-18 00:43:36 +08:00
|
|
|
rpmGlobalMacroContext, fileSystem, internalState @*/
|
1998-03-20 12:34:09 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
|
|
struct FileList_s fl;
|
1998-11-25 08:42:36 +08:00
|
|
|
char *s, **files, **fp;
|
|
|
|
const char *fileName;
|
1998-07-26 05:00:26 +08:00
|
|
|
char buf[BUFSIZ];
|
2001-04-29 09:05:43 +08:00
|
|
|
struct AttrRec_s arbuf;
|
|
|
|
AttrRec specialDocAttrRec = &arbuf;
|
1998-07-26 05:00:26 +08:00
|
|
|
char *specialDoc = NULL;
|
2000-07-06 04:39:15 +08:00
|
|
|
|
|
|
|
#ifdef MULTILIB
|
|
|
|
multiLib = rpmExpandNumeric("%{_multilibno}");
|
|
|
|
if (multiLib)
|
|
|
|
multiLib = RPMFILE_MULTILIB(multiLib);
|
|
|
|
#endif /* MULTILIB */
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
nullAttrRec(specialDocAttrRec);
|
1998-07-26 05:00:26 +08:00
|
|
|
pkg->cpioList = NULL;
|
|
|
|
|
|
|
|
if (pkg->fileFile) {
|
1999-01-28 03:40:01 +08:00
|
|
|
const char *ffn;
|
2001-04-29 09:05:43 +08:00
|
|
|
FILE * f;
|
1999-11-13 01:20:49 +08:00
|
|
|
FD_t fd;
|
1999-01-28 03:40:01 +08:00
|
|
|
|
2000-02-22 11:09:53 +08:00
|
|
|
/* XXX W2DO? urlPath might be useful here. */
|
|
|
|
if (*pkg->fileFile == '/') {
|
|
|
|
ffn = rpmGetPath(pkg->fileFile, NULL);
|
|
|
|
} else {
|
|
|
|
/* XXX FIXME: add %{_buildsubdir} */
|
|
|
|
ffn = rpmGetPath("%{_builddir}/",
|
|
|
|
(spec->buildSubdir ? spec->buildSubdir : "") ,
|
|
|
|
"/", pkg->fileFile, NULL);
|
|
|
|
}
|
1999-11-15 03:15:18 +08:00
|
|
|
fd = Fopen(ffn, "r.fpio");
|
1998-09-06 04:02:08 +08:00
|
|
|
|
1999-11-13 01:20:49 +08:00
|
|
|
if (fd == NULL || Ferror(fd)) {
|
1998-07-26 05:00:26 +08:00
|
|
|
rpmError(RPMERR_BADFILENAME,
|
2001-01-16 07:09:42 +08:00
|
|
|
_("Could not open %%files file %s: %s\n"),
|
2000-02-12 07:16:47 +08:00
|
|
|
ffn, Fstrerror(fd));
|
1998-07-26 05:00:26 +08:00
|
|
|
return RPMERR_BADFILENAME;
|
1998-03-20 12:34:09 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
ffn = _free(ffn);
|
2000-08-10 00:49:10 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
/*@+voidabstract@*/ f = fdGetFp(fd); /*@=voidabstract@*/
|
2001-05-04 05:00:18 +08:00
|
|
|
if (f != NULL)
|
2001-04-29 09:05:43 +08:00
|
|
|
while (fgets(buf, sizeof(buf), f)) {
|
1998-07-26 05:00:26 +08:00
|
|
|
handleComments(buf);
|
1998-08-01 04:11:49 +08:00
|
|
|
if (expandMacros(spec, spec->macros, buf, sizeof(buf))) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("line: %s\n"), buf);
|
1998-07-26 05:00:26 +08:00
|
|
|
return RPMERR_BADSPEC;
|
|
|
|
}
|
|
|
|
appendStringBuf(pkg->fileList, buf);
|
|
|
|
}
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) Fclose(fd);
|
1998-03-20 12:34:09 +08:00
|
|
|
}
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Init the file list structure */
|
2001-07-16 22:48:07 +08:00
|
|
|
memset(&fl, 0, sizeof(fl));
|
2000-07-06 04:39:15 +08:00
|
|
|
|
1999-11-24 08:03:54 +08:00
|
|
|
/* XXX spec->buildRootURL == NULL, then xstrdup("") is returned */
|
|
|
|
fl.buildRootURL = rpmGenPath(spec->rootURL, spec->buildRootURL, NULL);
|
1999-01-28 03:40:01 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
if (hge(pkg->header, RPMTAG_DEFAULTPREFIX, NULL, (void **)&fl.prefix, NULL))
|
1999-09-21 11:22:53 +08:00
|
|
|
fl.prefix = xstrdup(fl.prefix);
|
2001-04-29 09:05:43 +08:00
|
|
|
else
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.prefix = NULL;
|
1998-03-20 12:34:09 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.fileCount = 0;
|
|
|
|
fl.totalFileSize = 0;
|
|
|
|
fl.processingFailed = 0;
|
1998-03-20 12:34:09 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.passedSpecialDoc = 0;
|
1999-10-05 01:29:58 +08:00
|
|
|
fl.isSpecialDoc = 0;
|
|
|
|
|
|
|
|
fl.isDir = 0;
|
|
|
|
fl.inFtw = 0;
|
|
|
|
fl.currentFlags = 0;
|
|
|
|
fl.currentVerifyFlags = 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
fl.noGlob = 0;
|
|
|
|
fl.devtype = 0;
|
|
|
|
fl.devmajor = 0;
|
|
|
|
fl.devminor = 0;
|
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
nullAttrRec(&fl.cur_ar);
|
|
|
|
nullAttrRec(&fl.def_ar);
|
1998-11-26 03:43:31 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
fl.defVerifyFlags = RPMVERIFY_ALL;
|
1999-05-18 00:27:38 +08:00
|
|
|
fl.nLangs = 0;
|
|
|
|
fl.currentLangs = NULL;
|
1998-03-20 12:34:09 +08:00
|
|
|
|
2001-03-17 00:33:25 +08:00
|
|
|
fl.currentSpecdFlags = 0;
|
|
|
|
fl.defSpecdFlags = 0;
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.docDirCount = 0;
|
1999-09-21 11:22:53 +08:00
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/doc");
|
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/man");
|
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/info");
|
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/X11R6/man");
|
2000-12-13 04:03:45 +08:00
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/doc");
|
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/man");
|
|
|
|
fl.docDirs[fl.docDirCount++] = xstrdup("/usr/share/info");
|
1999-01-06 07:13:56 +08:00
|
|
|
fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_docdir}", NULL);
|
1999-07-23 07:05:43 +08:00
|
|
|
fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_mandir}", NULL);
|
|
|
|
fl.docDirs[fl.docDirCount++] = rpmGetPath("%{_infodir}", NULL);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
fl.fileList = NULL;
|
|
|
|
fl.fileListRecsAlloced = 0;
|
|
|
|
fl.fileListRecsUsed = 0;
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
s = getStringBuf(pkg->fileList);
|
|
|
|
files = splitString(s, strlen(s), '\n');
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1998-11-25 03:30:38 +08:00
|
|
|
for (fp = files; *fp != NULL; fp++) {
|
1998-07-26 05:00:26 +08:00
|
|
|
s = *fp;
|
|
|
|
SKIPSPACE(s);
|
1998-11-25 03:30:38 +08:00
|
|
|
if (*s == '\0')
|
|
|
|
continue;
|
1998-07-26 05:00:26 +08:00
|
|
|
fileName = NULL;
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullpass@*/ /* LCL: buf is NULL ?!? */
|
1998-07-26 05:00:26 +08:00
|
|
|
strcpy(buf, s);
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullpass@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
/* Reset for a new line in %files */
|
|
|
|
fl.isDir = 0;
|
|
|
|
fl.inFtw = 0;
|
1999-04-30 22:59:47 +08:00
|
|
|
fl.currentFlags = 0;
|
2001-03-17 00:33:25 +08:00
|
|
|
/* turn explicit flags into %def'd ones (gosh this is hacky...) */
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentSpecdFlags = ((unsigned)fl.defSpecdFlags) >> 8;
|
1999-10-05 01:29:58 +08:00
|
|
|
fl.currentVerifyFlags = fl.defVerifyFlags;
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.isSpecialDoc = 0;
|
1999-05-18 00:27:38 +08:00
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
fl.noGlob = 0;
|
|
|
|
fl.devtype = 0;
|
|
|
|
fl.devmajor = 0;
|
|
|
|
fl.devminor = 0;
|
|
|
|
|
1999-05-18 00:27:38 +08:00
|
|
|
/* XXX should reset to %deflang value */
|
|
|
|
if (fl.currentLangs) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < fl.nLangs; i++)
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@-unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs[i] = _free(fl.currentLangs[i]);
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@=unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs = _free(fl.currentLangs);
|
1999-05-18 00:27:38 +08:00
|
|
|
}
|
|
|
|
fl.nLangs = 0;
|
1998-11-25 03:30:38 +08:00
|
|
|
|
1998-11-26 03:43:31 +08:00
|
|
|
dupAttrRec(&fl.def_ar, &fl.cur_ar);
|
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullpass@*/ /* LCL: buf is NULL ?!? */
|
1998-11-25 03:30:38 +08:00
|
|
|
if (parseForVerify(buf, &fl))
|
|
|
|
continue;
|
|
|
|
if (parseForAttr(buf, &fl))
|
|
|
|
continue;
|
2001-07-16 22:48:07 +08:00
|
|
|
if (parseForDev(buf, &fl))
|
|
|
|
continue;
|
1998-11-25 03:30:38 +08:00
|
|
|
if (parseForConfig(buf, &fl))
|
|
|
|
continue;
|
|
|
|
if (parseForLang(buf, &fl))
|
|
|
|
continue;
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: pkg->fileFile might be NULL */
|
1998-11-25 03:30:38 +08:00
|
|
|
if (parseForSimple(spec, pkg, buf, &fl, &fileName))
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullstate@*/
|
1998-11-25 03:30:38 +08:00
|
|
|
continue;
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullpass@*/
|
1998-11-25 03:30:38 +08:00
|
|
|
if (fileName == NULL)
|
|
|
|
continue;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
if (fl.isSpecialDoc) {
|
|
|
|
/* Save this stuff for last */
|
2001-04-29 09:05:43 +08:00
|
|
|
specialDoc = _free(specialDoc);
|
1999-09-21 11:22:53 +08:00
|
|
|
specialDoc = xstrdup(fileName);
|
2001-04-29 09:05:43 +08:00
|
|
|
dupAttrRec(&fl.cur_ar, specialDocAttrRec);
|
1998-07-26 05:00:26 +08:00
|
|
|
} else {
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: pkg->fileFile might be NULL */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) processBinaryFile(pkg, &fl, fileName);
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullstate@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Now process special doc, if there is one */
|
|
|
|
if (specialDoc) {
|
|
|
|
if (installSpecialDoc) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) doScript(spec, RPMBUILD_STRINGBUF, "%doc", pkg->specialDoc, test);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-04-30 22:59:47 +08:00
|
|
|
/* Reset for %doc */
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.isDir = 0;
|
|
|
|
fl.inFtw = 0;
|
|
|
|
fl.currentFlags = 0;
|
|
|
|
fl.currentVerifyFlags = 0;
|
1999-05-18 00:27:38 +08:00
|
|
|
|
2001-07-16 22:48:07 +08:00
|
|
|
fl.noGlob = 0;
|
|
|
|
fl.devtype = 0;
|
|
|
|
fl.devmajor = 0;
|
|
|
|
fl.devminor = 0;
|
|
|
|
|
1999-05-18 00:27:38 +08:00
|
|
|
/* XXX should reset to %deflang value */
|
|
|
|
if (fl.currentLangs) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < fl.nLangs; i++)
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@-unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs[i] = _free(fl.currentLangs[i]);
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@=unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs = _free(fl.currentLangs);
|
1999-05-18 00:27:38 +08:00
|
|
|
}
|
|
|
|
fl.nLangs = 0;
|
1999-04-30 22:59:47 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
dupAttrRec(specialDocAttrRec, &fl.cur_ar);
|
|
|
|
freeAttrRec(specialDocAttrRec);
|
1999-04-30 22:59:47 +08:00
|
|
|
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@-nullstate@*/ /* FIX: pkg->fileFile might be NULL */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) processBinaryFile(pkg, &fl, specialDoc);
|
2001-05-04 05:00:18 +08:00
|
|
|
/*@=nullstate@*/
|
1999-04-30 22:59:47 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
specialDoc = _free(specialDoc);
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
freeSplitString(files);
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-01-19 09:38:55 +08:00
|
|
|
if (fl.processingFailed)
|
|
|
|
goto exit;
|
|
|
|
|
|
|
|
/* Verify that file attributes scope over hardlinks correctly. */
|
2002-01-12 07:03:22 +08:00
|
|
|
if (checkHardLinks(&fl))
|
|
|
|
(void) rpmlibNeedsFeature(pkg->header,
|
|
|
|
"PartialHardlinkSets", "4.0.4-1");
|
2001-01-19 09:38:55 +08:00
|
|
|
|
2001-01-24 23:58:35 +08:00
|
|
|
genCpioListAndHeader(&fl, (TFI_t *)&pkg->cpioList, pkg->header, 0);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-01-19 09:38:55 +08:00
|
|
|
if (spec->timeCheck)
|
|
|
|
timeCheck(spec->timeCheck, pkg->header);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-19 09:38:55 +08:00
|
|
|
exit:
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.buildRootURL = _free(fl.buildRootURL);
|
|
|
|
fl.prefix = _free(fl.prefix);
|
1998-11-26 03:43:31 +08:00
|
|
|
|
|
|
|
freeAttrRec(&fl.cur_ar);
|
|
|
|
freeAttrRec(&fl.def_ar);
|
|
|
|
|
1999-05-18 00:27:38 +08:00
|
|
|
if (fl.currentLangs) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < fl.nLangs; i++)
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@-unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs[i] = _free(fl.currentLangs[i]);
|
2001-05-01 06:32:22 +08:00
|
|
|
/*@=unqualifiedtrans@*/
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.currentLangs = _free(fl.currentLangs);
|
1999-05-18 00:27:38 +08:00
|
|
|
}
|
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
|
|
|
|
while (fl.docDirCount--)
|
|
|
|
fl.docDirs[fl.docDirCount] = _free(fl.docDirs[fl.docDirCount]);
|
1998-07-26 05:00:26 +08:00
|
|
|
return fl.processingFailed;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
1999-04-17 22:23:42 +08:00
|
|
|
void initSourceHeader(Spec spec)
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
|
|
|
HeaderIterator hi;
|
2000-12-03 05:53:44 +08:00
|
|
|
int_32 tag, type, count;
|
2000-11-12 18:02:54 +08:00
|
|
|
const void * ptr;
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->sourceHeader = headerNew();
|
|
|
|
/* Only specific tags are added to the source package header */
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
1999-10-30 00:06:01 +08:00
|
|
|
for (hi = headerInitIterator(spec->packages->header);
|
|
|
|
headerNextIterator(hi, &tag, &type, &ptr, &count);
|
2000-12-03 05:53:44 +08:00
|
|
|
ptr = headerFreeData(ptr, type))
|
1999-10-30 00:06:01 +08:00
|
|
|
{
|
1998-07-26 05:00:26 +08:00
|
|
|
switch (tag) {
|
2000-07-11 11:46:56 +08:00
|
|
|
case RPMTAG_NAME:
|
|
|
|
case RPMTAG_VERSION:
|
|
|
|
case RPMTAG_RELEASE:
|
|
|
|
case RPMTAG_EPOCH:
|
|
|
|
case RPMTAG_SUMMARY:
|
|
|
|
case RPMTAG_DESCRIPTION:
|
|
|
|
case RPMTAG_PACKAGER:
|
|
|
|
case RPMTAG_DISTRIBUTION:
|
|
|
|
case RPMTAG_DISTURL:
|
|
|
|
case RPMTAG_VENDOR:
|
|
|
|
case RPMTAG_LICENSE:
|
|
|
|
case RPMTAG_GROUP:
|
|
|
|
case RPMTAG_OS:
|
|
|
|
case RPMTAG_ARCH:
|
|
|
|
case RPMTAG_CHANGELOGTIME:
|
|
|
|
case RPMTAG_CHANGELOGNAME:
|
|
|
|
case RPMTAG_CHANGELOGTEXT:
|
|
|
|
case RPMTAG_URL:
|
|
|
|
case HEADER_I18NTABLE:
|
2001-05-04 05:00:18 +08:00
|
|
|
if (ptr)
|
|
|
|
(void)headerAddEntry(spec->sourceHeader, tag, type, ptr, count);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
2000-07-11 11:46:56 +08:00
|
|
|
default:
|
1998-07-26 05:00:26 +08:00
|
|
|
/* do not copy */
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
2001-06-20 00:59:23 +08:00
|
|
|
hi = headerFreeIterator(hi);
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
1996-06-08 02:32:10 +08:00
|
|
|
|
1999-04-17 22:23:42 +08:00
|
|
|
/* Add the build restrictions */
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@-branchstate@*/
|
1999-10-30 00:06:01 +08:00
|
|
|
for (hi = headerInitIterator(spec->buildRestrictions);
|
|
|
|
headerNextIterator(hi, &tag, &type, &ptr, &count);
|
2000-12-03 05:53:44 +08:00
|
|
|
ptr = headerFreeData(ptr, type))
|
1999-10-30 00:06:01 +08:00
|
|
|
{
|
2001-05-04 05:00:18 +08:00
|
|
|
if (ptr)
|
|
|
|
(void) headerAddEntry(spec->sourceHeader, tag, type, ptr, count);
|
1999-04-17 22:23:42 +08:00
|
|
|
}
|
2001-06-20 00:59:23 +08:00
|
|
|
hi = headerFreeIterator(hi);
|
2001-10-16 01:53:34 +08:00
|
|
|
/*@=branchstate@*/
|
1999-04-17 22:23:42 +08:00
|
|
|
|
2001-05-07 03:17:14 +08:00
|
|
|
if (spec->BANames && spec->BACount > 0) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddEntry(spec->sourceHeader, RPMTAG_BUILDARCHS,
|
1999-04-17 22:23:42 +08:00
|
|
|
RPM_STRING_ARRAY_TYPE,
|
2001-05-07 03:17:14 +08:00
|
|
|
spec->BANames, spec->BACount);
|
1999-04-17 22:23:42 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int processSourceFiles(Spec spec)
|
|
|
|
{
|
|
|
|
struct Source *srcPtr;
|
|
|
|
StringBuf sourceFiles;
|
|
|
|
int x, isSpec = 1;
|
2001-04-29 09:05:43 +08:00
|
|
|
struct FileList_s fl;
|
1999-12-22 01:11:43 +08:00
|
|
|
char *s, **files, **fp;
|
1999-04-17 22:23:42 +08:00
|
|
|
Package pkg;
|
|
|
|
|
|
|
|
sourceFiles = newStringBuf();
|
|
|
|
|
1999-04-21 23:32:23 +08:00
|
|
|
/* XXX
|
|
|
|
* XXX This is where the source header for noarch packages needs
|
|
|
|
* XXX to be initialized.
|
|
|
|
*/
|
|
|
|
if (spec->sourceHeader == NULL)
|
|
|
|
initSourceHeader(spec);
|
1999-04-17 22:23:42 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
/* Construct the file list and source entries */
|
|
|
|
appendLineStringBuf(sourceFiles, spec->specFile);
|
2001-05-04 05:00:18 +08:00
|
|
|
if (spec->sourceHeader != NULL)
|
1998-08-02 21:48:37 +08:00
|
|
|
for (srcPtr = spec->sources; srcPtr != NULL; srcPtr = srcPtr->next) {
|
1998-07-26 05:00:26 +08:00
|
|
|
if (srcPtr->flags & RPMBUILD_ISSOURCE) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_SOURCE,
|
1998-07-26 05:00:26 +08:00
|
|
|
RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1);
|
|
|
|
if (srcPtr->flags & RPMBUILD_ISNO) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOSOURCE,
|
1998-07-26 05:00:26 +08:00
|
|
|
RPM_INT32_TYPE, &srcPtr->num, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (srcPtr->flags & RPMBUILD_ISPATCH) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_PATCH,
|
1998-07-26 05:00:26 +08:00
|
|
|
RPM_STRING_ARRAY_TYPE, &srcPtr->source, 1);
|
|
|
|
if (srcPtr->flags & RPMBUILD_ISNO) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerAddOrAppendEntry(spec->sourceHeader, RPMTAG_NOPATCH,
|
1998-07-26 05:00:26 +08:00
|
|
|
RPM_INT32_TYPE, &srcPtr->num, 1);
|
|
|
|
}
|
|
|
|
}
|
1998-09-06 04:02:08 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
{ const char * sfn;
|
|
|
|
sfn = rpmGetPath( ((srcPtr->flags & RPMBUILD_ISNO) ? "!" : ""),
|
1999-01-06 07:13:56 +08:00
|
|
|
"%{_sourcedir}/", srcPtr->source, NULL);
|
2001-04-29 09:05:43 +08:00
|
|
|
appendLineStringBuf(sourceFiles, sfn);
|
|
|
|
sfn = _free(sfn);
|
1998-09-06 04:02:08 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
1998-08-02 21:48:37 +08:00
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
|
|
|
for (srcPtr = pkg->icon; srcPtr != NULL; srcPtr = srcPtr->next) {
|
2001-04-29 09:05:43 +08:00
|
|
|
const char * sfn;
|
|
|
|
sfn = rpmGetPath( ((srcPtr->flags & RPMBUILD_ISNO) ? "!" : ""),
|
1999-01-06 07:13:56 +08:00
|
|
|
"%{_sourcedir}/", srcPtr->source, NULL);
|
2001-04-29 09:05:43 +08:00
|
|
|
appendLineStringBuf(sourceFiles, sfn);
|
|
|
|
sfn = _free(sfn);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
spec->sourceCpioList = NULL;
|
|
|
|
|
2001-07-04 03:26:58 +08:00
|
|
|
fl.fileList = xcalloc((spec->numSources + 1), sizeof(*fl.fileList));
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.processingFailed = 0;
|
|
|
|
fl.fileListRecsUsed = 0;
|
|
|
|
fl.totalFileSize = 0;
|
|
|
|
fl.prefix = NULL;
|
2001-07-04 03:26:58 +08:00
|
|
|
fl.buildRootURL = NULL;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
s = getStringBuf(sourceFiles);
|
|
|
|
files = splitString(s, strlen(s), '\n');
|
|
|
|
|
|
|
|
/* The first source file is the spec file */
|
|
|
|
x = 0;
|
1998-11-25 03:30:38 +08:00
|
|
|
for (fp = files; *fp != NULL; fp++) {
|
1999-12-22 01:11:43 +08:00
|
|
|
const char * diskURL, *diskPath;
|
2001-04-29 09:05:43 +08:00
|
|
|
FileListRec flp;
|
1999-12-22 01:11:43 +08:00
|
|
|
|
|
|
|
diskURL = *fp;
|
|
|
|
SKIPSPACE(diskURL);
|
|
|
|
if (! *diskURL)
|
1998-11-25 03:30:38 +08:00
|
|
|
continue;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-11-25 03:30:38 +08:00
|
|
|
flp = &fl.fileList[x];
|
|
|
|
|
|
|
|
flp->flags = isSpec ? RPMFILE_SPECFILE : 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
/* files with leading ! are no source files */
|
1999-12-22 01:11:43 +08:00
|
|
|
if (*diskURL == '!') {
|
1998-11-25 03:30:38 +08:00
|
|
|
flp->flags |= RPMFILE_GHOST;
|
1999-12-22 01:11:43 +08:00
|
|
|
diskURL++;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-10-30 07:03:12 +08:00
|
|
|
|
2001-04-29 09:05:43 +08:00
|
|
|
(void) urlPath(diskURL, &diskPath);
|
1999-10-30 07:03:12 +08:00
|
|
|
|
1999-12-22 01:11:43 +08:00
|
|
|
flp->diskURL = xstrdup(diskURL);
|
|
|
|
diskPath = strrchr(diskPath, '/');
|
|
|
|
if (diskPath)
|
|
|
|
diskPath++;
|
1999-10-30 07:03:12 +08:00
|
|
|
else
|
1999-12-22 01:11:43 +08:00
|
|
|
diskPath = diskURL;
|
1999-10-30 07:03:12 +08:00
|
|
|
|
1999-12-22 01:11:43 +08:00
|
|
|
flp->fileURL = xstrdup(diskPath);
|
1998-11-25 03:30:38 +08:00
|
|
|
flp->verifyFlags = RPMVERIFY_ALL;
|
|
|
|
|
2000-02-16 00:40:28 +08:00
|
|
|
if (Stat(diskURL, &flp->fl_st)) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad file: %s: %s\n"),
|
2000-02-16 00:40:28 +08:00
|
|
|
diskURL, strerror(errno));
|
|
|
|
fl.processingFailed = 1;
|
|
|
|
}
|
1998-11-25 03:30:38 +08:00
|
|
|
|
1998-11-25 08:42:36 +08:00
|
|
|
flp->uname = getUname(flp->fl_uid);
|
|
|
|
flp->gname = getGname(flp->fl_gid);
|
1999-09-21 11:22:53 +08:00
|
|
|
flp->langs = xstrdup("");
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-11-25 08:42:36 +08:00
|
|
|
fl.totalFileSize += flp->fl_size;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-11-25 03:30:38 +08:00
|
|
|
if (! (flp->uname && flp->gname)) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_BADSPEC, _("Bad owner/group: %s\n"), diskURL);
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.processingFailed = 1;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
isSpec = 0;
|
|
|
|
x++;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
fl.fileListRecsUsed = x;
|
|
|
|
freeSplitString(files);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
if (! fl.processingFailed) {
|
2001-05-04 05:00:18 +08:00
|
|
|
if (spec->sourceHeader != NULL)
|
|
|
|
genCpioListAndHeader(&fl, (TFI_t *)&spec->sourceCpioList,
|
|
|
|
spec->sourceHeader, 1);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
sourceFiles = freeStringBuf(sourceFiles);
|
2001-04-29 09:05:43 +08:00
|
|
|
fl.fileList = freeFileList(fl.fileList, fl.fileListRecsUsed);
|
1998-07-26 05:00:26 +08:00
|
|
|
return fl.processingFailed;
|
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static StringBuf getOutputFrom(char * dir, char * argv[],
|
|
|
|
const char * writePtr, int writeBytesLeft,
|
1998-07-26 05:00:26 +08:00
|
|
|
int failNonZero)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals fileSystem, internalState@*/
|
|
|
|
/*@modifies fileSystem, internalState@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
{
|
|
|
|
int progPID;
|
|
|
|
int toProg[2];
|
|
|
|
int fromProg[2];
|
|
|
|
int status;
|
|
|
|
void *oldhandler;
|
|
|
|
StringBuf readBuff;
|
1999-06-17 23:44:47 +08:00
|
|
|
int done;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-10-17 01:42:18 +08:00
|
|
|
/*@-type@*/ /* FIX: cast? */
|
1998-07-26 05:00:26 +08:00
|
|
|
oldhandler = signal(SIGPIPE, SIG_IGN);
|
2001-10-17 01:42:18 +08:00
|
|
|
/*@=type@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
toProg[0] = toProg[1] = 0;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) pipe(toProg);
|
1999-10-05 01:29:58 +08:00
|
|
|
fromProg[0] = fromProg[1] = 0;
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) pipe(fromProg);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
if (!(progPID = fork())) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(toProg[1]);
|
|
|
|
(void) close(fromProg[0]);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) dup2(toProg[0], STDIN_FILENO); /* Make stdin the in pipe */
|
|
|
|
(void) dup2(fromProg[1], STDOUT_FILENO); /* Make stdout the out pipe */
|
1996-06-08 02:32:10 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(toProg[0]);
|
|
|
|
(void) close(fromProg[1]);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
if (dir) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) chdir(dir);
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) execvp(argv[0], argv);
|
1999-11-11 06:09:49 +08:00
|
|
|
/* XXX this error message is probably not seen. */
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_EXEC, _("Couldn't exec %s: %s\n"),
|
1999-10-04 23:15:46 +08:00
|
|
|
argv[0], strerror(errno));
|
1998-07-26 05:00:26 +08:00
|
|
|
_exit(RPMERR_EXEC);
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
if (progPID < 0) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_FORK, _("Couldn't fork %s: %s\n"),
|
1999-10-04 23:15:46 +08:00
|
|
|
argv[0], strerror(errno));
|
1998-07-26 05:00:26 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(toProg[0]);
|
|
|
|
(void) close(fromProg[1]);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
/* Do not block reading or writing from/to prog. */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) fcntl(fromProg[0], F_SETFL, O_NONBLOCK);
|
|
|
|
(void) fcntl(toProg[1], F_SETFL, O_NONBLOCK);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
readBuff = newStringBuf();
|
|
|
|
|
|
|
|
do {
|
1999-06-17 23:44:47 +08:00
|
|
|
fd_set ibits, obits;
|
|
|
|
struct timeval tv;
|
|
|
|
int nfd, nbw, nbr;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
done = 0;
|
|
|
|
top:
|
|
|
|
/* XXX the select is mainly a timer since all I/O is non-blocking */
|
|
|
|
FD_ZERO(&ibits);
|
|
|
|
FD_ZERO(&obits);
|
|
|
|
if (fromProg[0] >= 0) {
|
|
|
|
FD_SET(fromProg[0], &ibits);
|
|
|
|
}
|
|
|
|
if (toProg[1] >= 0) {
|
|
|
|
FD_SET(toProg[1], &obits);
|
|
|
|
}
|
|
|
|
tv.tv_sec = 1;
|
|
|
|
tv.tv_usec = 0;
|
|
|
|
nfd = ((fromProg[0] > toProg[1]) ? fromProg[0] : toProg[1]);
|
|
|
|
if ((rc = select(nfd, &ibits, &obits, NULL, &tv)) < 0) {
|
|
|
|
if (errno == EINTR)
|
|
|
|
goto top;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
1998-10-02 21:45:30 +08:00
|
|
|
/* Write any data to program */
|
1999-06-17 23:44:47 +08:00
|
|
|
if (toProg[1] >= 0 && FD_ISSET(toProg[1], &obits)) {
|
|
|
|
if (writeBytesLeft) {
|
|
|
|
if ((nbw = write(toProg[1], writePtr,
|
1998-07-26 05:00:26 +08:00
|
|
|
(1024<writeBytesLeft) ? 1024 : writeBytesLeft)) < 0) {
|
|
|
|
if (errno != EAGAIN) {
|
|
|
|
perror("getOutputFrom()");
|
1998-11-21 04:18:22 +08:00
|
|
|
exit(EXIT_FAILURE);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-06-17 23:44:47 +08:00
|
|
|
nbw = 0;
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1999-06-17 23:44:47 +08:00
|
|
|
writeBytesLeft -= nbw;
|
|
|
|
writePtr += nbw;
|
|
|
|
} else if (toProg[1] >= 0) { /* close write fd */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(toProg[1]);
|
1998-09-10 23:09:21 +08:00
|
|
|
toProg[1] = -1;
|
1999-06-17 23:44:47 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
/* Read any data from prog */
|
1999-10-01 01:45:42 +08:00
|
|
|
{ char buf[BUFSIZ+1];
|
|
|
|
while ((nbr = read(fromProg[0], buf, sizeof(buf)-1)) > 0) {
|
|
|
|
buf[nbr] = '\0';
|
|
|
|
appendStringBuf(readBuff, buf);
|
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
|
|
|
|
1998-10-08 19:55:37 +08:00
|
|
|
/* terminate on (non-blocking) EOF or error */
|
1999-06-17 23:44:47 +08:00
|
|
|
done = (nbr == 0 || (nbr < 0 && errno != EAGAIN));
|
|
|
|
|
|
|
|
} while (!done);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-10-02 21:45:30 +08:00
|
|
|
/* Clean up */
|
1998-09-10 23:09:21 +08:00
|
|
|
if (toProg[1] >= 0)
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(toProg[1]);
|
1999-06-17 23:44:47 +08:00
|
|
|
if (fromProg[0] >= 0)
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) close(fromProg[0]);
|
2001-10-17 01:42:18 +08:00
|
|
|
/*@-type@*/ /* FIX: cast? */
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) signal(SIGPIPE, oldhandler);
|
2001-10-17 01:42:18 +08:00
|
|
|
/*@=type@*/
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-10-02 21:45:30 +08:00
|
|
|
/* Collect status from prog */
|
1998-11-17 05:40:28 +08:00
|
|
|
(void)waitpid(progPID, &status, 0);
|
1998-07-26 05:00:26 +08:00
|
|
|
if (failNonZero && (!WIFEXITED(status) || WEXITSTATUS(status))) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_EXEC, _("%s failed\n"), argv[0]);
|
1998-07-26 05:00:26 +08:00
|
|
|
return NULL;
|
1996-06-08 02:32:10 +08:00
|
|
|
}
|
1998-10-02 21:45:30 +08:00
|
|
|
if (writeBytesLeft) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(RPMERR_EXEC, _("failed to write all data to %s\n"), argv[0]);
|
1998-10-02 21:45:30 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
1998-07-26 05:00:26 +08:00
|
|
|
return readBuff;
|
1997-03-31 22:14:20 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1999-07-24 03:19:15 +08:00
|
|
|
typedef struct {
|
2001-06-06 04:39:35 +08:00
|
|
|
/*@observer@*/ /*@null@*/ const char * msg;
|
|
|
|
/*@observer@*/ const char * argv[4];
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTag ntag;
|
|
|
|
rpmTag vtag;
|
|
|
|
rpmTag ftag;
|
1999-07-24 03:19:15 +08:00
|
|
|
int mask;
|
|
|
|
int xor;
|
|
|
|
} DepMsg_t;
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@-exportlocal -exportheadervar@*/
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@unchecked@*/
|
1999-07-24 03:19:15 +08:00
|
|
|
DepMsg_t depMsgs[] = {
|
|
|
|
{ "Provides", { "%{__find_provides}", NULL, NULL, NULL },
|
|
|
|
RPMTAG_PROVIDENAME, RPMTAG_PROVIDEVERSION, RPMTAG_PROVIDEFLAGS,
|
|
|
|
0, -1 },
|
2000-11-12 19:11:49 +08:00
|
|
|
{ "PreReq", { NULL, NULL, NULL, NULL },
|
1999-07-24 03:19:15 +08:00
|
|
|
RPMTAG_REQUIRENAME, RPMTAG_REQUIREVERSION, RPMTAG_REQUIREFLAGS,
|
|
|
|
RPMSENSE_PREREQ, 0 },
|
2000-11-12 19:11:49 +08:00
|
|
|
{ "Requires(interp)", { NULL, "interp", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_INTERP), 0 },
|
|
|
|
{ "Requires(rpmlib)", { NULL, "rpmlib", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_RPMLIB), 0 },
|
|
|
|
{ "Requires(verify)", { NULL, "verify", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
RPMSENSE_SCRIPT_VERIFY, 0 },
|
|
|
|
{ "Requires(pre)", { NULL, "pre", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_SCRIPT_PRE), 0 },
|
|
|
|
{ "Requires(post)", { NULL, "post", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_SCRIPT_POST), 0 },
|
|
|
|
{ "Requires(preun)", { NULL, "preun", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_SCRIPT_PREUN), 0 },
|
|
|
|
{ "Requires(postun)", { NULL, "postun", NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS,
|
|
|
|
_notpre(RPMSENSE_SCRIPT_POSTUN), 0 },
|
1999-07-24 03:19:15 +08:00
|
|
|
{ "Requires", { "%{__find_requires}", NULL, NULL, NULL },
|
|
|
|
-1, -1, RPMTAG_REQUIREFLAGS, /* XXX inherit name/version arrays */
|
|
|
|
RPMSENSE_PREREQ, RPMSENSE_PREREQ },
|
|
|
|
{ "Conflicts", { "%{__find_conflicts}", NULL, NULL, NULL },
|
|
|
|
RPMTAG_CONFLICTNAME, RPMTAG_CONFLICTVERSION, RPMTAG_CONFLICTFLAGS,
|
|
|
|
0, -1 },
|
|
|
|
{ "Obsoletes", { "%{__find_obsoletes}", NULL, NULL, NULL },
|
|
|
|
RPMTAG_OBSOLETENAME, RPMTAG_OBSOLETEVERSION, RPMTAG_OBSOLETEFLAGS,
|
|
|
|
0, -1 },
|
|
|
|
{ NULL, { NULL, NULL, NULL, NULL }, 0, 0, 0, 0, 0 }
|
|
|
|
};
|
2001-06-04 21:55:58 +08:00
|
|
|
/*@=exportlocal =exportheadervar@*/
|
1999-07-24 03:19:15 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-01-24 23:58:35 +08:00
|
|
|
static int generateDepends(Spec spec, Package pkg, TFI_t cpioList, int multiLib)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@globals rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
2001-10-18 00:43:36 +08:00
|
|
|
/*@modifies cpioList, rpmGlobalMacroContext,
|
|
|
|
fileSystem, internalState @*/
|
1997-03-31 22:14:20 +08:00
|
|
|
{
|
2001-01-24 07:03:28 +08:00
|
|
|
TFI_t fi = cpioList;
|
1998-07-26 05:00:26 +08:00
|
|
|
StringBuf writeBuf;
|
|
|
|
int writeBytes;
|
|
|
|
StringBuf readBuf;
|
1999-07-24 03:19:15 +08:00
|
|
|
DepMsg_t *dm;
|
|
|
|
char *myargv[4];
|
1999-10-05 01:29:58 +08:00
|
|
|
int failnonzero = 0;
|
1999-07-24 03:19:15 +08:00
|
|
|
int rc = 0;
|
2001-01-24 07:03:28 +08:00
|
|
|
int i;
|
1997-03-31 22:14:20 +08:00
|
|
|
|
2001-03-17 00:33:25 +08:00
|
|
|
if (!(fi && fi->fc > 0))
|
1997-03-31 22:14:20 +08:00
|
|
|
return 0;
|
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
if (! (pkg->autoReq || pkg->autoProv))
|
1997-03-31 22:14:20 +08:00
|
|
|
return 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
|
|
|
writeBuf = newStringBuf();
|
2001-01-24 07:03:28 +08:00
|
|
|
for (i = 0, writeBytes = 0; i < fi->fc; i++) {
|
2000-07-06 04:39:15 +08:00
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
if (fi->fmapflags && multiLib == 2) {
|
|
|
|
if (!(fi->fmapflags[i] & CPIO_MULTILIB))
|
2000-07-06 04:39:15 +08:00
|
|
|
continue;
|
2001-01-24 07:03:28 +08:00
|
|
|
fi->fmapflags[i] &= ~CPIO_MULTILIB;
|
2000-07-06 04:39:15 +08:00
|
|
|
}
|
|
|
|
|
2001-01-24 07:03:28 +08:00
|
|
|
appendStringBuf(writeBuf, fi->dnl[fi->dil[i]]);
|
|
|
|
writeBytes += strlen(fi->dnl[fi->dil[i]]);
|
|
|
|
appendLineStringBuf(writeBuf, fi->bnl[i]);
|
|
|
|
writeBytes += strlen(fi->bnl[i]) + 1;
|
1997-03-31 22:14:20 +08:00
|
|
|
}
|
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
for (dm = depMsgs; dm->msg != NULL; dm++) {
|
2001-01-24 07:03:28 +08:00
|
|
|
int tag, tagflags;
|
1999-07-24 03:19:15 +08:00
|
|
|
|
|
|
|
tag = (dm->ftag > 0) ? dm->ftag : dm->ntag;
|
2000-11-12 19:11:49 +08:00
|
|
|
tagflags = 0;
|
1997-03-31 22:14:20 +08:00
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
switch(tag) {
|
|
|
|
case RPMTAG_PROVIDEFLAGS:
|
|
|
|
if (!pkg->autoProv)
|
|
|
|
continue;
|
|
|
|
failnonzero = 1;
|
2000-11-12 19:11:49 +08:00
|
|
|
tagflags = RPMSENSE_FIND_PROVIDES;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-24 03:19:15 +08:00
|
|
|
case RPMTAG_REQUIREFLAGS:
|
|
|
|
if (!pkg->autoReq)
|
|
|
|
continue;
|
|
|
|
failnonzero = 0;
|
2000-11-12 19:11:49 +08:00
|
|
|
tagflags = RPMSENSE_FIND_REQUIRES;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-24 03:19:15 +08:00
|
|
|
default:
|
|
|
|
continue;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@notreached@*/ /*@switchbreak@*/ break;
|
1997-03-31 22:14:20 +08:00
|
|
|
}
|
1999-07-24 03:19:15 +08:00
|
|
|
|
|
|
|
/* Get the script name to run */
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@-nullderef@*/ /* FIX: double indirection. @*/
|
2000-11-12 19:11:49 +08:00
|
|
|
myargv[0] = (dm->argv[0] ? rpmExpand(dm->argv[0], NULL) : NULL);
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@=nullderef@*/
|
1999-07-24 03:19:15 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
if (!(myargv[0] && *myargv[0] != '%')) {
|
2001-04-29 09:05:43 +08:00
|
|
|
myargv[0] = _free(myargv[0]);
|
1999-07-24 03:19:15 +08:00
|
|
|
continue;
|
1999-10-05 01:29:58 +08:00
|
|
|
}
|
1999-07-24 03:19:15 +08:00
|
|
|
|
|
|
|
rpmMessage(RPMMESS_NORMAL, _("Finding %s: (using %s)...\n"),
|
|
|
|
dm->msg, myargv[0]);
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
if (*myargv[0] != '/') { /* XXX FIXME: stat script here */
|
2001-04-29 09:05:43 +08:00
|
|
|
myargv[0] = _free(myargv[0]);
|
1999-07-24 03:19:15 +08:00
|
|
|
continue;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-07-24 03:19:15 +08:00
|
|
|
#endif
|
1997-03-31 22:14:20 +08:00
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
/* Expand rest of script arguments (if any) */
|
|
|
|
for (i = 1; i < 4; i++) {
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@-nullderef@*/ /* FIX: double indirection. @*/
|
1999-07-24 03:19:15 +08:00
|
|
|
myargv[i] = dm->argv[i] ? rpmExpand(dm->argv[i], NULL) : NULL;
|
2001-06-06 03:26:22 +08:00
|
|
|
/*@=nullderef@*/
|
1999-07-24 03:19:15 +08:00
|
|
|
}
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
readBuf = getOutputFrom(NULL, myargv,
|
|
|
|
getStringBuf(writeBuf), writeBytes, failnonzero);
|
|
|
|
|
|
|
|
/* Free expanded args */
|
2001-04-29 09:05:43 +08:00
|
|
|
for (i = 0; i < 4; i++)
|
|
|
|
myargv[i] = _free(myargv[i]);
|
1998-01-13 05:31:29 +08:00
|
|
|
|
1998-11-17 05:40:28 +08:00
|
|
|
if (readBuf == NULL) {
|
1999-07-24 03:19:15 +08:00
|
|
|
rc = RPMERR_EXEC;
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(rc, _("Failed to find %s:\n"), dm->msg);
|
1999-07-24 03:19:15 +08:00
|
|
|
break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-01-23 12:23:33 +08:00
|
|
|
|
1999-07-24 03:19:15 +08:00
|
|
|
/* Parse dependencies into header */
|
2000-11-12 19:11:49 +08:00
|
|
|
tagflags &= ~RPMSENSE_MULTILIB;
|
|
|
|
if (multiLib > 1)
|
|
|
|
tagflags |= RPMSENSE_MULTILIB;
|
|
|
|
else
|
|
|
|
tagflags &= ~RPMSENSE_MULTILIB;
|
|
|
|
rc = parseRCPOT(spec, pkg, getStringBuf(readBuf), tag, 0, tagflags);
|
2001-05-06 03:28:32 +08:00
|
|
|
readBuf = freeStringBuf(readBuf);
|
1999-07-24 03:19:15 +08:00
|
|
|
|
|
|
|
if (rc) {
|
2001-01-16 07:09:42 +08:00
|
|
|
rpmError(rc, _("Failed to find %s:\n"), dm->msg);
|
1999-07-24 03:19:15 +08:00
|
|
|
break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
|
|
|
}
|
1998-01-23 12:23:33 +08:00
|
|
|
|
2001-05-06 03:28:32 +08:00
|
|
|
writeBuf = freeStringBuf(writeBuf);
|
1999-07-24 03:19:15 +08:00
|
|
|
return rc;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-01-23 12:23:33 +08:00
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
2001-05-04 05:00:18 +08:00
|
|
|
static void printDepMsg(DepMsg_t * dm, int count, const char ** names,
|
|
|
|
const char ** versions, int *flags)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@*/
|
1998-01-23 12:23:33 +08:00
|
|
|
{
|
1999-07-23 06:38:44 +08:00
|
|
|
int hasVersions = (versions != NULL);
|
|
|
|
int hasFlags = (flags != NULL);
|
2000-11-12 19:11:49 +08:00
|
|
|
int bingo = 0;
|
|
|
|
int i;
|
1999-07-23 06:38:44 +08:00
|
|
|
|
|
|
|
for (i = 0; i < count; i++, names++, versions++, flags++) {
|
|
|
|
if (hasFlags && !((*flags & dm->mask) ^ dm->xor))
|
|
|
|
continue;
|
|
|
|
if (bingo == 0) {
|
2001-06-06 04:39:35 +08:00
|
|
|
rpmMessage(RPMMESS_NORMAL, "%s:", (dm->msg ? dm->msg : ""));
|
1999-07-23 06:38:44 +08:00
|
|
|
bingo = 1;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-07-23 06:38:44 +08:00
|
|
|
rpmMessage(RPMMESS_NORMAL, " %s", *names);
|
|
|
|
|
2000-07-06 04:39:15 +08:00
|
|
|
if (hasFlags && isDependsMULTILIB(*flags))
|
|
|
|
rpmMessage(RPMMESS_NORMAL, " (multilib)");
|
|
|
|
|
1999-07-23 06:38:44 +08:00
|
|
|
if (hasVersions && !(*versions != NULL && **versions != '\0'))
|
|
|
|
continue;
|
|
|
|
if (!(hasFlags && (*flags && RPMSENSE_SENSEMASK)))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
rpmMessage(RPMMESS_NORMAL, " ");
|
|
|
|
if (*flags & RPMSENSE_LESS)
|
|
|
|
rpmMessage(RPMMESS_NORMAL, "<");
|
|
|
|
if (*flags & RPMSENSE_GREATER)
|
|
|
|
rpmMessage(RPMMESS_NORMAL, ">");
|
|
|
|
if (*flags & RPMSENSE_EQUAL)
|
|
|
|
rpmMessage(RPMMESS_NORMAL, "=");
|
|
|
|
|
|
|
|
rpmMessage(RPMMESS_NORMAL, " %s", *versions);
|
|
|
|
}
|
|
|
|
if (bingo)
|
1998-07-26 05:00:26 +08:00
|
|
|
rpmMessage(RPMMESS_NORMAL, "\n");
|
1999-07-23 06:38:44 +08:00
|
|
|
}
|
|
|
|
|
2001-01-11 22:13:04 +08:00
|
|
|
/**
|
|
|
|
*/
|
1999-07-23 06:38:44 +08:00
|
|
|
static void printDeps(Header h)
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@*/
|
1999-07-23 06:38:44 +08:00
|
|
|
{
|
2001-04-29 09:05:43 +08:00
|
|
|
HGE_t hge = (HGE_t)headerGetEntryMinMemory;
|
|
|
|
HFD_t hfd = headerFreeData;
|
|
|
|
const char ** names = NULL;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType dnt = -1;
|
2001-04-29 09:05:43 +08:00
|
|
|
const char ** versions = NULL;
|
2001-06-12 12:10:21 +08:00
|
|
|
rpmTagType dvt = -1;
|
2001-04-29 09:05:43 +08:00
|
|
|
int * flags = NULL;
|
|
|
|
DepMsg_t * dm;
|
2001-10-16 22:58:57 +08:00
|
|
|
int count, xx;
|
1999-07-23 06:38:44 +08:00
|
|
|
|
|
|
|
for (dm = depMsgs; dm->msg != NULL; dm++) {
|
|
|
|
switch (dm->ntag) {
|
|
|
|
case 0:
|
2001-04-29 09:05:43 +08:00
|
|
|
names = hfd(names, dnt);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
case -1:
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
default:
|
2001-04-29 09:05:43 +08:00
|
|
|
names = hfd(names, dnt);
|
|
|
|
if (!hge(h, dm->ntag, &dnt, (void **) &names, &count))
|
1999-07-23 06:38:44 +08:00
|
|
|
continue;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-07-23 06:38:44 +08:00
|
|
|
switch (dm->vtag) {
|
|
|
|
case 0:
|
2001-04-29 09:05:43 +08:00
|
|
|
versions = hfd(versions, dvt);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
case -1:
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
default:
|
2001-04-29 09:05:43 +08:00
|
|
|
versions = hfd(versions, dvt);
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(h, dm->vtag, &dvt, (void **) &versions, NULL);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1999-07-23 06:38:44 +08:00
|
|
|
switch (dm->ftag) {
|
|
|
|
case 0:
|
|
|
|
flags = NULL;
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
case -1:
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1999-07-23 06:38:44 +08:00
|
|
|
default:
|
2001-10-16 22:58:57 +08:00
|
|
|
xx = hge(h, dm->ftag, NULL, (void **) &flags, NULL);
|
2001-10-14 06:01:38 +08:00
|
|
|
/*@switchbreak@*/ break;
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@-noeffect@*/
|
1999-07-23 06:38:44 +08:00
|
|
|
printDepMsg(dm, count, names, versions, flags);
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@=noeffect@*/
|
1998-01-23 12:23:33 +08:00
|
|
|
}
|
2001-04-29 09:05:43 +08:00
|
|
|
names = hfd(names, dnt);
|
|
|
|
versions = hfd(versions, dvt);
|
1998-07-26 05:00:26 +08:00
|
|
|
}
|
1998-01-23 12:23:33 +08:00
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
int processBinaryFiles(Spec spec, int installSpecialDoc, int test)
|
|
|
|
{
|
|
|
|
Package pkg;
|
1999-10-05 01:29:58 +08:00
|
|
|
int res = 0;
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1998-08-02 21:48:37 +08:00
|
|
|
for (pkg = spec->packages; pkg != NULL; pkg = pkg->next) {
|
1999-10-05 01:29:58 +08:00
|
|
|
const char *n, *v, *r;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
if (pkg->fileList == NULL)
|
1998-07-26 05:00:26 +08:00
|
|
|
continue;
|
|
|
|
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) headerNVR(pkg->header, &n, &v, &r);
|
1999-10-05 01:29:58 +08:00
|
|
|
rpmMessage(RPMMESS_NORMAL, _("Processing files: %s-%s-%s\n"), n, v, r);
|
1998-07-26 05:00:26 +08:00
|
|
|
|
1999-10-05 01:29:58 +08:00
|
|
|
if ((rc = processPackageFiles(spec, pkg, installSpecialDoc, test)))
|
1998-07-26 05:00:26 +08:00
|
|
|
res = rc;
|
|
|
|
|
2000-07-06 04:39:15 +08:00
|
|
|
/* XXX This should be added always so that packages look alike.
|
|
|
|
* XXX However, there is logic in files.c/depends.c that checks for
|
|
|
|
* XXX existence (rather than value) that will need to change as well.
|
|
|
|
*/
|
2001-04-29 09:05:43 +08:00
|
|
|
if (headerIsEntry(pkg->header, RPMTAG_MULTILIBS)) {
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) generateDepends(spec, pkg, pkg->cpioList, 1);
|
|
|
|
(void) generateDepends(spec, pkg, pkg->cpioList, 2);
|
2000-07-06 04:39:15 +08:00
|
|
|
} else
|
2001-05-01 06:32:22 +08:00
|
|
|
(void) generateDepends(spec, pkg, pkg->cpioList, 0);
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@-noeffect@*/
|
1999-07-23 06:38:44 +08:00
|
|
|
printDeps(pkg->header);
|
2001-10-15 11:22:10 +08:00
|
|
|
/*@=noeffect@*/
|
1998-01-23 12:23:33 +08:00
|
|
|
}
|
|
|
|
|
1998-07-26 05:00:26 +08:00
|
|
|
return res;
|
1998-01-23 12:23:33 +08:00
|
|
|
}
|