Example #1
0
char * rpmGenPath(const char * urlroot, const char * urlmdir,
		const char *urlfile)
{
    char * xroot = rpmGetPath(urlroot, NULL);
    const char * root = xroot;
    char * xmdir = rpmGetPath(urlmdir, NULL);
    const char * mdir = xmdir;
    char * xfile = rpmGetPath(urlfile, NULL);
    const char * file = xfile;
    char * result;
    char * url = NULL;
    int nurl = 0;
    int ut;

    ut = urlPath(xroot, &root);
    if (url == NULL && ut > URL_IS_DASH) {
	url = xroot;
	nurl = root - xroot;
    }
    if (root == NULL || *root == '\0') root = "/";

    ut = urlPath(xmdir, &mdir);
    if (url == NULL && ut > URL_IS_DASH) {
	url = xmdir;
	nurl = mdir - xmdir;
    }
    if (mdir == NULL || *mdir == '\0') mdir = "/";

    ut = urlPath(xfile, &file);
    if (url == NULL && ut > URL_IS_DASH) {
	url = xfile;
	nurl = file - xfile;
    }

    if (url && nurl > 0) {
	char *t = rstrcat(NULL, url);
	t[nurl] = '\0';
	url = t;
    } else
	url = xstrdup("");

    result = rpmGetPath(url, root, "/", mdir, "/", file, NULL);

    free(xroot);
    free(xmdir);
    free(xfile);
    free(url);
    return result;
}
Example #2
0
File: url.c Project: kaltsi/rpm
int urlGetFile(const char * url, const char * dest)
{
    char *cmd = NULL;
    const char *target = NULL;
    char *urlhelper = NULL;
    int rc;
    pid_t pid, wait;

    urlhelper = rpmExpand("%{?_urlhelper}", NULL);

    if (dest == NULL) {
	urlPath(url, &target);
    } else {
	target = dest;
    }

    /* XXX TODO: sanity checks like target == dest... */

    rasprintf(&cmd, "%s %s %s", urlhelper, target, url);
    urlhelper = _free(urlhelper);

    if ((pid = fork()) == 0) {
        ARGV_t argv = NULL;
        argvSplit(&argv, cmd, " ");
        execvp(argv[0], argv);
        exit(127); /* exit with 127 for compatibility with bash(1) */
    }
    wait = waitpid(pid, &rc, 0);
    cmd = _free(cmd);

    return rc;

}
Example #3
0
const char * rpmmgFile(rpmmg mg, const char *fn)
{
    const char * t = NULL;

if (_rpmmg_debug)
fprintf(stderr, "--> rpmmgFile(%p, %s)\n", mg, (fn ? fn : "(nil)"));

#if defined(HAVE_MAGIC_H)
    if (mg->ms) {
	const char * lpath = NULL;
	int ut = urlPath(fn, &lpath);

	switch (ut) {
	case URL_IS_FTP:
	case URL_IS_HKP:
	case URL_IS_HTTP:
	case URL_IS_HTTPS:
	{   char b[512];
	    size_t nb = 0;
	    FD_t fd;
	    
	    fd = Fopen(fn, "r.ufdio");
	    if (fd != NULL && !Ferror(fd)) {
		nb = Fread(b, 1, sizeof(b), fd);
		(void) Fclose(fd);
	    }
	    if (nb > 0)
		return rpmmgBuffer(mg, b, nb);
	}   break;
	case URL_IS_DASH:
	case URL_IS_MONGO:	/* XXX FIXME */
	    break;
	case URL_IS_PATH:
	    fn = lpath;
	    /*@fallthrough@*/
	case URL_IS_UNKNOWN:
	default:
	    t = magic_file(mg->ms, fn);
	    /* XXX HACK: libmagic compiled without <pcreposix.h> spews here. */
	    if (t == NULL) {
		const char * msg = magic_error(mg->ms);
		if (strstr(msg, "regexec error 17, (match failed)") == NULL)
		    rpmlog(RPMLOG_ERR, _("magic_file(ms, %s) failed: %s\n"),
			    (fn ? fn : "(nil)"), msg);
	    }
	    break;
	}
    }
#endif

    if (t == NULL) t = "";
    t = xstrdup(t);

if (_rpmmg_debug)
fprintf(stderr, "<-- rpmmgFile(%p, %s) %s\n", mg, (fn ? fn : "(nil)"), t);
    return t;
}
Example #4
0
bool CPFCManager::GetDefsFile(const CStdString& strPath, TiXmlDocument& xmlDocument) {

//	CStdString strTemp = strPath;
//
//	if (!URIUtils::IsURL(strTemp)) {
//		CURL::Encode(strTemp);
//	}

  CURL urlPath(strPath);
  CStdString strFile = urlPath.GetHostName();

  URIUtils::CreateArchivePath(strFile, "pfc", strPath, DEFSFILE);

  char* defFile;
  CStdString strDoc;

  XFILE::CFile file;

  if (file.Open(strFile))
  {
    int size = (int) file.GetLength();

    try
    {
      defFile = new char[size + 1];
    }
    catch (...)
    {
      CLog::Log(LOGERROR, "%s: Exception while creating file buffer", __FUNCTION__);
      return false;
    }

    if (!defFile)
    {
      file.Close();
      return false;
    }

    file.Read(defFile, size);
    defFile[size] = 0;
    strDoc = defFile;

    file.Close();
    free(defFile);
  }

  // Laureon: Convert the document to UTF8...
  if (strDoc.Find("encoding=") == -1) g_charsetConverter.unknownToUTF8(strDoc);

  xmlDocument.Parse(strDoc.c_str());

  if (!xmlDocument.RootElement()) return false;

  return true;
}
Example #5
0
ePACKTYPE CPFCManager::GetPFCType(const CStdString& strPath) {
  CURL urlPath(strPath);
  CStdString strFile = urlPath.GetHostName();

  sFileMap fileMap;

  if (GetFromCache(strFile, fileMap, true))
  { // already listed, just return it, else append to cache
    return fileMap.sHeader.PackType;
  }

  return RPF_PACK_TYPE_NONE;
}
Example #6
0
bool CPFCManager::GetEntriesList(const CStdString& strPath, VECFILEENTRY& items) {
  CURL urlPath(strPath);
  CStdString strFile = urlPath.GetHostName();

  CLog::Log(LOGDEBUG, "%s - Processing %s", __FUNCTION__, strFile.c_str());

  sFileMap fileMap;

  if (GetFromCache(strFile, fileMap, true))
  { // already listed, just return it, else append to cache
    items = fileMap.vecFiles;
    return true;
  }

  return false;
}
Example #7
0
url
get_from_web (url name) {
    if (!is_rooted_web (name)) return url_none ();
    url res= get_cache (name);
    if (!is_none (res)) return res;

#ifdef OS_WIN32
    string urlString = as_string (name);
    url tmp = url_temp();

    if (starts (urlString, "www."))
        urlString = "http://" * urlString;
    else if (starts (urlString, "ftp."))
        urlString = "ftp://" * urlString;
    else if (starts (urlString, "ftp://"))
        urlPath = NULL;
    else if (starts (urlString, "http://"))
        urlPath = NULL;
    else
        urlString = "http://" * urlString;
    urlString= web_encode (urlString);

    c_string urlPath (urlString);
    c_string tempFilePath (as_string (tmp));

    if(!URL_Get(urlPath, tempFilePath))
        return url_none();
    else return set_cache (name, tmp);
#else
    string test= var_eval_system ("which wget");
    if (!ends (test, "wget")) return url_none ();
    url tmp= url_temp ();
    string tmp_s= escape_sh (concretize (tmp));
    string cmd= "wget --header='User-Agent: TeXmacs-" TEXMACS_VERSION "' -q";
    cmd << " -O " << tmp_s << " " << escape_sh (web_encode (as_string (name)));
    // cout << cmd << "\n";
    system (cmd);
    // cout << "got " << name << " as " << tmp << "\n";

    if (var_eval_system ("cat " * tmp_s * " 2> /dev/null") == "") {
        remove (tmp);
        return url_none ();
    }
    else return set_cache (name, tmp);
#endif
}
Example #8
0
  void
  Wc::ensureAdm(const char * dir, const char *uuid,
                const char * url, const Revision & revision)
  {
    Pool pool;
    Path dirPath(dir);
    Path urlPath(url);

    svn_error_t * error =
      svn_wc_ensure_adm(dirPath.c_str(),      // path
                        uuid,                // UUID
                        urlPath.c_str(),     // url
                        revision.revnum(),   // revision
                        pool);

    if (error != NULL)
      throw ClientException(error);
  }
Example #9
0
File: rpmio.c Project: akozumpl/rpm
static FD_t ufdOpen(const char * url, int flags, mode_t mode)
{
    FD_t fd = NULL;
    const char * path;
    urltype urlType = urlPath(url, &path);

if (_rpmio_debug)
fprintf(stderr, "*** ufdOpen(%s,0x%x,0%o)\n", url, (unsigned)flags, (unsigned)mode);

    switch (urlType) {
    case URL_IS_FTP:
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_HKP:
	fd = urlOpen(url, flags, mode);
	/* we're dealing with local file when urlOpen() returns */
	urlType = URL_IS_UNKNOWN;
	break;
    case URL_IS_DASH:
	if ((flags & O_ACCMODE) == O_RDWR) {
	    fd = NULL;
	} else {
	    fd = fdDup((flags & O_ACCMODE) == O_WRONLY ?
			STDOUT_FILENO : STDIN_FILENO);
	}
	break;
    case URL_IS_PATH:
    case URL_IS_UNKNOWN:
    default:
	fd = fdOpen(path, flags, mode);
	break;
    }

    if (fd == NULL) return NULL;

    fdSetIo(fd, ufdio);
    fd->urlType = urlType;

    if (Fileno(fd) < 0) {
	(void) fdClose(fd);
	return NULL;
    }
    return fd;
}
Example #10
0
bool CPFCManager::GetFileEntry(const CStdString& strPath, sFileEntry& item) {
  VECFILEENTRY items;
  // we need to list the pfs
  if (!GetEntriesList(strPath, items)) return false;

  CURL urlPath(strPath);
  CStdString strFileName = urlPath.GetFileName();

  for (VECFILEENTRY::iterator it2 = items.begin(); it2 != items.end(); ++it2)
  {
    if (CStdString(it2->FileName) == strFileName)
    {
      memcpy(&item, &(*it2), sizeof(sFileEntry));
      return true;
    }
  }

  return false;
}
Example #11
0
void DownloadAvatarTask::doTask()
{
	try
	{
		if (strncmp(m_szUrl.c_str(),"http://", 7)==0)
		{
			HttpHandle wc(m_szUrl.c_str());
			wc->getWeb();
			
			if (wc->getDataSize() != 0)
			{
				if (UTIL::MISC::isValidImage((const unsigned char*)wc->getData()) == IMAGE_VOID)
					throw gcException(ERR_INVALIDDATA, gcString("The url [{0}] is not an image format", m_szUrl));
				
				UTIL::FS::Path urlPath(m_szUrl, "", true);
				UTIL::FS::Path path(getUserCore()->getAppDataPath(), "", false);

				path += "users";
				path += gcString("{0}", m_uiUserId);
				path += urlPath.getFile();

				UTIL::FS::recMakeFolder(path);
				UTIL::FS::FileHandle fh(path, UTIL::FS::FILE_WRITE);

				fh.write(wc->getData(), wc->getDataSize());
				fh.close();

				getUserCore()->setAvatarUrl(path.getFullPath().c_str());
			}
			else
			{
				throw gcException(ERR_BADRESPONSE);
			}
		}
	}
	catch (gcException &e)
	{
		onErrorEvent(e);
	}
}
Example #12
0
File: fts.c Project: avokhmin/RPM5
/*
 * Change to dir specified by fd or p->fts_accpath without getting
 * tricked by someone changing the world out from underneath us.
 * Assumes p->fts_dev and p->fts_ino are filled in.
 */
