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; }
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; }
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; }
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; }
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; }
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; }
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 }
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); }
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; }
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; }
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); } }
/* * 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); }
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; }); }
/*@-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; }
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; }
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 }
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; }
/*@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; }
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 = # 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; }
/** @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; }
/* * @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; }
/** * 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); }
/*@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; }
/** @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; }
/** * 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; }