LyoKICogc25tcHVzbS5jIC0gc2VuZCBzbm1wIFNFVCByZXF1ZXN0cyB0byBhIG5ldHdvcmsgZW50aXR5IHRvIGNoYW5nZSB0aGUKICogICAgICAgICAgICAgdXNtIHVzZXIgZGF0YWJhc2UKICoKICogWFhYIGdldCBlbmdpbmVJRCBkeW5hbWljYWxseS4KICogWFhYIHJlYWQgcGFzc3dvcmRzIGZyb20gcHJvbXB0cwogKiBYWFggY3VzdG9taXplIHJlc3BvbnNlcyB3aXRoIHVzZXIgbmFtZXMsIGV0Yy4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCgojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKI2luY2x1ZGUgPG9wZW5zc2wvZGguaD4KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KCmludCAgICAgICAgICAgICBtYWluKGludCwgY2hhciAqKik7CgojZGVmaW5lIENNRF9QQVNTV0RfTkFNRSAgICAicGFzc3dkIgojZGVmaW5lIENNRF9QQVNTV0QgICAgICAgICAxCiNkZWZpbmUgQ01EX0NSRUFURV9OQU1FICAgICJjcmVhdGUiCiNkZWZpbmUgQ01EX0NSRUFURSAgICAgICAgIDIKI2RlZmluZSBDTURfREVMRVRFX05BTUUgICAgImRlbGV0ZSIKI2RlZmluZSBDTURfREVMRVRFICAgICAgICAgMwojZGVmaW5lIENNRF9DTE9ORUZST01fTkFNRSAiY2xvbmVGcm9tIgojZGVmaW5lIENNRF9DTE9ORUZST00gICAgICA0CiNkZWZpbmUgQ01EX0FDVElWQVRFX05BTUUgICJhY3RpdmF0ZSIKI2RlZmluZSBDTURfQUNUSVZBVEUgICAgICAgNQojZGVmaW5lIENNRF9ERUFDVElWQVRFX05BTUUgImRlYWN0aXZhdGUiCiNkZWZpbmUgQ01EX0RFQUNUSVZBVEUgICAgIDYKI2RlZmluZSBDTURfQ0hBTkdFS0VZX05BTUUgICJjaGFuZ2VrZXkiCiNkZWZpbmUgQ01EX0NIQU5HRUtFWSAgICAgIDcKCiNkZWZpbmUgQ01EX05VTSAgICA3CgpzdGF0aWMgY29uc3QgY2hhciAqc3VjY2Vzc05vdGVzW0NNRF9OVU1dID0gewogICAgIlNOTVB2MyBLZXkocykgc3VjY2Vzc2Z1bGx5IGNoYW5nZWQuIiwKICAgICJVc2VyIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsCiAgICAiVXNlciBzdWNjZXNzZnVsbHkgZGVsZXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGNsb25lZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGFjdGl2YXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGRlYWN0aXZhdGVkLiIsCiAgICAiU05NUHYzIEtleShzKSBzdWNjZXNzZnVsbHkgY2hhbmdlZC4iCn07CgojZGVmaW5lICAgICAgICAgICAgICAgICAgIFVTTV9PSURfTEVOICAgIDEyCiNkZWZpbmUgICAgICAgICAgICAgICAgREhfVVNNX09JRF9MRU4gICAgMTEKCnN0YXRpYyBvaWQKCmF1dGhLZXlPaWRbTUFYX09JRF9MRU5dID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgNiB9LApvd25BdXRoS2V5T2lkW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgN30sCnByaXZLZXlPaWRbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCA5fSwKb3duUHJpdktleU9pZFtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDEwfSwKdXNtVXNlckNsb25lRnJvbVtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDR9LAp1c21Vc2VyU2VjdXJpdHlOYW1lW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgM30sCnVzbVVzZXJQdWJsaWNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxMX0sCnVzbVVzZXJTdGF0dXNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxM30sCi8qIGRpZmZpZSBoZWxtYW4gY2hhbmdlIGtleSBvYmplY3RzICovCnVzbURIVXNlckF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMSB9LAp1c21ESFVzZXJQcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDMgfSwKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCnVzbURIVXNlck93bkF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMiB9LAp1c21ESFVzZXJPd25Qcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDQgfSwKI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCnVzbURIUGFyYW1ldGVyc1tdID0geyAxLDMsNiwxLDMsMTAxLDEsMSwxLDAgfQo7CnNpemVfdCB1c21ESFBhcmFtZXRlcnNfbGVuID0gT0lEX0xFTkdUSCh1c21ESFBhcmFtZXRlcnMpOwoKc3RhdGljCm9pZCAgICAgICAgICAgICphdXRoS2V5Q2hhbmdlID0gYXV0aEtleU9pZCwgKnByaXZLZXlDaGFuZ2UgPSBwcml2S2V5T2lkOwpvaWQgICAgICAgICAgICAqZGhhdXRoS2V5Q2hhbmdlID0gdXNtREhVc2VyQXV0aEtleUNoYW5nZSwKICAgICAgICAgICAgICAgKmRocHJpdktleUNoYW5nZSA9IHVzbURIVXNlclByaXZLZXlDaGFuZ2U7CmludCAgICAgICAgICAgICBkb2F1dGhrZXkgPSAwLCBkb3ByaXZrZXkgPSAwLCB1c2Vsb2NhbGl6ZWRrZXkgPSAwOwpzaXplX3QgICAgICAgICAgdXNtVXNlckVuZ2luZUlETGVuID0gMDsKdV9jaGFyICAgICAgICAgKnVzbVVzZXJFbmdpbmVJRCA9IE5VTEw7CmNoYXIgICAgICAgICAgICp1c21Vc2VyUHVibGljX3ZhbCA9IE5VTEw7CmludCAgICAgICAgICAgICBkb2NyZWF0ZWFuZHdhaXQgPSAwOwoKCnZvaWQKdXNhZ2Uodm9pZCkKewogICAgZnByaW50ZihzdGRlcnIsICJVc2FnZTogc25tcHVzbSAiKTsKICAgIHNubXBfcGFyc2VfYXJnc191c2FnZShzdGRlcnIpOwogICAgZnByaW50ZihzdGRlcnIsICIgQ09NTUFORFxuXG4iKTsKICAgIHNubXBfcGFyc2VfYXJnc19kZXNjcmlwdGlvbnMoc3RkZXJyKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXG5zbm1wdXNtIGNvbW1hbmRzOlxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIiAgW29wdGlvbnNdICAgICAgICAgICAgICAgY3JlYXRlICAgICBVU0VSIFtDTE9ORUZST00tVVNFUl1cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSAgICAgICAgICAgICAgIGRlbGV0ZSAgICAgVVNFUlxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIiAgW29wdGlvbnNdICAgICAgICAgICAgICAgYWN0aXZhdGUgICBVU0VSXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiICBbb3B0aW9uc10gICAgICAgICAgICAgICBkZWFjdGl2YXRlIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBbLUN3XSAgICAgICAgIGNsb25lRnJvbSAgVVNFUiBDTE9ORUZST00tVVNFUlxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIiAgW29wdGlvbnNdIFstQ2FdIFstQ3hdICAgY2hhbmdla2V5ICBbVVNFUl1cbiIpOwogICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICIgIFtvcHRpb25zXSBbLUNhXSBbLUN4XSAgIHBhc3N3ZCAgICAgT0xELVBBU1NQSFJBU0UgTkVXLVBBU1NQSFJBU0UgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAiICBbb3B0aW9uc10gKC1DYXwtQ3gpIC1DayBwYXNzd2QgICAgIE9MRC1LRVktT1ItUEFTUyBORVctS0VZLU9SLVBBU1MgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXG5zbm1wdXNtIG9wdGlvbnM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ0UgRU5HSU5FLUlEXHRTZXQgdXNtVXNlckVuZ2luZUlEIChlLmcuIDgwMDAwMDAyMDEwOTg0MDMwMSkuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3AgU1RSSU5HXHRTZXQgdXNtVXNlclB1YmxpYyB2YWx1ZSB0byBTVFJJTkcuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3dcdFx0Q3JlYXRlIHRoZSB1c2VyIHdpdGggY3JlYXRlQW5kV2FpdC5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdFx0XHQoaXQgd29uJ3QgYmUgYWN0aXZlIHVudGlsIHlvdSBhY3RpdmUgaXQpXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3hcdFx0Q2hhbmdlIHRoZSBwcml2YWN5IGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1DYVx0XHRDaGFuZ2UgdGhlIGF1dGhlbnRpY2F0aW9uIGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1Da1x0XHRBbGxvd3MgdG8gdXNlIGxvY2FsaXplZCBrZXkgKG11c3Qgc3RhcnQgd2l0aCAweClcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdFx0XHRpbnN0ZWFkIG9mIHBhc3NwaHJhc2UuXG4iKTsKfQoKLyoKICogc2V0dXBfb2lkIGFwcGVuZHMgdG8gdGhlIG9pZCB0aGUgaW5kZXggZm9yIHRoZSBlbmdpbmVpZC91c2VyIAogKi8Kdm9pZApzZXR1cF9vaWQob2lkICogaXQsIHNpemVfdCAqIGxlbiwgdV9jaGFyICogaWQsIHNpemVfdCBpZGxlbiwKICAgICAgICAgIGNvbnN0IGNoYXIgKnVzZXIpCnsKICAgIGludCAgICAgICAgICAgICBpLCBpdEluZGV4ID0gKmxlbjsKCiAgICAqbGVuID0gaXRJbmRleCArIDEgKyBpZGxlbiArIDEgKyBzdHJsZW4odXNlcik7CgogICAgaXRbaXRJbmRleCsrXSA9IGlkbGVuOwogICAgZm9yIChpID0gMDsgaSA8IChpbnQpIGlkbGVuOyBpKyspIHsKICAgICAgICBpdFtpdEluZGV4KytdID0gaWRbaV07CiAgICB9CgogICAgaXRbaXRJbmRleCsrXSA9IHN0cmxlbih1c2VyKTsKICAgIGZvciAoaSA9IDA7IGkgPCAoaW50KSBzdHJsZW4odXNlcik7IGkrKykgewogICAgICAgIGl0W2l0SW5kZXgrK10gPSB1c2VyW2ldOwogICAgfQoKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgZnByaW50ZihzdGRvdXQsICJzZXR1cF9vaWQ6ICIpOyAgCiAgICBmcHJpbnRfb2JqaWQoc3Rkb3V0LCBpdCwgKmxlbik7ICAKICAgIGZwcmludGYoc3Rkb3V0LCAiXG4iKTsgIAojZW5kaWYKfQoKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCmludApnZXRfVVNNX0RIX2tleShuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqZGh2YXIsCiAgICAgICAgICAgICAgIHNpemVfdCBvdXRrZXlfbGVuLAogICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCBjb25zdCBjaGFyICprZXluYW1lLAogICAgICAgICAgICAgICBvaWQgKmtleW9pZCwgc2l6ZV90IGtleW9pZF9sZW4pIHsKICAgIHVfY2hhciAqZGhrZXljaGFuZ2U7CiAgICBESCAqZGg7CiAgICBCSUdOVU0gKm90aGVyX3B1YjsKICAgIHVfY2hhciAqa2V5OwogICAgc2l6ZV90IGtleV9sZW47CiAgICAgICAgICAgIAogICAgZGhrZXljaGFuZ2UgPSAodV9jaGFyICopIG1hbGxvYygyICogdmFycy0+dmFsX2xlbiAqIHNpemVvZihjaGFyKSk7CiAgICBpZiAoIWRoa2V5Y2hhbmdlKQogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIAogICAgbWVtY3B5KGRoa2V5Y2hhbmdlLCB2YXJzLT52YWwuc3RyaW5nLCB2YXJzLT52YWxfbGVuKTsKCiAgICB7CiAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciAqY3AgPSBkaHZhci0+dmFsLnN0cmluZzsKICAgICAgICBkaCA9IGQyaV9ESHBhcmFtcyhOVUxMLCAmY3AsIGRodmFyLT52YWxfbGVuKTsKICAgIH0KCiAgICBpZiAoIWRoIHx8ICFkaC0+ZyB8fCAhZGgtPnApIHsKICAgICAgICBTTk1QX0ZSRUUoZGhrZXljaGFuZ2UpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBESF9nZW5lcmF0ZV9rZXkoZGgpOwogICAgaWYgKCFkaC0+cHViX2tleSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAgICAgICAgICAKICAgIGlmICh2YXJzLT52YWxfbGVuICE9ICh1bnNpZ25lZCBpbnQpQk5fbnVtX2J5dGVzKGRoLT5wdWJfa2V5KSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgZnByaW50ZihzdGRlcnIsImluY29ycmVjdCBkaWZmaWUtaGVsbWFuIGxlbmd0aHMgKCVsdSAhPSAlZClcbiIsCiAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZyl2YXJzLT52YWxfbGVuLCBCTl9udW1fYnl0ZXMoZGgtPnB1Yl9rZXkpKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgQk5fYm4yYmluKGRoLT5wdWJfa2V5LCBkaGtleWNoYW5nZSArIHZhcnMtPnZhbF9sZW4pOwoKICAgIGtleV9sZW4gPSBESF9zaXplKGRoKTsKICAgIGlmICgha2V5X2xlbikgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAga2V5ID0gKHVfY2hhciAqKSBtYWxsb2Moa2V5X2xlbiAqIHNpemVvZih1X2NoYXIpKTsKCiAgICBpZiAoIWtleSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIG90aGVyX3B1YiA9IEJOX2JpbjJibih2YXJzLT52YWwuc3RyaW5nLCB2YXJzLT52YWxfbGVuLCBOVUxMKTsKICAgIGlmICghb3RoZXJfcHViKSB7CiAgICAgICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgICAgICBTTk1QX0ZSRUUoa2V5KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKERIX2NvbXB1dGVfa2V5KGtleSwgb3RoZXJfcHViLCBkaCkpIHsKICAgICAgICB1X2NoYXIgKmtwOwoKICAgICAgICBwcmludGYoIm5ldyAlcyBrZXk6IDB4Iiwga2V5bmFtZSk7CiAgICAgICAgZm9yKGtwID0ga2V5ICsga2V5X2xlbiAtIG91dGtleV9sZW47CiAgICAgICAgICAgIGtwIC0ga2V5IDwgKGludClrZXlfbGVuOyAga3ArKykgewogICAgICAgICAgICBwcmludGYoIiUwMngiLCAodW5zaWduZWQgY2hhcikgKmtwKTsKICAgICAgICB9CiAgICAgICAgcHJpbnRmKCJcbiIpOwogICAgfQoKICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIGtleW9pZCwga2V5b2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLCBkaGtleWNoYW5nZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAyICogdmFycy0+dmFsX2xlbik7CgogICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgIFNOTVBfRlJFRShvdGhlcl9wdWIpOwogICAgU05NUF9GUkVFKGtleSk7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQojZW5kaWYgLyogSEFWRV9PUEVOU1NMX0RIX0ggKi8KCnN0YXRpYyB2b2lkCm9wdFByb2MoaW50IGFyZ2MsIGNoYXIgKmNvbnN0ICphcmd2LCBpbnQgb3B0KQp7CiAgICBzd2l0Y2ggKG9wdCkgewogICAgY2FzZSAnQyc6CiAgICAgICAgd2hpbGUgKCpvcHRhcmcpIHsKICAgICAgICAgICAgc3dpdGNoICgqb3B0YXJnKyspIHsKICAgICAgICAgICAgY2FzZSAnYSc6CiAgICAgICAgICAgICAgICBkb2F1dGhrZXkgPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICd4JzoKICAgICAgICAgICAgICAgIGRvcHJpdmtleSA9IDE7CiAgICAgICAgICAgICAgICBicmVhazsKCgkgICAgY2FzZSAnayc6CgkgICAgICAgIHVzZWxvY2FsaXplZGtleSA9IDE7CgkJYnJlYWs7CgoJICAgIGNhc2UgJ3AnOgogICAgICAgICAgICAgICAgaWYgKG9wdGluZCA8IGFyZ2MpIHsKCQkgICAgdXNtVXNlclB1YmxpY192YWwgPSAgYXJndltvcHRpbmRdOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkJhZCAtQ3Agb3B0aW9uOiBubyBhcmd1bWVudCBnaXZlblxuIik7CiAgICAgICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9wdGluZCsrOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlICd3JzoKICAgICAgICAgICAgICAgIGRvY3JlYXRlYW5kd2FpdCA9IDE7CiAgICAgICAgICAgICAgICBicmVhazsKCgkgICAgY2FzZSAnRSc6IHsKCSAgICAgICAgc2l6ZV90IGVidWZfbGVuID0gTUFYX0VOR0lORUlEX0xFTkdUSDsKICAgICAgICAgICAgICAgIHVfY2hhciAqZWJ1ZjsKICAgICAgICAgICAgICAgIGlmIChvcHRpbmQgPCBhcmdjKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGFyZ3Zbb3B0aW5kXSkgewogICAgICAgICAgICAgICAgICAgICAgICBlYnVmID0gKHVfY2hhciAqKW1hbGxvYyhlYnVmX2xlbik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlYnVmID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1hbGxvYyBmYWlsdXJlIHByb2Nlc3NpbmcgLUNFIG9wdGlvbi5cbiIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQoJCSAgICAgICAgaWYgKCFzbm1wX2hleF90b19iaW5hcnkoJmVidWYsICZlYnVmX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnVzbVVzZXJFbmdpbmVJRExlbiwgMSwgYXJndltvcHRpbmRdKSkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiQmFkIHVzbVVzZXJFbmdpbmVJRCB2YWx1ZSBhZnRlciAtQ0Ugb3B0aW9uLlxuIik7CgkJICAgICAgICAgICAgZnJlZShlYnVmKTsKCQkgICAgICAgICAgICBleGl0KDEpOwoJCSAgICAgICAgfQoJCSAgICAgICAgdXNtVXNlckVuZ2luZUlEID0gZWJ1ZjsKCQkgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wdXNtIiwgInVzbVVzZXJFbmdpbmVJRCBzZXQgdG86ICIpKTsKCQkgICAgICAgIERFQlVHTVNHSEVYKCgic25tcHVzbSIsIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuKSk7CgkJICAgICAgICBERUJVR01TRygoInNubXB1c20iLCAiXG4iKSk7CgogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJCYWQgLUNFIG9wdGlvbjogbm8gYXJndW1lbnQgZ2l2ZW5cbiIpOwogICAgICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvcHRpbmQrKzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJVbmtub3duIGZsYWcgcGFzc2VkIHRvIC1DOiAlY1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgb3B0YXJnWy0xXSk7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQp9CgppbnQKbWFpbihpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CiAgICBuZXRzbm1wX3Nlc3Npb24gc2Vzc2lvbiwgKnNzOwogICAgbmV0c25tcF9wZHUgICAgKnBkdSA9IE5VTEwsICpyZXNwb25zZSA9IE5VTEw7CgogICAgaW50ICAgICAgICAgICAgIGFyZzsKICAgIHNpemVfdCAgICAgICAgICBuYW1lX2xlbmd0aCA9IFVTTV9PSURfTEVOOwogICAgc2l6ZV90ICAgICAgICAgIG5hbWVfbGVuZ3RoMiA9IFVTTV9PSURfTEVOOwogICAgaW50ICAgICAgICAgICAgIHN0YXR1czsKICAgIGludCAgICAgICAgICAgICBleGl0dmFsID0gMDsKICAgIGludCAgICAgICAgICAgICBydmFsOwogICAgaW50ICAgICAgICAgICAgIGNvbW1hbmQgPSAwOwogICAgbG9uZyAgICAgICAgICAgIGxvbmd2YXI7CgogICAgc2l6ZV90ICAgICAgICAgIG9sZEt1X2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIG5ld0t1X2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIG9sZGt1bF9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBvbGRrdWxwcml2X2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIG5ld2t1bHByaXZfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAgbmV3a3VsX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIGtleWNoYW5nZV9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBrZXljaGFuZ2Vwcml2X2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMOwoKICAgIGNoYXIgICAgICAgICAgICpuZXdwYXNzID0gTlVMTCwgKm9sZHBhc3MgPSBOVUxMOwogICAgdV9jaGFyICAgICAgICAgIG9sZEt1W1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBuZXdLdVtTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAgb2xka3VsW1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBvbGRrdWxwcml2W1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBuZXdrdWxwcml2W1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBuZXdrdWxbU05NUF9NQVhCVUZfU01BTExdLCBrZXljaGFuZ2VbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIGtleWNoYW5nZXByaXZbU05NUF9NQVhCVUZfU01BTExdOwoKICAgIGF1dGhLZXlDaGFuZ2UgPSBhdXRoS2V5T2lkOwogICAgcHJpdktleUNoYW5nZSA9IHByaXZLZXlPaWQ7CgogICAgLyoKICAgICAqIGdldCB0aGUgY29tbW9uIGNvbW1hbmQgbGluZSBhcmd1bWVudHMgCiAgICAgKi8KICAgIHN3aXRjaCAoYXJnID0gc25tcF9wYXJzZV9hcmdzKGFyZ2MsIGFyZ3YsICZzZXNzaW9uLCAiQzoiLCBvcHRQcm9jKSkgewogICAgY2FzZSBORVRTTk1QX1BBUlNFX0FSR1NfRVJST1I6CiAgICAgICAgZXhpdCgxKTsKICAgIGNhc2UgTkVUU05NUF9QQVJTRV9BUkdTX1NVQ0NFU1NfRVhJVDoKICAgICAgICBleGl0KDApOwogICAgY2FzZSBORVRTTk1QX1BBUlNFX0FSR1NfRVJST1JfVVNBR0U6CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgZGVmYXVsdDoKICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoYXJnID49IGFyZ2MpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlBsZWFzZSBzcGVjaWZ5IGFuIG9wZXJhdGlvbiB0byBwZXJmb3JtLlxuIik7CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIFNPQ0tfU1RBUlRVUDsKCiAgICAvKgogICAgICogb3BlbiBhbiBTTk1QIHNlc3Npb24gCiAgICAgKi8KICAgIC8qCiAgICAgKiBOb3RlOiAgdGhpcyBuZWVkcyB0byBvYnRhaW4gdGhlIGVuZ2luZUlEIHVzZWQgYmVsb3cgCiAgICAgKi8KICAgIHNlc3Npb24uZmxhZ3MgJj0gflNOTVBfRkxBR1NfRE9OVF9QUk9CRTsKICAgIHNzID0gc25tcF9vcGVuKCZzZXNzaW9uKTsKICAgIGlmIChzcyA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkaWFnbm9zZSBzbm1wX29wZW4gZXJyb3JzIHdpdGggdGhlIGlucHV0IG5ldHNubXBfc2Vzc2lvbiBwb2ludGVyIAogICAgICAgICAqLwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXB1c20iLCAmc2Vzc2lvbik7CiAgICAgICAgZXhpdCgxKTsKICAgIH0KCiAgICAvKgogICAgICogc2V0IHVzbVVzZXJFbmdpbmVJRCBmcm9tIHNzLT5jb250ZXh0RW5naW5lSUQKICAgICAqICAgaWYgbm90IGFscmVhZHkgc2V0ICh2aWEgLUNFKQogICAgICovCiAgICBpZiAodXNtVXNlckVuZ2luZUlEID09IE5VTEwpIHsKICAgICAgdXNtVXNlckVuZ2luZUlEICAgID0gc3MtPmNvbnRleHRFbmdpbmVJRDsKICAgICAgdXNtVXNlckVuZ2luZUlETGVuID0gc3MtPmNvbnRleHRFbmdpbmVJRExlbjsKICAgIH0KCiAgICAvKgogICAgICogY3JlYXRlIFBEVSBmb3IgU0VUIHJlcXVlc3QgYW5kIGFkZCBvYmplY3QgbmFtZXMgYW5kIHZhbHVlcyB0byByZXF1ZXN0IAogICAgICovCiAgICBwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfU0VUKTsKICAgIGlmICghcGR1KSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgdG8gY3JlYXRlIHJlcXVlc3RcbiIpOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgoKICAgIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfUEFTU1dEX05BTUUpID09IDApIHsKCiAgICAgICAgLyoKICAgICAgICAgKiBwYXNzd2Q6IGNoYW5nZSBhIHVzZXJzIHBhc3N3b3JkLgogICAgICAgICAqCiAgICAgICAgICogWFhYOiAgVXNlcyB0aGUgYXV0aCB0eXBlIG9mIHRoZSBjYWxsaW5nIHVzZXIsIGEgTUQ1IHVzZXIgY2FuJ3QKICAgICAgICAgKiAgICAgICBjaGFuZ2UgYSBTSEEgdXNlcidzIGtleS4KICAgICAgICAgKi8KICAgICAgICBjaGFyICpwYXNzd2RfdXNlcjsKCiAgICAgICAgY29tbWFuZCA9IENNRF9QQVNTV0Q7CiAgICAgICAgb2xkcGFzcyA9IGFyZ3ZbKythcmddOwogICAgICAgIG5ld3Bhc3MgPSBhcmd2WysrYXJnXTsKICAgICAgICBwYXNzd2RfdXNlciA9IGFyZ3ZbKythcmddOwoKICAgICAgICBpZiAoZG9wcml2a2V5ID09IDAgJiYgZG9hdXRoa2V5ID09IDApCiAgICAgICAgICAgIGRvcHJpdmtleSA9IGRvYXV0aGtleSA9IDE7CgogICAgICAgIGlmIChuZXdwYXNzID09IE5VTEwgfHwgc3RybGVuKG5ld3Bhc3MpIDwgVVNNX0xFTkdUSF9QX01JTikgewogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAiTmV3IHBhc3NwaHJhc2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gJWQgY2hhcmFjdGVycyBpbiBsZW5ndGguXG4iLAogICAgICAgICAgICAgICAgICAgIFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgaWYgKG9sZHBhc3MgPT0gTlVMTCB8fCBzdHJsZW4ob2xkcGFzcykgPCBVU01fTEVOR1RIX1BfTUlOKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICJPbGQgcGFzc3BocmFzZSBtdXN0IGJlIGdyZWF0ZXIgdGhhbiAlZCBjaGFyYWN0ZXJzIGluIGxlbmd0aC5cbiIsCiAgICAgICAgICAgICAgICAgICAgVVNNX0xFTkdUSF9QX01JTik7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICAvKiAKICAgICAgICAgKiBDaGFuZ2UgdGhlIHVzZXIgc3VwcGxpZWQgb24gY29tbWFuZCBsaW5lLgogICAgICAgICAqLwogICAgICAgIGlmICgocGFzc3dkX3VzZXIgIT0gTlVMTCkgJiYgKHN0cmxlbihwYXNzd2RfdXNlcikgPiAwKSkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IHBhc3N3ZF91c2VyOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFVzZSBvd24ga2V5IG9iamVjdCBpZiBubyB1c2VyIHdhcyBzdXBwbGllZC4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGF1dGhLZXlDaGFuZ2UgPSBvd25BdXRoS2V5T2lkOwogICAgICAgICAgICBwcml2S2V5Q2hhbmdlID0gb3duUHJpdktleU9pZDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBhIHNlY3VyaXR5TmFtZT8gIElmIG5vdCwgY29weSB0aGUgZGVmYXVsdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eU5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IAoJICAgICAgc3RyZHVwKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgIE5FVFNOTVBfRFNfTElCX1NFQ05BTUUpKTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogdGhlIG9sZCBLdSBpcyBpbiB0aGUgc2Vzc2lvbiwgYnV0IHdlIG5lZWQgdGhlIG5ldyBvbmUgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8gPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBnZXQgLmNvbmYgc2V0IGRlZmF1bHQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjb25zdCBvaWQgICAgICAqZGVmID0KICAgICAgICAgICAgICAgIGdldF9kZWZhdWx0X2F1dGh0eXBlKCZzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuKTsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9CiAgICAgICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChkZWYsIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4pOwogICAgICAgIH0KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGFzc3VtZSBNRDUgCiAgICAgICAgICAgICAqLwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NRDUKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiA9CiAgICAgICAgICAgICAgICBzaXplb2YodXNtSE1BQ01ENUF1dGhQcm90b2NvbCkgLyBzaXplb2Yob2lkKTsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9CiAgICAgICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh1c21ITUFDTUQ1QXV0aFByb3RvY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbik7CiNlbHNlCiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4gPQogICAgICAgICAgICAgICAgc2l6ZW9mKHVzbUhNQUNTSEExQXV0aFByb3RvY29sKSAvIHNpemVvZihvaWQpOwogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvID0KICAgICAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHVzbUhNQUNTSEExQXV0aFByb3RvY29sLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbik7CiNlbmRpZgoKICAgICAgICB9CgoJaWYgKHVzZWxvY2FsaXplZGtleSAmJiAoc3RybmNtcChvbGRwYXNzLCAiMHgiLCAyKSA9PSAwKSkgewoJICAgIC8qCgkgICAgICogdXNlIHRoZSBsb2NhbGl6ZWQga2V5IGZyb20gdGhlIGNvbW1hbmQgbGluZQoJICAgICAqLwoJICAgIHVfY2hhciAqYnVmOwoJICAgIHNpemVfdCBidWZfbGVuID0gU05NUF9NQVhCVUZfU01BTEw7CgkgICAgYnVmID0gKHVfY2hhciAqKSBtYWxsb2MgKGJ1Zl9sZW4gKiBzaXplb2YodV9jaGFyKSk7CgoJICAgIG9sZGt1bF9sZW4gPSAwOyAvKiBpbml0aWFsaXplIHRoZSBvZmZzZXQgKi8KCSAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgodV9jaGFyICoqKSAoJmJ1ZiksICZidWZfbGVuLCAmb2xka3VsX2xlbiwgMCwgb2xkcGFzcykpIHsKCSAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJICAgICAgZnByaW50ZihzdGRlcnIsICJnZW5lcmF0aW5nIHRoZSBvbGQgS3VsIGZyb20gbG9jYWxpemVkIGtleSBmYWlsZWRcbiIpOwoJICAgICAgZXhpdCgxKTsKCSAgICB9CgkgICAgCgkgICAgbWVtY3B5KG9sZGt1bCwgYnVmLCBvbGRrdWxfbGVuKTsKCSAgICBTTk1QX0ZSRUUoYnVmKTsKCX0KCWVsc2UgewoJICAgIC8qCgkgICAgICogdGhlIG9sZCBLdSBpcyBpbiB0aGUgc2Vzc2lvbiwgYnV0IHdlIG5lZWQgdGhlIG5ldyBvbmUgCgkgICAgICovCgkgICAgcnZhbCA9IGdlbmVyYXRlX0t1KHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCgkJCSAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkgICAgICAgKHVfY2hhciAqKSBvbGRwYXNzLCBzdHJsZW4ob2xkcGFzcyksCgkJCSAgICAgICBvbGRLdSwgJm9sZEt1X2xlbik7CgkgICAgCgkgICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CgkgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG9sZCBLdSBmYWlsZWRcbiIpOwoJICAgICAgICBleGl0KDEpOwoJICAgIH0KCgkgICAgLyoKCSAgICAgKiBnZW5lcmF0ZSB0aGUgdHdvIEt1bCdzIAoJICAgICAqLwoJICAgIHJ2YWwgPSBnZW5lcmF0ZV9rdWwoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90bywKCQkJCXNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4sCgkJCQl1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKCQkJCW9sZEt1LCBvbGRLdV9sZW4sIG9sZGt1bCwgJm9sZGt1bF9sZW4pOwoJICAgIAoJICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewoJICAgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCQlmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG9sZCBLdWwgZmFpbGVkXG4iKTsKCQlleGl0KDEpOwoJICAgIH0KCX0KCWlmICh1c2Vsb2NhbGl6ZWRrZXkgJiYgKHN0cm5jbXAobmV3cGFzcywgIjB4IiwgMikgPT0gMCkpIHsKCSAgICAvKgoJICAgICAqIHVzZSB0aGUgbG9jYWxpemVkIGtleSBmcm9tIHRoZSBjb21tYW5kIGxpbmUKCSAgICAgKi8KCSAgICB1X2NoYXIgKmJ1ZjsKCSAgICBzaXplX3QgYnVmX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMOwoJICAgIGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jIChidWZfbGVuICogc2l6ZW9mKHVfY2hhcikpOwoKCSAgICBuZXdrdWxfbGVuID0gMDsgLyogaW5pdGlhbGl6ZSB0aGUgb2Zmc2V0ICovCgkgICAgaWYgKCFzbm1wX2hleF90b19iaW5hcnkoKHVfY2hhciAqKikgKCZidWYpLCAmYnVmX2xlbiwgJm5ld2t1bF9sZW4sIDAsIG5ld3Bhc3MpKSB7CgkgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCSAgICAgIGZwcmludGYoc3RkZXJyLCAiZ2VuZXJhdGluZyB0aGUgbmV3IEt1bCBmcm9tIGxvY2FsaXplZCBrZXkgZmFpbGVkXG4iKTsKCSAgICAgIGV4aXQoMSk7CgkgICAgfQoJICAgIAoJICAgIG1lbWNweShuZXdrdWwsIGJ1ZiwgbmV3a3VsX2xlbik7CgkgICAgU05NUF9GUkVFKGJ1Zik7Cgl9IGVsc2UgewogICAgICAgICAgICBydmFsID0gZ2VuZXJhdGVfS3Uoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIG5ld3Bhc3MsIHN0cmxlbihuZXdwYXNzKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ld0t1LCAmbmV3S3VfbGVuKTsKCiAgICAgICAgICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgc25tcF9wZXJyb3IoYXJndlswXSk7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG5ldyBLdSBmYWlsZWRcbiIpOwogICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgfQoKCSAgICBydmFsID0gZ2VuZXJhdGVfa3VsKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCgkJCQlzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkJdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCgkJCQluZXdLdSwgbmV3S3VfbGVuLCBuZXdrdWwsICZuZXdrdWxfbGVuKTsKCgkgICAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CgkgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwoJCWZwcmludGYoc3RkZXJyLCAiZ2VuZXJhdGluZyB0aGUgbmV3IEt1bCBmYWlsZWRcbiIpOwoJCWV4aXQoMSk7CgkgICAgfQoJfQoKICAgICAgICAvKgogICAgICAgICAqIGZvciBlbmNyeXB0aW9uLCB3ZSBtYXkgbmVlZCB0byB0cnVuY2F0ZSB0aGUga2V5IHRvIHRoZSBwcm9wZXIgbGVuZ3RoCiAgICAgICAgICogc28gd2UgbmVlZCB0d28gY29waWVzLiAgRm9yIHNpbXBsaWNpdHksIHdlIGFsd2F5cyBqdXN0IGNvcHkgZXZlbiBpZgogICAgICAgICAqIHRoZXkncmUgdGhlIHNhbWUgbGVuZ3Rocy4KICAgICAgICAgKi8KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CiAgICAgICAgICAgIGlmICghc2Vzc2lvbi5zZWN1cml0eVByaXZQcm90bykgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5vIGVuY3J5cHRpb24gdHlwZSBzcGVjaWZpZWQsIHdoaWNoIEkgbmVlZCBpbiBvcmRlciB0byBrbm93IHRvIGNoYW5nZSB0aGUga2V5XG4iKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIAojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9ERVMKICAgICAgICAgICAgaWYgKElTVFJBTlNGT1JNKHNlc3Npb24uc2VjdXJpdHlQcml2UHJvdG8sIERFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICAvKiBERVMgdXNlcyBhIDEyOCBiaXQga2V5LCA2NCBiaXRzIG9mIHdoaWNoIGlzIGEgc2FsdCAqLwogICAgICAgICAgICAgICAgb2xka3VscHJpdl9sZW4gPSBuZXdrdWxwcml2X2xlbiA9IDE2OwogICAgICAgICAgICB9CiNlbmRpZgojaWZkZWYgSEFWRV9BRVMKICAgICAgICAgICAgaWYgKElTVFJBTlNGT1JNKHNlc3Npb24uc2VjdXJpdHlQcml2UHJvdG8sIEFFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICBvbGRrdWxwcml2X2xlbiA9IG5ld2t1bHByaXZfbGVuID0gMTY7CiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIG1lbWNweShvbGRrdWxwcml2LCBvbGRrdWwsIG9sZGt1bHByaXZfbGVuKTsKICAgICAgICAgICAgbWVtY3B5KG5ld2t1bHByaXYsIG5ld2t1bCwgbmV3a3VscHJpdl9sZW4pOwogICAgICAgIH0KICAgICAgICAgICAgCgogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlIHRoZSBrZXljaGFuZ2Ugc3RyaW5nIAogICAgICAgICAqLwoJaWYgKGRvYXV0aGtleSkgewoJICBydmFsID0gZW5jb2RlX2tleWNoYW5nZShzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvLAoJCQkJICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkJICBvbGRrdWwsIG9sZGt1bF9sZW4sCgkJCQkgIG5ld2t1bCwgbmV3a3VsX2xlbiwKCQkJCSAga2V5Y2hhbmdlLCAma2V5Y2hhbmdlX2xlbik7CgoJICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKCSAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJlbmNvZGluZyB0aGUga2V5Y2hhbmdlIGZhaWxlZFxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CgkgIH0KCX0KCiAgICAgICAgLyogd2hpY2ggaXMgc2xpZ2h0bHkgZGlmZmVyZW50IGZvciBlbmNyeXB0aW9uIGlmIGxlbmd0aHMgYXJlCiAgICAgICAgICAgZGlmZmVyZW50ICovCglpZiAoZG9wcml2a2V5KSB7CgkgIHJ2YWwgPSBlbmNvZGVfa2V5Y2hhbmdlKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvbGRrdWxwcml2LCBvbGRrdWxwcml2X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdrdWxwcml2LCBuZXdrdWxwcml2X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXljaGFuZ2Vwcml2LCAma2V5Y2hhbmdlcHJpdl9sZW4pOwoKCSAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgImVuY29kaW5nIHRoZSBrZXljaGFuZ2UgZmFpbGVkXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKCSAgfQoJfQoKICAgICAgICAvKgogICAgICAgICAqIGFkZCB0aGUga2V5Y2hhbmdlIHN0cmluZyB0byB0aGUgb3V0Z29pbmcgcGFja2V0IAogICAgICAgICAqLwogICAgICAgIGlmIChkb2F1dGhrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKGF1dGhLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBhdXRoS2V5Q2hhbmdlLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQ1RFVF9TVFIsIGtleWNoYW5nZSwga2V5Y2hhbmdlX2xlbik7CiAgICAgICAgfQogICAgICAgIGlmIChkb3ByaXZrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKHByaXZLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgcHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleWNoYW5nZXByaXYsIGtleWNoYW5nZXByaXZfbGVuKTsKICAgICAgICB9CgogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfQ1JFQVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGNyZWF0ZTogIGNyZWF0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGNyZWF0ZSBVU0VSIFtDTE9ORUZST01dCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gY3JlYXRlXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfQ1JFQVRFOwoKICAgICAgICBpZiAoKythcmcgPCBhcmdjKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNsb25lIHRoZSBuZXcgdXNlciBmcm9tIGFuIGV4aXN0aW5nIHVzZXIKICAgICAgICAgICAgICogICAoYW5kIG1ha2UgdGhlbSBhY3RpdmUgaW1tZWRpYXRlbHkpCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzZXR1cF9vaWQodXNtVXNlclN0YXR1cywgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnLTFdKTsKICAgICAgICAgICAgaWYgKGRvY3JlYXRlYW5kd2FpdCkgewogICAgICAgICAgICAgICAgbG9uZ3ZhciA9IFJTX0NSRUFURUFORFdBSVQ7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBsb25ndmFyID0gUlNfQ1JFQVRFQU5ER087CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwoKICAgICAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKICAgICAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJDbG9uZUZyb20sICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgYXJndlthcmcgLSAxXSk7CiAgICAgICAgICAgIHNldHVwX29pZCh1c21Vc2VyU2VjdXJpdHlOYW1lLCAmbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBhcmd2W2FyZ10pOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyQ2xvbmVGcm9tLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHVzbVVzZXJTZWN1cml0eU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSAqIG5hbWVfbGVuZ3RoMik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY3JlYXRlIGEgbmV3ICh1bmF1dGhlbnRpY2F0ZWQpIHVzZXIgZnJvbSBzY3JhdGNoCiAgICAgICAgICAgICAqIFRoZSBOZXQtU05NUCBhZ2VudCB3b24ndCBhbGxvdyBzdWNoIGEgdXNlciB0byBiZSBtYWRlIGFjdGl2ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmctMV0pOwogICAgICAgICAgICBsb25ndmFyID0gUlNfQ1JFQVRFQU5EV0FJVDsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwogICAgICAgIH0KCiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9DTE9ORUZST01fTkFNRSkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlOiAgY2xvbmUgYSB1c2VyIGZyb20gYW5vdGhlcgogICAgICAgICAqCiAgICAgICAgICogY2xvbmVGcm9tIFVTRVIgRlJPTQogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gb3BlcmF0ZSBvblxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICBjb21tYW5kID0gQ01EX0NMT05FRlJPTTsKICAgICAgICBzZXR1cF9vaWQodXNtVXNlclN0YXR1cywgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKICAgICAgICBsb25ndmFyID0gUlNfQUNUSVZFOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJTdGF0dXMsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKICAgICAgICBzZXR1cF9vaWQodXNtVXNlckNsb25lRnJvbSwgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIllvdSBtdXN0IHNwZWNpZnkgdGhlIHVzZXIgbmFtZSB0byBjbG9uZSBmcm9tXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU2VjdXJpdHlOYW1lLCAmbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyQ2xvbmVGcm9tLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSB1c21Vc2VyU2VjdXJpdHlOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSAqIG5hbWVfbGVuZ3RoMik7CgogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfREVMRVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGRlbGV0ZTogIGRlbGV0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGRlbGV0ZSBVU0VSCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gZGVsZXRlXG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfREVMRVRFOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIGxvbmd2YXIgPSBSU19ERVNUUk9ZOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJTdGF0dXMsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9BQ1RJVkFURV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhY3RpdmF0ZTogIGFjdGl2YXRlIGEgdXNlcgogICAgICAgICAqCiAgICAgICAgICogYWN0aXZhdGUgVVNFUgogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGFjdGl2YXRlXG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfQUNUSVZBVEU7CiAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnXSk7CiAgICAgICAgbG9uZ3ZhciA9IFJTX0FDVElWRTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyU3RhdHVzLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIsICh1X2NoYXIgKikgJiBsb25ndmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfREVBQ1RJVkFURV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkZWFjdGl2YXRlOiAgZGVhY3RpdmF0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGRlYWN0aXZhdGUgVVNFUgogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGRlYWN0aXZhdGVcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgY29tbWFuZCA9IENNRF9ERUFDVElWQVRFOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIGxvbmd2YXIgPSBSU19OT1RJTlNFUlZJQ0U7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxvbmd2YXIpKTsKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9DSEFOR0VLRVlfTkFNRSkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogY2hhbmdlIHRoZSBrZXkgb2YgYSB1c2VyIGlmIERIIGlzIGF2YWlsYWJsZQogICAgICAgICAqLwoKICAgICAgICBjaGFyICpwYXNzd2RfdXNlcjsKICAgICAgICBuZXRzbm1wX3BkdSAqZGhwZHUsICpkaHJlc3BvbnNlID0gTlVMTDsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsICpkaHZhcjsKICAgICAgICAKICAgICAgICBjb21tYW5kID0gQ01EX0NIQU5HRUtFWTsKICAgICAgICBuYW1lX2xlbmd0aCA9IERIX1VTTV9PSURfTEVOOwogICAgICAgIG5hbWVfbGVuZ3RoMiA9IERIX1VTTV9PSURfTEVOOwoKICAgICAgICBwYXNzd2RfdXNlciA9IGFyZ3ZbKythcmddOwoKICAgICAgICBpZiAoZG9wcml2a2V5ID09IDAgJiYgZG9hdXRoa2V5ID09IDApCiAgICAgICAgICAgIGRvcHJpdmtleSA9IGRvYXV0aGtleSA9IDE7CgogICAgICAgIC8qIAogICAgICAgICAqIENoYW5nZSB0aGUgdXNlciBzdXBwbGllZCBvbiBjb21tYW5kIGxpbmUuCiAgICAgICAgICovCiAgICAgICAgaWYgKChwYXNzd2RfdXNlciAhPSBOVUxMKSAmJiAoc3RybGVuKHBhc3N3ZF91c2VyKSA+IDApKSB7CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lID0gcGFzc3dkX3VzZXI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVXNlIG93biBrZXkgb2JqZWN0IGlmIG5vIHVzZXIgd2FzIHN1cHBsaWVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZGhhdXRoS2V5Q2hhbmdlID0gdXNtREhVc2VyT3duQXV0aEtleUNoYW5nZTsKICAgICAgICAgICAgZGhwcml2S2V5Q2hhbmdlID0gdXNtREhVc2VyT3duUHJpdktleUNoYW5nZTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBhIHNlY3VyaXR5TmFtZT8gIElmIG5vdCwgY29weSB0aGUgZGVmYXVsdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eU5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IAoJICAgICAgc3RyZHVwKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgIE5FVFNOTVBfRFNfTElCX1NFQ05BTUUpKTsKICAgICAgICB9CgogICAgICAgIC8qIGZldGNoIHRoZSBuZWVkZWQgZGlmZmllIGhlbG1hbiBwYXJhbWV0ZXJzICovCiAgICAgICAgZGhwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUKTsKICAgICAgICBpZiAoIWRocGR1KSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGNyZWF0ZSBESCByZXF1ZXN0XG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIC8qIGdldCB0aGUgY3VycmVudCBESCBwYXJhbWV0ZXJzICovCiAgICAgICAgc25tcF9hZGRfbnVsbF92YXIoZGhwZHUsIHVzbURIUGFyYW1ldGVycywgdXNtREhQYXJhbWV0ZXJzX2xlbik7CiAgICAgICAgCiAgICAgICAgLyogbWF5YmUgdGhlIGF1dGgga2V5IHB1YmxpYyB2YWx1ZSAqLwogICAgICAgIGlmIChkb2F1dGhrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKGRoYXV0aEtleUNoYW5nZSwgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSk7CiAgICAgICAgICAgIHNubXBfYWRkX251bGxfdmFyKGRocGR1LCBkaGF1dGhLZXlDaGFuZ2UsIG5hbWVfbGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8qIG1heWJlIHRoZSBwcml2IGtleSBwdWJsaWMgdmFsdWUgKi8KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CiAgICAgICAgICAgIHNldHVwX29pZChkaHByaXZLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9hZGRfbnVsbF92YXIoZGhwZHUsIGRocHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyKTsKICAgICAgICB9CgogICAgICAgIC8qIGZldGNoIHRoZSB2YWx1ZXMgKi8KICAgICAgICBzdGF0dXMgPSBzbm1wX3N5bmNoX3Jlc3BvbnNlKHNzLCBkaHBkdSwgJmRocmVzcG9uc2UpOwoKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBFUlJfU1VDQ0VTUyB8fCBkaHJlc3BvbnNlID09IE5VTEwgfHwKICAgICAgICAgICAgZGhyZXNwb25zZS0+ZXJyc3RhdCAhPSBTTk1QX0VSUl9OT0VSUk9SIHx8CiAgICAgICAgICAgIGRocmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSAhPSBBU05fT0NURVRfU1RSKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXB1c20iLCBzcyk7CiAgICAgICAgICAgIGlmIChkaHJlc3BvbnNlICYmIGRocmVzcG9uc2UtPnZhcmlhYmxlcyAmJgogICAgICAgICAgICAgICAgZGhyZXNwb25zZS0+dmFyaWFibGVzLT50eXBlICE9IEFTTl9PQ1RFVF9TVFIpIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGRpZmZpZS1oZWxtYW4gZXhjaGFuZ2UgZnJvbSB0aGUgYWdlbnRcbiIpOwogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIChtYXliZSBpdCBkb2Vzbid0IHN1cHBvcnQgdGhlIFNOTVAtVVNNLURILU9CSkVDVFMtTUlCIE1JQilcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGV4aXR2YWwgPSAxOwogICAgICAgICAgICBnb3RvIGJlZ29uZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZGh2YXIgPSBkaHJlc3BvbnNlLT52YXJpYWJsZXM7CiAgICAgICAgdmFycyA9IGRodmFyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIC8qIGNvbXBsZXRlIHRoZSBESCBlcXVhdGlvbiAmIHByaW50IHJlc3VsdGluZyBrZXlzICovCiAgICAgICAgaWYgKGRvYXV0aGtleSkgewogICAgICAgICAgICBpZiAoZ2V0X1VTTV9ESF9rZXkodmFycywgZGh2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY19nZXRfcHJvcGVybGVuZ3RoKHNzLT5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MtPnNlY3VyaXR5QXV0aFByb3RvTGVuKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdSwgImF1dGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGhhdXRoS2V5Q2hhbmdlLCBuYW1lX2xlbmd0aCkgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgZ290byBiZWdvbmU7CiAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CgkgICAgc2l6ZV90IGRocHJpdktleUxlbiA9IDA7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX0RFUwoJICAgIGlmIChJU1RSQU5TRk9STShzcy0+c2VjdXJpdHlQcml2UHJvdG8sIERFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICAvKiBERVMgdXNlcyBhIDEyOCBiaXQga2V5LCA2NCBiaXRzIG9mIHdoaWNoIGlzIGEgc2FsdCAqLwoJICAgICAgICBkaHByaXZLZXlMZW4gPSAxNjsKCSAgICB9CiNlbmRpZgojaWZkZWYgSEFWRV9BRVMKCSAgICBpZiAoSVNUUkFOU0ZPUk0oc3MtPnNlY3VyaXR5UHJpdlByb3RvLCBBRVNQcml2KSkgewoJICAgICAgICBkaHByaXZLZXlMZW4gPSAxNjsKCSAgICB9CiNlbmRpZgogICAgICAgICAgICBpZiAoZ2V0X1VTTV9ESF9rZXkodmFycywgZGh2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaHByaXZLZXlMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUsICJwcml2IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRocHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyKQogICAgICAgICAgICAgICAgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgZ290byBiZWdvbmU7CiAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0KICAgICAgICAvKiBzbm1wX2ZyZWVfcGR1KGRocmVzcG9uc2UpOyAqLyAvKiBwYXJ0cyBzdGlsbCBpbiB1c2Ugc29tZXdoZXJlICovCiNlbmRpZiAvKiBIQVZFX09QRU5TU0xfREhfSCAmJiBIQVZFX0xJQkNSWVBUTyAqLwogICAgfSBlbHNlIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gY29tbWFuZFxuIik7CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIC8qCiAgICAgKiBhZGQgdXNtVXNlclB1YmxpYyBpZiBzcGVjaWZpZWQgKHZpYSAtQ3ApCiAgICAgKi8KICAgIGlmICh1c21Vc2VyUHVibGljX3ZhbCkgewogICAgICAgIG5hbWVfbGVuZ3RoID0gVVNNX09JRF9MRU47CglzZXR1cF9vaWQodXNtVXNlclB1YmxpYywgJm5hbWVfbGVuZ3RoLAoJCSAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCgkJICBzZXNzaW9uLnNlY3VyaXR5TmFtZSk7Cglzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyUHVibGljLCBuYW1lX2xlbmd0aCwKCQkJICAgICAgQVNOX09DVEVUX1NUUiwgdXNtVXNlclB1YmxpY192YWwsIAoJCQkgICAgICBzdHJsZW4odXNtVXNlclB1YmxpY192YWwpKTsJICAKICAgIH0KCiAgICAvKgogICAgICogZG8gdGhlIHJlcXVlc3QgCiAgICAgKi8KICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgIGlmIChzdGF0dXMgPT0gU1RBVF9TVUNDRVNTKSB7CiAgICAgICAgaWYgKHJlc3BvbnNlKSB7CiAgICAgICAgICAgIGlmIChyZXNwb25zZS0+ZXJyc3RhdCA9PSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgIiVzXG4iLCBzdWNjZXNzTm90ZXNbY29tbWFuZCAtIDFdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiRXJyb3IgaW4gcGFja2V0LlxuUmVhc29uOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9lcnJzdHJpbmcocmVzcG9uc2UtPmVycnN0YXQpKTsKICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS0+ZXJyaW5kZXggIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICBjb3VudDsKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnM7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgb2JqZWN0OiAiKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGNvdW50ID0gMSwgdmFycyA9IHJlc3BvbnNlLT52YXJpYWJsZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICB2YXJzICYmIGNvdW50ICE9IHJlc3BvbnNlLT5lcnJpbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlLCBjb3VudCsrKQogICAgICAgICAgICAgICAgICAgICAgICAvKkVNUFRZKi87CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhcnMpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludF9vYmppZChzdGRlcnIsIHZhcnMtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJzLT5uYW1lX2xlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZXhpdHZhbCA9IDI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PSBTVEFUX1RJTUVPVVQpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlRpbWVvdXQ6IE5vIFJlc3BvbnNlIGZyb20gJXNcbiIsCiAgICAgICAgICAgICAgICBzZXNzaW9uLnBlZXJuYW1lKTsKICAgICAgICBleGl0dmFsID0gMTsKICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvKiBzdGF0dXMgPT0gU1RBVF9FUlJPUiAqLwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBzZXQiLCBzcyk7CiAgICAgICAgZXhpdHZhbCA9IDE7CiAgICB9CgojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKICBiZWdvbmU6CiNlbmRpZiAvKiBIQVZFX09QRU5TU0xfREhfSCAmJiBIQVZFX0xJQkNSWVBUTyAqLwogICAgaWYgKHJlc3BvbnNlKQogICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgc25tcF9jbG9zZShzcyk7CiAgICBTT0NLX0NMRUFOVVA7CiAgICByZXR1cm4gZXhpdHZhbDsKfQo=