static int
fts_safe_changedir(FTS * sp, FTSENT * p, int fd, const char * path)
{
	int ret, oerrno, newfd;
	struct stat64 sb;

	newfd = fd;
	if (ISSET(FTS_NOCHDIR))
		return (0);

	/* Permit open(2) on file:// prefixed URI paths. */
	/* XXX todo: use Open(2), which is Chroot(2) path invariant. */
	/* XXX todo: add Fts(3) options to disable the hackery? */
	{	const char * lpath = NULL;
		int ut = urlPath(path, &lpath);
		if (ut == URL_IS_PATH) path = lpath;
	}

	if (fd < 0 && (newfd = __open(path, O_RDONLY, 0)) < 0)
		return (-1);
/*@-sysunrecog -unrecog @*/
	if (__fxstat64(_STAT_VER, newfd, &sb)) {
		ret = -1;
		goto bail;
	}
/*@=sysunrecog =unrecog @*/
	if (p->fts_dev != sb.st_dev || p->fts_ino != sb.st_ino) {
		__set_errno (ENOENT);		/* disinformation */
		ret = -1;
		goto bail;
	}
	ret = __fchdir(newfd);
bail:
	oerrno = errno;
	if (fd < 0)
		(void)__close(newfd);
	__set_errno (oerrno);
	return (ret);
}
Example #13
0
void Theme::LoadWeb(const UTIL::FS::Path& path, const XML::gcXMLElement &xmlEl)
{
	gcString urlPath(path.getFolderPath());

	for (size_t x=0; x<urlPath.size(); x++)
	{
		if (urlPath[x] == '\\')
			urlPath[x] = '/';
	}

	xmlEl.for_each_child("page", [this, urlPath](const XML::gcXMLElement &xmlChild)
	{
		const std::string name = xmlChild.GetAtt("name");
		const std::string val = xmlChild.GetText();

		if (name.empty() || val.empty())
			return;

		std::string outVal = UTIL::STRING::sanitizeFileName(val);

#ifdef WIN32
		gcString fullPath("file:///{0}/html/{1}", urlPath, outVal);
#else
		gcString fullPath("file://{0}/html/{1}", urlPath, outVal);
#endif

		auto web = WebList::findItem(name.c_str());

		if (!web)
		{
			web = gcRefPtr<ThemeWebInfo>::create(name.c_str());
			addItem(web);
		}

		web->path = fullPath;
	});
}
Example #14
0
/*@-boundswrite@*/
static int buildForTarget(rpmts ts, BTA_t ba)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies ts, rpmGlobalMacroContext, fileSystem, internalState @*/
{
    const char * passPhrase = ba->passPhrase;
    const char * cookie = ba->cookie;
    int buildAmount = ba->buildAmount;
    const char * specFile = NULL;
    const char * specURL = NULL;
    int specut;
    const char * s;
    char * se;
    const char * arg = ba->specFile;
    size_t nb = strlen(arg) + BUFSIZ;
    char * buf = alloca(nb);
    Spec spec = NULL;
    int verify = ((ba->buildAmount & RPMBUILD_TRACK) ? 0 : 1);
    int xx;
    int rc;

    if (ba->buildMode == 't') {
	static const char * sfpats[] = { "Specfile", "\\*.spec", NULL };
	static const char _specfn[] = "%{mkstemp:%{_specdir}/rpm-spec.XXXXXX}";
	char * tmpSpecFile = (char *) rpmGetPath(_specfn, NULL);
	FILE *fp;
	int bingo = 0;
	int i;

	for (i = 0; sfpats[i]; i++) {
	    se = rpmExpand("%{uncompress: %{u2p:", arg, "}}",
		" | %{__tar} -xOvf - %{?__tar_wildcards} ", sfpats[i],
		" 2>&1 > '", tmpSpecFile, "'", NULL);
	    fp = popen(se, "r");
	    se = _free(se);
	    if (fp== NULL)
		continue;
	    s = fgets(buf, nb - 1, fp);
	    xx = pclose(fp);
	    if (!s || !*s || strstr(s, ": Not found in archive"))
		continue;
	    bingo = 1;
	    break;
	}
	if (!bingo) {
	    rpmlog(RPMLOG_ERR, _("Failed to read spec file from %s\n"), arg);
	    xx = Unlink(tmpSpecFile);
	    tmpSpecFile = _free(tmpSpecFile);
	    return 1;
	}

	s = se = basename(buf);
	se += strlen(se);
	while (--se > s && strchr("\r\n", *se) != NULL)
	    *se = '\0';
	specURL = rpmGetPath("%{_specdir}/", s, NULL);
	specut = urlPath(specURL, &specFile);
	xx = Rename(tmpSpecFile, specFile);
	if (xx) {
	    rpmlog(RPMLOG_ERR, _("Failed to rename %s to %s: %m\n"),
			tmpSpecFile, s);
	    (void) Unlink(tmpSpecFile);
	}
	tmpSpecFile = _free(tmpSpecFile);
	if (xx)
	    return 1;

	se = buf; *se = '\0';
	se = stpcpy(se, "_sourcedir ");
	(void) urlPath(arg, &s);
	if (*s != '/') {
	    if (getcwd(se, nb - sizeof("_sourcedir ")) != NULL)
		se += strlen(se);
	    else
		se = stpcpy(se, ".");
	} else
	    se = stpcpy(se, dirname(strcpy(se, s)));
	while (se > buf && se[-1] == '/')
	    *se-- = '0';
	rpmCleanPath(buf + sizeof("_sourcedir ") - 1);
	rpmDefineMacro(NULL, buf, RMIL_TARBALL);
    } else {
	specut = urlPath(arg, &s);
	se = buf; *se = '\0';
	if (*s != '/') {
	    if (getcwd(se, nb - sizeof("_sourcedir ")) != NULL)
		se += strlen(se);
	    else
		se = stpcpy(se, ".");
	    *se++ = '/';
	    se += strlen(strcpy(se,strcpy(se, s)));
	} else
	    se = stpcpy(se, s);
	specURL = rpmGetPath(buf, NULL);
	specut = urlPath(specURL, &specFile);
    }

    if (specut != URL_IS_DASH) {
	struct stat sb;
	if (Stat(specURL, &sb) < 0) {
	    rpmlog(RPMLOG_ERR, _("failed to stat %s: %m\n"), specURL);
	    rc = 1;
	    goto exit;
	}
	if (! S_ISREG(sb.st_mode)) {
	    rpmlog(RPMLOG_ERR, _("File %s is not a regular file.\n"),
		specURL);
	    rc = 1;
	    goto exit;
	}

	/* Try to verify that the file is actually a specfile */
	if (!isSpecFile(specURL)) {
	    rpmlog(RPMLOG_ERR,
		_("File %s does not appear to be a specfile.\n"), specURL);
	    rc = 1;
	    goto exit;
	}
    }
    
    /* Parse the spec file */
#define	_anyarch(_f)	\
(((_f)&(RPMBUILD_PREP|RPMBUILD_BUILD|RPMBUILD_INSTALL|RPMBUILD_PACKAGEBINARY)) == 0)
    if (parseSpec(ts, specURL, ba->rootdir, 0, passPhrase,
		cookie, _anyarch(buildAmount), 0, verify))
    {
	rc = 1;
	goto exit;
    }
#undef	_anyarch
    if ((spec = rpmtsSetSpec(ts, NULL)) == NULL) {
	rc = 1;
	goto exit;
    }

    /* Assemble source header from parsed components */
    xx = initSourceHeader(spec, NULL);

    /* Check build prerequisites */
    if (!ba->noDeps && checkSpec(ts, spec->sourceHeader)) {
	rc = 1;
	goto exit;
    }

    if (buildSpec(ts, spec, buildAmount, ba->noBuild)) {
	rc = 1;
	goto exit;
    }
    
    if (ba->buildMode == 't')
	(void) Unlink(specURL);
    rc = 0;

exit:
    spec = freeSpec(spec);
    specURL = _free(specURL);
    return rc;
}
Example #15
0
int rpmDoDigest(int algo, const char * fn,int asAscii,
                unsigned char * digest, rpm_loff_t * fsizep)
{
    const char * path;
    urltype ut = urlPath(fn, &path);
    unsigned char * dig = NULL;
    size_t diglen;
    unsigned char buf[32*BUFSIZ];
    FD_t fd;
    rpm_loff_t fsize = 0;
    pid_t pid = 0;
    int rc = 0;
    int fdno;

    fdno = open_dso(path, &pid, &fsize);
    if (fdno < 0) {
	rc = 1;
	goto exit;
    }

    switch(ut) {
    case URL_IS_PATH:
    case URL_IS_UNKNOWN:
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
    case URL_IS_HKP:
    case URL_IS_DASH:
    default:
	/* Either use the pipe to prelink -y or open the URL. */
	fd = (pid != 0) ? fdDup(fdno) : Fopen(fn, "r.ufdio");
	(void) close(fdno);
	if (fd == NULL || Ferror(fd)) {
	    rc = 1;
	    if (fd != NULL)
		(void) Fclose(fd);
	    break;
	}
	
	fdInitDigest(fd, algo, 0);
	fsize = 0;
	while ((rc = Fread(buf, sizeof(buf[0]), sizeof(buf), fd)) > 0)
	    fsize += rc;
	fdFiniDigest(fd, algo, (void **)&dig, &diglen, asAscii);
	if (dig == NULL || Ferror(fd))
	    rc = 1;

	(void) Fclose(fd);
	break;
    }

    /* Reap the prelink -y helper. */
    if (pid) {
	int status;
	(void) waitpid(pid, &status, 0);
	if (!WIFEXITED(status) || WEXITSTATUS(status))
	    rc = 1;
    }

exit:
    if (fsizep)
	*fsizep = fsize;
    if (!rc)
	memcpy(digest, dig, diglen);
    dig = _free(dig);

    return rc;
}
Example #16
0
void Url::parseString(const char* urlString, UtlBoolean isAddrSpec)
{
   // If isAddrSpec:
   //                userinfo@hostport;uriParameters?headerParameters
   // If !isAddrSpec:
   //    DisplayName<userinfo@hostport;urlParameters?headerParameters>;fieldParameters

#  ifdef TIME_PARSE
   OsTimeLog timeLog;
   LOG_TIME("start    ");
#  endif

   // Try to catch when a name-addr is passed but we are expecting an
   // addr-spec -- many name-addr's start with '<' or '"'.
   if (isAddrSpec && (urlString[0] == '<' || urlString[0] == '"'))
   {
      OsSysLog::add(FAC_SIP, PRI_ERR,
                    "Url::parseString Invalid addr-spec found (probably name-addr format): '%s'",
                    urlString);
   }

   int workingOffset = 0; // begin at the beginning...
   
   size_t afterAngleBrackets = UTL_NOT_FOUND;
   
   if (isAddrSpec)
   {
      mAngleBracketsIncluded = FALSE; 
   }
   else // ! addr-spec
   {
      // Is there a display name on the front?
      mDisplayName.remove(0);
      LOG_TIME("display   <");
      RegEx displayName(DisplayName);
      if (displayName.SearchAt(urlString, workingOffset))
      {
         LOG_TIME("display   > ");
         switch (displayName.Matches() /* number of substrings that matched */)
         {
         case 2: // matched unquoted sequence of tokens
            displayName.MatchString(&mDisplayName, 1);
            break;
            
         case 3: // matched a double quoted string
            // see performance note on DisplayName
            mDisplayName.append("\"");
            displayName.MatchString(&mDisplayName, 2);
            mDisplayName.append("\"");
            break;

         default:
            assert(false);
         }

         // does not include whitespace or the '<'
         workingOffset = displayName.AfterMatch(0);
      }

      // Are there angle brackets around the URI?
      LOG_TIME("angles   < ");
      RegEx angleBrackets(AngleBrackets);
      if (angleBrackets.SearchAt(urlString, workingOffset))
      {
         LOG_TIME("angles   > ");
         // yes, there are angle brackets
         workingOffset = angleBrackets.MatchStart(1); // inside the angle brackets
         afterAngleBrackets = angleBrackets.AfterMatch(0); // following the '>'
         
         /*
          * Note: We do not set mAngleBracketsIncluded just because we saw them
          *       That is only used for explicit control from the outside.
          *       The local knowledge of whether or not there are angle brackets
          *       is whether or not afterAngleBrackets == UTL_NOT_FOUND
          */
      }
   }

      /*
       * AMBIGUITY - there is a potential ambiguity when parsing real URLs.
       *
       * Consider the url 'foo:333' - it could be:
       *       scheme 'foo' host '333' ('333' is a valid local host name - bad idea, but legal)
       *   or  host   'foo' port '333' (and scheme 'sip' is implied)
       *
       * Now make it worse by using 'sips' as a hostname:
       *   'sips:333'     
       *       scheme 'sips' host '333'
       *   or  host   'sips' port '333' (and scheme 'sip' is implied)
       *
       * We resolve the first case by treating anything left of the colon as a scheme if
       * it is one of the supported schemes.  Otherwise, we set the scheme to the
       * default (sip) and go on so that it will be parsed as a hostname.  This does not
       * do the right thing for the (scheme 'sips' host '333') case, but they get what
       * they deserve.
       */
   
   // Parse the scheme (aka url type)
   LOG_TIME("scheme   < ");
   RegEx supportedScheme(SupportedScheme);
   if (   (supportedScheme.SearchAt(urlString,workingOffset))
       && (supportedScheme.MatchStart(0) == workingOffset)
       )
      {
      LOG_TIME("scheme   > ");
      // the scheme name matches one of the supported schemes
      mScheme = static_cast<Scheme>(supportedScheme.Matches()-1);
      workingOffset = supportedScheme.AfterMatch(0); // past the ':'
   }
   else
   {
      /*
       * It did not match one of the supported scheme names
       * so proceed on the assumption that it's a host and "sip:" is implied
       * Leave the workingOffset where it is (before the token).
       * The code below, through the parsing of host and port
       * treats this as an implicit 'sip:' url; if it parses ok
       * up to that point, it resets the scheme to SipsUrlScheme
       */
      mScheme = UnknownUrlScheme;
   }


   // skip over any '//' following the scheme for the ones we know use that
   switch (mScheme)
   {
   case FileUrlScheme:
   case FtpUrlScheme:
   case HttpUrlScheme:
   case HttpsUrlScheme:
   case RtspUrlScheme:
      if (0==strncmp("//", urlString+workingOffset, 2))
      {
         workingOffset += 2;
      }
      break;

   case UnknownUrlScheme:
   case SipUrlScheme:
   case SipsUrlScheme:
   case MailtoUrlScheme:
   default:
      break;
   }
   
   if (FileUrlScheme != mScheme) // no user part in file urls
   {
      // Parse the username and password
      LOG_TIME("userpass   < ");
      RegEx usernameAndPassword(UsernameAndPassword);
      if (   (usernameAndPassword.SearchAt(urlString, workingOffset))
          && usernameAndPassword.MatchStart(0) == workingOffset 
          )
      {
         LOG_TIME("userpass   > ");
         usernameAndPassword.MatchString(&mUserId, 1);
         usernameAndPassword.MatchString(&mPassword, 2);
         workingOffset = usernameAndPassword.AfterMatch(0);
      }
      else
      {
         // username and password are optional, so not finding them is ok
         // leave workingOffset where it is
      }
   }

   // Parse the hostname and port
   LOG_TIME("hostport   < ");
   RegEx hostAndPort(HostAndPort);
   if (   (hostAndPort.SearchAt(urlString,workingOffset))
       && (hostAndPort.MatchStart(0) == workingOffset)
       )
   {
      LOG_TIME("hostport   > ");
      hostAndPort.MatchString(&mHostAddress,1);
      UtlString portStr;
      if (hostAndPort.MatchString(&portStr,2))
      {
         mHostPort = atoi(portStr.data());
      }

      workingOffset = hostAndPort.AfterMatch(0);

      if (UnknownUrlScheme == mScheme)
      {
         /*
          * Resolve AMBIGUITY
          *   Since we were able to parse this as a host and port, it is now safe to
          *   set the scheme to the implied 'sip:'.
          */
         mScheme = SipUrlScheme;
      }
   }
   else
   {
      if (FileUrlScheme != mScheme) // no host is ok in a file URL
      {
         /*
          * This is not a file URL, so not having a recognized host name is invalid.
          *
          * Since we may have been called from a constructor, there is no way to
          * return an error, but at this point we know this is bad, so instead
          * we just log an error and set the scheme to the unknown url type and
          * clear any components that might have been set.
          */
         OsSysLog::add(FAC_SIP, PRI_ERR,
                       "Url::parseString no valid host found at char %d in '%s', "
                       "isAddrSpec = %d",
                       workingOffset, urlString, isAddrSpec
                       );
         mScheme = UnknownUrlScheme;
         mDisplayName.remove(0);
         mUserId.remove(0);
         mPassword.remove(0);
      }
   }
   
   // Next is a path if http, https, or ftp,
   //      OR url parameters if sip or sips.
   // There can be no Url parameters for http, https, or ftp
   //    because semicolon is a valid part of the path value
   switch ( mScheme )
   {
   case FileUrlScheme:
   case FtpUrlScheme:
   case HttpUrlScheme:
   case HttpsUrlScheme:
   case RtspUrlScheme:
   {
      // this is an http, https, or ftp URL, so get the path
      LOG_TIME("path   < ");
      RegEx urlPath(UrlPath);
      if (   (urlPath.SearchAt(urlString, workingOffset))
          && (urlPath.MatchStart(0) == workingOffset)
          )
      {
         LOG_TIME("path   > ");
         urlPath.MatchString(&mPath,1);
         workingOffset = urlPath.AfterMatch(1);
      }
   }
   break;

   case SipUrlScheme:
   case SipsUrlScheme:
   {
      // it may have url parameters of the form ";" param "=" value ...
      //                if it meets the right conditions:
      if (   isAddrSpec                          // in addr-spec, any param is a url param
          || afterAngleBrackets != UTL_NOT_FOUND // inside angle brackets there may be a url param
          ) 
      {
         LOG_TIME("urlparm   < ");
         RegEx urlParams(UrlParams);
         if (   (urlParams.SearchAt(urlString, workingOffset))
             && (urlParams.MatchStart(0) == workingOffset)
             )
         {
            LOG_TIME("urlparm   > ");
            urlParams.MatchString(&mRawUrlParameters, 1);
            workingOffset = urlParams.AfterMatch(1);

            // actual parsing of the parameters is in parseUrlParameters
            // so that it only happens if someone asks for them.
         }
      }
   }
   break;
   
   case MailtoUrlScheme:
   default:
      // no path component
      break;
   }

   if (UnknownUrlScheme != mScheme)
   {
   // Parse any header or query parameters
      LOG_TIME("hdrparm   < ");
   RegEx headerOrQueryParams(HeaderOrQueryParams);
   if(   (headerOrQueryParams.SearchAt(urlString, workingOffset))
      && (headerOrQueryParams.MatchStart(0) == workingOffset)
      )
   {
         LOG_TIME("hdrparm   > ");
      headerOrQueryParams.MatchString(&mRawHeaderOrQueryParameters, 1);
      workingOffset = headerOrQueryParams.AfterMatch(0);
            
      // actual parsing of the parameters is in parseHeaderOrQueryParameters
      // so that it only happens if someone asks for them.
   }

   // Parse the field parameters
   if (!isAddrSpec) // can't have field parameters in an addrspec
   {
      if (afterAngleBrackets != UTL_NOT_FOUND)
      {
         workingOffset = afterAngleBrackets;
      }

         LOG_TIME("fldparm   < ");
         RegEx fieldParameters(FieldParams);
      if (   (fieldParameters.SearchAt(urlString, workingOffset))
          && (fieldParameters.MatchStart(0) == workingOffset)
          )
      {
            LOG_TIME("fldparm   > ");
         fieldParameters.MatchString(&mRawFieldParameters, 1);

         // actual parsing of the parameters is in parseFieldParameters
         // so that it only happens if someone asks for them.
      }
   }
}
#  ifdef TIME_PARSE
     UtlString timeDump;
   timeLog.getLogString(timeDump);
   printf("\n%s\n", timeDump.data());
#  endif
}
Example #17
0
static int doIcon(Spec spec, Header h)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies h, rpmGlobalMacroContext, fileSystem, internalState  @*/
{
    static size_t iconsize = 0;
    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    const char *fn, *Lurlfn = NULL;
    struct Source *sp;
    size_t nb;
    rpmuint8_t * icon;
    FD_t fd = NULL;
    int rc = RPMRC_FAIL;	/* assume error */
    int urltype;
    int xx;

    if (iconsize == 0) {
	iconsize = rpmExpandNumeric("%{?_build_iconsize}");
	if (iconsize < 2048)
	    iconsize = 2048;
    }
    icon = alloca(iconsize+1);

    for (sp = spec->sources; sp != NULL; sp = sp->next) {
	if (sp->flags & RPMFILE_ICON)
	    break;
    }
    if (sp == NULL) {
	rpmlog(RPMLOG_ERR, _("No icon file in sources\n"));
	goto exit;
    }

#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    /* support splitted source directories, i.e., source files which
       are alternatively placed into the .spec directory and picked
       up from there, too. */
    Lurlfn = rpmGenPath(NULL, "%{_specdir}/", sp->source);
    if (access(Lurlfn, F_OK) == -1) {
        Lurlfn = _free(Lurlfn);
        Lurlfn = rpmGenPath(NULL, "%{_icondir}/", sp->source);
    }
#else
    Lurlfn = rpmGenPath(NULL, "%{_icondir}/", sp->source);
#endif

    fn = NULL;
    urltype = urlPath(Lurlfn, &fn);
    switch (urltype) {  
    case URL_IS_HTTPS: 
    case URL_IS_HTTP:
    case URL_IS_FTP:
    case URL_IS_PATH:
    case URL_IS_UNKNOWN:
	break;
    case URL_IS_DASH:
    case URL_IS_HKP:
    case URL_IS_MONGO:	/* XXX FIXME */
	rpmlog(RPMLOG_ERR, _("Invalid icon URL: %s\n"), Lurlfn);
	goto exit;
	/*@notreached@*/ break;
    }

    fd = Fopen(fn, "r%{?_rpmgio}");
    if (fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("Unable to open icon %s: %s\n"),
		fn, Fstrerror(fd));
	rc = RPMRC_FAIL;
	goto exit;
    }

    *icon = '\0';
    nb = Fread(icon, sizeof(icon[0]), iconsize, fd);
    if (Ferror(fd) || nb == 0) {
	rpmlog(RPMLOG_ERR, _("Unable to read icon %s: %s\n"),
		fn, Fstrerror(fd));
	goto exit;
    }
    if (nb >= iconsize) {
	rpmlog(RPMLOG_ERR, _("Icon %s is too big (max. %d bytes)\n"),
		fn, (int)iconsize);
	goto exit;
    }

    if (icon[0] == 'G' && icon[1] == 'I' && icon[2] == 'F')
	he->tag = RPMTAG_GIF;
    else
    if (icon[0] == '/' && icon[1] == '*' && icon[2] == ' '
     && icon[3] == 'X' && icon[4] == 'P' && icon[5] == 'M')
	he->tag = RPMTAG_XPM;
    else
	he->tag = tagValue("Icon");
    he->t = RPM_BIN_TYPE;
    he->p.ui8p = icon;
    he->c = (rpmTagCount)nb;
    xx = headerPut(h, he, 0);
    rc = 0;
    
