LyoKICogUUVNVSBOVlJBTSBlbXVsYXRpb24gZm9yIERTMTIyNVkgY2hpcAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJzeXNidXMuaCIKI2luY2x1ZGUgInRyYWNlLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBEZXZpY2VTdGF0ZSBxZGV2OwogICAgdWludDMyX3QgY2hpcF9zaXplOwogICAgY2hhciAqZmlsZW5hbWU7CiAgICBGSUxFICpmaWxlOwogICAgdWludDhfdCAqY29udGVudHM7Cn0gTnZSYW1TdGF0ZTsKCnN0YXRpYyB1aW50MzJfdCBudnJhbV9yZWFkYiAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkcikKewogICAgTnZSYW1TdGF0ZSAqcyA9IG9wYXF1ZTsKICAgIHVpbnQzMl90IHZhbDsKCiAgICB2YWwgPSBzLT5jb250ZW50c1thZGRyXTsKICAgIHRyYWNlX252cmFtX3JlYWQoYWRkciwgdmFsKTsKICAgIHJldHVybiB2YWw7Cn0KCnN0YXRpYyB1aW50MzJfdCBudnJhbV9yZWFkdyAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkcikKewogICAgdWludDMyX3QgdjsKICAgIHYgPSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIpOwogICAgdiB8PSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIgKyAxKSA8PCA4OwogICAgcmV0dXJuIHY7Cn0KCnN0YXRpYyB1aW50MzJfdCBudnJhbV9yZWFkbCAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkcikKewogICAgdWludDMyX3QgdjsKICAgIHYgPSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIpOwogICAgdiB8PSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIgKyAxKSA8PCA4OwogICAgdiB8PSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIgKyAyKSA8PCAxNjsKICAgIHYgfD0gbnZyYW1fcmVhZGIob3BhcXVlLCBhZGRyICsgMykgPDwgMjQ7CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIHZvaWQgbnZyYW1fd3JpdGViICh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyLCB1aW50MzJfdCB2YWwpCnsKICAgIE52UmFtU3RhdGUgKnMgPSBvcGFxdWU7CgogICAgdmFsICY9IDB4ZmY7CiAgICB0cmFjZV9udnJhbV93cml0ZShhZGRyLCBzLT5jb250ZW50c1thZGRyXSwgdmFsKTsKCiAgICBzLT5jb250ZW50c1thZGRyXSA9IHZhbDsKICAgIGlmIChzLT5maWxlKSB7CiAgICAgICAgZnNlZWsocy0+ZmlsZSwgYWRkciwgU0VFS19TRVQpOwogICAgICAgIGZwdXRjKHZhbCwgcy0+ZmlsZSk7CiAgICAgICAgZmZsdXNoKHMtPmZpbGUpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZXcgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWwgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMywgKHZhbCA+PiAyNCkgJiAweGZmKTsKfQoKc3RhdGljIENQVVJlYWRNZW1vcnlGdW5jICogY29uc3QgbnZyYW1fcmVhZFtdID0gewogICAgJm52cmFtX3JlYWRiLAogICAgJm52cmFtX3JlYWR3LAogICAgJm52cmFtX3JlYWRsLAp9OwoKc3RhdGljIENQVVdyaXRlTWVtb3J5RnVuYyAqIGNvbnN0IG52cmFtX3dyaXRlW10gPSB7CiAgICAmbnZyYW1fd3JpdGViLAogICAgJm52cmFtX3dyaXRldywKICAgICZudnJhbV93cml0ZWwsCn07CgpzdGF0aWMgaW50IG52cmFtX3Bvc3RfbG9hZCh2b2lkICpvcGFxdWUsIGludCB2ZXJzaW9uX2lkKQp7CiAgICBOdlJhbVN0YXRlICpzID0gb3BhcXVlOwoKICAgIC8qIENsb3NlIGZpbGUsIGFzIGZpbGVuYW1lIG1heSBoYXMgY2hhbmdlZCBpbiBsb2FkL3N0b3JlIHByb2Nlc3MgKi8KICAgIGlmIChzLT5maWxlKSB7CiAgICAgICAgZmNsb3NlKHMtPmZpbGUpOwogICAgfQoKICAgIC8qIFdyaXRlIGJhY2sgbnZyYW0gY29udGVudHMgKi8KICAgIHMtPmZpbGUgPSBmb3BlbihzLT5maWxlbmFtZSwgIndiIik7CiAgICBpZiAocy0+ZmlsZSkgewogICAgICAgIC8qIFdyaXRlIGJhY2sgY29udGVudHMsIGFzICd3YicgbW9kZSBjbGVhbmVkIHRoZSBmaWxlICovCiAgICAgICAgaWYgKGZ3cml0ZShzLT5jb250ZW50cywgcy0+Y2hpcF9zaXplLCAxLCBzLT5maWxlKSAhPSAxKSB7CiAgICAgICAgICAgIHByaW50ZigibnZyYW1fcG9zdF9sb2FkOiBzaG9ydCB3cml0ZVxuIik7CiAgICAgICAgfQogICAgICAgIGZmbHVzaChzLT5maWxlKTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGNvbnN0IFZNU3RhdGVEZXNjcmlwdGlvbiB2bXN0YXRlX252cmFtID0gewogICAgLm5hbWUgPSAibnZyYW0iLAogICAgLnZlcnNpb25faWQgPSAwLAogICAgLm1pbmltdW1fdmVyc2lvbl9pZCA9IDAsCiAgICAubWluaW11bV92ZXJzaW9uX2lkX29sZCA9IDAsCiAgICAucG9zdF9sb2FkID0gbnZyYW1fcG9zdF9sb2FkLAogICAgLmZpZWxkcyA9IChWTVN0YXRlRmllbGRbXSkgewogICAgICAgIFZNU1RBVEVfVkFSUkFZX1VJTlQzMihjb250ZW50cywgTnZSYW1TdGF0ZSwgY2hpcF9zaXplLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2bXN0YXRlX2luZm9fdWludDgsIHVpbnQ4X3QpLAogICAgICAgIFZNU1RBVEVfRU5EX09GX0xJU1QoKQogICAgfQp9OwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgU3lzQnVzRGV2aWNlIGJ1c2RldjsKICAgIE52UmFtU3RhdGUgbnZyYW07Cn0gU3lzQnVzTnZSYW1TdGF0ZTsKCnN0YXRpYyBpbnQgbnZyYW1fc3lzYnVzX2luaXRmbihTeXNCdXNEZXZpY2UgKmRldikKewogICAgTnZSYW1TdGF0ZSAqcyA9ICZGUk9NX1NZU0JVUyhTeXNCdXNOdlJhbVN0YXRlLCBkZXYpLT5udnJhbTsKICAgIEZJTEUgKmZpbGU7CiAgICBpbnQgc19pbzsKCiAgICBzLT5jb250ZW50cyA9IGdfbWFsbG9jMChzLT5jaGlwX3NpemUpOwoKICAgIHNfaW8gPSBjcHVfcmVnaXN0ZXJfaW9fbWVtb3J5KG52cmFtX3JlYWQsIG52cmFtX3dyaXRlLCBzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgREVWSUNFX05BVElWRV9FTkRJQU4pOwogICAgc3lzYnVzX2luaXRfbW1pbyhkZXYsIHMtPmNoaXBfc2l6ZSwgc19pbyk7CgogICAgLyogUmVhZCBjdXJyZW50IGZpbGUgKi8KICAgIGZpbGUgPSBmb3BlbihzLT5maWxlbmFtZSwgInJiIik7CiAgICBpZiAoZmlsZSkgewogICAgICAgIC8qIFJlYWQgbnZyYW0gY29udGVudHMgKi8KICAgICAgICBpZiAoZnJlYWQocy0+Y29udGVudHMsIHMtPmNoaXBfc2l6ZSwgMSwgZmlsZSkgIT0gMSkgewogICAgICAgICAgICBwcmludGYoIm52cmFtX3N5c2J1c19pbml0Zm46IHNob3J0IHJlYWRcbiIpOwogICAgICAgIH0KICAgICAgICBmY2xvc2UoZmlsZSk7CiAgICB9CiAgICBudnJhbV9wb3N0X2xvYWQocywgMCk7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBTeXNCdXNEZXZpY2VJbmZvIG52cmFtX3N5c2J1c19pbmZvID0gewogICAgLnFkZXYubmFtZSAgPSAiZHMxMjI1eSIsCiAgICAucWRldi5zaXplICA9IHNpemVvZihTeXNCdXNOdlJhbVN0YXRlKSwKICAgIC5xZGV2LnZtc2QgID0gJnZtc3RhdGVfbnZyYW0sCiAgICAuaW5pdCAgICAgICA9IG52cmFtX3N5c2J1c19pbml0Zm4sCiAgICAucWRldi5wcm9wcyA9IChQcm9wZXJ0eVtdKSB7CiAgICAgICAgREVGSU5FX1BST1BfVUlOVDMyKCJzaXplIiwgU3lzQnVzTnZSYW1TdGF0ZSwgbnZyYW0uY2hpcF9zaXplLCAweDIwMDApLAogICAgICAgIERFRklORV9QUk9QX1NUUklORygiZmlsZW5hbWUiLCBTeXNCdXNOdlJhbVN0YXRlLCBudnJhbS5maWxlbmFtZSksCiAgICAgICAgREVGSU5FX1BST1BfRU5EX09GX0xJU1QoKSwKICAgIH0sCn07CgpzdGF0aWMgdm9pZCBudnJhbV9yZWdpc3Rlcih2b2lkKQp7CiAgICBzeXNidXNfcmVnaXN0ZXJfd2l0aHByb3AoJm52cmFtX3N5c2J1c19pbmZvKTsKfQoKZGV2aWNlX2luaXQobnZyYW1fcmVnaXN0ZXIpCg==