LyoKICogUUVNVSBOVlJBTSBlbXVsYXRpb24gZm9yIERTMTIyNVkgY2hpcAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJzeXNidXMuaCIKI2luY2x1ZGUgInRyYWNlLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEZXZpY2VTdGF0ZSBxZGV2OwogICAgTWVtb3J5UmVnaW9uIGlvbWVtOwogICAgdWludDMyX3QgY2hpcF9zaXplOwogICAgY2hhciAqZmlsZW5hbWU7CiAgICBGSUxFICpmaWxlOwogICAgdWludDhfdCAqY29udGVudHM7Cn0gTnZSYW1TdGF0ZTsKCnN0YXRpYyB1aW50NjRfdCBudnJhbV9yZWFkKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVuc2lnbmVkIHNpemUpCnsKICAgIE52UmFtU3RhdGUgKnMgPSBvcGFxdWU7CiAgICB1aW50MzJfdCB2YWw7CgogICAgdmFsID0gcy0+Y29udGVudHNbYWRkcl07CiAgICB0cmFjZV9udnJhbV9yZWFkKGFkZHIsIHZhbCk7CiAgICByZXR1cm4gdmFsOwp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZSh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyLCB1aW50NjRfdCB2YWwsCiAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIHNpemUpCnsKICAgIE52UmFtU3RhdGUgKnMgPSBvcGFxdWU7CgogICAgdmFsICY9IDB4ZmY7CiAgICB0cmFjZV9udnJhbV93cml0ZShhZGRyLCBzLT5jb250ZW50c1thZGRyXSwgdmFsKTsKCiAgICBzLT5jb250ZW50c1thZGRyXSA9IHZhbDsKICAgIGlmIChzLT5maWxlKSB7CiAgICAgICAgZnNlZWsocy0+ZmlsZSwgYWRkciwgU0VFS19TRVQpOwogICAgICAgIGZwdXRjKHZhbCwgcy0+ZmlsZSk7CiAgICAgICAgZmZsdXNoKHMtPmZpbGUpOwogICAgfQp9CgpzdGF0aWMgY29uc3QgTWVtb3J5UmVnaW9uT3BzIG52cmFtX29wcyA9IHsKICAgIC5yZWFkID0gbnZyYW1fcmVhZCwKICAgIC53cml0ZSA9IG52cmFtX3dyaXRlLAogICAgLmltcGwgPSB7CiAgICAgICAgLm1pbl9hY2Nlc3Nfc2l6ZSA9IDEsCiAgICAgICAgLm1heF9hY2Nlc3Nfc2l6ZSA9IDEsCiAgICB9LAogICAgLmVuZGlhbm5lc3MgPSBERVZJQ0VfTElUVExFX0VORElBTiwKfTsKCnN0YXRpYyBpbnQgbnZyYW1fcG9zdF9sb2FkKHZvaWQgKm9wYXF1ZSwgaW50IHZlcnNpb25faWQpCnsKICAgIE52UmFtU3RhdGUgKnMgPSBvcGFxdWU7CgogICAgLyogQ2xvc2UgZmlsZSwgYXMgZmlsZW5hbWUgbWF5IGhhcyBjaGFuZ2VkIGluIGxvYWQvc3RvcmUgcHJvY2VzcyAqLwogICAgaWYgKHMtPmZpbGUpIHsKICAgICAgICBmY2xvc2Uocy0+ZmlsZSk7CiAgICB9CgogICAgLyogV3JpdGUgYmFjayBudnJhbSBjb250ZW50cyAqLwogICAgcy0+ZmlsZSA9IGZvcGVuKHMtPmZpbGVuYW1lLCAid2IiKTsKICAgIGlmIChzLT5maWxlKSB7CiAgICAgICAgLyogV3JpdGUgYmFjayBjb250ZW50cywgYXMgJ3diJyBtb2RlIGNsZWFuZWQgdGhlIGZpbGUgKi8KICAgICAgICBpZiAoZndyaXRlKHMtPmNvbnRlbnRzLCBzLT5jaGlwX3NpemUsIDEsIHMtPmZpbGUpICE9IDEpIHsKICAgICAgICAgICAgcHJpbnRmKCJudnJhbV9wb3N0X2xvYWQ6IHNob3J0IHdyaXRlXG4iKTsKICAgICAgICB9CiAgICAgICAgZmZsdXNoKHMtPmZpbGUpOwogICAgfQoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgY29uc3QgVk1TdGF0ZURlc2NyaXB0aW9uIHZtc3RhdGVfbnZyYW0gPSB7CiAgICAubmFtZSA9ICJudnJhbSIsCiAgICAudmVyc2lvbl9pZCA9IDAsCiAgICAubWluaW11bV92ZXJzaW9uX2lkID0gMCwKICAgIC5taW5pbXVtX3ZlcnNpb25faWRfb2xkID0gMCwKICAgIC5wb3N0X2xvYWQgPSBudnJhbV9wb3N0X2xvYWQsCiAgICAuZmllbGRzID0gKFZNU3RhdGVGaWVsZFtdKSB7CiAgICAgICAgVk1TVEFURV9WQVJSQVlfVUlOVDMyKGNvbnRlbnRzLCBOdlJhbVN0YXRlLCBjaGlwX3NpemUsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZtc3RhdGVfaW5mb191aW50OCwgdWludDhfdCksCiAgICAgICAgVk1TVEFURV9FTkRfT0ZfTElTVCgpCiAgICB9Cn07Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBTeXNCdXNEZXZpY2UgYnVzZGV2OwogICAgTnZSYW1TdGF0ZSBudnJhbTsKfSBTeXNCdXNOdlJhbVN0YXRlOwoKc3RhdGljIGludCBudnJhbV9zeXNidXNfaW5pdGZuKFN5c0J1c0RldmljZSAqZGV2KQp7CiAgICBOdlJhbVN0YXRlICpzID0gJkZST01fU1lTQlVTKFN5c0J1c052UmFtU3RhdGUsIGRldiktPm52cmFtOwogICAgRklMRSAqZmlsZTsKCiAgICBzLT5jb250ZW50cyA9IGdfbWFsbG9jMChzLT5jaGlwX3NpemUpOwoKICAgIG1lbW9yeV9yZWdpb25faW5pdF9pbygmcy0+aW9tZW0sICZudnJhbV9vcHMsIHMsICJudnJhbSIsIHMtPmNoaXBfc2l6ZSk7CiAgICBzeXNidXNfaW5pdF9tbWlvX3JlZ2lvbihkZXYsICZzLT5pb21lbSk7CgogICAgLyogUmVhZCBjdXJyZW50IGZpbGUgKi8KICAgIGZpbGUgPSBmb3BlbihzLT5maWxlbmFtZSwgInJiIik7CiAgICBpZiAoZmlsZSkgewogICAgICAgIC8qIFJlYWQgbnZyYW0gY29udGVudHMgKi8KICAgICAgICBpZiAoZnJlYWQocy0+Y29udGVudHMsIHMtPmNoaXBfc2l6ZSwgMSwgZmlsZSkgIT0gMSkgewogICAgICAgICAgICBwcmludGYoIm52cmFtX3N5c2J1c19pbml0Zm46IHNob3J0IHJlYWRcbiIpOwogICAgICAgIH0KICAgICAgICBmY2xvc2UoZmlsZSk7CiAgICB9CiAgICBudnJhbV9wb3N0X2xvYWQocywgMCk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBTeXNCdXNEZXZpY2VJbmZvIG52cmFtX3N5c2J1c19pbmZvID0gewogICAgLnFkZXYubmFtZSAgPSAiZHMxMjI1eSIsCiAgICAucWRldi5zaXplICA9IHNpemVvZihTeXNCdXNOdlJhbVN0YXRlKSwKICAgIC5xZGV2LnZtc2QgID0gJnZtc3RhdGVfbnZyYW0sCiAgICAuaW5pdCAgICAgICA9IG52cmFtX3N5c2J1c19pbml0Zm4sCiAgICAucWRldi5wcm9wcyA9IChQcm9wZXJ0eVtdKSB7CiAgICAgICAgREVGSU5FX1BST1BfVUlOVDMyKCJzaXplIiwgU3lzQnVzTnZSYW1TdGF0ZSwgbnZyYW0uY2hpcF9zaXplLCAweDIwMDApLAogICAgICAgIERFRklORV9QUk9QX1NUUklORygiZmlsZW5hbWUiLCBTeXNCdXNOdlJhbVN0YXRlLCBudnJhbS5maWxlbmFtZSksCiAgICAgICAgREVGSU5FX1BST1BfRU5EX09GX0xJU1QoKSwKICAgIH0sCn07CgpzdGF0aWMgdm9pZCBudnJhbV9yZWdpc3Rlcih2b2lkKQp7CiAgICBzeXNidXNfcmVnaXN0ZXJfd2l0aHByb3AoJm52cmFtX3N5c2J1c19pbmZvKTsKfQoKZGV2aWNlX2luaXQobnZyYW1fcmVnaXN0ZXIpCg==