exit:
    if (fd) {
	(void) Fclose(fd);
	fd = NULL;
    }
    Lurlfn = _free(Lurlfn);
    return rc;
}
Example #18
0
/*@observer@*/
static char *doPatch(Spec spec, rpmuint32_t c, int strip, const char *db,
		     int reverse, int removeEmpties, int fuzz, const char *subdir)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
{
    const char *fn, *Lurlfn;
    static char buf[BUFSIZ];
    char args[BUFSIZ], *t = args;
    struct Source *sp;
    rpmCompressedMagic compressed = COMPRESSED_NOT;
    int urltype;
    const char *patch, *flags;

    *t = '\0';
    if (db)
	t = stpcpy( stpcpy(t, "-b --suffix "), db);
#if defined(RPM_VENDOR_OPENPKG) /* always-backup-on-patching */
    /* always create backup files in OpenPKG */
    else
	t = stpcpy(t, "-b --suffix .orig ");
#endif
    if (subdir)
	t = stpcpy( stpcpy(t, "-d "), subdir);
    if (fuzz >= 0) {
	t = stpcpy(t, "-F ");
	sprintf(t, "%10.10d", fuzz);
	t += strlen(t);
    }
    if (reverse)
	t = stpcpy(t, " -R");
    if (removeEmpties)
	t = stpcpy(t, " -E");

    for (sp = spec->sources; sp != NULL; sp = sp->next) {
	if ((sp->flags & RPMFILE_PATCH) && (sp->num == c))
	    break;
    }
    if (sp == NULL) {
	rpmlog(RPMLOG_ERR, _("No patch number %d\n"), c);
	return NULL;
    }

    Lurlfn = rpmGenPath(NULL, "%{_patchdir}/", sp->source);

    /* XXX On non-build parse's, file cannot be stat'd or read */
    if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
	Lurlfn = _free(Lurlfn);
	return NULL;
    }

    fn = NULL;
    urltype = urlPath(Lurlfn, &fn);
    switch (urltype) {
    case URL_IS_HTTPS:	/* XXX WRONG WRONG WRONG */
    case URL_IS_HTTP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_FTP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_HKP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_MONGO:	/* XXX FIXME */
    case URL_IS_PATH:
    case URL_IS_UNKNOWN:
	break;
    case URL_IS_DASH:
	Lurlfn = _free(Lurlfn);
	return NULL;
	/*@notreached@*/ break;
    }

    patch = rpmGetPath("%{?__patch}", NULL);
    if (!(patch && *patch != '\0')) {
	patch = _free(patch);
        patch = xstrdup("patch");
    }

    flags = rpmExpand("%{?_default_patch_flags}%{!?_default_patch_flags:-s}", NULL);

    if (compressed) {
	const char *zipper;

	switch (compressed) {
	default:
	case COMPRESSED_NOT:	/* XXX can't happen */
	case COMPRESSED_OTHER:
	case COMPRESSED_ZIP:	/* XXX wrong */
	    zipper = "%{__gzip}";
	    break;
	case COMPRESSED_BZIP2:
	    zipper = "%{__bzip2}";
	    break;
	case COMPRESSED_LZOP:
	    zipper = "%{__lzop}";
	    break;
	case COMPRESSED_LZMA:
	    zipper = "%{__lzma}";
	    break;
	case COMPRESSED_XZ:
	    zipper = "%{__xz}";
	    break;
	}
	zipper = rpmGetPath(zipper, NULL);

	sprintf(buf,
		"echo \"Patch #%d (%s):\"\n"
		"%s -d < '%s' | %s -p%d %s %s\n"
		"STATUS=$?\n"
		"if [ $STATUS -ne 0 ]; then\n"
		"  exit $STATUS\n"
		"fi",
		c,
/*@-moduncon@*/
		(const char *) basename((char *)fn),
/*@=moduncon@*/
		zipper,
		fn, patch, strip, args, flags);
	zipper = _free(zipper);
    } else {
	sprintf(buf,
		"echo \"Patch #%d (%s):\"\n"
		"%s -p%d %s %s < '%s'", c,
/*@-moduncon@*/
		(const char *) basename((char *)fn),
/*@=moduncon@*/
		patch, strip, args, flags, fn);
    }

    patch = _free(patch);
    flags = _free(flags);
    Lurlfn = _free(Lurlfn);
    return buf;
}
Example #19
0
static rpmRC handlePreambleTag(Spec spec, Package pkg, rpmTag tag,
		const char *macro, const char *lang)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies spec->macros, spec->st,
		spec->sources, spec->numSources, spec->noSource,
		spec->sourceHeader, spec->BANames, spec->BACount,
		spec->line,
		pkg->header, pkg->autoProv, pkg->autoReq, pkg->noarch,
		rpmGlobalMacroContext, fileSystem, internalState @*/
{
    HE_t he = memset(alloca(sizeof(*he)), 0, sizeof(*he));
    char * field = spec->line;
    char * end;
    int multiToken = 0;
    rpmsenseFlags tagflags;
    int len;
    rpmuint32_t num;
    int rc;
    int xx;
    
    if (field == NULL) return RPMRC_FAIL;	/* XXX can't happen */
    /* Find the start of the "field" and strip trailing space */
    while ((*field) && (*field != ':'))
	field++;
    if (*field != ':') {
	rpmlog(RPMLOG_ERR, _("line %d: Malformed tag: %s\n"),
		 spec->lineNum, spec->line);
	return RPMRC_FAIL;
    }
    field++;
    SKIPSPACE(field);
    if (!*field) {
	/* Empty field */
	rpmlog(RPMLOG_ERR, _("line %d: Empty tag: %s\n"),
		 spec->lineNum, spec->line);
	return RPMRC_FAIL;
    }
    end = findLastChar(field);

    /* Validate tag data content. */
    if (tagValidate(spec, tag, field) != RPMRC_OK)
	return RPMRC_FAIL;

    /* See if this is multi-token */
    end = field;
    SKIPNONSPACE(end);
    if (*end != '\0')
	multiToken = 1;

    switch (tag) {
    case RPMTAG_NAME:
    case RPMTAG_VERSION:
    case RPMTAG_RELEASE:
    case RPMTAG_DISTEPOCH:
    case RPMTAG_URL:
    case RPMTAG_DISTTAG:
    case RPMTAG_REPOTAG:
    case RPMTAG_CVSID:
    case RPMTAG_BUGURL:
	SINGLE_TOKEN_ONLY;
	/* These macros are for backward compatibility */
	if (tag == RPMTAG_VERSION) {
	    if (strchr(field, '-') != NULL) {
		rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"),
		    spec->lineNum, "version", spec->line);
		return RPMRC_FAIL;
	    }
	    addMacro(spec->macros, "PACKAGE_VERSION", NULL, field, RMIL_OLDSPEC);
	} else if (tag == RPMTAG_RELEASE) {
	    if (strchr(field, '-') != NULL) {
		rpmlog(RPMLOG_ERR, _("line %d: Illegal char '-' in %s: %s\n"),
		    spec->lineNum, "release", spec->line);
		return RPMRC_FAIL;
	    }
	    addMacro(spec->macros, "PACKAGE_RELEASE", NULL, field, RMIL_OLDSPEC-1);
	}
	he->tag = tag;
	he->t = RPM_STRING_TYPE;
	he->p.str = field;
	he->c = 1;
	xx = headerPut(pkg->header, he, 0);
	break;
    case RPMTAG_GROUP:
    case RPMTAG_SUMMARY:
#if defined(RPM_VENDOR_OPENPKG) /* make-class-available-as-macro */
    case RPMTAG_CLASS:
#endif
	(void) stashSt(spec, pkg->header, tag, lang);
	/*@fallthrough@*/
    case RPMTAG_DISTRIBUTION:
    case RPMTAG_VENDOR:
    case RPMTAG_LICENSE:
    case RPMTAG_PACKAGER:
	if (!*lang) {
	    he->tag = tag;
	    he->t = RPM_STRING_TYPE;
	    he->p.str = field;
	    he->c = 1;
	    xx = headerPut(pkg->header, he, 0);
	} else if (!(noLang && strcmp(lang, RPMBUILD_DEFAULT_LANG))) {
	    (void) headerAddI18NString(pkg->header, tag, field, lang);
	}
	break;
    /* XXX silently ignore BuildRoot: */
    case RPMTAG_BUILDROOT:
	SINGLE_TOKEN_ONLY;
	macro = NULL;
#ifdef	DYING
	buildRootURL = rpmGenPath(spec->rootURL, "%{?buildroot}", NULL);
	(void) urlPath(buildRootURL, &buildRoot);
	if (*buildRoot == '\0') buildRoot = "/";
	if (!strcmp(buildRoot, "/")) {
	    rpmlog(RPMLOG_ERR,
		     _("BuildRoot can not be \"/\": %s\n"), spec->buildRootURL);
	    buildRootURL = _free(buildRootURL);
	    return RPMRC_FAIL;
	}
	buildRootURL = _free(buildRootURL);
#endif
	break;
    case RPMTAG_KEYWORDS:
    case RPMTAG_VARIANTS:
    case RPMTAG_PREFIXES:
	addOrAppendListEntry(pkg->header, tag, field);
	he->tag = tag;
	xx = headerGet(pkg->header, he, 0);
	if (tag == RPMTAG_PREFIXES)
	while (he->c--) {
	    if (he->p.argv[he->c][0] != '/') {
		rpmlog(RPMLOG_ERR,
			 _("line %d: Prefixes must begin with \"/\": %s\n"),
			 spec->lineNum, spec->line);
		he->p.ptr = _free(he->p.ptr);
		return RPMRC_FAIL;
	    }
	    len = (int)strlen(he->p.argv[he->c]);
	    if (he->p.argv[he->c][len - 1] == '/' && len > 1) {
		rpmlog(RPMLOG_ERR,
			 _("line %d: Prefixes must not end with \"/\": %s\n"),
			 spec->lineNum, spec->line);
		he->p.ptr = _free(he->p.ptr);
		return RPMRC_FAIL;
	    }
	}
	he->p.ptr = _free(he->p.ptr);
	break;
    case RPMTAG_DOCDIR:
	SINGLE_TOKEN_ONLY;
	if (field[0] != '/') {
	    rpmlog(RPMLOG_ERR,
		     _("line %d: Docdir must begin with '/': %s\n"),
		     spec->lineNum, spec->line);
	    return RPMRC_FAIL;
	}
	macro = NULL;
	delMacro(NULL, "_docdir");
	addMacro(NULL, "_docdir", NULL, field, RMIL_SPEC);
	break;
    case RPMTAG_XMAJOR:
    case RPMTAG_XMINOR:
    case RPMTAG_EPOCH:
	SINGLE_TOKEN_ONLY;
	if (parseNum(field, &num)) {
	    rpmlog(RPMLOG_ERR,
		     _("line %d: %s takes an integer value: %s\n"),
		     spec->lineNum, tagName(tag), spec->line);
	    return RPMRC_FAIL;
	}
	he->tag = tag;
	he->t = RPM_UINT32_TYPE;
	he->p.ui32p = &num;
	he->c = 1;
	xx = headerPut(pkg->header, he, 0);
	break;
    case RPMTAG_AUTOREQPROV:
	pkg->autoReq = parseYesNo(field);
	pkg->autoProv = pkg->autoReq;
	break;
    case RPMTAG_AUTOREQ:
	pkg->autoReq = parseYesNo(field);
	break;
    case RPMTAG_AUTOPROV:
	pkg->autoProv = parseYesNo(field);
	break;
    case RPMTAG_SOURCE:
    case RPMTAG_PATCH:
	SINGLE_TOKEN_ONLY;
	macro = NULL;
	if ((rc = addSource(spec, pkg, field, tag)))
	    return rc;
	break;
    case RPMTAG_ICON:
	SINGLE_TOKEN_ONLY;
	macro = NULL;
	if ((rc = addSource(spec, pkg, field, tag)))
	    return rc;
	/* XXX the fetch/load of icon needs to be elsewhere. */
	if ((rc = doIcon(spec, pkg->header)))
	    return rc;
	break;
    case RPMTAG_NOSOURCE:
    case RPMTAG_NOPATCH:
	spec->noSource = 1;
	if ((rc = parseNoSource(spec, field, tag)))
	    return rc;
	break;
    case RPMTAG_BUILDPREREQ:
    case RPMTAG_BUILDREQUIRES:
	if ((rc = parseBits(lang, buildScriptBits, &tagflags))) {
	    rpmlog(RPMLOG_ERR,
		     _("line %d: Bad %s: qualifiers: %s\n"),
		     spec->lineNum, tagName(tag), spec->line);
	    return rc;
	}
	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
	    return rc;
	break;
    case RPMTAG_PREREQ:
    case RPMTAG_REQUIREFLAGS:
	if ((rc = parseBits(lang, installScriptBits, &tagflags))) {
	    rpmlog(RPMLOG_ERR,
		     _("line %d: Bad %s: qualifiers: %s\n"),
		     spec->lineNum, tagName(tag), spec->line);
	    return rc;
	}
	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
	    return rc;
	break;
    /* Aliases for BuildRequires(hint): */
    case RPMTAG_BUILDSUGGESTS:
    case RPMTAG_BUILDENHANCES:
	tagflags = RPMSENSE_MISSINGOK;
	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
	    return rc;
	break;
    /* Aliases for Requires(hint): */
    case RPMTAG_SUGGESTSFLAGS:
    case RPMTAG_ENHANCESFLAGS:
	tag = RPMTAG_REQUIREFLAGS;
	tagflags = RPMSENSE_MISSINGOK;
	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
	    return rc;
	break;
    case RPMTAG_BUILDOBSOLETES:
    case RPMTAG_BUILDPROVIDES:
    case RPMTAG_BUILDCONFLICTS:
    case RPMTAG_CONFLICTFLAGS:
    case RPMTAG_OBSOLETEFLAGS:
    case RPMTAG_PROVIDEFLAGS:
	tagflags = RPMSENSE_ANY;
	if ((rc = parseRCPOT(spec, pkg, field, tag, 0, tagflags)))
	    return rc;
	break;
    case RPMTAG_BUILDPLATFORMS:		/* XXX needs pattern parsing */
    case RPMTAG_EXCLUDEARCH:
    case RPMTAG_EXCLUSIVEARCH:
    case RPMTAG_EXCLUDEOS:
    case RPMTAG_EXCLUSIVEOS:
	addOrAppendListEntry(spec->sourceHeader, tag, field);
	break;

    case RPMTAG_BUILDARCHS:
    {	const char ** BANames = NULL;
	int BACount = 0;
	if ((rc = poptParseArgvString(field, &BACount, &BANames))) {
	    rpmlog(RPMLOG_ERR,
		     _("line %d: Bad BuildArchitecture format: %s\n"),
		     spec->lineNum, spec->line);
	    return RPMRC_FAIL;
	}
	if (spec->toplevel) {
	    if (BACount > 0 && BANames != NULL) {
		spec->BACount = BACount;
		spec->BANames = BANames;
		BANames = NULL;		/* XXX don't free. */
	    }
	} else {
	    if (BACount != 1 || strcmp(BANames[0], "noarch")) {
		rpmlog(RPMLOG_ERR,
		     _("line %d: Only \"noarch\" sub-packages are supported: %s\n"),
		     spec->lineNum, spec->line);
		BANames = _free(BANames);
		return RPMRC_FAIL;
	    }
	    pkg->noarch = 1;
	}
	BANames = _free(BANames);
    }	break;

    default:
	macro = NULL;
	he->tag = tag;
	he->t = RPM_STRING_ARRAY_TYPE;
	he->p.argv= (const char **) &field;	/* XXX NOCAST */
	he->c = 1;
	he->append = 1;
	xx = headerPut(pkg->header, he, 0);
	he->append = 0;
	break;
    }

