00001
00002
00003
00004
00005
00006
00007
00008
00013 #include <zypp/parser/yum/YUMPatchParser.h>
00014 #include <zypp/parser/yum/YUMPrimaryParser.h>
00015 #include <istream>
00016 #include <string>
00017 #include "zypp/parser/xml_parser_assert.h"
00018 #include <libxml/xmlreader.h>
00019 #include <libxml/tree.h>
00020 #include <zypp/parser/LibXMLHelper.h>
00021 #include <zypp/base/Logger.h>
00022 #include <zypp/parser/yum/schemanames.h>
00023 #include <zypp/ZYppFactory.h>
00024
00025 using namespace std;
00026 namespace zypp {
00027 namespace parser {
00028 namespace yum {
00029
00030 YUMPatchParser::~YUMPatchParser()
00031 { }
00032
00033 YUMPatchParser::YUMPatchParser(istream &is, const string& baseUrl)
00034 : XMLNodeIterator<YUMPatchData_Ptr>(is, baseUrl,PATCHSCHEMA)
00035 , _zypp_architecture( getZYpp()->architecture() )
00036 {
00037 fetchNext();
00038 }
00039
00040 YUMPatchParser::YUMPatchParser()
00041 : _zypp_architecture( getZYpp()->architecture() )
00042 { }
00043
00044 YUMPatchParser::YUMPatchParser(YUMPatchData_Ptr& entry)
00045 : XMLNodeIterator<YUMPatchData_Ptr>(entry)
00046 , _zypp_architecture( getZYpp()->architecture() )
00047 { }
00048
00049
00050
00051 bool
00052 YUMPatchParser::isInterested(const xmlNodePtr nodePtr)
00053 {
00054 return _helper.isElement(nodePtr) && _helper.name(nodePtr) == "patch";
00055 }
00056
00057
00058 YUMPatchData_Ptr
00059 YUMPatchParser::process(const xmlTextReaderPtr reader)
00060 {
00061 xml_assert(reader);
00062 YUMPatchData_Ptr patchPtr = new YUMPatchData;
00063 xmlNodePtr dataNode = xmlTextReaderExpand(reader);
00064 xml_assert(dataNode);
00065 patchPtr->timestamp = _helper.attribute(dataNode,"timestamp");
00066 patchPtr->patchId = _helper.attribute(dataNode,"patchid");
00067 patchPtr->engine = _helper.attribute(dataNode,"engine");
00068
00069
00070 patchPtr->rebootNeeded = false;
00071 patchPtr->packageManager = false;
00072
00073
00074 YUMPrimaryParser prim;
00075
00076 for (xmlNodePtr child = dataNode->children;
00077 child && child != dataNode;
00078 child = child->next) {
00079 if (_helper.isElement(child)) {
00080 string name = _helper.name(child);
00081 if (name == "name") {
00082 patchPtr->name = _helper.content(child);
00083 }
00084 else if (name == "arch") {
00085 patchPtr->arch = _helper.content(child);
00086 try {
00087 if (!Arch(patchPtr->arch).compatibleWith( _zypp_architecture )) {
00088 patchPtr = NULL;
00089 break;
00090 }
00091 }
00092 catch( const Exception & excpt_r ) {
00093 ZYPP_CAUGHT( excpt_r );
00094 DBG << "Skipping malformed " << patchPtr->arch << endl;
00095 patchPtr = NULL;
00096 break;
00097 }
00098 }
00099 else if (name == "summary") {
00100 patchPtr->summary.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00101 }
00102 else if (name == "description") {
00103 patchPtr->description.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00104 }
00105 else if (name == "version") {
00106 patchPtr->epoch = _helper.attribute(child,"epoch");
00107 patchPtr->ver = _helper.attribute(child,"ver");
00108 patchPtr->rel = _helper.attribute(child,"rel");
00109 }
00110 else if (name == "provides") {
00111 prim.parseDependencyEntries(& patchPtr->provides, child);
00112 }
00113 else if (name == "conflicts") {
00114 prim.parseDependencyEntries(& patchPtr->conflicts, child);
00115 }
00116 else if (name == "obsoletes") {
00117 prim.parseDependencyEntries(& patchPtr->obsoletes, child);
00118 }
00119 else if (name == "requires") {
00120 prim.parseDependencyEntries(& patchPtr->requires, child);
00121 }
00122 else if (name == "recommends") {
00123 prim.parseDependencyEntries(& patchPtr->recommends, child);
00124 }
00125 else if (name == "suggests") {
00126 prim.parseDependencyEntries(& patchPtr->suggests, child);
00127 }
00128 else if (name == "supplements") {
00129 prim.parseDependencyEntries(& patchPtr->supplements, child);
00130 }
00131 else if (name == "enhances") {
00132 prim.parseDependencyEntries(& patchPtr->enhances, child);
00133 }
00134 else if (name == "freshens") {
00135 prim.parseDependencyEntries(& patchPtr->freshens, child);
00136 }
00137 else if (name == "category") {
00138 patchPtr->category = _helper.content(child);
00139 }
00140 else if (name == "reboot-needed") {
00141 patchPtr->rebootNeeded = true;
00142 }
00143 else if (name == "package-manager") {
00144 patchPtr->packageManager = true;
00145 }
00146 else if (name == "update-script") {
00147 patchPtr->updateScript = _helper.content(child);
00148 }
00149 else if (name == "atoms") {
00150 parseAtomsNode(patchPtr, child);
00151 }
00152 else {
00153 WAR << "YUM <data> contains the unknown element <" << name << "> "
00154 << _helper.positionInfo(child) << ", skipping" << endl;
00155 }
00156 }
00157 }
00158 return patchPtr;
00159 }
00160
00161
00162 void
00163 YUMPatchParser::parseAtomsNode(YUMPatchData_Ptr dataPtr,
00164 xmlNodePtr formatNode)
00165 {
00166 xml_assert(formatNode);
00167 for (xmlNodePtr child = formatNode->children;
00168 child != 0;
00169 child = child ->next) {
00170 if (_helper.isElement(child)) {
00171 string name = _helper.name(child);
00172 XXX << "parseAtomsNode(" << name << ")" << endl;
00173 if (name == "package")
00174 {
00175 parsePackageNode( dataPtr, child );
00176 }
00177 else if (name == "script")
00178 {
00179 parseScriptNode( dataPtr, child );
00180 }
00181 else if (name == "message")
00182 {
00183 parseMessageNode( dataPtr, child );
00184 }
00185 else {
00186 WAR << "YUM <atoms> contains the unknown element <" << name << "> "
00187 << _helper.positionInfo(child) << ", skipping" << endl;
00188 }
00189 }
00190 }
00191 }
00192
00193 void
00194 YUMPatchParser::parseFormatNode(YUMPatchPackage *dataPtr,
00195 xmlNodePtr formatNode)
00196 {
00197 xml_assert(formatNode);
00198 dataPtr->installOnly = false;
00199
00200
00201 YUMPrimaryParser prim;
00202
00203 for (xmlNodePtr child = formatNode->children;
00204 child != 0;
00205 child = child ->next) {
00206 if (_helper.isElement(child)) {
00207 string name = _helper.name(child);
00208 if (name == "license") {
00209 dataPtr->license = _helper.content(child);
00210 }
00211 else if (name == "vendor") {
00212 dataPtr->vendor = _helper.content(child);
00213 }
00214 else if (name == "group") {
00215 dataPtr->group = _helper.content(child);
00216 }
00217 else if (name == "buildhost") {
00218 dataPtr->buildhost = _helper.content(child);
00219 }
00220 else if (name == "sourcerpm") {
00221 dataPtr->sourcerpm = _helper.content(child);
00222 }
00223 else if (name == "header-range") {
00224 dataPtr->headerStart = _helper.attribute(child,"start");
00225 dataPtr->headerEnd = _helper.attribute(child,"end");
00226 }
00227 else if (name == "provides") {
00228 prim.parseDependencyEntries(& dataPtr->provides, child);
00229 }
00230 else if (name == "conflicts") {
00231 prim.parseDependencyEntries(& dataPtr->conflicts, child);
00232 }
00233 else if (name == "obsoletes") {
00234 prim.parseDependencyEntries(& dataPtr->obsoletes, child);
00235 }
00236 else if (name == "requires") {
00237 prim.parseDependencyEntries(& dataPtr->requires, child);
00238 }
00239 else if (name == "recommends") {
00240 prim.parseDependencyEntries(& dataPtr->recommends, child);
00241 }
00242 else if (name == "suggests") {
00243 prim.parseDependencyEntries(& dataPtr->suggests, child);
00244 }
00245 else if (name == "supplements") {
00246 prim.parseDependencyEntries(& dataPtr->supplements, child);
00247 }
00248 else if (name == "enhances") {
00249 prim.parseDependencyEntries(& dataPtr->enhances, child);
00250 }
00251 else if (name == "file") {
00252 dataPtr->files.push_back
00253 (FileData(_helper.content(child),
00254 _helper.attribute(child,"type")));
00255 }
00256
00257 else if (name == "authors") {
00258 prim.parseAuthorEntries(& dataPtr->authors, child);
00259 }
00260 else if (name == "keywords") {
00261 prim.parseKeywordEntries(& dataPtr->keywords, child);
00262 }
00263 else if (name == "media") {
00264 dataPtr->media = _helper.attribute(child,"mediaid");
00265 }
00266 else if (name == "dirsizes") {
00267 prim.parseDirsizeEntries(& dataPtr->dirSizes, child);
00268 }
00269 else if (name == "freshens") {
00270 prim.parseDependencyEntries(& dataPtr->freshens, child);
00271 }
00272 else if (name == "install-only") {
00273 dataPtr->installOnly = true;
00274 }
00275 else {
00276 WAR << "YUM <atom/package/format> contains the unknown element <"
00277 << name << "> "
00278 << _helper.positionInfo(child) << ", skipping" << endl;
00279 }
00280 }
00281 }
00282 }
00283
00284 void
00285 YUMPatchParser::parsePkgPlainRpmNode(YUMPatchPackage *dataPtr,
00286 xmlNodePtr formatNode)
00287 {
00288 YUMPlainRpm plainRpm;
00289 plainRpm.arch = _helper.attribute( formatNode, "arch" );
00290 plainRpm.filename = _helper.attribute( formatNode, "filename" );
00291 plainRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
00292 plainRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
00293 plainRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
00294 for (xmlNodePtr child = formatNode->children;
00295 child != 0;
00296 child = child ->next) {
00297 if (_helper.isElement(child)) {
00298 string name = _helper.name(child);
00299 WAR << "YUM <atom/package/pkgfiles/plain> contains the unknown element <"
00300 << name << "> "
00301 << _helper.positionInfo(child) << ", skipping" << endl;
00302 }
00303 }
00304 dataPtr->plainRpms.push_back(plainRpm);
00305 }
00306
00307 void
00308 YUMPatchParser::parsePkgPatchRpmNode(YUMPatchPackage *dataPtr,
00309 xmlNodePtr formatNode)
00310 {
00311 YUMPatchRpm patchRpm;
00312 patchRpm.arch = _helper.attribute( formatNode, "arch" );
00313 patchRpm.filename = _helper.attribute( formatNode, "filename" );
00314 patchRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
00315 patchRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
00316 patchRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
00317 for (xmlNodePtr child = formatNode->children;
00318 child != 0;
00319 child = child ->next) {
00320 if (_helper.isElement(child)) {
00321 string name = _helper.name(child);
00322 if (name == "base-version") {
00323 YUMBaseVersion base_version;
00324 parsePkgBaseVersionNode( &base_version, child);
00325 patchRpm.baseVersions.push_back( base_version );
00326 }
00327 else if (name == "location") {
00328 patchRpm.location = _helper.attribute(child,"href");
00329 }
00330 else if (name == "media") {
00331 patchRpm.media = _helper.content(child);
00332 }
00333 else if (name == "checksum") {
00334 patchRpm.checksumType = _helper.attribute(child,"type");
00335 patchRpm.checksum = _helper.content(child);
00336 }
00337 else if (name == "time") {
00338
00339 patchRpm.buildtime = _helper.attribute(child,"build");
00340 }
00341 else if (name == "size") {
00342
00343
00344 patchRpm.downloadsize = _helper.attribute(child,"archive");
00345 }
00346 else {
00347 WAR << "YUM <atom/package/pkgfiles/patch> contains the unknown element <"
00348 << name << "> "
00349 << _helper.positionInfo(child) << ", skipping" << endl;
00350 }
00351 }
00352 }
00353 dataPtr->patchRpms.push_back(patchRpm);
00354 }
00355
00356 void
00357 YUMPatchParser::parsePkgDeltaRpmNode(YUMPatchPackage *dataPtr,
00358 xmlNodePtr formatNode)
00359 {
00360 YUMDeltaRpm deltaRpm;
00361 deltaRpm.arch = _helper.attribute( formatNode, "arch" );
00362 deltaRpm.filename = _helper.attribute( formatNode, "filename" );
00363 deltaRpm.downloadsize = _helper.attribute( formatNode, "downloadsize" );
00364 deltaRpm.md5sum = _helper.attribute( formatNode, "md5sum" );
00365 deltaRpm.buildtime = _helper.attribute( formatNode, "buildtime" );
00366 for (xmlNodePtr child = formatNode->children;
00367 child != 0;
00368 child = child ->next) {
00369 if (_helper.isElement(child)) {
00370 string name = _helper.name(child);
00371 if (name == "base-version") {
00372 parsePkgBaseVersionNode( &(deltaRpm.baseVersion), child);
00373 }
00374 else if (name == "location") {
00375 deltaRpm.location = _helper.attribute(child,"href");
00376 }
00377 else if (name == "media") {
00378 deltaRpm.media = _helper.content(child);
00379 }
00380 else if (name == "checksum") {
00381 deltaRpm.checksumType = _helper.attribute(child,"type");
00382 deltaRpm.checksum = _helper.content(child);
00383 }
00384 else if (name == "time") {
00385
00386 deltaRpm.buildtime = _helper.attribute(child,"build");
00387 }
00388 else if (name == "size") {
00389
00390
00391 deltaRpm.downloadsize = _helper.attribute(child,"archive");
00392 }
00393 else {
00394 WAR << "YUM <atom/package/pkgfiles/delta> contains the unknown element <"
00395 << name << "> "
00396 << _helper.positionInfo(child) << ", skipping" << endl;
00397 }
00398 }
00399 }
00400 dataPtr->deltaRpms.push_back(deltaRpm);
00401 }
00402
00403
00404 void
00405 YUMPatchParser::parsePkgBaseVersionNode(YUMBaseVersion *dataPtr,
00406 xmlNodePtr formatNode)
00407 {
00408 dataPtr->epoch = _helper.attribute( formatNode, "epoch" );
00409 dataPtr->ver = _helper.attribute( formatNode, "ver" );
00410 dataPtr->rel = _helper.attribute( formatNode, "rel" );
00411 dataPtr->md5sum = _helper.attribute( formatNode, "md5sum" );
00412 dataPtr->buildtime = _helper.attribute( formatNode, "buildtime" );
00413 dataPtr->source_info = _helper.attribute( formatNode, "source-info" );
00414 }
00415
00416 void
00417 YUMPatchParser::parsePkgFilesNode(YUMPatchPackage *dataPtr,
00418 xmlNodePtr formatNode)
00419 {
00420 for (xmlNodePtr child = formatNode->children;
00421 child != 0;
00422 child = child ->next) {
00423 if (_helper.isElement(child)) {
00424 string name = _helper.name(child);
00425 if (name == "plainrpm") {
00426 parsePkgPlainRpmNode( dataPtr, child );
00427 }
00428 else if (name == "patchrpm") {
00429 parsePkgPatchRpmNode( dataPtr, child );
00430 }
00431 else if (name == "deltarpm") {
00432 parsePkgDeltaRpmNode( dataPtr, child );
00433 }
00434 else {
00435 WAR << "YUM <atom/package/pkgfiles> contains the unknown element <"
00436 << name << "> "
00437 << _helper.positionInfo(child) << ", skipping" << endl;
00438 }
00439 }
00440 }
00441 }
00442
00443
00444
00445
00446
00447
00448 void
00449 YUMPatchParser::parsePackageNode(YUMPatchData_Ptr dataPtr,
00450 xmlNodePtr formatNode)
00451 {
00452 shared_ptr<YUMPatchPackage> package(new YUMPatchPackage);
00453 package->type = _helper.attribute(formatNode,"type");
00454 package->installOnly = false;
00455
00456
00457 YUMPrimaryParser prim;
00458
00459 for (xmlNodePtr child = formatNode->children;
00460 child != 0;
00461 child = child ->next) {
00462 if (_helper.isElement(child)) {
00463 string name = _helper.name(child);
00464 XXX << "parsePackageNode(" << name << ")" << endl;
00465 if (name == "name") {
00466 package->name = _helper.content(child);
00467 }
00468 else if (name == "arch") {
00469 package->arch = _helper.content(child);
00470 }
00471 else if (name == "version") {
00472 package->epoch = _helper.attribute(child,"epoch");
00473 package->ver = _helper.attribute(child,"ver");
00474 package->rel = _helper.attribute(child,"rel");
00475 }
00476 else if (name == "checksum") {
00477 package->checksumType = _helper.attribute(child,"type");
00478 package->checksumPkgid = _helper.attribute(child,"pkgid");
00479 package->checksum = _helper.content(child);
00480 }
00481 else if (name == "summary") {
00482 package->summary = _helper.content(child);
00483 }
00484 else if (name == "description") {
00485 package->description = _helper.content(child);
00486 }
00487 else if (name == "packager") {
00488 package->packager = _helper.content(child);
00489 }
00490 else if (name == "url") {
00491 package->url = _helper.content(child);
00492 }
00493 else if (name == "time") {
00494 package->timeFile = _helper.attribute(child,"file");
00495 package->timeBuild = _helper.attribute(child,"build");
00496 }
00497 else if (name == "size") {
00498 package->sizePackage = _helper.attribute(child,"package");
00499 package->sizeInstalled = _helper.attribute(child,"installed");
00500 package->sizeArchive = _helper.attribute(child,"archive");
00501 }
00502 else if (name == "location") {
00503 package->location = _helper.attribute(child,"href");
00504 }
00505 else if (name == "format") {
00506 parseFormatNode (&*package, child);
00507 }
00508 else if (name == "pkgfiles")
00509 {
00510 parsePkgFilesNode (&*package, child);
00511 }
00512 else if (name == "license-to-confirm")
00513 {
00514 package->license_to_confirm.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00515 }
00516 else {
00517 WAR << "YUM <atoms/package> contains the unknown element <"
00518 << name << "> "
00519 << _helper.positionInfo(child) << ", skipping" << endl;
00520 }
00521 }
00522 }
00523 dataPtr->atoms.push_back(package);
00524 }
00525
00526 void
00527 YUMPatchParser::parseScriptNode(YUMPatchData_Ptr dataPtr,
00528 xmlNodePtr formatNode)
00529 {
00530 shared_ptr<YUMPatchScript> script(new YUMPatchScript);
00531 script->do_media = "1";
00532 script->undo_media = "1";
00533
00534
00535 YUMPrimaryParser prim;
00536
00537 for (xmlNodePtr child = formatNode->children;
00538 child != 0;
00539 child = child ->next) {
00540 if (_helper.isElement(child)) {
00541 string name = _helper.name(child);
00542 if (name == "name") {
00543 script->name = _helper.content(child);
00544 }
00545 else if (name == "version") {
00546 script->epoch = _helper.attribute(child,"epoch");
00547 script->ver = _helper.attribute(child,"ver");
00548 script->rel = _helper.attribute(child,"rel");
00549 }
00550 else if (name == "do") {
00551 script->do_script = _helper.content(child);
00552 }
00553 else if (name == "undo") {
00554 script->undo_script = _helper.content(child);
00555 }
00556 else if (name == "do-location") {
00557 script->do_location = _helper.attribute(child,"href");
00558 }
00559 else if (name == "undo-location") {
00560 script->undo_location = _helper.attribute(child,"href");
00561 }
00562 else if (name == "do-media") {
00563 script->do_media = _helper.attribute(child,"mediaid");
00564 }
00565 else if (name == "undo-media") {
00566 script->undo_media = _helper.attribute(child,"mediaid");
00567 }
00568 else if (name == "do-checksum") {
00569 script->do_checksum_type = _helper.attribute(child,"type");
00570 script->do_checksum = _helper.content(child);
00571 }
00572 else if (name == "undo-checksum") {
00573 script->undo_checksum_type = _helper.attribute(child,"type");
00574 script->undo_checksum = _helper.content(child);
00575 }
00576 else if (name == "provides") {
00577 prim.parseDependencyEntries(& script->provides, child);
00578 }
00579 else if (name == "conflicts") {
00580 prim.parseDependencyEntries(& script->conflicts, child);
00581 }
00582 else if (name == "obsoletes") {
00583 prim.parseDependencyEntries(& script->obsoletes, child);
00584 }
00585 else if (name == "requires") {
00586 prim.parseDependencyEntries(& script->requires, child);
00587 }
00588 else if (name == "recommends") {
00589 prim.parseDependencyEntries(& script->recommends, child);
00590 }
00591 else if (name == "suggests") {
00592 prim.parseDependencyEntries(& script->suggests, child);
00593 }
00594 else if (name == "supplements") {
00595 prim.parseDependencyEntries(& script->supplements, child);
00596 }
00597 else if (name == "enhances") {
00598 prim.parseDependencyEntries(& script->enhances, child);
00599 }
00600 else if (name == "freshens") {
00601 prim.parseDependencyEntries(& script->freshens, child);
00602 }
00603 else {
00604 WAR << "YUM <atoms/script> contains the unknown element <"
00605 << name << "> "
00606 << _helper.positionInfo(child) << ", skipping" << endl;
00607 }
00608 }
00609 }
00610 dataPtr->atoms.push_back(script);
00611 }
00612
00613 void
00614 YUMPatchParser::parseMessageNode(YUMPatchData_Ptr dataPtr,
00615 xmlNodePtr formatNode)
00616 {
00617 shared_ptr<YUMPatchMessage> message(new YUMPatchMessage);
00618
00619
00620 YUMPrimaryParser prim;
00621
00622 for (xmlNodePtr child = formatNode->children;
00623 child != 0;
00624 child = child ->next) {
00625 if (_helper.isElement(child)) {
00626 string name = _helper.name(child);
00627 if (name == "name") {
00628 message->name = _helper.content(child);
00629 }
00630 else if (name == "version") {
00631 message->epoch = _helper.attribute(child,"epoch");
00632 message->ver = _helper.attribute(child,"ver");
00633 message->rel = _helper.attribute(child,"rel");
00634 }
00635 else if (name == "text") {
00636 message->text.setText(_helper.content(child), Locale(_helper.attribute(child,"lang")));
00637 }
00638 else if (name == "provides") {
00639 prim.parseDependencyEntries(& message->provides, child);
00640 }
00641 else if (name == "conflicts") {
00642 prim.parseDependencyEntries(& message->conflicts, child);
00643 }
00644 else if (name == "obsoletes") {
00645 prim.parseDependencyEntries(& message->obsoletes, child);
00646 }
00647 else if (name == "requires") {
00648 prim.parseDependencyEntries(& message->requires, child);
00649 }
00650 else if (name == "recommends") {
00651 prim.parseDependencyEntries(& message->recommends, child);
00652 }
00653 else if (name == "suggests") {
00654 prim.parseDependencyEntries(& message->suggests, child);
00655 }
00656 else if (name == "supplements") {
00657 prim.parseDependencyEntries(& message->supplements, child);
00658 }
00659 else if (name == "enhances") {
00660 prim.parseDependencyEntries(& message->enhances, child);
00661 }
00662 else if (name == "freshens") {
00663 prim.parseDependencyEntries(& message->freshens, child);
00664 }
00665 else {
00666 WAR << "YUM <atoms/message> contains the unknown element <"
00667 << name << "> "
00668 << _helper.positionInfo(child) << ", skipping" << endl;
00669 }
00670 }
00671 }
00672 dataPtr->atoms.push_back(message);
00673 }
00674
00675 }
00676 }
00677 }