LyoKICogUUVNVSBOVlJBTSBlbXVsYXRpb24gZm9yIERTMTIyNVkgY2hpcAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJzeXNidXMuaCIKI2luY2x1ZGUgInRyYWNlLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEZXZpY2VTdGF0ZSBxZGV2OwogICAgdWludDMyX3QgY2hpcF9zaXplOwogICAgY2hhciAqZmlsZW5hbWU7CiAgICBRRU1VRmlsZSAqZmlsZTsKICAgIHVpbnQ4X3QgKmNvbnRlbnRzOwp9IE52UmFtU3RhdGU7CgpzdGF0aWMgdWludDMyX3QgbnZyYW1fcmVhZGIgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIpCnsKICAgIE52UmFtU3RhdGUgKnMgPSBvcGFxdWU7CiAgICB1aW50MzJfdCB2YWw7CgogICAgdmFsID0gcy0+Y29udGVudHNbYWRkcl07CiAgICB0cmFjZV9udnJhbV9yZWFkKGFkZHIsIHZhbCk7CiAgICByZXR1cm4gdmFsOwp9CgpzdGF0aWMgdWludDMyX3QgbnZyYW1fcmVhZHcgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIpCnsKICAgIHVpbnQzMl90IHY7CiAgICB2ID0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyKTsKICAgIHYgfD0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyICsgMSkgPDwgODsKICAgIHJldHVybiB2Owp9CgpzdGF0aWMgdWludDMyX3QgbnZyYW1fcmVhZGwgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIpCnsKICAgIHVpbnQzMl90IHY7CiAgICB2ID0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyKTsKICAgIHYgfD0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyICsgMSkgPDwgODsKICAgIHYgfD0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyICsgMikgPDwgMTY7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDMpIDw8IDI0OwogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyB2b2lkIG52cmFtX3dyaXRlYiAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkciwgdWludDMyX3QgdmFsKQp7CiAgICBOdlJhbVN0YXRlICpzID0gb3BhcXVlOwoKICAgIHZhbCAmPSAweGZmOwogICAgdHJhY2VfbnZyYW1fd3JpdGUoYWRkciwgcy0+Y29udGVudHNbYWRkcl0sIHZhbCk7CgogICAgcy0+Y29udGVudHNbYWRkcl0gPSB2YWw7CiAgICBpZiAocy0+ZmlsZSkgewogICAgICAgIHFlbXVfZnNlZWsocy0+ZmlsZSwgYWRkciwgU0VFS19TRVQpOwogICAgICAgIHFlbXVfcHV0X2J5dGUocy0+ZmlsZSwgKGludCl2YWwpOwogICAgICAgIHFlbXVfZmZsdXNoKHMtPmZpbGUpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZXcgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWwgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMywgKHZhbCA+PiAyNCkgJiAweGZmKTsKfQoKc3RhdGljIENQVVJlYWRNZW1vcnlGdW5jICogY29uc3QgbnZyYW1fcmVhZFtdID0gewogICAgJm52cmFtX3JlYWRiLAogICAgJm52cmFtX3JlYWR3LAogICAgJm52cmFtX3JlYWRsLAp9OwoKc3RhdGljIENQVVdyaXRlTWVtb3J5RnVuYyAqIGNvbnN0IG52cmFtX3dyaXRlW10gPSB7CiAgICAmbnZyYW1fd3JpdGViLAogICAgJm52cmFtX3dyaXRldywKICAgICZudnJhbV93cml0ZWwsCn07CgpzdGF0aWMgaW50IG52cmFtX3Bvc3RfbG9hZCh2b2lkICpvcGFxdWUsIGludCB2ZXJzaW9uX2lkKQp7CiAgICBOdlJhbVN0YXRlICpzID0gb3BhcXVlOwoKICAgIC8qIENsb3NlIGZpbGUsIGFzIGZpbGVuYW1lIG1heSBoYXMgY2hhbmdlZCBpbiBsb2FkL3N0b3JlIHByb2Nlc3MgKi8KICAgIGlmIChzLT5maWxlKSB7CiAgICAgICAgcWVtdV9mY2xvc2Uocy0+ZmlsZSk7CiAgICB9CgogICAgLyogV3JpdGUgYmFjayBudnJhbSBjb250ZW50cyAqLwogICAgcy0+ZmlsZSA9IHFlbXVfZm9wZW4ocy0+ZmlsZW5hbWUsICJ3YiIpOwogICAgaWYgKHMtPmZpbGUpIHsKICAgICAgICAvKiBXcml0ZSBiYWNrIGNvbnRlbnRzLCBhcyAnd2InIG1vZGUgY2xlYW5lZCB0aGUgZmlsZSAqLwogICAgICAgIHFlbXVfcHV0X2J1ZmZlcihzLT5maWxlLCBzLT5jb250ZW50cywgcy0+Y2hpcF9zaXplKTsKICAgICAgICBxZW11X2ZmbHVzaChzLT5maWxlKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGNvbnN0IFZNU3RhdGVEZXNjcmlwdGlvbiB2bXN0YXRlX252cmFtID0gewogICAgLm5hbWUgPSAibnZyYW0iLAogICAgLnZlcnNpb25faWQgPSAwLAogICAgLm1pbmltdW1fdmVyc2lvbl9pZCA9IDAsCiAgICAubWluaW11bV92ZXJzaW9uX2lkX29sZCA9IDAsCiAgICAucG9zdF9sb2FkID0gbnZyYW1fcG9zdF9sb2FkLAogICAgLmZpZWxkcyA9IChWTVN0YXRlRmllbGRbXSkgewogICAgICAgIFZNU1RBVEVfVkFSUkFZX1VJTlQzMihjb250ZW50cywgTnZSYW1TdGF0ZSwgY2hpcF9zaXplLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2bXN0YXRlX2luZm9fdWludDgsIHVpbnQ4X3QpLAogICAgICAgIFZNU1RBVEVfRU5EX09GX0xJU1QoKQogICAgfQp9OwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgU3lzQnVzRGV2aWNlIGJ1c2RldjsKICAgIE52UmFtU3RhdGUgbnZyYW07Cn0gU3lzQnVzTnZSYW1TdGF0ZTsKCnN0YXRpYyBpbnQgbnZyYW1fc3lzYnVzX2luaXRmbihTeXNCdXNEZXZpY2UgKmRldikKewogICAgTnZSYW1TdGF0ZSAqcyA9ICZGUk9NX1NZU0JVUyhTeXNCdXNOdlJhbVN0YXRlLCBkZXYpLT5udnJhbTsKICAgIFFFTVVGaWxlICpmaWxlOwogICAgaW50IHNfaW87CgogICAgcy0+Y29udGVudHMgPSBxZW11X21hbGxvY3oocy0+Y2hpcF9zaXplKTsKCiAgICBzX2lvID0gY3B1X3JlZ2lzdGVyX2lvX21lbW9yeShudnJhbV9yZWFkLCBudnJhbV93cml0ZSwgcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFVklDRV9OQVRJVkVfRU5ESUFOKTsKICAgIHN5c2J1c19pbml0X21taW8oZGV2LCBzLT5jaGlwX3NpemUsIHNfaW8pOwoKICAgIC8qIFJlYWQgY3VycmVudCBmaWxlICovCiAgICBmaWxlID0gcWVtdV9mb3BlbihzLT5maWxlbmFtZSwgInJiIik7CiAgICBpZiAoZmlsZSkgewogICAgICAgIC8qIFJlYWQgbnZyYW0gY29udGVudHMgKi8KICAgICAgICBxZW11X2dldF9idWZmZXIoZmlsZSwgcy0+Y29udGVudHMsIHMtPmNoaXBfc2l6ZSk7CiAgICAgICAgcWVtdV9mY2xvc2UoZmlsZSk7CiAgICB9CiAgICBudnJhbV9wb3N0X2xvYWQocywgMCk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBTeXNCdXNEZXZpY2VJbmZvIG52cmFtX3N5c2J1c19pbmZvID0gewogICAgLnFkZXYubmFtZSAgPSAiZHMxMjI1eSIsCiAgICAucWRldi5zaXplICA9IHNpemVvZihTeXNCdXNOdlJhbVN0YXRlKSwKICAgIC5xZGV2LnZtc2QgID0gJnZtc3RhdGVfbnZyYW0sCiAgICAuaW5pdCAgICAgICA9IG52cmFtX3N5c2J1c19pbml0Zm4sCiAgICAucWRldi5wcm9wcyA9IChQcm9wZXJ0eVtdKSB7CiAgICAgICAgREVGSU5FX1BST1BfVUlOVDMyKCJzaXplIiwgU3lzQnVzTnZSYW1TdGF0ZSwgbnZyYW0uY2hpcF9zaXplLCAweDIwMDApLAogICAgICAgIERFRklORV9QUk9QX1NUUklORygiZmlsZW5hbWUiLCBTeXNCdXNOdlJhbVN0YXRlLCBudnJhbS5maWxlbmFtZSksCiAgICAgICAgREVGSU5FX1BST1BfRU5EX09GX0xJU1QoKSwKICAgIH0sCn07CgpzdGF0aWMgdm9pZCBudnJhbV9yZWdpc3Rlcih2b2lkKQp7CiAgICBzeXNidXNfcmVnaXN0ZXJfd2l0aHByb3AoJm52cmFtX3N5c2J1c19pbmZvKTsKfQoKZGV2aWNlX2luaXQobnZyYW1fcmVnaXN0ZXIpCg==