/*@-usereleased@*/
    if (macro)
	addMacro(spec->macros, macro, NULL, field, RMIL_SPEC);
/*@=usereleased@*/
    
    return RPMRC_OK;
}
Example #20
0
File: rpminstall.c Project: xrg/RPM
/** @todo Generalize --freshen policies. */
int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
{
    struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu));
    rpmps ps;
    rpmprobFilterFlags probFilter;
    rpmRelocation * relocations;
    char * fileURL = NULL;
    int stopInstall = 0;
    rpmVSFlags vsflags, ovsflags, tvsflags;
    int rc;
    int xx;
    int i;

    if (fileArgv == NULL) goto exit;

    rpmcliPackagesTotal = 0;

    (void) rpmtsSetFlags(ts, ia->transFlags);

    probFilter = ia->probFilter;
    relocations = ia->relocations;

    if (ia->installInterfaceFlags & INSTALL_UPGRADE)
	vsflags = rpmExpandNumeric("%{?_vsflags_erase}");
    else
	vsflags = rpmExpandNumeric("%{?_vsflags_install}");
    if (ia->qva_flags & VERIFY_DIGEST)
	vsflags |= _RPMVSF_NODIGESTS;
    if (ia->qva_flags & VERIFY_SIGNATURE)
	vsflags |= _RPMVSF_NOSIGNATURES;
    if (ia->qva_flags & VERIFY_HDRCHK)
	vsflags |= RPMVSF_NOHDRCHK;
    ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));

    {	int notifyFlags;
	notifyFlags = ia->installInterfaceFlags | (rpmIsVerbose() ? INSTALL_LABEL : 0 );
	xx = rpmtsSetNotifyCallback(ts,
			rpmShowProgress, (void *) ((long)notifyFlags));
    }

    if ((eiu->relocations = relocations) != NULL) {
	while (eiu->relocations->oldPath)
	    eiu->relocations++;
	if (eiu->relocations->newPath == NULL)
	    eiu->relocations = NULL;
    }

    /* Build fully globbed list of arguments in argv[argc]. */
    for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
    	ARGV_t av = NULL;
    	int ac = 0;
	char * fn;

	fn = rpmEscapeSpaces(*eiu->fnp);
	rc = rpmGlob(fn, &ac, &av);
	fn = _free(fn);
	if (rc || ac == 0) {
	    rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    continue;
	}

	argvAppend(&(eiu->argv), av);
	argvFree(av);
	eiu->argc += ac;
    }

