00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <sys/types.h>
00014 #include <regex.h>
00015
00016 #include <zypp/parser/yum/YUMFileListParser.h>
00017 #include <istream>
00018 #include <string>
00019 #include "zypp/parser/xml_parser_assert.h"
00020 #include <libxml/xmlstring.h>
00021 #include <libxml/xmlreader.h>
00022 #include <libxml/tree.h>
00023 #include <zypp/parser/LibXMLHelper.h>
00024 #include <zypp/parser/yum/schemanames.h>
00025 #include <iostream>
00026 #include <zypp/base/Logger.h>
00027 #include <zypp/ZYppFactory.h>
00028 #include <boost/regex.hpp>
00029 #include <boost/algorithm/string.hpp>
00030
00031 using namespace std;
00032 namespace zypp
00033 {
00034 namespace parser
00035 {
00036 namespace yum
00037 {
00038
00039 static boost::regex filenameRegex("^.*(/bin/|/sbin/|/lib/|/lib64/|/etc/|/usr/share/dict/words/|/usr/games/|/usr/share/magic\\.mime|/opt/gnome/games).*$");
00040 static regex_t filenameRegexT;
00041 static bool filenameRegexOk = false;
00042
00043 YUMFileListParser::YUMFileListParser(std::istream &is, const std::string& baseUrl, parser::ParserProgress::Ptr progress )
00044 : XMLNodeIterator<YUMFileListData_Ptr>(is, baseUrl,FILELISTSCHEMA, progress)
00045 , _zypp_architecture( getZYpp()->architecture() )
00046 {
00047 fetchNext();
00048 }
00049
00050 YUMFileListParser::YUMFileListParser()
00051 : _zypp_architecture( getZYpp()->architecture() )
00052 { }
00053
00054 YUMFileListParser::YUMFileListParser(YUMFileListData_Ptr& entry)
00055 : XMLNodeIterator<YUMFileListData_Ptr>(entry)
00056 , _zypp_architecture( getZYpp()->architecture() )
00057 { }
00058
00059
00060
00061 YUMFileListParser::~YUMFileListParser()
00062 {}
00063
00064
00065
00066
00067
00068 bool
00069 YUMFileListParser::isInterested(const xmlNodePtr nodePtr)
00070 {
00071 bool result = (_helper.isElement(nodePtr)
00072 && _helper.name(nodePtr) == "package");
00073 return result;
00074 }
00075
00076
00077
00078 YUMFileListData_Ptr
00079 YUMFileListParser::process(const xmlTextReaderPtr reader)
00080 {
00081 xml_assert(reader);
00082 YUMFileListData_Ptr dataPtr = new YUMFileListData;
00083 xmlNodePtr dataNode = xmlTextReaderExpand(reader);
00084 xml_assert(dataNode);
00085
00086 dataPtr->pkgId = _helper.attribute(dataNode,"pkgid");
00087 dataPtr->name = _helper.attribute(dataNode,"name");
00088 dataPtr->arch = _helper.attribute(dataNode,"arch");
00089 try
00090 {
00091 if (!Arch(dataPtr->arch).compatibleWith( _zypp_architecture ))
00092 {
00093 dataPtr = NULL;
00094 return dataPtr;
00095 }
00096 }
00097 catch ( const Exception & excpt_r )
00098 {
00099 ZYPP_CAUGHT( excpt_r );
00100 DBG << "Skipping malformed " << dataPtr->arch << endl;
00101 dataPtr = NULL;
00102 return dataPtr;
00103 }
00104
00105 for (xmlNodePtr child = dataNode->children;
00106 child != 0;
00107 child = child->next)
00108 {
00109 if (_helper.isElement(child))
00110 {
00111 string name = _helper.name(child);
00112 if (name == "version")
00113 {
00114 dataPtr->epoch = _helper.attribute(child,"epoch");
00115 dataPtr->ver = _helper.attribute(child,"ver");
00116 dataPtr->rel = _helper.attribute(child,"rel");
00117 }
00118 else if (name == "file")
00119 {
00120 string filename = _helper.content( child );
00121 if (!filenameRegexOk)
00122 {
00123 const char * filenameRegexPattern = "/(s?bin|lib(64)?|etc)/|^/usr/(games/|share/(dict/words|magic\\.mime)$)|^/opt/gnome/games/";
00124 regcomp (&filenameRegexT, filenameRegexPattern, REG_EXTENDED | REG_NOSUB);
00125
00126 filenameRegexOk = true;
00127 }
00128
00129 bool match;
00130 match = !regexec (&filenameRegexT, filename.c_str(), 0 , NULL , 0 );
00131
00132 if (match)
00133 dataPtr->files.push_back( FileData( filename, _helper.attribute( child, "type" ) ) );
00134 }
00135 else
00136 {
00137 WAR << "YUM <filelists> contains the unknown element <" << name << "> "
00138 << _helper.positionInfo(child) << ", skipping" << endl;
00139 }
00140 }
00141 }
00142
00143 return dataPtr;
00144 }
00145
00146
00147 }
00148 }
00149 }