LyoKICogc25tcHVzbS5jIC0gc2VuZCBzbm1wIFNFVCByZXF1ZXN0cyB0byBhIG5ldHdvcmsgZW50aXR5IHRvIGNoYW5nZSB0aGUKICogICAgICAgICAgICAgdXNtIHVzZXIgZGF0YWJhc2UKICoKICogWFhYIGdldCBlbmdpbmVJRCBkeW5hbWljYWxseS4KICogWFhYIHJlYWQgcGFzc3dvcmRzIGZyb20gcHJvbXB0cwogKiBYWFggY3VzdG9taXplIHJlc3BvbnNlcyB3aXRoIHVzZXIgbmFtZXMsIGV0Yy4KICovCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9VTklTVERfSAojaW5jbHVkZSA8dW5pc3RkLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpZiBIQVZFX05FVElORVRfSU5fSAojaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgojZW5kaWYKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaWZkZWYgV0lOMzIKIyAgaW5jbHVkZSA8c3lzL3RpbWViLmg+CiMgZWxzZQojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVuZGlmCiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9TWVNfU0VMRUNUX0gKI2luY2x1ZGUgPHN5cy9zZWxlY3QuaD4KI2VuZGlmCiNpZiBIQVZFX1dJTlNPQ0tfSAojaW5jbHVkZSA8d2luc29jay5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCgojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKI2luY2x1ZGUgPG9wZW5zc2wvZGguaD4KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KCmludCAgICAgICAgICAgICBtYWluKGludCwgY2hhciAqKik7CgojZGVmaW5lIENNRF9QQVNTV0RfTkFNRSAgICAicGFzc3dkIgojZGVmaW5lIENNRF9QQVNTV0QgICAgICAgICAxCiNkZWZpbmUgQ01EX0NSRUFURV9OQU1FICAgICJjcmVhdGUiCiNkZWZpbmUgQ01EX0NSRUFURSAgICAgICAgIDIKI2RlZmluZSBDTURfREVMRVRFX05BTUUgICAgImRlbGV0ZSIKI2RlZmluZSBDTURfREVMRVRFICAgICAgICAgMwojZGVmaW5lIENNRF9DTE9ORUZST01fTkFNRSAiY2xvbmVGcm9tIgojZGVmaW5lIENNRF9DTE9ORUZST00gICAgICA0CiNkZWZpbmUgQ01EX0FDVElWQVRFX05BTUUgICJhY3RpdmF0ZSIKI2RlZmluZSBDTURfQUNUSVZBVEUgICAgICAgNQojZGVmaW5lIENNRF9ERUFDVElWQVRFX05BTUUgImRlYWN0aXZhdGUiCiNkZWZpbmUgQ01EX0RFQUNUSVZBVEUgICAgIDYKI2RlZmluZSBDTURfQ0hBTkdFS0VZX05BTUUgICJjaGFuZ2VrZXkiCiNkZWZpbmUgQ01EX0NIQU5HRUtFWSAgICAgIDcKCiNkZWZpbmUgQ01EX05VTSAgICA3CgpzdGF0aWMgY29uc3QgY2hhciAqc3VjY2Vzc05vdGVzW0NNRF9OVU1dID0gewogICAgIlNOTVB2MyBLZXkocykgc3VjY2Vzc2Z1bGx5IGNoYW5nZWQuIiwKICAgICJVc2VyIHN1Y2Nlc3NmdWxseSBjcmVhdGVkLiIsCiAgICAiVXNlciBzdWNjZXNzZnVsbHkgZGVsZXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGNsb25lZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGFjdGl2YXRlZC4iLAogICAgIlVzZXIgc3VjY2Vzc2Z1bGx5IGRlYWN0aXZhdGVkLiIsCiAgICAiU05NUHYzIEtleShzKSBzdWNjZXNzZnVsbHkgY2hhbmdlZC4iCn07CgojZGVmaW5lICAgICAgICAgICAgICAgICAgIFVTTV9PSURfTEVOICAgIDEyCiNkZWZpbmUgICAgICAgICAgICAgICAgREhfVVNNX09JRF9MRU4gICAgMTEKCnN0YXRpYyBvaWQKCmF1dGhLZXlPaWRbTUFYX09JRF9MRU5dID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgNiB9LApvd25BdXRoS2V5T2lkW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgN30sCnByaXZLZXlPaWRbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCA5fSwKb3duUHJpdktleU9pZFtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDEwfSwKdXNtVXNlckNsb25lRnJvbVtNQVhfT0lEX0xFTl0gPSB7MSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDIsIDIsIDEsIDR9LAp1c21Vc2VyU2VjdXJpdHlOYW1lW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMiwgMiwgMSwgM30sCnVzbVVzZXJQdWJsaWNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxMX0sCnVzbVVzZXJTdGF0dXNbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAyLCAyLCAxLCAxM30sCi8qIGRpZmZpZSBoZWxtYW4gY2hhbmdlIGtleSBvYmplY3RzICovCnVzbURIVXNlckF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMSB9LAp1c21ESFVzZXJQcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDMgfSwKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCnVzbURIVXNlck93bkF1dGhLZXlDaGFuZ2VbTUFYX09JRF9MRU5dID0gezEsIDMsIDYsIDEsIDMsIDEwMSwgMSwgMSwgMiwgMSwgMiB9LAp1c21ESFVzZXJPd25Qcml2S2V5Q2hhbmdlW01BWF9PSURfTEVOXSA9IHsxLCAzLCA2LCAxLCAzLCAxMDEsIDEsIDEsIDIsIDEsIDQgfSwKI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICYmIEhBVkVfTElCQ1JZUFRPICovCnVzbURIUGFyYW1ldGVyc1tdID0geyAxLDMsNiwxLDMsMTAxLDEsMSwxLDAgfQo7CnNpemVfdCB1c21ESFBhcmFtZXRlcnNfbGVuID0gT0lEX0xFTkdUSCh1c21ESFBhcmFtZXRlcnMpOwoKc3RhdGljCm9pZCAgICAgICAgICAgICphdXRoS2V5Q2hhbmdlID0gYXV0aEtleU9pZCwgKnByaXZLZXlDaGFuZ2UgPSBwcml2S2V5T2lkOwpvaWQgICAgICAgICAgICAqZGhhdXRoS2V5Q2hhbmdlID0gdXNtREhVc2VyQXV0aEtleUNoYW5nZSwKICAgICAgICAgICAgICAgKmRocHJpdktleUNoYW5nZSA9IHVzbURIVXNlclByaXZLZXlDaGFuZ2U7CmludCAgICAgICAgICAgICBkb2F1dGhrZXkgPSAwLCBkb3ByaXZrZXkgPSAwLCB1c2Vsb2NhbGl6ZWRrZXkgPSAwOwpzaXplX3QgICAgICAgICAgdXNtVXNlckVuZ2luZUlETGVuID0gMDsKdV9jaGFyICAgICAgICAgKnVzbVVzZXJFbmdpbmVJRCA9IE5VTEw7CmNoYXIgICAgICAgICAgICp1c21Vc2VyUHVibGljX3ZhbCA9IE5VTEw7CgoKdm9pZAp1c2FnZSh2b2lkKQp7CiAgICBmcHJpbnRmKHN0ZGVyciwgIlVzYWdlOiBzbm1wdXNtICIpOwogICAgc25tcF9wYXJzZV9hcmdzX3VzYWdlKHN0ZGVycik7CiAgICBmcHJpbnRmKHN0ZGVyciwgIiBDT01NQU5EXG5cbiIpOwogICAgc25tcF9wYXJzZV9hcmdzX2Rlc2NyaXB0aW9ucyhzdGRlcnIpOwogICAgZnByaW50ZihzdGRlcnIsICJcbnNubXB1c20gY29tbWFuZHM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiICBbb3B0aW9uc10gY3JlYXRlICAgICBVU0VSIFtDTE9ORUZST00tVVNFUl1cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBkZWxldGUgICAgIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBjbG9uZUZyb20gIFVTRVIgQ0xPTkVGUk9NLVVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBhY3RpdmF0ZSAgIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBkZWFjdGl2YXRlIFVTRVJcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICIgIFtvcHRpb25zXSBbLUNhXSBbLUN4XSBjaGFuZ2VrZXkgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAiICBbb3B0aW9uc10gWy1DYV0gWy1DeF0gcGFzc3dkIE9MRC1QQVNTUEhSQVNFIE5FVy1QQVNTUEhSQVNFIFtVU0VSXVxuIik7CiAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgIiAgW29wdGlvbnNdICgtQ2F8LUN4KSAtQ2sgcGFzc3dkIE9MRC1LRVktT1ItUEFTU1BIUkFTRSBORVctS0VZLU9SLVBBU1NQSFJBU0UgW1VTRVJdXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXG5zbm1wdXNtIG9wdGlvbnM6XG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ0UgRU5HSU5FLUlEXHRTZXQgdXNtVXNlckVuZ2luZUlEIChlLmcuIDgwMDAwMDAyMDEwOTg0MDMwMSkuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3AgU1RSSU5HXHRTZXQgdXNtVXNlclB1YmxpYyB2YWx1ZSB0byBTVFJJTkcuXG4iKTsKICAgIGZwcmludGYoc3RkZXJyLCAiXHQtQ3hcdFx0Q2hhbmdlIHRoZSBwcml2YWN5IGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1DYVx0XHRDaGFuZ2UgdGhlIGF1dGhlbnRpY2F0aW9uIGtleS5cbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdC1Da1x0XHRBbGxvd3MgdG8gdXNlIGxvY2FsaXplZCBrZXkgKG11c3Qgc3RhcnQgd2l0aCAweClcbiIpOwogICAgZnByaW50ZihzdGRlcnIsICJcdFx0XHRpbnN0ZWFkIG9mIHBhc3NwaHJhc2UuXG4iKTsKfQoKLyoKICogc2V0dXBfb2lkIGFwcGVuZHMgdG8gdGhlIG9pZCB0aGUgaW5kZXggZm9yIHRoZSBlbmdpbmVpZC91c2VyIAogKi8Kdm9pZApzZXR1cF9vaWQob2lkICogaXQsIHNpemVfdCAqIGxlbiwgdV9jaGFyICogaWQsIHNpemVfdCBpZGxlbiwKICAgICAgICAgIGNvbnN0IGNoYXIgKnVzZXIpCnsKICAgIGludCAgICAgICAgICAgICBpLCBpdEluZGV4ID0gKmxlbjsKCiAgICAqbGVuID0gaXRJbmRleCArIDEgKyBpZGxlbiArIDEgKyBzdHJsZW4odXNlcik7CgogICAgaXRbaXRJbmRleCsrXSA9IGlkbGVuOwogICAgZm9yIChpID0gMDsgaSA8IChpbnQpIGlkbGVuOyBpKyspIHsKICAgICAgICBpdFtpdEluZGV4KytdID0gaWRbaV07CiAgICB9CgogICAgaXRbaXRJbmRleCsrXSA9IHN0cmxlbih1c2VyKTsKICAgIGZvciAoaSA9IDA7IGkgPCAoaW50KSBzdHJsZW4odXNlcik7IGkrKykgewogICAgICAgIGl0W2l0SW5kZXgrK10gPSB1c2VyW2ldOwogICAgfQoKI2lmZGVmIE5FVFNOTVBfRU5BQkxFX1RFU1RJTkdfQ09ERQogICAgZnByaW50ZihzdGRvdXQsICJzZXR1cF9vaWQ6ICIpOyAgCiAgICBmcHJpbnRfb2JqaWQoc3Rkb3V0LCBpdCwgKmxlbik7ICAKICAgIGZwcmludGYoc3Rkb3V0LCAiXG4iKTsgIAojZW5kaWYKfQoKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCmludApnZXRfVVNNX0RIX2tleShuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqZGh2YXIsCiAgICAgICAgICAgICAgIHNpemVfdCBvdXRrZXlfbGVuLAogICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LCBjb25zdCBjaGFyICprZXluYW1lLAogICAgICAgICAgICAgICBvaWQgKmtleW9pZCwgc2l6ZV90IGtleW9pZF9sZW4pIHsKICAgIHVfY2hhciAqZGhrZXljaGFuZ2U7CiAgICBESCAqZGg7CiAgICBCSUdOVU0gKm90aGVyX3B1YjsKICAgIHVfY2hhciAqa2V5OwogICAgc2l6ZV90IGtleV9sZW47CiAgICB1bnNpZ25lZCBjaGFyICpjcDsKICAgICAgICAgICAgCiAgICBkaGtleWNoYW5nZSA9ICh1X2NoYXIgKikgbWFsbG9jKDIgKiB2YXJzLT52YWxfbGVuICogc2l6ZW9mKGNoYXIpKTsKICAgIGlmICghZGhrZXljaGFuZ2UpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgCiAgICBtZW1jcHkoZGhrZXljaGFuZ2UsIHZhcnMtPnZhbC5zdHJpbmcsIHZhcnMtPnZhbF9sZW4pOwoKICAgIGNwID0gZGh2YXItPnZhbC5zdHJpbmc7CiAgICBkaCA9IGQyaV9ESHBhcmFtcyhOVUxMLCAoY29uc3QgdW5zaWduZWQgY2hhciAqKikgJmNwLAogICAgICAgICAgICAgICAgICAgICAgZGh2YXItPnZhbF9sZW4pOwoKICAgIGlmICghZGggfHwgIWRoLT5nIHx8ICFkaC0+cCkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIERIX2dlbmVyYXRlX2tleShkaCk7CiAgICBpZiAoIWRoLT5wdWJfa2V5KSB7CiAgICAgICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CiAgICAgICAgICAgIAogICAgaWYgKHZhcnMtPnZhbF9sZW4gIT0gQk5fbnVtX2J5dGVzKGRoLT5wdWJfa2V5KSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgZnByaW50ZihzdGRlcnIsImluY29ycmVjdCBkaWZmaWUtaGVsbWFuIGxlbmd0aHMgKCVsdSAhPSAlZClcbiIsCiAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZyl2YXJzLT52YWxfbGVuLCBCTl9udW1fYnl0ZXMoZGgtPnB1Yl9rZXkpKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgQk5fYm4yYmluKGRoLT5wdWJfa2V5LCBkaGtleWNoYW5nZSArIHZhcnMtPnZhbF9sZW4pOwoKICAgIGtleV9sZW4gPSBESF9zaXplKGRoKTsKICAgIGlmICgha2V5X2xlbikgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQogICAga2V5ID0gKHVfY2hhciAqKSBtYWxsb2Moa2V5X2xlbiAqIHNpemVvZih1X2NoYXIpKTsKCiAgICBpZiAoIWtleSkgewogICAgICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgfQoKICAgIG90aGVyX3B1YiA9IEJOX2JpbjJibih2YXJzLT52YWwuc3RyaW5nLCB2YXJzLT52YWxfbGVuLCBOVUxMKTsKICAgIGlmICghb3RoZXJfcHViKSB7CiAgICAgICAgU05NUF9GUkVFKGRoa2V5Y2hhbmdlKTsKICAgICAgICBTTk1QX0ZSRUUoa2V5KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICB9CgogICAgaWYgKERIX2NvbXB1dGVfa2V5KGtleSwgb3RoZXJfcHViLCBkaCkpIHsKICAgICAgICB1X2NoYXIgKmtwOwoKICAgICAgICBwcmludGYoIm5ldyAlcyBrZXk6IDB4Iiwga2V5bmFtZSk7CiAgICAgICAgZm9yKGtwID0ga2V5ICsga2V5X2xlbiAtIG91dGtleV9sZW47CiAgICAgICAgICAgIGtwIC0ga2V5IDwga2V5X2xlbjsgIGtwKyspIHsKICAgICAgICAgICAgcHJpbnRmKCIlMDJ4IiwgKHVuc2lnbmVkIGNoYXIpICprcCk7CiAgICAgICAgfQogICAgICAgIHByaW50ZigiXG4iKTsKICAgIH0KCiAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBrZXlvaWQsIGtleW9pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiwgZGhrZXljaGFuZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgMiAqIHZhcnMtPnZhbF9sZW4pOwoKICAgIFNOTVBfRlJFRShkaGtleWNoYW5nZSk7CiAgICBTTk1QX0ZSRUUob3RoZXJfcHViKTsKICAgIFNOTVBfRlJFRShrZXkpOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KI2VuZGlmIC8qIEhBVkVfT1BFTlNTTF9ESF9IICovCgpzdGF0aWMgdm9pZApvcHRQcm9jKGludCBhcmdjLCBjaGFyICpjb25zdCAqYXJndiwgaW50IG9wdCkKewogICAgc3dpdGNoIChvcHQpIHsKICAgIGNhc2UgJ0MnOgogICAgICAgIHdoaWxlICgqb3B0YXJnKSB7CiAgICAgICAgICAgIHN3aXRjaCAoKm9wdGFyZysrKSB7CiAgICAgICAgICAgIGNhc2UgJ2EnOgogICAgICAgICAgICAgICAgZG9hdXRoa2V5ID0gMTsKICAgICAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICAgICAgY2FzZSAneCc6CiAgICAgICAgICAgICAgICBkb3ByaXZrZXkgPSAxOwogICAgICAgICAgICAgICAgYnJlYWs7CgoJICAgIGNhc2UgJ2snOgoJICAgICAgICB1c2Vsb2NhbGl6ZWRrZXkgPSAxOwoJCWJyZWFrOwoKCSAgICBjYXNlICdwJzoKICAgICAgICAgICAgICAgIGlmIChvcHRpbmQgPCBhcmdjKSB7CgkJICAgIHVzbVVzZXJQdWJsaWNfdmFsID0gIGFyZ3Zbb3B0aW5kXTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJCYWQgLUNwIG9wdGlvbjogbm8gYXJndW1lbnQgZ2l2ZW5cbiIpOwogICAgICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBvcHRpbmQrKzsKICAgICAgICAgICAgICAgIGJyZWFrOwoKCSAgICBjYXNlICdFJzogewoJICAgICAgICBzaXplX3QgZWJ1Zl9sZW4gPSBNQVhfRU5HSU5FSURfTEVOR1RIOwogICAgICAgICAgICAgICAgdV9jaGFyICplYnVmOwogICAgICAgICAgICAgICAgaWYgKG9wdGluZCA8IGFyZ2MpIHsKICAgICAgICAgICAgICAgICAgICBpZiAoYXJndltvcHRpbmRdKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGVidWYgPSAodV9jaGFyICopbWFsbG9jKGVidWZfbGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVidWYgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibWFsbG9jIGZhaWx1cmUgcHJvY2Vzc2luZyAtQ0Ugb3B0aW9uLlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJICAgICAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgmZWJ1ZiwgJmVidWZfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdXNtVXNlckVuZ2luZUlETGVuLCAxLCBhcmd2W29wdGluZF0pKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJCYWQgdXNtVXNlckVuZ2luZUlEIHZhbHVlIGFmdGVyIC1DRSBvcHRpb24uXG4iKTsKCQkgICAgICAgICAgICBmcmVlKGVidWYpOwoJCSAgICAgICAgICAgIGV4aXQoMSk7CgkJICAgICAgICB9CgkJICAgICAgICB1c21Vc2VyRW5naW5lSUQgPSBlYnVmOwoJCSAgICAgICAgREVCVUdNU0dUTCgoInNubXB1c20iLCAidXNtVXNlckVuZ2luZUlEIHNldCB0bzogIikpOwoJCSAgICAgICAgREVCVUdNU0dIRVgoKCJzbm1wdXNtIiwgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4pKTsKCQkgICAgICAgIERFQlVHTVNHKCgic25tcHVzbSIsICJcbiIpKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIkJhZCAtQ0Ugb3B0aW9uOiBubyBhcmd1bWVudCBnaXZlblxuIik7CiAgICAgICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9wdGluZCsrOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gZmxhZyBwYXNzZWQgdG8gLUM6ICVjXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBvcHRhcmdbLTFdKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CiAgICB9Cn0KCmludAptYWluKGludCBhcmdjLCBjaGFyICphcmd2W10pCnsKICAgIG5ldHNubXBfc2Vzc2lvbiBzZXNzaW9uLCAqc3M7CiAgICBuZXRzbm1wX3BkdSAgICAqcGR1ID0gTlVMTCwgKnJlc3BvbnNlID0gTlVMTDsKCiAgICBpbnQgICAgICAgICAgICAgYXJnOwogICAgc2l6ZV90ICAgICAgICAgIG5hbWVfbGVuZ3RoID0gVVNNX09JRF9MRU47CiAgICBzaXplX3QgICAgICAgICAgbmFtZV9sZW5ndGgyID0gVVNNX09JRF9MRU47CiAgICBpbnQgICAgICAgICAgICAgc3RhdHVzOwogICAgaW50ICAgICAgICAgICAgIGV4aXR2YWwgPSAwOwogICAgaW50ICAgICAgICAgICAgIHJ2YWw7CiAgICBpbnQgICAgICAgICAgICAgY29tbWFuZCA9IDA7CiAgICBsb25nICAgICAgICAgICAgbG9uZ3ZhcjsKCiAgICBzaXplX3QgICAgICAgICAgb2xkS3VfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAgbmV3S3VfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAgb2xka3VsX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIG9sZGt1bHByaXZfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAgbmV3a3VscHJpdl9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTCwKICAgICAgICBuZXdrdWxfbGVuID0gU05NUF9NQVhCVUZfU01BTEwsCiAgICAgICAga2V5Y2hhbmdlX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMLAogICAgICAgIGtleWNoYW5nZXByaXZfbGVuID0gU05NUF9NQVhCVUZfU01BTEw7CgogICAgY2hhciAgICAgICAgICAgKm5ld3Bhc3MgPSBOVUxMLCAqb2xkcGFzcyA9IE5VTEw7CiAgICB1X2NoYXIgICAgICAgICAgb2xkS3VbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIG5ld0t1W1NOTVBfTUFYQlVGX1NNQUxMXSwKICAgICAgICBvbGRrdWxbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIG9sZGt1bHByaXZbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIG5ld2t1bHByaXZbU05NUF9NQVhCVUZfU01BTExdLAogICAgICAgIG5ld2t1bFtTTk1QX01BWEJVRl9TTUFMTF0sIGtleWNoYW5nZVtTTk1QX01BWEJVRl9TTUFMTF0sCiAgICAgICAga2V5Y2hhbmdlcHJpdltTTk1QX01BWEJVRl9TTUFMTF07CgogICAgYXV0aEtleUNoYW5nZSA9IGF1dGhLZXlPaWQ7CiAgICBwcml2S2V5Q2hhbmdlID0gcHJpdktleU9pZDsKCiAgICAvKgogICAgICogZ2V0IHRoZSBjb21tb24gY29tbWFuZCBsaW5lIGFyZ3VtZW50cyAKICAgICAqLwogICAgc3dpdGNoIChhcmcgPSBzbm1wX3BhcnNlX2FyZ3MoYXJnYywgYXJndiwgJnNlc3Npb24sICJDOiIsIG9wdFByb2MpKSB7CiAgICBjYXNlIC0yOgogICAgICAgIGV4aXQoMCk7CiAgICBjYXNlIC0xOgogICAgICAgIHVzYWdlKCk7CiAgICAgICAgZXhpdCgxKTsKICAgIGRlZmF1bHQ6CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGFyZyA+PSBhcmdjKSB7CiAgICAgICAgZnByaW50ZihzdGRlcnIsICJQbGVhc2Ugc3BlY2lmeSBhbiBvcGVyYXRpb24gdG8gcGVyZm9ybS5cbiIpOwogICAgICAgIHVzYWdlKCk7CiAgICAgICAgZXhpdCgxKTsKICAgIH0KCiAgICBTT0NLX1NUQVJUVVA7CgogICAgLyoKICAgICAqIG9wZW4gYW4gU05NUCBzZXNzaW9uIAogICAgICovCiAgICAvKgogICAgICogTm90ZTogIHRoaXMgbmVlZHMgdG8gb2J0YWluIHRoZSBlbmdpbmVJRCB1c2VkIGJlbG93IAogICAgICovCiAgICBzZXNzaW9uLmZsYWdzICY9IH5TTk1QX0ZMQUdTX0RPTlRfUFJPQkU7CiAgICBzcyA9IHNubXBfb3Blbigmc2Vzc2lvbik7CiAgICBpZiAoc3MgPT0gTlVMTCkgewogICAgICAgIC8qCiAgICAgICAgICogZGlhZ25vc2Ugc25tcF9vcGVuIGVycm9ycyB3aXRoIHRoZSBpbnB1dCBuZXRzbm1wX3Nlc3Npb24gcG9pbnRlciAKICAgICAgICAgKi8KICAgICAgICBzbm1wX3Nlc3NfcGVycm9yKCJzbm1wdXNtIiwgJnNlc3Npb24pOwogICAgICAgIGV4aXQoMSk7CiAgICB9CgogICAgLyoKICAgICAqIHNldCB1c21Vc2VyRW5naW5lSUQgZnJvbSBzcy0+Y29udGV4dEVuZ2luZUlECiAgICAgKiAgIGlmIG5vdCBhbHJlYWR5IHNldCAodmlhIC1DRSkKICAgICAqLwogICAgaWYgKHVzbVVzZXJFbmdpbmVJRCA9PSBOVUxMKSB7CiAgICAgIHVzbVVzZXJFbmdpbmVJRCAgICA9IHNzLT5jb250ZXh0RW5naW5lSUQ7CiAgICAgIHVzbVVzZXJFbmdpbmVJRExlbiA9IHNzLT5jb250ZXh0RW5naW5lSURMZW47CiAgICB9CgogICAgLyoKICAgICAqIGNyZWF0ZSBQRFUgZm9yIFNFVCByZXF1ZXN0IGFuZCBhZGQgb2JqZWN0IG5hbWVzIGFuZCB2YWx1ZXMgdG8gcmVxdWVzdCAKICAgICAqLwogICAgcGR1ID0gc25tcF9wZHVfY3JlYXRlKFNOTVBfTVNHX1NFVCk7CiAgICBpZiAoIXBkdSkgewogICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGNyZWF0ZSByZXF1ZXN0XG4iKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKCiAgICBpZiAoc3RyY21wKGFyZ3ZbYXJnXSwgQ01EX1BBU1NXRF9OQU1FKSA9PSAwKSB7CgogICAgICAgIC8qCiAgICAgICAgICogcGFzc3dkOiBjaGFuZ2UgYSB1c2VycyBwYXNzd29yZC4KICAgICAgICAgKgogICAgICAgICAqIFhYWDogIFVzZXMgdGhlIGF1dGggdHlwZSBvZiB0aGUgY2FsbGluZyB1c2VyLCBhIE1ENSB1c2VyIGNhbid0CiAgICAgICAgICogICAgICAgY2hhbmdlIGEgU0hBIHVzZXIncyBrZXkuCiAgICAgICAgICovCiAgICAgICAgY2hhciAqcGFzc3dkX3VzZXI7CgogICAgICAgIGNvbW1hbmQgPSBDTURfUEFTU1dEOwogICAgICAgIG9sZHBhc3MgPSBhcmd2WysrYXJnXTsKICAgICAgICBuZXdwYXNzID0gYXJndlsrK2FyZ107CiAgICAgICAgcGFzc3dkX3VzZXIgPSBhcmd2WysrYXJnXTsKCiAgICAgICAgaWYgKGRvcHJpdmtleSA9PSAwICYmIGRvYXV0aGtleSA9PSAwKQogICAgICAgICAgICBkb3ByaXZrZXkgPSBkb2F1dGhrZXkgPSAxOwoKICAgICAgICBpZiAobmV3cGFzcyA9PSBOVUxMIHx8IHN0cmxlbihuZXdwYXNzKSA8IFVTTV9MRU5HVEhfUF9NSU4pIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIk5ldyBwYXNzcGhyYXNlIG11c3QgYmUgZ3JlYXRlciB0aGFuICVkIGNoYXJhY3RlcnMgaW4gbGVuZ3RoLlxuIiwKICAgICAgICAgICAgICAgICAgICBVU01fTEVOR1RIX1BfTUlOKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGlmIChvbGRwYXNzID09IE5VTEwgfHwgc3RybGVuKG9sZHBhc3MpIDwgVVNNX0xFTkdUSF9QX01JTikgewogICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKICAgICAgICAgICAgICAgICAgICAiT2xkIHBhc3NwaHJhc2UgbXVzdCBiZSBncmVhdGVyIHRoYW4gJWQgY2hhcmFjdGVycyBpbiBsZW5ndGguXG4iLAogICAgICAgICAgICAgICAgICAgIFVTTV9MRU5HVEhfUF9NSU4pOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgLyogCiAgICAgICAgICogQ2hhbmdlIHRoZSB1c2VyIHN1cHBsaWVkIG9uIGNvbW1hbmQgbGluZS4KICAgICAgICAgKi8KICAgICAgICBpZiAoKHBhc3N3ZF91c2VyICE9IE5VTEwpICYmIChzdHJsZW4ocGFzc3dkX3VzZXIpID4gMCkpIHsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUgPSBwYXNzd2RfdXNlcjsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBVc2Ugb3duIGtleSBvYmplY3QgaWYgbm8gdXNlciB3YXMgc3VwcGxpZWQuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBhdXRoS2V5Q2hhbmdlID0gb3duQXV0aEtleU9pZDsKICAgICAgICAgICAgcHJpdktleUNoYW5nZSA9IG93blByaXZLZXlPaWQ7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGRvIHdlIGhhdmUgYSBzZWN1cml0eU5hbWU/ICBJZiBub3QsIGNvcHkgdGhlIGRlZmF1bHQgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNlc3Npb24uc2VjdXJpdHlOYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eU5hbWUgPSAKCSAgICAgIHN0cmR1cChuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQkgICBORVRTTk1QX0RTX0xJQl9TRUNOQU1FKSk7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIHRoZSBvbGQgS3UgaXMgaW4gdGhlIHNlc3Npb24sIGJ1dCB3ZSBuZWVkIHRoZSBuZXcgb25lIAogICAgICAgICAqLwogICAgICAgIGlmIChzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZ2V0IC5jb25mIHNldCBkZWZhdWx0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgY29uc3Qgb2lkICAgICAgKmRlZiA9CiAgICAgICAgICAgICAgICBnZXRfZGVmYXVsdF9hdXRodHlwZSgmc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbik7CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8gPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQoZGVmLCBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuKTsKICAgICAgICB9CiAgICAgICAgaWYgKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8gPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBhc3N1bWUgTUQ1IAogICAgICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUQ1CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4gPQogICAgICAgICAgICAgICAgc2l6ZW9mKHVzbUhNQUNNRDVBdXRoUHJvdG9jb2wpIC8gc2l6ZW9mKG9pZCk7CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8gPQogICAgICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQodXNtSE1BQ01ENUF1dGhQcm90b2NvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4pOwojZWxzZQogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuID0KICAgICAgICAgICAgICAgIHNpemVvZih1c21ITUFDU0hBMUF1dGhQcm90b2NvbCkgLyBzaXplb2Yob2lkKTsKICAgICAgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90byA9CiAgICAgICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh1c21ITUFDU0hBMUF1dGhQcm90b2NvbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4pOwojZW5kaWYKCiAgICAgICAgfQoKCWlmICh1c2Vsb2NhbGl6ZWRrZXkgJiYgKHN0cm5jbXAob2xkcGFzcywgIjB4IiwgMikgPT0gMCkpIHsKCSAgICAvKgoJICAgICAqIHVzZSB0aGUgbG9jYWxpemVkIGtleSBmcm9tIHRoZSBjb21tYW5kIGxpbmUKCSAgICAgKi8KCSAgICB1X2NoYXIgKmJ1ZjsKCSAgICBzaXplX3QgYnVmX2xlbiA9IFNOTVBfTUFYQlVGX1NNQUxMOwoJICAgIGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jIChidWZfbGVuICogc2l6ZW9mKHVfY2hhcikpOwoKCSAgICBvbGRrdWxfbGVuID0gMDsgLyogaW5pdGlhbGl6ZSB0aGUgb2Zmc2V0ICovCgkgICAgaWYgKCFzbm1wX2hleF90b19iaW5hcnkoKHVfY2hhciAqKikgKCZidWYpLCAmYnVmX2xlbiwgJm9sZGt1bF9sZW4sIDAsIG9sZHBhc3MpKSB7CgkgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCSAgICAgIGZwcmludGYoc3RkZXJyLCAiZ2VuZXJhdGluZyB0aGUgb2xkIEt1bCBmcm9tIGxvY2FsaXplZCBrZXkgZmFpbGVkXG4iKTsKCSAgICAgIGV4aXQoMSk7CgkgICAgfQoJICAgIAoJICAgIG1lbWNweShvbGRrdWwsIGJ1Ziwgb2xka3VsX2xlbik7CgkgICAgU05NUF9GUkVFKGJ1Zik7Cgl9CgllbHNlIHsKCSAgICAvKgoJICAgICAqIHRoZSBvbGQgS3UgaXMgaW4gdGhlIHNlc3Npb24sIGJ1dCB3ZSBuZWVkIHRoZSBuZXcgb25lIAoJICAgICAqLwoJICAgIHJ2YWwgPSBnZW5lcmF0ZV9LdShzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvLAoJCQkgICAgICAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiwKCQkJICAgICAgICh1X2NoYXIgKikgb2xkcGFzcywgc3RybGVuKG9sZHBhc3MpLAoJCQkgICAgICAgb2xkS3UsICZvbGRLdV9sZW4pOwoJICAgIAoJICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewoJICAgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCSAgICAgICAgZnByaW50ZihzdGRlcnIsICJnZW5lcmF0aW5nIHRoZSBvbGQgS3UgZmFpbGVkXG4iKTsKCSAgICAgICAgZXhpdCgxKTsKCSAgICB9CgoJICAgIC8qCgkgICAgICogZ2VuZXJhdGUgdGhlIHR3byBLdWwncyAKCSAgICAgKi8KCSAgICBydmFsID0gZ2VuZXJhdGVfa3VsKHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCgkJCQlzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAoJCQkJdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCgkJCQlvbGRLdSwgb2xkS3VfbGVuLCBvbGRrdWwsICZvbGRrdWxfbGVuKTsKCSAgICAKCSAgICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKCSAgICAgICAgc25tcF9wZXJyb3IoYXJndlswXSk7CgkJZnByaW50ZihzdGRlcnIsICJnZW5lcmF0aW5nIHRoZSBvbGQgS3VsIGZhaWxlZFxuIik7CgkJZXhpdCgxKTsKCSAgICB9Cgl9CglpZiAodXNlbG9jYWxpemVka2V5ICYmIChzdHJuY21wKG5ld3Bhc3MsICIweCIsIDIpID09IDApKSB7CgkgICAgLyoKCSAgICAgKiB1c2UgdGhlIGxvY2FsaXplZCBrZXkgZnJvbSB0aGUgY29tbWFuZCBsaW5lCgkgICAgICovCgkgICAgdV9jaGFyICpidWY7CgkgICAgc2l6ZV90IGJ1Zl9sZW4gPSBTTk1QX01BWEJVRl9TTUFMTDsKCSAgICBidWYgPSAodV9jaGFyICopIG1hbGxvYyAoYnVmX2xlbiAqIHNpemVvZih1X2NoYXIpKTsKCgkgICAgbmV3a3VsX2xlbiA9IDA7IC8qIGluaXRpYWxpemUgdGhlIG9mZnNldCAqLwoJICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCh1X2NoYXIgKiopICgmYnVmKSwgJmJ1Zl9sZW4sICZuZXdrdWxfbGVuLCAwLCBuZXdwYXNzKSkgewoJICAgICAgc25tcF9wZXJyb3IoYXJndlswXSk7CgkgICAgICBmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG5ldyBLdWwgZnJvbSBsb2NhbGl6ZWQga2V5IGZhaWxlZFxuIik7CgkgICAgICBleGl0KDEpOwoJICAgIH0KCSAgICAKCSAgICBtZW1jcHkobmV3a3VsLCBidWYsIG5ld2t1bF9sZW4pOwoJICAgIFNOTVBfRlJFRShidWYpOwoJfSBlbHNlIHsKICAgICAgICAgICAgcnZhbCA9IGdlbmVyYXRlX0t1KHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSBuZXdwYXNzLCBzdHJsZW4obmV3cGFzcyksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXdLdSwgJm5ld0t1X2xlbik7CgogICAgICAgICAgICBpZiAocnZhbCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIHNubXBfcGVycm9yKGFyZ3ZbMF0pOwogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJnZW5lcmF0aW5nIHRoZSBuZXcgS3UgZmFpbGVkXG4iKTsKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIH0KCgkgICAgcnZhbCA9IGdlbmVyYXRlX2t1bChzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvLAoJCQkJc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiwKCQkJCXVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAoJCQkJbmV3S3UsIG5ld0t1X2xlbiwgbmV3a3VsLCAmbmV3a3VsX2xlbik7CgoJICAgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewoJICAgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKCQlmcHJpbnRmKHN0ZGVyciwgImdlbmVyYXRpbmcgdGhlIG5ldyBLdWwgZmFpbGVkXG4iKTsKCQlleGl0KDEpOwoJICAgIH0KCX0KCiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgZW5jcnlwdGlvbiwgd2UgbWF5IG5lZWQgdG8gdHJ1bmNhdGUgdGhlIGtleSB0byB0aGUgcHJvcGVyIGxlbmd0aAogICAgICAgICAqIHNvIHdlIG5lZWQgdHdvIGNvcGllcy4gIEZvciBzaW1wbGljaXR5LCB3ZSBhbHdheXMganVzdCBjb3B5IGV2ZW4gaWYKICAgICAgICAgKiB0aGV5J3JlIHRoZSBzYW1lIGxlbmd0aHMuCiAgICAgICAgICovCiAgICAgICAgaWYgKGRvcHJpdmtleSkgewogICAgICAgICAgICBpZiAoIXNlc3Npb24uc2VjdXJpdHlQcml2UHJvdG8pIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJubyBlbmNyeXB0aW9uIHR5cGUgc3BlY2lmaWVkLCB3aGljaCBJIG5lZWQgaW4gb3JkZXIgdG8ga25vdyB0byBjaGFuZ2UgdGhlIGtleVxuIik7CiAgICAgICAgICAgICAgICBleGl0KDEpOwogICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfREVTCiAgICAgICAgICAgIGlmIChJU1RSQU5TRk9STShzZXNzaW9uLnNlY3VyaXR5UHJpdlByb3RvLCBERVNQcml2KSkgewogICAgICAgICAgICAgICAgLyogREVTIHVzZXMgYSAxMjggYml0IGtleSwgNjQgYml0cyBvZiB3aGljaCBpcyBhIHNhbHQgKi8KICAgICAgICAgICAgICAgIG9sZGt1bHByaXZfbGVuID0gbmV3a3VscHJpdl9sZW4gPSAxNjsKICAgICAgICAgICAgfQojZW5kaWYKI2lmZGVmIEhBVkVfQUVTCiAgICAgICAgICAgIGlmIChJU1RSQU5TRk9STShzZXNzaW9uLnNlY3VyaXR5UHJpdlByb3RvLCBBRVNQcml2KSkgewogICAgICAgICAgICAgICAgb2xka3VscHJpdl9sZW4gPSBuZXdrdWxwcml2X2xlbiA9IDE2OwogICAgICAgICAgICB9CiNlbmRpZgogICAgICAgICAgICBtZW1jcHkob2xka3VscHJpdiwgb2xka3VsLCBvbGRrdWxwcml2X2xlbik7CiAgICAgICAgICAgIG1lbWNweShuZXdrdWxwcml2LCBuZXdrdWwsIG5ld2t1bHByaXZfbGVuKTsKICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvKgogICAgICAgICAqIGNyZWF0ZSB0aGUga2V5Y2hhbmdlIHN0cmluZyAKICAgICAgICAgKi8KCWlmIChkb2F1dGhrZXkpIHsKCSAgcnZhbCA9IGVuY29kZV9rZXljaGFuZ2Uoc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90bywKCQkJCSAgc2Vzc2lvbi5zZWN1cml0eUF1dGhQcm90b0xlbiwKCQkJCSAgb2xka3VsLCBvbGRrdWxfbGVuLAoJCQkJICBuZXdrdWwsIG5ld2t1bF9sZW4sCgkJCQkgIGtleWNoYW5nZSwgJmtleWNoYW5nZV9sZW4pOwoKCSAgaWYgKHJ2YWwgIT0gU05NUEVSUl9TVUNDRVNTKSB7CgkgICAgc25tcF9wZXJyb3IoYXJndlswXSk7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiZW5jb2RpbmcgdGhlIGtleWNoYW5nZSBmYWlsZWRcbiIpOwogICAgICAgICAgICB1c2FnZSgpOwogICAgICAgICAgICBleGl0KDEpOwoJICB9Cgl9CgogICAgICAgIC8qIHdoaWNoIGlzIHNsaWdodGx5IGRpZmZlcmVudCBmb3IgZW5jcnlwdGlvbiBpZiBsZW5ndGhzIGFyZQogICAgICAgICAgIGRpZmZlcmVudCAqLwoJaWYgKGRvcHJpdmtleSkgewoJICBydmFsID0gZW5jb2RlX2tleWNoYW5nZShzZXNzaW9uLnNlY3VyaXR5QXV0aFByb3RvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlBdXRoUHJvdG9MZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xka3VscHJpdiwgb2xka3VscHJpdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV3a3VscHJpdiwgbmV3a3VscHJpdl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5Y2hhbmdlcHJpdiwgJmtleWNoYW5nZXByaXZfbGVuKTsKCgkgIGlmIChydmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICBzbm1wX3BlcnJvcihhcmd2WzBdKTsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJlbmNvZGluZyB0aGUga2V5Y2hhbmdlIGZhaWxlZFxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CgkgIH0KCX0KCiAgICAgICAgLyoKICAgICAgICAgKiBhZGQgdGhlIGtleWNoYW5nZSBzdHJpbmcgdG8gdGhlIG91dGdvaW5nIHBhY2tldCAKICAgICAgICAgKi8KICAgICAgICBpZiAoZG9hdXRoa2V5KSB7CiAgICAgICAgICAgIHNldHVwX29pZChhdXRoS2V5Q2hhbmdlLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgYXV0aEtleUNoYW5nZSwgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLCBrZXljaGFuZ2UsIGtleWNoYW5nZV9sZW4pOwogICAgICAgIH0KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CiAgICAgICAgICAgIHNldHVwX29pZChwcml2S2V5Q2hhbmdlLCAmbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSk7CiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHByaXZLZXlDaGFuZ2UsIG5hbWVfbGVuZ3RoMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXljaGFuZ2Vwcml2LCBrZXljaGFuZ2Vwcml2X2xlbik7CiAgICAgICAgfQoKICAgIH0gZWxzZSBpZiAoc3RyY21wKGFyZ3ZbYXJnXSwgQ01EX0NSRUFURV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBjcmVhdGU6ICBjcmVhdGUgYSB1c2VyCiAgICAgICAgICoKICAgICAgICAgKiBjcmVhdGUgVVNFUiBbQ0xPTkVGUk9NXQogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGNyZWF0ZVxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICBjb21tYW5kID0gQ01EX0NSRUFURTsKCiAgICAgICAgaWYgKCsrYXJnIDwgYXJnYykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBjbG9uZSB0aGUgbmV3IHVzZXIgZnJvbSBhbiBleGlzdGluZyB1c2VyCiAgICAgICAgICAgICAqICAgKGFuZCBtYWtlIHRoZW0gYWN0aXZlIGltbWVkaWF0ZWx5KQogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZy0xXSk7CiAgICAgICAgICAgIGxvbmd2YXIgPSBSU19DUkVBVEVBTkRHTzsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwoKICAgICAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKICAgICAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJDbG9uZUZyb20sICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLAogICAgICAgICAgICAgICAgICAgICAgYXJndlthcmcgLSAxXSk7CiAgICAgICAgICAgIHNldHVwX29pZCh1c21Vc2VyU2VjdXJpdHlOYW1lLCAmbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBhcmd2W2FyZ10pOwogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyQ2xvbmVGcm9tLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHVzbVVzZXJTZWN1cml0eU5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSAqIG5hbWVfbGVuZ3RoMik7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogY3JlYXRlIGEgbmV3ICh1bmF1dGhlbnRpY2F0ZWQpIHVzZXIgZnJvbSBzY3JhdGNoCiAgICAgICAgICAgICAqIFRoZSBOZXQtU05NUCBhZ2VudCB3b24ndCBhbGxvdyBzdWNoIGEgdXNlciB0byBiZSBtYWRlIGFjdGl2ZS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmctMV0pOwogICAgICAgICAgICBsb25ndmFyID0gUlNfQ1JFQVRFQU5EV0FJVDsKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwogICAgICAgIH0KCiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9DTE9ORUZST01fTkFNRSkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogY3JlYXRlOiAgY2xvbmUgYSB1c2VyIGZyb20gYW5vdGhlcgogICAgICAgICAqCiAgICAgICAgICogY2xvbmVGcm9tIFVTRVIgRlJPTQogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gb3BlcmF0ZSBvblxuIik7CiAgICAgICAgICAgIHVzYWdlKCk7CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgfQoKICAgICAgICBjb21tYW5kID0gQ01EX0NMT05FRlJPTTsKICAgICAgICBzZXR1cF9vaWQodXNtVXNlclN0YXR1cywgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKICAgICAgICBsb25ndmFyID0gUlNfQUNUSVZFOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJTdGF0dXMsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICAgICAgbmFtZV9sZW5ndGggPSBVU01fT0lEX0xFTjsKICAgICAgICBzZXR1cF9vaWQodXNtVXNlckNsb25lRnJvbSwgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgIllvdSBtdXN0IHNwZWNpZnkgdGhlIHVzZXIgbmFtZSB0byBjbG9uZSBmcm9tXG4iKTsKICAgICAgICAgICAgdXNhZ2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU2VjdXJpdHlOYW1lLCAmbmFtZV9sZW5ndGgyLAogICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwgYXJndlthcmddKTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyQ2xvbmVGcm9tLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSB1c21Vc2VyU2VjdXJpdHlOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yob2lkKSAqIG5hbWVfbGVuZ3RoMik7CgogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfREVMRVRFX05BTUUpID09IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGRlbGV0ZTogIGRlbGV0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGRlbGV0ZSBVU0VSCiAgICAgICAgICovCiAgICAgICAgaWYgKCsrYXJnID49IGFyZ2MpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJZb3UgbXVzdCBzcGVjaWZ5IHRoZSB1c2VyIG5hbWUgdG8gZGVsZXRlXG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfREVMRVRFOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIGxvbmd2YXIgPSBSU19ERVNUUk9ZOwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIHVzbVVzZXJTdGF0dXMsIG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiwgKHVfY2hhciAqKSAmIGxvbmd2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihsb25ndmFyKSk7CiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9BQ1RJVkFURV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhY3RpdmF0ZTogIGFjdGl2YXRlIGEgdXNlcgogICAgICAgICAqCiAgICAgICAgICogYWN0aXZhdGUgVVNFUgogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGFjdGl2YXRlXG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIGNvbW1hbmQgPSBDTURfQUNUSVZBVEU7CiAgICAgICAgc2V0dXBfb2lkKHVzbVVzZXJTdGF0dXMsICZuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sIGFyZ3ZbYXJnXSk7CiAgICAgICAgbG9uZ3ZhciA9IFJTX0FDVElWRTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyU3RhdHVzLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIsICh1X2NoYXIgKikgJiBsb25ndmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobG9uZ3ZhcikpOwogICAgfSBlbHNlIGlmIChzdHJjbXAoYXJndlthcmddLCBDTURfREVBQ1RJVkFURV9OQU1FKSA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBkZWFjdGl2YXRlOiAgZGVhY3RpdmF0ZSBhIHVzZXIKICAgICAgICAgKgogICAgICAgICAqIGRlYWN0aXZhdGUgVVNFUgogICAgICAgICAqLwogICAgICAgIGlmICgrK2FyZyA+PSBhcmdjKSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiWW91IG11c3Qgc3BlY2lmeSB0aGUgdXNlciBuYW1lIHRvIGRlYWN0aXZhdGVcbiIpOwogICAgICAgICAgICBleGl0KDEpOwogICAgICAgIH0KCiAgICAgICAgY29tbWFuZCA9IENNRF9ERUFDVElWQVRFOwogICAgICAgIHNldHVwX29pZCh1c21Vc2VyU3RhdHVzLCAmbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgIHVzbVVzZXJFbmdpbmVJRCwgdXNtVXNlckVuZ2luZUlETGVuLCBhcmd2W2FyZ10pOwogICAgICAgIGxvbmd2YXIgPSBSU19OT1RJTlNFUlZJQ0U7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgdXNtVXNlclN0YXR1cywgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSLCAodV9jaGFyICopICYgbG9uZ3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKGxvbmd2YXIpKTsKI2lmIGRlZmluZWQoSEFWRV9PUEVOU1NMX0RIX0gpICYmIGRlZmluZWQoSEFWRV9MSUJDUllQVE8pCiAgICB9IGVsc2UgaWYgKHN0cmNtcChhcmd2W2FyZ10sIENNRF9DSEFOR0VLRVlfTkFNRSkgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogY2hhbmdlIHRoZSBrZXkgb2YgYSB1c2VyIGlmIERIIGlzIGF2YWlsYWJsZQogICAgICAgICAqLwoKICAgICAgICBjaGFyICpwYXNzd2RfdXNlcjsKICAgICAgICBuZXRzbm1wX3BkdSAqZGhwZHUsICpkaHJlc3BvbnNlID0gTlVMTDsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsICpkaHZhcjsKICAgICAgICAKICAgICAgICBjb21tYW5kID0gQ01EX0NIQU5HRUtFWTsKICAgICAgICBuYW1lX2xlbmd0aCA9IERIX1VTTV9PSURfTEVOOwogICAgICAgIG5hbWVfbGVuZ3RoMiA9IERIX1VTTV9PSURfTEVOOwoKICAgICAgICBwYXNzd2RfdXNlciA9IGFyZ3ZbKythcmddOwoKICAgICAgICBpZiAoZG9wcml2a2V5ID09IDAgJiYgZG9hdXRoa2V5ID09IDApCiAgICAgICAgICAgIGRvcHJpdmtleSA9IGRvYXV0aGtleSA9IDE7CgogICAgICAgIC8qIAogICAgICAgICAqIENoYW5nZSB0aGUgdXNlciBzdXBwbGllZCBvbiBjb21tYW5kIGxpbmUuCiAgICAgICAgICovCiAgICAgICAgaWYgKChwYXNzd2RfdXNlciAhPSBOVUxMKSAmJiAoc3RybGVuKHBhc3N3ZF91c2VyKSA+IDApKSB7CiAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lID0gcGFzc3dkX3VzZXI7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVXNlIG93biBrZXkgb2JqZWN0IGlmIG5vIHVzZXIgd2FzIHN1cHBsaWVkLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZGhhdXRoS2V5Q2hhbmdlID0gdXNtREhVc2VyT3duQXV0aEtleUNoYW5nZTsKICAgICAgICAgICAgZGhwcml2S2V5Q2hhbmdlID0gdXNtREhVc2VyT3duUHJpdktleUNoYW5nZTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZG8gd2UgaGF2ZSBhIHNlY3VyaXR5TmFtZT8gIElmIG5vdCwgY29weSB0aGUgZGVmYXVsdCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc2Vzc2lvbi5zZWN1cml0eU5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSA9IAoJICAgICAgc3RyZHVwKG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAoJCQkJCSAgIE5FVFNOTVBfRFNfTElCX1NFQ05BTUUpKTsKICAgICAgICB9CgogICAgICAgIC8qIGZldGNoIHRoZSBuZWVkZWQgZGlmZmllIGhlbG1hbiBwYXJhbWV0ZXJzICovCiAgICAgICAgZGhwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUKTsKICAgICAgICBpZiAoIWRocGR1KSB7CiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiRmFpbGVkIHRvIGNyZWF0ZSBESCByZXF1ZXN0XG4iKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CgogICAgICAgIC8qIGdldCB0aGUgY3VycmVudCBESCBwYXJhbWV0ZXJzICovCiAgICAgICAgc25tcF9hZGRfbnVsbF92YXIoZGhwZHUsIHVzbURIUGFyYW1ldGVycywgdXNtREhQYXJhbWV0ZXJzX2xlbik7CiAgICAgICAgCiAgICAgICAgLyogbWF5YmUgdGhlIGF1dGgga2V5IHB1YmxpYyB2YWx1ZSAqLwogICAgICAgIGlmIChkb2F1dGhrZXkpIHsKICAgICAgICAgICAgc2V0dXBfb2lkKGRoYXV0aEtleUNoYW5nZSwgJm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLnNlY3VyaXR5TmFtZSk7CiAgICAgICAgICAgIHNubXBfYWRkX251bGxfdmFyKGRocGR1LCBkaGF1dGhLZXlDaGFuZ2UsIG5hbWVfbGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgICAgIAogICAgICAgIC8qIG1heWJlIHRoZSBwcml2IGtleSBwdWJsaWMgdmFsdWUgKi8KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CiAgICAgICAgICAgIHNldHVwX29pZChkaHByaXZLZXlDaGFuZ2UsICZuYW1lX2xlbmd0aDIsCiAgICAgICAgICAgICAgICAgICAgICB1c21Vc2VyRW5naW5lSUQsIHVzbVVzZXJFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24uc2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgc25tcF9hZGRfbnVsbF92YXIoZGhwZHUsIGRocHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyKTsKICAgICAgICB9CgogICAgICAgIC8qIGZldGNoIHRoZSB2YWx1ZXMgKi8KICAgICAgICBzdGF0dXMgPSBzbm1wX3N5bmNoX3Jlc3BvbnNlKHNzLCBkaHBkdSwgJmRocmVzcG9uc2UpOwoKICAgICAgICBpZiAoc3RhdHVzICE9IFNOTVBFUlJfU1VDQ0VTUyB8fCBkaHJlc3BvbnNlID09IE5VTEwgfHwKICAgICAgICAgICAgZGhyZXNwb25zZS0+ZXJyc3RhdCAhPSBTTk1QX0VSUl9OT0VSUk9SIHx8CiAgICAgICAgICAgIGRocmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSAhPSBBU05fT0NURVRfU1RSKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXB1c20iLCBzcyk7CiAgICAgICAgICAgIGlmIChkaHJlc3BvbnNlICYmIGRocmVzcG9uc2UtPnZhcmlhYmxlcyAmJgogICAgICAgICAgICAgICAgZGhyZXNwb25zZS0+dmFyaWFibGVzLT50eXBlICE9IEFTTl9PQ1RFVF9TVFIpIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLAogICAgICAgICAgICAgICAgICAgICAgICAiQ2FuJ3QgZ2V0IGRpZmZpZS1oZWxtYW4gZXhjaGFuZ2UgZnJvbSB0aGUgYWdlbnRcbiIpOwogICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIChtYXliZSBpdCBkb2Vzbid0IHN1cHBvcnQgdGhlIFNOTVAtVVNNLURILU9CSkVDVFMtTUlCIE1JQilcbiIpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGV4aXR2YWwgPSAxOwogICAgICAgICAgICBnb3RvIGJlZ29uZTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgZGh2YXIgPSBkaHJlc3BvbnNlLT52YXJpYWJsZXM7CiAgICAgICAgdmFycyA9IGRodmFyLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIC8qIGNvbXBsZXRlIHRoZSBESCBlcXVhdGlvbiAmIHByaW50IHJlc3VsdGluZyBrZXlzICovCiAgICAgICAgaWYgKGRvYXV0aGtleSkgewogICAgICAgICAgICBpZiAoZ2V0X1VTTV9ESF9rZXkodmFycywgZGh2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY19nZXRfcHJvcGVybGVuZ3RoKHNzLT5zZWN1cml0eUF1dGhQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3MtPnNlY3VyaXR5QXV0aFByb3RvTGVuKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdSwgImF1dGgiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGhhdXRoS2V5Q2hhbmdlLCBuYW1lX2xlbmd0aCkgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgZ290byBiZWdvbmU7CiAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0KICAgICAgICBpZiAoZG9wcml2a2V5KSB7CgkgICAgc2l6ZV90IGRocHJpdktleUxlbiA9IDA7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX0RFUwoJICAgIGlmIChJU1RSQU5TRk9STShzcy0+c2VjdXJpdHlQcml2UHJvdG8sIERFU1ByaXYpKSB7CiAgICAgICAgICAgICAgICAvKiBERVMgdXNlcyBhIDEyOCBiaXQga2V5LCA2NCBiaXRzIG9mIHdoaWNoIGlzIGEgc2FsdCAqLwoJICAgICAgICBkaHByaXZLZXlMZW4gPSAxNjsKCSAgICB9CiNlbmRpZgojaWZkZWYgSEFWRV9BRVMKCSAgICBpZiAoSVNUUkFOU0ZPUk0oc3MtPnNlY3VyaXR5UHJpdlByb3RvLCBBRVNQcml2KSkgewoJICAgICAgICBkaHByaXZLZXlMZW4gPSAxNjsKCSAgICB9CiNlbmRpZgogICAgICAgICAgICBpZiAoZ2V0X1VTTV9ESF9rZXkodmFycywgZGh2YXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaHByaXZLZXlMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUsICJwcml2IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRocHJpdktleUNoYW5nZSwgbmFtZV9sZW5ndGgyKQogICAgICAgICAgICAgICAgIT0gU05NUEVSUl9TVUNDRVNTKQogICAgICAgICAgICAgICAgZ290byBiZWdvbmU7CiAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlOwogICAgICAgIH0KICAgICAgICAvKiBzbm1wX2ZyZWVfcGR1KGRocmVzcG9uc2UpOyAqLyAvKiBwYXJ0cyBzdGlsbCBpbiB1c2Ugc29tZXdoZXJlICovCiNlbmRpZiAvKiBIQVZFX09QRU5TU0xfREhfSCAmJiBIQVZFX0xJQkNSWVBUTyAqLwogICAgfSBlbHNlIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlVua25vd24gY29tbWFuZFxuIik7CiAgICAgICAgdXNhZ2UoKTsKICAgICAgICBleGl0KDEpOwogICAgfQoKICAgIC8qCiAgICAgKiBhZGQgdXNtVXNlclB1YmxpYyBpZiBzcGVjaWZpZWQgKHZpYSAtQ3ApCiAgICAgKi8KICAgIGlmICh1c21Vc2VyUHVibGljX3ZhbCkgewogICAgICAgIG5hbWVfbGVuZ3RoID0gVVNNX09JRF9MRU47CglzZXR1cF9vaWQodXNtVXNlclB1YmxpYywgJm5hbWVfbGVuZ3RoLAoJCSAgdXNtVXNlckVuZ2luZUlELCB1c21Vc2VyRW5naW5lSURMZW4sCgkJICBzZXNzaW9uLnNlY3VyaXR5TmFtZSk7Cglzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCB1c21Vc2VyUHVibGljLCBuYW1lX2xlbmd0aCwKCQkJICAgICAgQVNOX09DVEVUX1NUUiwgdXNtVXNlclB1YmxpY192YWwsIAoJCQkgICAgICBzdHJsZW4odXNtVXNlclB1YmxpY192YWwpKTsJICAKICAgIH0KCiAgICAvKgogICAgICogZG8gdGhlIHJlcXVlc3QgCiAgICAgKi8KICAgIHN0YXR1cyA9IHNubXBfc3luY2hfcmVzcG9uc2Uoc3MsIHBkdSwgJnJlc3BvbnNlKTsKICAgIGlmIChzdGF0dXMgPT0gU1RBVF9TVUNDRVNTKSB7CiAgICAgICAgaWYgKHJlc3BvbnNlKSB7CiAgICAgICAgICAgIGlmIChyZXNwb25zZS0+ZXJyc3RhdCA9PSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZG91dCwgIiVzXG4iLCBzdWNjZXNzTm90ZXNbY29tbWFuZCAtIDFdKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiRXJyb3IgaW4gcGFja2V0LlxuUmVhc29uOiAlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9lcnJzdHJpbmcocmVzcG9uc2UtPmVycnN0YXQpKTsKICAgICAgICAgICAgICAgIGlmIChyZXNwb25zZS0+ZXJyaW5kZXggIT0gMCkgewogICAgICAgICAgICAgICAgICAgIGludCAgICAgICAgICAgICBjb3VudDsKICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnM7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJGYWlsZWQgb2JqZWN0OiAiKTsKICAgICAgICAgICAgICAgICAgICBmb3IgKGNvdW50ID0gMSwgdmFycyA9IHJlc3BvbnNlLT52YXJpYWJsZXM7CiAgICAgICAgICAgICAgICAgICAgICAgICB2YXJzICYmIGNvdW50ICE9IHJlc3BvbnNlLT5lcnJpbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgIHZhcnMgPSB2YXJzLT5uZXh0X3ZhcmlhYmxlLCBjb3VudCsrKQogICAgICAgICAgICAgICAgICAgICAgICAvKkVNUFRZKi87CiAgICAgICAgICAgICAgICAgICAgaWYgKHZhcnMpCiAgICAgICAgICAgICAgICAgICAgICAgIGZwcmludF9vYmppZChzdGRlcnIsIHZhcnMtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJzLT5uYW1lX2xlbmd0aCk7CiAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJcbiIpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZXhpdHZhbCA9IDI7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgaWYgKHN0YXR1cyA9PSBTVEFUX1RJTUVPVVQpIHsKICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlRpbWVvdXQ6IE5vIFJlc3BvbnNlIGZyb20gJXNcbiIsCiAgICAgICAgICAgICAgICBzZXNzaW9uLnBlZXJuYW1lKTsKICAgICAgICBleGl0dmFsID0gMTsKICAgIH0gZWxzZSB7ICAgICAgICAgICAgICAgICAgICAvKiBzdGF0dXMgPT0gU1RBVF9FUlJPUiAqLwogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBzZXQiLCBzcyk7CiAgICAgICAgZXhpdHZhbCA9IDE7CiAgICB9CgojaWYgZGVmaW5lZChIQVZFX09QRU5TU0xfREhfSCkgJiYgZGVmaW5lZChIQVZFX0xJQkNSWVBUTykKICBiZWdvbmU6CiNlbmRpZiAvKiBIQVZFX09QRU5TU0xfREhfSCAmJiBIQVZFX0xJQkNSWVBUTyAqLwogICAgaWYgKHJlc3BvbnNlKQogICAgICAgIHNubXBfZnJlZV9wZHUocmVzcG9uc2UpOwogICAgc25tcF9jbG9zZShzcyk7CiAgICBTT0NLX0NMRUFOVVA7CiAgICByZXR1cm4gZXhpdHZhbDsKfQo=