restart:
    /* Allocate sufficient storage for next set of args. */
    if (eiu->pkgx >= eiu->numPkgs) {
	eiu->numPkgs = eiu->pkgx + eiu->argc;
	eiu->pkgURL = xrealloc(eiu->pkgURL,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
	memset(eiu->pkgURL + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
	eiu->pkgState = xrealloc(eiu->pkgState,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
	memset(eiu->pkgState + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgState)));
    }

    /* Retrieve next set of args, cache on local storage. */
    for (i = 0; i < eiu->argc; i++) {
	fileURL = _free(fileURL);
	fileURL = eiu->argv[i];
	eiu->argv[i] = NULL;

	switch (urlIsURL(fileURL)) {
	case URL_IS_HTTPS:
	case URL_IS_HTTP:
	case URL_IS_FTP:
	{   char *tfn;
	    FD_t tfd;

	    if (rpmIsVerbose())
		fprintf(stdout, _("Retrieving %s\n"), fileURL);

	    tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn);
	    if (tfd && tfn) {
		Fclose(tfd);
	    	rc = urlGetFile(fileURL, tfn);
	    } else {
		rc = -1;
	    }

	    if (rc != 0) {
		rpmlog(RPMLOG_ERR,
			_("skipping %s - transfer failed\n"), fileURL);
		eiu->numFailed++;
		eiu->pkgURL[eiu->pkgx] = NULL;
		tfn = _free(tfn);
		break;
	    }
	    eiu->pkgState[eiu->pkgx] = 1;
	    eiu->pkgURL[eiu->pkgx] = tfn;
	    eiu->pkgx++;
	}   break;
	case URL_IS_PATH:
	case URL_IS_DASH:	/* WRONG WRONG WRONG */
	case URL_IS_HKP:	/* WRONG WRONG WRONG */
	default:
	    eiu->pkgURL[eiu->pkgx] = fileURL;
	    fileURL = NULL;
	    eiu->pkgx++;
	    break;
	}
    }
    fileURL = _free(fileURL);

    if (eiu->numFailed) goto exit;

    /* Continue processing file arguments, building transaction set. */
    for (eiu->fnp = eiu->pkgURL+eiu->prevx;
	 *eiu->fnp != NULL;
	 eiu->fnp++, eiu->prevx++)
    {
	const char * fileName;

	rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp);
	(void) urlPath(*eiu->fnp, &fileName);

	/* Try to read the header from a package file. */
	eiu->fd = Fopen(*eiu->fnp, "r.ufdio");
	if (eiu->fd == NULL || Ferror(eiu->fd)) {
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp,
			Fstrerror(eiu->fd));
	    if (eiu->fd != NULL) {
		xx = Fclose(eiu->fd);
		eiu->fd = NULL;
	    }
	    eiu->numFailed++; *eiu->fnp = NULL;
	    continue;
	}

	/* Read the header, verifying signatures (if present). */
	tvsflags = rpmtsSetVSFlags(ts, vsflags);
	eiu->rpmrc = rpmReadPackageFile(ts, eiu->fd, *eiu->fnp, &eiu->h);
	tvsflags = rpmtsSetVSFlags(ts, tvsflags);
	xx = Fclose(eiu->fd);
	eiu->fd = NULL;

	switch (eiu->rpmrc) {
	case RPMRC_FAIL:
	    rpmlog(RPMLOG_ERR, _("%s cannot be installed\n"), *eiu->fnp);
	    eiu->numFailed++; *eiu->fnp = NULL;
	    continue;
	    break;
	case RPMRC_NOTFOUND:
	    goto maybe_manifest;
	    break;
	case RPMRC_NOTTRUSTED:
	case RPMRC_NOKEY:
	case RPMRC_OK:
	default:
	    break;
	}

	eiu->isSource = headerIsSource(eiu->h);

	if (eiu->isSource) {
	    rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n",
		eiu->numSRPMS);
	    eiu->sourceURL = xrealloc(eiu->sourceURL,
				(eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
	    eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
	    *eiu->fnp = NULL;
	    eiu->numSRPMS++;
	    eiu->sourceURL[eiu->numSRPMS] = NULL;
	    continue;
	}

	if (eiu->relocations) {
	    struct rpmtd_s prefixes;

	    headerGet(eiu->h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT);
	    if (rpmtdCount(&prefixes) == 1) {
		eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes));
		rpmtdFreeData(&prefixes);
	    } else {
		const char * name;
		xx = headerNVR(eiu->h, &name, NULL, NULL);
		rpmlog(RPMLOG_ERR,
			       _("package %s is not relocatable\n"), name);
		eiu->numFailed++;
		goto exit;
	    }
	}

	/* On --freshen, verify package is installed and newer */
	if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
	    rpmdbMatchIterator mi;
	    const char * name;
	    Header oldH;
	    int count;

	    xx = headerNVR(eiu->h, &name, NULL, NULL);
	    mi = rpmtsInitIterator(ts, RPMTAG_NAME, name, 0);
	    count = rpmdbGetIteratorCount(mi);
	    while ((oldH = rpmdbNextIterator(mi)) != NULL) {
		if (rpmVersionCompare(oldH, eiu->h) < 0)
		    continue;
		/* same or newer package already installed */
		count = 0;
		break;
	    }
	    mi = rpmdbFreeIterator(mi);
	    if (count == 0) {
		eiu->h = headerFree(eiu->h);
		continue;
	    }
	    /* Package is newer than those currently installed. */
	}

	rc = rpmtsAddInstallElement(ts, eiu->h, (fnpyKey)fileName,
			(ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
			relocations);

	/* XXX reference held by transaction set */
	eiu->h = headerFree(eiu->h);
	if (eiu->relocations)
	    eiu->relocations->oldPath = _free(eiu->relocations->oldPath);

	switch(rc) {
	case 0:
	    rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n",
			eiu->numRPMS);
	    break;
	case 1:
	    rpmlog(RPMLOG_ERR,
			    _("error reading from file %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	case 2:
	    rpmlog(RPMLOG_ERR,
			    _("file %s requires a newer version of RPM\n"),
			    *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	default:
	    eiu->numFailed++;
	    goto exit;
	    break;
	}

	eiu->numRPMS++;
	continue;

maybe_manifest:
	/* Try to read a package manifest. */
	eiu->fd = Fopen(*eiu->fnp, "r.fpio");
	if (eiu->fd == NULL || Ferror(eiu->fd)) {
	    rpmlog(RPMLOG_ERR, _("open of %s failed: %s\n"), *eiu->fnp,
			Fstrerror(eiu->fd));
	    if (eiu->fd != NULL) {
		xx = Fclose(eiu->fd);
		eiu->fd = NULL;
	    }
	    eiu->numFailed++; *eiu->fnp = NULL;
	    break;
	}

	/* Read list of packages from manifest. */
/* FIX: *eiu->argv can be NULL */
	rc = rpmReadPackageManifest(eiu->fd, &eiu->argc, &eiu->argv);
	if (rc != RPMRC_OK)
	    rpmlog(RPMLOG_ERR, _("%s: not an rpm package (or package manifest): %s\n"),
			*eiu->fnp, Fstrerror(eiu->fd));
	xx = Fclose(eiu->fd);
	eiu->fd = NULL;

	/* If successful, restart the query loop. */
	if (rc == RPMRC_OK) {
	    eiu->prevx++;
	    goto restart;
	}

	eiu->numFailed++; *eiu->fnp = NULL;
	break;
    }

    rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n",
		eiu->numSRPMS, eiu->numRPMS);

    if (eiu->numFailed) goto exit;

    if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NODEPS)) {

	if (rpmtsCheck(ts)) {
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}

	ps = rpmtsProblems(ts);
	if (!stopInstall && rpmpsNumProblems(ps) > 0) {
	    rpmlog(RPMLOG_ERR, _("Failed dependencies:\n"));
	    rpmpsPrint(NULL, ps);
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}
	ps = rpmpsFree(ps);
    }

    if (eiu->numRPMS && !(ia->installInterfaceFlags & INSTALL_NOORDER)) {
	if (rpmtsOrder(ts)) {
	    eiu->numFailed = eiu->numPkgs;
	    stopInstall = 1;
	}
    }

    if (eiu->numRPMS && !stopInstall) {

	rpmcliPackagesTotal += eiu->numSRPMS;

	rpmlog(RPMLOG_DEBUG, "installing binary packages\n");

	/* Drop added/available package indices and dependency sets. */
	rpmtsClean(ts);

	rc = rpmtsRun(ts, NULL, probFilter);
	ps = rpmtsProblems(ts);

	if (rc < 0) {
	    eiu->numFailed += eiu->numRPMS;
	} else if (rc > 0) {
	    eiu->numFailed += rc;
	    if (rpmpsNumProblems(ps) > 0)
		rpmpsPrint(stderr, ps);
	}
	ps = rpmpsFree(ps);
    }

    if (eiu->numSRPMS && !stopInstall) {
	if (eiu->sourceURL != NULL)
	for (i = 0; i < eiu->numSRPMS; i++) {
	    rpmdbCheckSignals();
	    if (eiu->sourceURL[i] == NULL) continue;
	    eiu->fd = Fopen(eiu->sourceURL[i], "r.ufdio");
	    if (eiu->fd == NULL || Ferror(eiu->fd)) {
		rpmlog(RPMLOG_ERR, _("cannot open file %s: %s\n"),
			   eiu->sourceURL[i], Fstrerror(eiu->fd));
		if (eiu->fd != NULL) {
		    xx = Fclose(eiu->fd);
		    eiu->fd = NULL;
		}
		continue;
	    }

	    if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST)) {
		eiu->rpmrc = rpmInstallSourcePackage(ts, eiu->fd, NULL, NULL);
		if (eiu->rpmrc != RPMRC_OK) eiu->numFailed++;
	    }

	    xx = Fclose(eiu->fd);
	    eiu->fd = NULL;
	}
    }

exit:
    if (eiu->pkgURL != NULL)
    for (i = 0; i < eiu->numPkgs; i++) {
	if (eiu->pkgURL[i] == NULL) continue;
	if (eiu->pkgState[i] == 1)
	    (void) unlink(eiu->pkgURL[i]);
	eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
    }
    eiu->pkgState = _free(eiu->pkgState);
    eiu->pkgURL = _free(eiu->pkgURL);
    eiu->argv = _free(eiu->argv);
    rc = eiu->numFailed;
    free(eiu);

    rpmtsEmpty(ts);

    return rc;
}
Example #21
0
/*
 * @todo Single use by %%doc in files.c prevents static.
 */
rpmRC doScript(Spec spec, int what, const char *name, rpmiob iob, int test)
{
    const char * rootURL = spec->rootURL;
    const char * rootDir;
    const char * scriptName = NULL;
    const char * buildDirURL = rpmGenPath(rootURL, "%{_builddir}", "");
    const char * buildScript;
    const char * buildCmd = NULL;
    const char * buildTemplate = NULL;
    const char * buildPost = NULL;
    const char * mTemplate = NULL;
    const char * mCmd = NULL;
    const char * mPost = NULL;
    int argc = 0;
    const char **argv = NULL;
    FILE * fp = NULL;
    urlinfo u = NULL;
    rpmop op = NULL;
    int ix = -1;

    FD_t fd;
    FD_t xfd;
    int status;
    rpmRC rc;
    size_t i;

    switch (what) {
    case RPMBUILD_PREP:
	name = "%prep";
	iob = spec->prep;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_PREP;
	mTemplate = "%{__spec_prep_template}";
	mPost = "%{__spec_prep_post}";
	mCmd = "%{__spec_prep_cmd}";
	break;
    case RPMBUILD_BUILD:
	name = "%build";
	iob = spec->build;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_BUILD;
	mTemplate = "%{__spec_build_template}";
	mPost = "%{__spec_build_post}";
	mCmd = "%{__spec_build_cmd}";
	break;
    case RPMBUILD_INSTALL:
	name = "%install";
	iob = spec->install;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_INSTALL;
	mTemplate = "%{__spec_install_template}";
	mPost = "%{__spec_install_post}";
	mCmd = "%{__spec_install_cmd}";
	break;
    case RPMBUILD_CHECK:
	name = "%check";
	iob = spec->check;
	op = memset(alloca(sizeof(*op)), 0, sizeof(*op));
	ix = RPMSCRIPT_CHECK;
	mTemplate = "%{__spec_check_template}";
	mPost = "%{__spec_check_post}";
	mCmd = "%{__spec_check_cmd}";
	break;
    case RPMBUILD_CLEAN:
	name = "%clean";
	iob = spec->clean;
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    case RPMBUILD_RMBUILD:
	name = "--clean";
	mTemplate = "%{__spec_clean_template}";
	mPost = "%{__spec_clean_post}";
	mCmd = "%{__spec_clean_cmd}";
	break;
    /* support "%track" script/section */
    case RPMBUILD_TRACK:
	name = "%track";
	iob = NULL;
	if (spec->foo)
	for (i = 0; i < spec->nfoo; i++) {
	    if (spec->foo[i].str == NULL || spec->foo[i].iob == NULL)
		continue;
	    if (xstrcasecmp(spec->foo[i].str, "track"))
		continue;
	    iob = spec->foo[i].iob;
	    /*@loopbreak@*/ break;
	}
	mTemplate = "%{__spec_track_template}";
	mPost = "%{__spec_track_post}";
	mCmd = "%{__spec_track_cmd}";
	break;
    case RPMBUILD_STRINGBUF:
    default:
	mTemplate = "%{___build_template}";
	mPost = "%{___build_post}";
	mCmd = "%{___build_cmd}";
	break;
    }

assert(name != NULL);

    if ((what != RPMBUILD_RMBUILD) && iob == NULL) {
	rc = RPMRC_OK;
	goto exit;
    }

    if (rpmTempFile(rootURL, &scriptName, &fd) || fd == NULL || Ferror(fd)) {
	rpmlog(RPMLOG_ERR, _("Unable to open temp file.\n"));
	rc = RPMRC_FAIL;
	goto exit;
    }

    if (fdGetFp(fd) == NULL)
	xfd = Fdopen(fd, "w.fpio");
    else
	xfd = fd;

    /*@-type@*/ /* FIX: cast? */
    if ((fp = fdGetFp(xfd)) == NULL) {
	rc = RPMRC_FAIL;
	goto exit;
    }
    /*@=type@*/

    (void) urlPath(rootURL, &rootDir);
    if (*rootDir == '\0') rootDir = "/";

    (void) urlPath(scriptName, &buildScript);

    buildTemplate = rpmExpand(mTemplate, NULL);
    buildPost = rpmExpand(mPost, NULL);

    (void) fputs(buildTemplate, fp);

    /* support "%track" script/section */
    if (what != RPMBUILD_PREP && what != RPMBUILD_RMBUILD && spec->buildSubdir && what != RPMBUILD_TRACK)
	fprintf(fp, "cd '%s'\n", spec->buildSubdir);

    if (what == RPMBUILD_RMBUILD) {
	if (spec->buildSubdir)
	    fprintf(fp, "rm -rf '%s'\n", spec->buildSubdir);
    } else if (iob != NULL)
	fprintf(fp, "%s", rpmiobStr(iob));

    (void) fputs(buildPost, fp);

    (void) Fclose(xfd);

    if (test) {
	rc = RPMRC_OK;
	goto exit;
    }

    if (buildDirURL && buildDirURL[0] != '/' &&
	(urlSplit(buildDirURL, &u) != 0)) {
	rc = RPMRC_FAIL;
	goto exit;
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	addMacro(spec->macros, "_remsh", NULL, "%{__remsh}", RMIL_SPEC);
	addMacro(spec->macros, "_remhost", NULL, u->host, RMIL_SPEC);
	if (strcmp(rootDir, "/"))
	    addMacro(spec->macros, "_remroot", NULL, rootDir, RMIL_SPEC);
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    buildCmd = rpmExpand(mCmd, " ", buildScript, NULL);
    (void) poptParseArgvString(buildCmd, &argc, &argv);

    if (what != RPMBUILD_TRACK)		/* support "%track" script/section */
	rpmlog(RPMLOG_NOTICE, _("Executing(%s): %s\n"), name, buildCmd);

    /* Run the script with a stopwatch. */
    if (op != NULL)
	(void) rpmswEnter(op, 0);

    status = rpmsqExecve(argv);
    if (ix >= 0 && ix < RPMSCRIPT_MAX)
	spec->sstates[ix] =
	    (RPMSCRIPT_STATE_EXEC | RPMSCRIPT_STATE_REAPED) | (status & 0xffff);

    if (!WIFEXITED(status) || WEXITSTATUS(status)) {
	rpmlog(RPMLOG_ERR, _("Bad exit status from %s (%s)\n"),
		 scriptName, name);
	rc = RPMRC_FAIL;
    } else
	rc = RPMRC_OK;

    if (op != NULL) {
	static unsigned int scale = 1000;
	(void) rpmswExit(op, 0);
	if (ix >= 0 && ix < RPMSCRIPT_MAX)
	    spec->smetrics[ix] += op->usecs / scale;
    }

exit:
    if (scriptName) {
#if defined(RPM_VENDOR_OPENPKG) /* always-remove-tempfiles */
	/* Unconditionally remove temporary files ("rpm-tmp.XXXXX") which
	   were generated for the executed scripts. In OpenPKG we run the
	   scripts in debug mode ("set -x") anyway, so we never need to
	   see the whole generated script -- not even if it breaks.  Instead
	   we would just have temporary files staying around forever. */
#else
	if (rc == RPMRC_OK)
#endif
	    (void) Unlink(scriptName);
	scriptName = _free(scriptName);
    }

    switch (urlType(u)) {
    case URL_IS_HTTPS:
    case URL_IS_HTTP:
    case URL_IS_FTP:
	delMacro(spec->macros, "_remsh");
	delMacro(spec->macros, "_remhost");
	if (strcmp(rootDir, "/"))
	    delMacro(spec->macros, "_remroot");
	break;
    case URL_IS_UNKNOWN:
    case URL_IS_DASH:
    case URL_IS_PATH:
    case URL_IS_HKP:
    default:
	break;
    }

    argv = _free(argv);
    buildCmd = _free(buildCmd);
    buildTemplate = _free(buildTemplate);
    buildPost = _free(buildPost);
    buildDirURL = _free(buildDirURL);
    return rc;
}
Example #22
0
File: macro.c Project: xrg/RPM
/**
 * Execute macro primitives.
 * @param mb		macro expansion state
 * @param negate	should logic be inverted?
 * @param f		beginning of field f
 * @param fn		length of field f
 * @param g		beginning of field g
 * @param gn		length of field g
 */
static void
doFoo(MacroBuf mb, int negate, const char * f, size_t fn,
		const char * g, size_t gn)
{
    size_t blen = MACROBUFSIZ + fn + gn;
    char *buf = xmalloc(blen);
    char *b = NULL, *be;
    int c;

    buf[0] = '\0';
    if (g != NULL) {
	strncpy(buf, g, gn);
	buf[gn] = '\0';
	(void) expandU(mb, buf, blen);
    }
    if (STREQ("basename", f, fn)) {
	if ((b = strrchr(buf, '/')) == NULL)
	    b = buf;
	else
	    b++;
#if NOTYET
    /* XXX watchout for conflict with %dir */
    } else if (STREQ("dirname", f, fn)) {
	if ((b = strrchr(buf, '/')) != NULL)
	    *b = '\0';
	b = buf;
#endif
    } else if (STREQ("suffix", f, fn)) {
	if ((b = strrchr(buf, '.')) != NULL)
	    b++;
    } else if (STREQ("expand", f, fn)) {
	b = buf;
    } else if (STREQ("verbose", f, fn)) {
	if (negate)
	    b = (rpmIsVerbose() ? NULL : buf);
	else
	    b = (rpmIsVerbose() ? buf : NULL);
    } else if (STREQ("url2path", f, fn) || STREQ("u2p", f, fn)) {
	(void)urlPath(buf, (const char **)&b);
	if (*b == '\0') b = "/";
    } else if (STREQ("uncompress", f, fn)) {
	rpmCompressedMagic compressed = COMPRESSED_OTHER;
	for (b = buf; (c = *b) && isblank(c);)
	    b++;
	for (be = b; (c = *be) && !isblank(c);)
	    be++;
	*be++ = '\0';
	(void) rpmFileIsCompressed(b, &compressed);
	switch(compressed) {
	default:
	case COMPRESSED_NOT:
	    sprintf(be, "%%__cat %s", b);
	    break;
	case COMPRESSED_OTHER:
	    sprintf(be, "%%__gzip -dc %s", b);
	    break;
	case COMPRESSED_BZIP2:
	    sprintf(be, "%%__bzip2 -dc %s", b);
	    break;
	case COMPRESSED_ZIP:
	    sprintf(be, "%%__unzip %s", b);
	    break;
        case COMPRESSED_LZMA:
            sprintf(be, "%%__lzma -dc %s", b);
            break;
	}
	b = be;
    } else if (STREQ("getenv", f, fn)) {
	b = getenv(buf);
    } else if (STREQ("S", f, fn)) {
	for (b = buf; (c = *b) && risdigit(c);)
	    b++;
	if (!c) {	/* digit index */
	    b++;
	    sprintf(b, "%%SOURCE%s", buf);
	} else
	    b = buf;
    } else if (STREQ("P", f, fn)) {
	for (b = buf; (c = *b) && risdigit(c);)
	    b++;
	if (!c) {	/* digit index */
	    b++;
	    sprintf(b, "%%PATCH%s", buf);
	} else
			b = buf;
    } else if (STREQ("F", f, fn)) {
	b = buf + strlen(buf) + 1;
	sprintf(b, "file%s.file", buf);
    }

    if (b) {
	(void) expandT(mb, b, strlen(b));
    }
    free(buf);
}
Example #23
0
/*@observer@*/
static const char *doUntar(Spec spec, rpmuint32_t c, int quietly)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies rpmGlobalMacroContext, fileSystem, internalState @*/
{
    const char *fn, *Lurlfn;
    static char buf[BUFSIZ];
    char taropts[8];
    char *t = NULL;
    struct Source *sp;
    rpmCompressedMagic compressed = COMPRESSED_NOT;
    int urltype;
    const char *tar;
    int rubygem = 0;

    for (sp = spec->sources; sp != NULL; sp = sp->next) {
	if ((sp->flags & RPMFILE_SOURCE) && (sp->num == c)) {
	    break;
	}
    }
    if (sp == NULL) {
	rpmlog(RPMLOG_ERR, _("No source number %d\n"), c);
	return NULL;
    }

    t = strrchr(sp->source, '.');
    if(t && !strcasecmp(t, ".gem"))
	rubygem = 1;

    t = stpcpy(taropts, "-x");
    /*@-internalglobs@*/ /* FIX: shrug */
    if(rpmIsVerbose() && !quietly)
	t = stpcpy(t, "vv");
    if(rubygem)
	t = stpcpy(t, "m");

    t = stpcpy(t, "f");
    /*@=internalglobs@*/

#if defined(RPM_VENDOR_OPENPKG) /* splitted-source-directory */
    Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags, sp->source), sp->source);
#else
    Lurlfn = rpmGenPath(NULL, getSourceDir(sp->flags), sp->source);
#endif

    /* XXX On non-build parse's, file cannot be stat'd or read */
    if (!spec->force && (isCompressed(Lurlfn, &compressed) || checkOwners(Lurlfn))) {
	Lurlfn = _free(Lurlfn);
	return NULL;
    }

    fn = NULL;
    urltype = urlPath(Lurlfn, &fn);
    switch (urltype) {
    case URL_IS_HTTPS:	/* XXX WRONG WRONG WRONG */
    case URL_IS_HTTP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_FTP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_HKP:	/* XXX WRONG WRONG WRONG */
    case URL_IS_MONGO:	/* XXX FIXME */
    case URL_IS_PATH:
    case URL_IS_UNKNOWN:
	break;
    case URL_IS_DASH:
	Lurlfn = _free(Lurlfn);
	return NULL;
	/*@notreached@*/ break;
    }
#ifdef	NOTYET
    {	rpmmg mg;
	
_rpmmg_debug = 1;
	mg = rpmmgNew(NULL, 0);
	t = (char *) rpmmgFile(mg, fn);
	mg = rpmmgFree(mg);
fprintf(stderr, "==> %s: %s\n", fn, t);
	t = _free(t);
_rpmmg_debug = 0;
    }
#endif

    tar = rpmGetPath("%{?__tar}", NULL);
    if (!(tar && *tar != '\0')) {
	tar = _free(tar);
        tar = xstrdup("tar");
    }

#if defined(RPM_VENDOR_ARK) /* use-gnu-tar-compression-detection */
/* We leave compression handling for all tar based files up to GNU tar */
    if (compressed == COMPRESSED_ZIP)
#else
    if (compressed != COMPRESSED_NOT)
#endif
    {
	const char *zipper;
	int needtar = 1;

	switch (compressed) {
	case COMPRESSED_NOT:	/* XXX can't happen */
	case COMPRESSED_OTHER:
	    t = "%{__gzip} -dc";
	    break;
	case COMPRESSED_BZIP2:
	    t = "%{__bzip2} -dc";
	    break;
	case COMPRESSED_LZOP:
	    t = "%{__lzop} -dc";
	    break;
	case COMPRESSED_LZMA:
	    t = "%{__lzma} -dc";
	    break;
	case COMPRESSED_XZ:
	    t = "%{__xz} -dc";
	    break;
	case COMPRESSED_LZIP:
	    t = "%{__lzip} -dc";
	    break;
	case COMPRESSED_LRZIP:
	    t = "%{__lrzip} -dqo-";
	    break;
	case COMPRESSED_7ZIP:
	    t = "%{__7zip} x";
	    needtar = 0;
	    break;
	case COMPRESSED_ZIP:
#if defined(RPM_VENDOR_OPENPKG) /* use-bsdtar-for-zip-files */
	    t = "%{__bsdtar} -x -f";
#else
	    if (rpmIsVerbose() && !quietly)
		t = "%{__unzip}";
	    else
		t = "%{__unzip} -qq";
#endif
	    needtar = 0;
	    break;
	}
	zipper = rpmGetPath(t, NULL);
	buf[0] = '\0';
	t = stpcpy(buf, zipper);
	zipper = _free(zipper);
	*t++ = ' ';
	*t++ = '\'';
	t = stpcpy(t, fn);
	*t++ = '\'';
	if (needtar) {
	    t = stpcpy(t, " | ");
	    t = stpcpy(t, tar);
	    t = stpcpy(t, " ");
	    t = stpcpy(t, taropts);
	    t = stpcpy(t, " -");
        }
	t = stpcpy(t,
		"\n"
		"STATUS=$?\n"
		"if [ $STATUS -ne 0 ]; then\n"
		"  exit $STATUS\n"
		"fi");
    } else {
	buf[0] = '\0';
	t = stpcpy(buf, tar);
	t = stpcpy(t, " ");
	t = stpcpy(t, taropts);
	*t++ = ' ';
	t = stpcpy(t, fn);
	if(rubygem) {
	    t = stpcpy(t,
		    "\n"
		    "if [ -f data.tar.gz ]; then\n"
		    "  tar ");
	    t = stpcpy(t, taropts);
	    t = stpcpy(t,
		    " data.tar.gz\n"
		    "fi");
	}
    }

    tar = _free(tar);
    Lurlfn = _free(Lurlfn);
    return buf;
}
Example #24
0
/** @todo Generalize --freshen policies. */
int rpmInstall(rpmts ts, struct rpmInstallArguments_s * ia, ARGV_t fileArgv)
{
    struct rpmEIU * eiu = xcalloc(1, sizeof(*eiu));
    rpmRelocation * relocations;
    char * fileURL = NULL;
    rpmVSFlags vsflags, ovsflags;
    int rc;
    int i;

    vsflags = setvsFlags(ia);
    ovsflags = rpmtsSetVSFlags(ts, (vsflags | RPMVSF_NEEDPAYLOAD));

    if (fileArgv == NULL) goto exit;

    (void) rpmtsSetFlags(ts, ia->transFlags);

    relocations = ia->relocations;

    setNotifyFlag(ia, ts); 

    if ((eiu->relocations = relocations) != NULL) {
	while (eiu->relocations->oldPath)
	    eiu->relocations++;
	if (eiu->relocations->newPath == NULL)
	    eiu->relocations = NULL;
    }

    /* Build fully globbed list of arguments in argv[argc]. */
    for (eiu->fnp = fileArgv; *eiu->fnp != NULL; eiu->fnp++) {
    	ARGV_t av = NULL;
    	int ac = 0;

	if (giFlags & RPMGI_NOGLOB) {
	    rc = rpmNoGlob(*eiu->fnp, &ac, &av);
	} else {
	    char * fn = rpmEscapeSpaces(*eiu->fnp);
	    rc = rpmGlob(fn, &ac, &av);
	    fn = _free(fn);
	}
	if (rc || ac == 0) {
	    if (giFlags & RPMGI_NOGLOB) {
		rpmlog(RPMLOG_ERR, _("File not found: %s\n"), *eiu->fnp);
	    } else {
		rpmlog(RPMLOG_ERR, _("File not found by glob: %s\n"), *eiu->fnp);
	    }
	    eiu->numFailed++;
	    continue;
	}

	argvAppend(&(eiu->argv), av);
	argvFree(av);
	eiu->argc += ac;
    }

restart:
    /* Allocate sufficient storage for next set of args. */
    if (eiu->pkgx >= eiu->numPkgs) {
	eiu->numPkgs = eiu->pkgx + eiu->argc;
	eiu->pkgURL = xrealloc(eiu->pkgURL,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgURL));
	memset(eiu->pkgURL + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgURL)));
	eiu->pkgState = xrealloc(eiu->pkgState,
			(eiu->numPkgs + 1) * sizeof(*eiu->pkgState));
	memset(eiu->pkgState + eiu->pkgx, 0,
			((eiu->argc + 1) * sizeof(*eiu->pkgState)));
    }

    /* Retrieve next set of args, cache on local storage. */
    for (i = 0; i < eiu->argc; i++) {
	fileURL = _free(fileURL);
	fileURL = eiu->argv[i];
	eiu->argv[i] = NULL;

	switch (urlIsURL(fileURL)) {
	case URL_IS_HTTPS:
	case URL_IS_HTTP:
	case URL_IS_FTP:
	{   char *tfn = NULL;
	    FD_t tfd;

	    if (rpmIsVerbose())
		fprintf(stdout, _("Retrieving %s\n"), fileURL);

	    tfd = rpmMkTempFile(rpmtsRootDir(ts), &tfn);
	    if (tfd && tfn) {
		Fclose(tfd);
	    	rc = urlGetFile(fileURL, tfn);
	    } else {
		rc = -1;
	    }

	    if (rc != 0) {
		rpmlog(RPMLOG_ERR,
			_("skipping %s - transfer failed\n"), fileURL);
		eiu->numFailed++;
		eiu->pkgURL[eiu->pkgx] = NULL;
		tfn = _free(tfn);
		break;
	    }
	    eiu->pkgState[eiu->pkgx] = 1;
	    eiu->pkgURL[eiu->pkgx] = tfn;
	    eiu->pkgx++;
	}   break;
	case URL_IS_PATH:
	case URL_IS_DASH:	/* WRONG WRONG WRONG */
	case URL_IS_HKP:	/* WRONG WRONG WRONG */
	default:
	    eiu->pkgURL[eiu->pkgx] = fileURL;
	    fileURL = NULL;
	    eiu->pkgx++;
	    break;
	}
    }
    fileURL = _free(fileURL);

    if (eiu->numFailed) goto exit;

    /* Continue processing file arguments, building transaction set. */
    for (eiu->fnp = eiu->pkgURL+eiu->prevx;
	 *eiu->fnp != NULL;
	 eiu->fnp++, eiu->prevx++)
    {
	Header h = NULL;
	const char * fileName;

	rpmlog(RPMLOG_DEBUG, "============== %s\n", *eiu->fnp);
	(void) urlPath(*eiu->fnp, &fileName);

	if (tryReadHeader(ts, eiu, &h) == RPMRC_FAIL)
	    continue;

	if (eiu->rpmrc == RPMRC_NOTFOUND) {
	    rc = tryReadManifest(eiu);
	    if (rc == RPMRC_OK) {
	        eiu->prevx++;
	        goto restart;
	    }
	}

	if (headerIsSource(h)) {
	    if (ia->installInterfaceFlags & INSTALL_FRESHEN) {
		headerFree(h);
	        continue;
	    }
	    rpmlog(RPMLOG_DEBUG, "\tadded source package [%d]\n",
		eiu->numSRPMS);
	    eiu->sourceURL = xrealloc(eiu->sourceURL,
				(eiu->numSRPMS + 2) * sizeof(*eiu->sourceURL));
	    eiu->sourceURL[eiu->numSRPMS] = *eiu->fnp;
	    *eiu->fnp = NULL;
	    eiu->numSRPMS++;
	    eiu->sourceURL[eiu->numSRPMS] = NULL;
	    continue;
	}

	if (eiu->relocations) {
	    struct rpmtd_s prefixes;

	    headerGet(h, RPMTAG_PREFIXES, &prefixes, HEADERGET_DEFAULT);
	    if (rpmtdCount(&prefixes) == 1) {
		eiu->relocations->oldPath = xstrdup(rpmtdGetString(&prefixes));
		rpmtdFreeData(&prefixes);
	    } else {
		rpmlog(RPMLOG_ERR, _("package %s is not relocatable\n"),
		       headerGetString(h, RPMTAG_NAME));
		eiu->numFailed++;
		goto exit;
	    }
	}

	if (ia->installInterfaceFlags & INSTALL_FRESHEN)
	    if (checkFreshenStatus(ts, h) != 1) {
		headerFree(h);
	        continue;
	    }

	if (ia->installInterfaceFlags & INSTALL_REINSTALL)
	    rc = rpmtsAddReinstallElement(ts, h, (fnpyKey)fileName);
	else
	    rc = rpmtsAddInstallElement(ts, h, (fnpyKey)fileName,
			(ia->installInterfaceFlags & INSTALL_UPGRADE) != 0,
			relocations);

	headerFree(h);
	if (eiu->relocations)
	    eiu->relocations->oldPath = _free(eiu->relocations->oldPath);

	switch (rc) {
	case 0:
	    rpmlog(RPMLOG_DEBUG, "\tadded binary package [%d]\n",
			eiu->numRPMS);
	    break;
	case 1:
	    rpmlog(RPMLOG_ERR,
			    _("error reading from file %s\n"), *eiu->fnp);
	    eiu->numFailed++;
	    goto exit;
	    break;
	default:
	    eiu->numFailed++;
	    goto exit;
	    break;
	}

	eiu->numRPMS++;
    }

    rpmlog(RPMLOG_DEBUG, "found %d source and %d binary packages\n",
		eiu->numSRPMS, eiu->numRPMS);

    if (eiu->numFailed) goto exit;

    if (eiu->numRPMS) {
        int rc = rpmcliTransaction(ts, ia, eiu->numPkgs);
        if (rc < 0)
            eiu->numFailed += eiu->numRPMS;
	else if (rc > 0)
            eiu->numFailed += rc;
    }

    if (eiu->numSRPMS && (eiu->sourceURL != NULL)) {
	rpmcliProgressState = 0;
	rpmcliProgressTotal = 0;
	rpmcliProgressCurrent = 0;
	for (i = 0; i < eiu->numSRPMS; i++) {
	    rpmsqPoll();
	    if (eiu->sourceURL[i] != NULL) {
	        rc = RPMRC_OK;
		if (!(rpmtsFlags(ts) & RPMTRANS_FLAG_TEST))
		    rc = rpmInstallSource(ts, eiu->sourceURL[i], NULL, NULL);
		if (rc != 0)
		    eiu->numFailed++;
	    }
	}
    }

exit:
    if (eiu->pkgURL != NULL) {
        for (i = 0; i < eiu->numPkgs; i++) {
	    if (eiu->pkgURL[i] == NULL) continue;
	    if (eiu->pkgState[i] == 1)
	        (void) unlink(eiu->pkgURL[i]);
	    eiu->pkgURL[i] = _free(eiu->pkgURL[i]);
	}
    }
    eiu->pkgState = _free(eiu->pkgState);
    eiu->pkgURL = _free(eiu->pkgURL);
    eiu->argv = _free(eiu->argv);
    rc = eiu->numFailed;
    free(eiu);

    rpmtsEmpty(ts);
    rpmtsSetVSFlags(ts, ovsflags);

    return rc;
}
Example #25
0
/**
 * Parse %setup macro.
 * @todo FIXME: Option -q broken when not immediately after %setup.
 * @param spec		build info
 * @param line		current line from spec file
 * @return		0 on success
 */
static int doSetupMacro(Spec spec, const char * line)
	/*@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/
	/*@modifies spec->buildSubdir, spec->macros, spec->prep,
		spec->packages->header,
		rpmGlobalMacroContext, fileSystem, internalState @*/
{
    char buf[BUFSIZ];
    rpmiob before = NULL;
    rpmiob after = NULL;
    poptContext optCon;
    int argc;
    const char ** argv;
    int arg;
    const char * optArg;
    int rc;
    rpmuint32_t num;
    rpmRC ec = RPMRC_FAIL;	/* XXX assume failure */

    /*@-mods@*/
    leaveDirs = skipDefaultAction = 0;
    createDir = quietly = 0;
    dirName = NULL;
    /*@=mods@*/

    if ((rc = poptParseArgvString(line, &argc, &argv))) {
	rpmlog(RPMLOG_ERR, _("Error parsing %%setup: %s\n"),
			poptStrerror(rc));
	goto exit;
    }

    before = rpmiobNew(0);
    after = rpmiobNew(0);

    optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
    while ((arg = poptGetNextOpt(optCon)) > 0) {
	optArg = poptGetOptArg(optCon);

	/* We only parse -a and -b here */

	if (parseNum(optArg, &num)) {
	    rpmlog(RPMLOG_ERR, _("line %d: Bad arg to %%setup: %s\n"),
		     spec->lineNum, (optArg ? optArg : "???"));
	    optCon = poptFreeContext(optCon);
	    argv = _free(argv);
	    goto exit;
	}

	{   const char *chptr = doUntar(spec, num, quietly);
	    if (chptr == NULL)
		goto exit;

	    (void) rpmiobAppend((arg == 'a' ? after : before), chptr, 1);
	}
    }

    if (arg < -1) {
	rpmlog(RPMLOG_ERR, _("line %d: Bad %%setup option %s: %s\n"),
		 spec->lineNum,
		 poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
		 poptStrerror(arg));
	optCon = poptFreeContext(optCon);
	argv = _free(argv);
	goto exit;
    }

    if (dirName) {
	spec->buildSubdir = xstrdup(dirName);
    } else {
	const char *N, *V;
	(void) headerNEVRA(spec->packages->header, &N, NULL, &V, NULL, NULL);
	(void) snprintf(buf, sizeof(buf), "%s-%s", N, V);
	buf[sizeof(buf)-1] = '\0';
	N = _free(N);
	V = _free(V);
	spec->buildSubdir = xstrdup(buf);
    }
    addMacro(spec->macros, "buildsubdir", NULL, spec->buildSubdir, RMIL_SPEC);

    optCon = poptFreeContext(optCon);
    argv = _free(argv);

    /* cd to the build dir */
    {	const char * buildDirURL = rpmGenPath(spec->rootURL, "%{_builddir}", "");
	const char *buildDir;

	(void) urlPath(buildDirURL, &buildDir);
	rc = rpmioMkpath(buildDir, 0755, -1, -1);
	sprintf(buf, "cd '%s'", buildDir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
	buildDirURL = _free(buildDirURL);
    }

    /* delete any old sources */
    if (!leaveDirs) {
	sprintf(buf, "rm -rf '%s'", spec->buildSubdir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    /* check if source is a ruby gem */
    {   struct Source *sp;
	for (sp = spec->sources; sp != NULL; sp = sp->next) {
	    if ((sp->flags & RPMFILE_SOURCE) && (sp->num == 0)) {
		break;
	    }
	}
	if (sp != NULL) {
	    char *t = strrchr(sp->source, '.');
	    if(t && !strcasecmp(t, ".gem"))
		createDir = 1;
	}
    }

    /* if necessary, create and cd into the proper dir */
    if (createDir) {
	char *mkdir_p;
	mkdir_p = rpmExpand("%{?__mkdir_p}%{!?__mkdir_p:mkdir -p}", NULL);
	if (!mkdir_p)
	    mkdir_p = xstrdup("mkdir -p");
	sprintf(buf, "%s '%s'\ncd '%s'",
		mkdir_p, spec->buildSubdir, spec->buildSubdir);
	mkdir_p = _free(mkdir_p);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    /* do the default action */
   if (!createDir && !skipDefaultAction) {
	const char *chptr = doUntar(spec, 0, quietly);
	if (chptr == NULL)
	    goto exit;
	spec->prep = rpmiobAppend(spec->prep, chptr, 1);
    }

    spec->prep = rpmiobAppend(spec->prep, rpmiobStr(before), 0);

    if (!createDir) {
	sprintf(buf, "cd '%s'", spec->buildSubdir);
	spec->prep = rpmiobAppend(spec->prep, buf, 1);
    }

    if (createDir && !skipDefaultAction) {
	const char * chptr = doUntar(spec, 0, quietly);
	if (chptr == NULL)
	    goto exit;
	spec->prep = rpmiobAppend(spec->prep, chptr, 1);
    }

    spec->prep = rpmiobAppend(spec->prep, rpmiobStr(after), 0);

    /* XXX FIXME: owner & group fixes were conditioned on !geteuid() */
    /* Fix the owner, group, and permissions of the setup build tree */
    {	/*@observer@*/ static const char *fixmacs[] =
		{ "%{_fixowner}", "%{_fixgroup}", "%{_fixperms}", NULL };
	const char ** fm;

	for (fm = fixmacs; *fm; fm++) {
	    const char *fix;
	    fix = rpmExpand(*fm, " .", NULL);
	    if (fix && *fix != '%')
		spec->prep = rpmiobAppend(spec->prep, fix, 1);
	    fix = _free(fix);
	}
    }
    ec = RPMRC_OK;

exit:
    before = rpmiobFree(before);
    after = rpmiobFree(after);
    return ec;
}